void TLD::bbPredict(const vector<cv::Point2f>& points1,const vector<cv::Point2f>& points2, const BoundingBox& bb1,BoundingBox& bb2) { int npoints = (int)points1.size(); vector<float> xoff(npoints); vector<float> yoff(npoints); printf("tracked points : %d\n",npoints); for (int i=0;i<npoints;i++){ xoff[i]=points2[i].x-points1[i].x; yoff[i]=points2[i].y-points1[i].y; } float dx = median(xoff); float dy = median(yoff); float s; if (npoints>1){ vector<float> d; d.reserve(npoints*(npoints-1)/2); for (int i=0;i<npoints;i++){ for (int j=i+1;j<npoints;j++){ d.push_back(norm(points2[i]-points2[j])/norm(points1[i]-points1[j])); } } s = median(d); } else { s = 1.0; } float s1 = 0.5*(s-1)*bb1.width; float s2 = 0.5*(s-1)*bb1.height; printf("s= %f s1= %f s2= %f \n",s,s1,s2); bb2.x = round( bb1.x + dx -s1); bb2.y = round( bb1.y + dy -s2); bb2.width = round(bb1.width*s); bb2.height = round(bb1.height*s); printf("predicted bb: %d %d %d %d\n",bb2.x,bb2.y,bb2.br().x,bb2.br().y); }
void Detector::generateScanGrids(const BoundingBox& initBoundingBox) { vector<Size> gridSizes; Size bbSize = initBoundingBox.size(); double scale = 1.0; while (bbSize.width <= frame.cols && bbSize.height <= frame.rows) { gridSizes.push_back(bbSize); scale *= 1.2; bbSize = Size((int)(initBoundingBox.width * scale + 0.5), (int)(initBoundingBox.height * scale + 0.5)); } scale = 1.0 / STEP_S; bbSize = Size((int)(initBoundingBox.width * scale + 0.5), (int)(initBoundingBox.height * scale + 0.5)); //while (bbSize.width * bbSize.height >= MIN_BB_AREA) while (bbSize.width >= MIN_BB_SIDE && bbSize.height >= MIN_BB_SIDE) { gridSizes.push_back(bbSize); scale /= 1.2; bbSize = Size((int)(initBoundingBox.width * scale + 0.5), (int)(initBoundingBox.height * scale + 0.5)); } //int stepH = (int)(STEP_H * frame.cols + 0.5); //int stepV = (int)(STEP_V * frame.rows + 0.5); BoundingBox patch; for (vector<Size>::const_iterator scaleIt = gridSizes.begin(); scaleIt != gridSizes.end(); ++scaleIt) { patch.width = scaleIt->width; patch.height = scaleIt->height; int minSide = min(scaleIt->width, scaleIt->height); //int stepH = (int)(STEP_H * scaleIt->width + 0.5); //int stepV = (int)(STEP_V * scaleIt->height + 0.5); int stepH = (int)(STEP_H * minSide + 0.5); int stepV = (int)(STEP_V * minSide + 0.5); #ifdef DEBUG assert(stepH >= 1 && stepV >= 1); #endif for (patch.y = 0; patch.br().y < frame.rows; patch.y += stepV) { for (patch.x = 0; patch.br().x < frame.cols; patch.x += stepH) { patch.refreshOverlap(initBoundingBox); scanGrids.push_back(patch); } } } }
//利用剩下的不到一半的跟踪点输入来预测bounding box在当前帧的位置和大小 void TLD::bbPredict(const vector<cv::Point2f>& points1,const vector<cv::Point2f>& points2, const BoundingBox& bb1,BoundingBox& bb2) { int npoints = (int)points1.size(); vector<float> xoff(npoints);//位移 vector<float> yoff(npoints); printf("tracked points : %d\n",npoints); for (int i=0;i<npoints;i++){//计算每个特征点在两帧之间的位移 xoff[i]=points2[i].x-points1[i].x; yoff[i]=points2[i].y-points1[i].y; } float dx = median(xoff);//计算位移的中值 float dy = median(yoff); float s; //计算bounding box尺度scale的变化 //通过计算当前特征点相互间的距离与上一帧特征点相互间的距离的 //比值,以比值的中值作为尺度的变化因子 if (npoints>1){ vector<float> d; d.reserve(npoints*(npoints-1)/2); for (int i=0;i<npoints;i++){ for (int j=i+1;j<npoints;j++){ d.push_back(norm(points2[i]-points2[j])/norm(points1[i]-points1[j])); } } s = median(d); } else { s = 1.0; } float s1 = 0.5*(s-1)*bb1.width; float s2 = 0.5*(s-1)*bb1.height; printf("s= %f s1= %f s2= %f \n",s,s1,s2); //得到当前bounding box的位置与大小信息 //当前box的x坐标 = 前一帧box的x坐标 + 全部特征点位移的中值 - 当前box宽的一半 bb2.x = round( bb1.x + dx -s1); bb2.y = round( bb1.y + dy -s2); bb2.width = round(bb1.width*s); bb2.height = round(bb1.height*s); printf("predicted bb: %d %d %d %d\n",bb2.x,bb2.y,bb2.br().x,bb2.br().y); }
double PatchVariance::computeVariance(const BoundingBox& patch) const { double sum = integralImg.at<double>(patch.br()) - integralImg.at<double>(patch.br().y, patch.x) - integralImg.at<double>(patch.y, patch.br().x) + integralImg.at<double>(patch.tl()); double sumSq = sqIntegralImg.at<double>(patch.br()) - sqIntegralImg.at<double>(patch.br().y, patch.x) - sqIntegralImg.at<double>(patch.y, patch.br().x) + sqIntegralImg.at<double>(patch.tl()); return sumSq / patch.area() - pow(sum / patch.area(), 2); }