一.主要目的:
钣金上有很多pin及其相似,本文想尝试使用matchTemplate 来分辨出特定位置的pin是否和正确的pin相一致。
二.模板匹配方式概要:
在OpenCv和EmguCv中支持以下6种对比方式:
CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
CV_TM_SQDIFF_NORMED 归一化平方差匹配法
CV_TM_CCORR_NORMED 归一化相关匹配法
CV_TM_CCOEFF_NORMED 归一化相关系数匹配法
三.代码
#include"opencv2\core\core.hpp"
#include"opencv2\highgui\highgui.hpp"
#include"opencv2\imgproc\imgproc.hpp"
#include<iostream>
using namespace std;
using namespace cv;
Mat src,tmpl,result;
int matchMethod = 0;
Mat src_gray,tmpl_gray;
void on_match(int,void*);
int main()
{
src = imread("D:/Develop/opencv/opencvtest/Debug/2.jpg");
tmpl = imread("D:/Develop/opencv/opencvtest/Debug/t3.jpg");
imshow("tmpl",tmpl);
if (!src.data)
return-1;
cvtColor(src,src_gray,CV_RGB2GRAY);
if (!tmpl.data)
return-1;
cvtColor(tmpl,tmpl_gray,CV_RGB2GRAY);
namedWindow("MatchImage");
namedWindow("Result");
createTrackbar("匹配算法","MatchImage",&matchMethod,5,on_match);
on_match(matchMethod,0);
waitKey();
return 0;
}
void on_match(int,void*)
{
Mat img = src_gray.clone();
matchTemplate(src_gray,tmpl_gray,result,matchMethod);
///定位
double minValue,maxValue;
Point minLoc,maxLoc;
Point matchLoc;
minMaxLoc(result,&minValue,&maxValue,&minLoc,&maxLoc,Mat());
if( matchMethod == CV_TM_SQDIFF || matchMethod == CV_TM_SQDIFF_NORMED )
{ matchLoc = minLoc; }
else
{ matchLoc = maxLoc; }
rectangle(img,matchLoc,Point(matchLoc.x+tmpl.cols,matchLoc.y+tmpl.rows),Scalar::all(0),2,8,0);
rectangle( result, matchLoc, Point( matchLoc.x + tmpl.cols , matchLoc.y + tmpl.rows ), Scalar::all(0), 2, 8, 0 );
resize(img,img,Size(800,600),0,0,CV_INTER_LINEAR); //增加后对大图也能显示
resize(result,result,Size(800,600),0,0,CV_INTER_LINEAR);
namedWindow("MatchImage",CV_WND_PROP_FULLSCREEN);
namedWindow("Result",CV_WND_PROP_FULLSCREEN);
imshow("MatchImage",img);
imshow("Result",result);
}
四.匹配图片:
左--模板 右为--识别出的位置
五. 结果表明:六种方式就第三种没识别出来,其余都能识别出来
五.这里做了个小实验,我把凹槽处涂起来了,还是识别到了。假设换个没有凹槽的相同零件,这里就区分不开来了,仍旧会被它框选出来,所以接下来,尝试通过设定相似度阀值看下能否将他们区分出来。等找来零件,拍照再试,待续!