【opencv】邻域模版匹配

来源:互联网 发布:full node bitcoin 编辑:程序博客网 时间:2024/06/09 21:10

opencv的matchTemplate函数是对整幅图片进行运算,运算量较大。本文接上篇内容,即:

http://blog.csdn.net/qq_15947787/article/details/55260002

对于SURF目标检测中的多目标,通过鼠标左键单击事件,获得点击的图像坐标,计算当前图像中检测到的离点击位置最近的目标作为模版。

上篇中提到了动态背景下运动目标的检测,但是SURF运算量较大,也并不能做为跟踪使用,因此打算采用模版匹配进行跟踪,为了提高跟踪速度以及准确性,将上一帧图片检测到的目标作为模版,邻域面积的大小为模版面积大小的mul*mul倍。

于是编写了matchTemplateROI函数

image为待寻找目标的图像,而templ是上一帧图像中的目标,即模版,templpos即模版的位置以及大小,函数调用结束后,templ与templpos更新,再次读入下一帧图片,即可。

 

//************************************// Description: 模版匹配,在ROI区域中寻找templ,并可迭代// Method:    matchTemplateROI// FullName:  matchTemplateROI// Access:    public // Parameter: Mat & image 下一帧图像// Parameter: Mat & templ 上一帧图像中的模版,函数调用结束后为下一帧图像中的模版// Parameter: Rect & templpos 上一帧图像中模版的位置以及大小,函数调用结束后为下一帧图像中模版的位置以及大小// Parameter: float mul 邻域边长与模版变长的倍数,大于1// Returns:   void// Author:    小白// Date:      2017/02/23// History://************************************void matchTemplateROI(Mat& image, Mat& templ, Rect& templpos, float mul){    //! type of the template matching operation    //enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 };    //! computes the proximity map for the raster template and the image where the template is searched for    //CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ, OutputArray result, int method );    Rect ROI;    ROI.x = templpos.x - (templpos.width * mul - templpos.width)/2;    ROI.y = templpos.y - (templpos.height * mul - templpos.height)/2;    ROI.width = templpos.width * mul;    ROI.height = templpos.height * mul;    Mat linyu(image, ROI);//邻域    int Wresult, Hresult;    Wresult = linyu.cols - templ.cols + 1;    Hresult = linyu.rows - templ.rows + 1;    Mat result;//matchTemplate的输出 OutputArray result    result.create(Wresult, Hresult, CV_32FC1);    matchTemplate(linyu, templ, result, TM_SQDIFF_NORMED);    double minVal, maxVal;    Point minLoc, maxLoc;    minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);      templpos.x = minLoc.x + ROI.x;    templpos.y = minLoc.y + ROI.y;    templ = image(templpos);    rectangle(image, Point(ROI.x, ROI.y), Point(ROI.x + ROI.width, ROI.y + ROI.height), Scalar(255,0,0), 2, 8, 0);    rectangle(image, Point(minLoc.x + ROI.x, minLoc.y + ROI.y), Point(minLoc.x + templpos.width + ROI.x, minLoc.y + templpos.height + ROI.y),Scalar(0,0,255), 2, 8, 0);    imshow("image", image);    }

上面蓝框是搜索的邻域,红框是在邻域中找到的目标,也可以换一种方式绘制找到的目标位置。

int s = 15;    if (minLoc.x + ROI.x + templpos.width/2 - 1.5 * s > 0 && minLoc.y + ROI.y + templpos.height/2 - 1.5 * s > 0 && minLoc.x + ROI.x + templpos.width/2 + 1.5 * s < image.cols && minLoc.y + ROI.y + templpos.height/2 + 1.5 * s < image.rows)    {        rectangle(image, Point(minLoc.x + ROI.x + templpos.width/2 - s, minLoc.y + ROI.y + templpos.height/2 - s), Point(minLoc.x + ROI.x + templpos.width/2 + s, minLoc.y + ROI.y + templpos.height/2 + s), Scalar(0,0,255), 1, 8, 0);        line(image, Point(minLoc.x + ROI.x + templpos.width/2, minLoc.y + ROI.y + templpos.height/2 - 1.5 * s), Point(minLoc.x + ROI.x + templpos.width/2, minLoc.y + ROI.y + templpos.height/2 - 0.5 * s), Scalar(0,0,255), 1, 8, 0);        line(image, Point(minLoc.x + ROI.x + templpos.width/2 - 1.5 * s, minLoc.y + ROI.y + templpos.height/2), Point(minLoc.x + ROI.x + templpos.width/2 - 0.5 * s, minLoc.y + ROI.y + templpos.height/2), Scalar(0,0,255), 1, 8, 0);        line(image, Point(minLoc.x + ROI.x + templpos.width/2, minLoc.y + ROI.y + templpos.height/2 + 1.5 * s), Point(minLoc.x + ROI.x + templpos.width/2, minLoc.y + ROI.y + templpos.height/2 + 0.5 * s), Scalar(0,0,255), 1, 8, 0);        line(image, Point(minLoc.x + ROI.x + templpos.width/2 + 1.5 * s, minLoc.y + ROI.y + templpos.height/2), Point(minLoc.x + ROI.x + templpos.width/2 + 0.5 * s, minLoc.y + ROI.y + templpos.height/2), Scalar(0,0,255), 1, 8, 0);    }


替换上面的两个画矩形语句。

0 0
原创粉丝点击