昨天早上老师给了我一个图片:
![示例程序001--模板匹配 示例程序001--模板匹配](https://i-blog.csdnimg.cn/blog_migrate/a35f149da5917a522d3dcd837f002246.jpeg)
让我输出所有圆的位置。
用模板匹配的话我取了第二个圆作为模板,这样只能输出第二个圆的位置。输出5个圆的位置就要匹配5次,这实在是最笨的方法,肯定有简便的方法。今后知识面广了再回过头来看看。
老师说的二值,聚类这些概念我还没有接触过,现在只能做成这个样子了。
模板:![示例程序001--模板匹配 示例程序001--模板匹配](https://i-blog.csdnimg.cn/blog_migrate/d09faad5408423d405c830a5b769769b.jpeg)
运行结果:
![示例程序001--模板匹配 示例程序001--模板匹配](https://i-blog.csdnimg.cn/blog_migrate/2f8377500fdaa8b77d2cd08f6c535018.jpeg)
代码:
#include<cv.h>
#include<highgui.h>
#include<cvaux.h>
#include<iostream>
using namespace std;
int main()
{
//打开源图像并转灰度图像
IplImage *src=cvLoadImage("C:/Users/dzh/Desktop/模板匹配/source.jpg",1);
IplImage *srcGray=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
cvCvtColor(src,srcGray,CV_BGR2GRAY);
// cvNamedWindow("src", CV_WINDOW_AUTOSIZE);
// cvShowImage("src",srcGray);
//打开模板图片并转灰度
IplImage *temp=cvLoadImage("C:/Users/dzh/Desktop/模板匹配/temp.jpg",1); //第二个圆
// IplImage *temp=cvLoadImage("C:/Users/dzh/Desktop/模板匹配/temp1.jpg",1); //第一个圆
IplImage *tempGray=cvCreateImage(cvGetSize(temp),IPL_DEPTH_8U,1);
cvCvtColor(temp,tempGray,CV_BGR2GRAY);
// cvNamedWindow("temp",CV_WINDOW_AUTOSIZE);
// cvShowImage("temp",tempGray);
IplImage *res=0;
int w,h;
CvRect rect;
double min_val; //结果图像全局最小值
double max_val; //结果图像全局最大值
CvPoint min_loc; //结果图像全局最小值的位置
CvPoint max_loc; //结果图像全局最大值的位置
CvPoint pt1; //矩形的一个顶点
CvPoint pt2; //矩形对角线上的另一个顶点
w=src->width-temp->width; //宽度差
h=src->height-temp->height; //高度差
res=cvCreateImage(cvSize(w+1,h+1),IPL_DEPTH_32F,1); //必须为32位浮点型,IPL_DEPTH_32F(为什么)
// 以下是res尺寸不同的各种错误,现在还不知道是为什么
// res=cvCreateImage(cvSize(temp->width,temp->height),IPL_DEPTH_32F,1); //出现错误
// res=cvCreateImage(cvSize(w+1,h+1),8,1); //出现错误
// res=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_32F,1); //出现错误
// res=cvCreateImage(cvSize(w,h),IPL_DEPTH_32F,1); //出现错误
cvMatchTemplate(srcGray,tempGray,res,CV_TM_CCORR_NORMED); //模板匹配
//CV_TM_SQDIFF CV_TM_SQDIFF_NORMED CV_TM_CCORR (这三种Method的匹配效果不佳)
//CV_TM_CCORR_NORMED CV_TM_CCOEFF CV_TM_CCOEFF_NORMED (这三种Method的匹配效果完美)
// cvNamedWindow("res",CV_WINDOW_AUTOSIZE);
// cvShowImage("res",res);
cvMinMaxLoc(res,&min_val,&max_val,&min_loc,&max_loc,NULL); //找出最小值及最大值,及其位置
rect=cvRect(max_loc.x,max_loc.y,temp->width,temp->height);
pt1=cvPoint(rect.x,rect.y);
pt2=cvPoint(rect.x+rect.width,rect.y+rect.height);
cvRectangle( src,pt1, pt2, cvScalar(255,0,0),1,8,0);
//输出圆的位置
cout<<"圆的位置坐标为:"<<pt1.x<<","<<pt1.y<<endl;
cvNamedWindow("TempMatch", CV_WINDOW_AUTOSIZE);
// cvMoveWindow("mainWin", 100, 100);
cvShowImage("TempMatch", src);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&temp);
cvReleaseImage(&srcGray);
cvReleaseImage(&tempGray);
cvReleaseImage(&res);
return 0;
}