行业资讯

opencv的模板匹配

发布时间:2026/8/25 5:54:40
opencv的模板匹配 看到有人用opencv的模板匹配其实更多的是相关系数匹配!从前讲了很多相关系数就是没去做其实就是计算复杂度太大不值得那是刚好实现了基于形状轮廓的匹配心思不在opencv上而且一直从底层写起故而只学习opencv从来很少调用opencv到目前为止从2011接触opencv算起屈指可数用过的opencv调用1人脸识别这个自己实在写不出来或许不是写不出只是一门心思在机器视觉上机器视觉都全部完成了所以不是写不出来的问题是学习舍得之道2自己的机器视觉中用到canny写了很多版本接近opencv canny所以偶尔做对比时把玩其精髓为何3就是昨天今天用的这个cvtemplateMatch即就是ncc相关系数匹配opencv像一个老朋友陪伴15年了虽然opencv版本已经足够好足够多我还是用这个十几兆的opencv1.0好回归正题匹配关键在速度和稳定性以及精确度这是工业机器视觉的硬指标我们的兴趣在于最初的理想先使用笨方法不拐弯的直觉实现然后一步一步达成上面的三个硬指标好我们先达成第一虽然我们说的是ncc但一写起代码我就惯性思维到轮廓匹配实现走了弯路实际opencv很直接简单人家是模板匹配你非要把自己的轮廓再还原成图像模板再匹配这是退步第二原图不容易旋转只旋转roi图像模板中提炼的轮廓点这个当量极其小而ncc是旋转原图像假定中心旋转roi图像模板不旋转今天想明白这个道理roi图像旋转会出现不必要的补足像素而这些补足像素不在原图中所以匹配失败是必然的好纠正了这两步这就回归了opencv模板匹配正道1我的相机是5472*3648如果在这样的图像里取模板匹配工业现场就得挂机2我们高斯平滑后每4行4列取一个像素图像变成1368*912这就是他们说的金字塔图像3最关键我们就在这个1368*912中取模板并完成匹配为什么这个可以他的原理是高斯核是构建尺度缩放空间变换的唯一线性核尺度空间 图像G(x,y,σ) 定义为原始图像 I(x,y) 与高斯核 σ 的卷积筹备和证明整理-CSDN博客好opencv代码很简单a把1368*912处理成canny图像这里截图出来的模板就是canny图像道理很简单我们用二值特征图像获取模板然后在回二值特征图像匹配b我们完成的是-45度的匹配二值特征图像很方便旋转处理注意2436844这个绿框的起始点我们用来验证匹配结果610211你乘以4等于2440844他返回最大值以上是0度匹配我们看看1度2度3度结果最大值以及对应的坐标这幅图像静止还没动可以知道旋转45度只有0度最好因为opencv给出最大值为最佳匹配结果显然图像动一动比如10度那么再做一次0-45度旋转可以预见10最好!这样我们就简单粗暴的实现了opencv的ncc相关系数匹配opencv 相关系数匹配源代码如下IplImage* pTest8bytecvCreateImage(cvSize(localww1per4,localhh1per4 ),8,1);//使用了8位灰度图像cvSetData(pTest8byte,temp_buffer256192,localww1per4);//测试成功ok201911101905IplImage* cannyimgcvCreateImage(cvSize(pTest8byte-width,pTest8byte-height),8,1);cvCanny(pTest8byte,cannyimg,50,150,3);//cvSaveImage(c:\\opencvcannyimg202407251047.bmp,cannyimg);memcpy(globgaospydoutimgN精细for90,cannyimg-imageDataOrigin,localww1per4*localhh1per4);//canny图像也是255及0二值图像吗// //范例opencv// //读取图像和模板// IplImage* img cvLoadImage(input.jpg, CV_LOAD_IMAGE_GRAYSCALE);//IplImage* templ cvLoadImage(template.jpg, CV_LOAD_IMAGE_GRAYSCALE);IplImage* templ;IplImage* result;//for(int cv0;cv91;cv)//先完成一个0度匹配试一试opencv的函数// {//IplImage*templcvCreateImage(cvSize(globroiww, globroihh ),8,1);//使用了8位灰度图像,模板图像cvSetData(templ, globroiImg,globroiww);////使用 matchTemplate 进行匹配listCvPoint lp ;listdouble lpValue ;for(int m_baoguang0;m_baoguang45;m_baoguang){int 输出w0;int 输出h0;byte * 输出图像;double 弧度m_baoguang*3.1415926/180;//旋转0-45度//请确认是角度弧度//弧度RotateNormal((BYTE *)cannyimg-imageDataOrigin,输出图像, localww1per4, localhh1per4,//1368*912图像输出w,输出h,弧度);//IplImage*result cvCreateImage(cvSize(输出w - templ-width 1, 输出h - templ-height 1), IPL_DEPTH_32F, 1);IplImage* pTest8byteMcvCreateImage(cvSize(输出w,输出h ),8,1);//使用了8位灰度图像cvSetData(pTest8byteM,输出图像,输出w);//测试成功ok201911101905//ncc匹配//这里的cannyimg要旋转并记录每个角度的成绩和位置cvMatchTemplate(pTest8byteM, templ, result,CV_TM_CCOEFF);cvReleaseImage(pTest8byteM);CvPoint minLoc, maxLoc;double minVal, maxVal;cvMinMaxLoc(result, minVal, maxVal, minLoc, maxLoc, 0);lpValue.push_back(maxVal);lp.push_back(maxLoc);}for(int i315;i359;i){}opencv模板学习代码如下IplImage* pTest8bytecvCreateImage(cvSize(localww1per4,localhh1per4 ),8,1);//使用了8位灰度图像cvSetData(pTest8byte,temp_buffer256192,localww1per4);//测试成功ok201911101905IplImage* cannyimgcvCreateImage(cvSize(pTest8byte-width,pTest8byte-height),8,1);cvCanny(pTest8byte,cannyimg,50,150,3);//cvSaveImage(c:\\opencvcannyimg202407251047.bmp,cannyimg);memcpy(globgaospydoutimgN精细for45,cannyimg-imageDataOrigin,localww1per4*localhh1per4);//cannyimg-imageData好于imageDataOrigin,要做测试是否要改byte* roiImage new byte[roiww * roihh];this-globroiImg new byte[roiww * roihh];globroiwwroiww;globroihhroihh;int te roitop * localww1per4 roileft;for (int i 0; i roihh; i)for (int j 0; j roiww; j){globroiImg[i * roiww j] roiImage[i * roiww j] globgaospydoutimgN精细for45[i * localww1per4 j te ];}图像旋转源码机器视觉入门之路十六完成图像旋转c_机器视觉中怎么把左下角的图一到右上角-CSDN博客