opencv实战从0到N (7)—— 模板匹配,形状匹配

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

opencv实战从0到N (7)—— 模板匹配,形状匹配

模板匹配,形状匹配

1,区域像素值匹配

利用模板图像像卷积一样遍历整幅图像,以某种比对方式(距离差之和,相关度等)计算相似度,

在结果图像上寻找最大或最小值(方法不同有些值越大越相似,有些相反)作为匹配结果。

函数:matchTemplate(src, templ, result, match_method)

Mat TempleMatch(int match_method, Mat&templ, Mat&img, Point& matchLoc, double* matchValue)

{



    bool use_mask = false;

    Mat result, mask;



    bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method ==                     CV_TM_CCORR_NORMED);

    if (use_mask && method_accepts_mask)

    {
    
    matchTemplate(img, templ, result, match_method, mask);

    }

    else

    {

    matchTemplate(img, templ, result, match_method);

    }



/// Localizing the best match with minMaxLoc

double minVal; double maxVal; Point minLoc; Point maxLoc;



minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());



/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better

if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED)

{

    matchLoc = minLoc;

    *matchValue = minVal;



}

else

{

    matchLoc = maxLoc;

    *matchValue = maxVal;

}



return result;

}

2,外形轮廓匹配

先求出模板的轮廓,求轮廓的矩特征。再求出搜索图的所有轮廓及特征,与模板的轮廓特征

比较,差值最小的即为匹配结果。

函数:matchShapes(contours1, contours2, CV_CONTOURS_MATCH_I1, 0.0);


int ShapeMatch(Mat& srcImg, Mat& srcImg2)

{

cvtColor(srcImg, srcImg, CV_BGR2GRAY);

threshold(srcImg, srcImg, 150, 255, CV_THRESH_BINARY);

vector<vector<Point>> contours;

vector<Vec4i> hierarcy;

findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);



Mat src_gray;

cvtColor(srcImg2, src_gray, CV_BGR2GRAY);

threshold(src_gray, src_gray, 150, 255, CV_THRESH_BINARY);

vector<vector<Point>> contours2;

vector<Vec4i> hierarcy2;

findContours(src_gray, contours2, hierarcy2, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);



for (int i = 0; i<contours2.size(); i++)

{

double matchRate = matchShapes(contours[0], contours2[i], CV_CONTOURS_MATCH_I1, 0.0);//形状匹配:值越小越相似

if (matchRate <= 0.1)

{

drawContours(srcImg2, contours2, i, Scalar(0, 255, 0), 2, 8);

}

}



imwrite("dst.jpg", srcImg2);

return 0;



}

3.模板匹配测试:

bool use_mask;

Mat img; Mat templ; Mat mask; Mat result;

const char* image_window = "Source Image";

const char* result_window = "Result window";

int match_method;

int max_Trackbar = 5;



/// Function Headers

void MatchingMethod(int, void*);



int main(int argc, char** argv)

{



img = imread("2.jpg", IMREAD_COLOR);

templ = imread("tp.jpg", IMREAD_COLOR);



if (argc > 3) {

use_mask = true;

mask = imread(argv[3], IMREAD_COLOR);

}



if (img.empty() || templ.empty() || (use_mask && mask.empty()))

{

cout << "Can't read one of the images" << endl;

return -1;

}

/// Create windows

namedWindow(image_window, WINDOW_AUTOSIZE);

namedWindow(result_window, WINDOW_AUTOSIZE);

/// Create Trackbar

const char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";

createTrackbar(trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod);

//! [create_trackbar]



MatchingMethod(0, 0);

//! [wait_key]

waitKey(0);

return 0;

//! [wait_key]

}





void MatchingMethod(int, void*)

{

//! [copy_source]

/// Source image to display

Mat img_display;

img.copyTo(img_display);

/// Create the result matrix

int result_cols = img.cols - templ.cols + 1;

int result_rows = img.rows - templ.rows + 1;

result.create(result_rows, result_cols, CV_32FC1);

/// Do the Matching and Normalize

bool method_accepts_mask = (CV_TM_SQDIFF == match_method || match_method == CV_TM_CCORR_NORMED);

if (use_mask && method_accepts_mask)

{

matchTemplate(img, templ, result, match_method, mask);

}

else

{

matchTemplate(img, templ, result, match_method);

}



normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());



double minVal; double maxVal; Point minLoc; Point maxLoc;

Point matchLoc;

minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better

if (match_method == TM_SQDIFF || match_method == TM_SQDIFF_NORMED)

{

matchLoc = minLoc;

}

else

{

matchLoc = maxLoc;

}



rectangle(img_display, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar::all(0), 2, 8, 0);

rectangle(result, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar::all(0), 2, 8, 0);

imshow(image_window, img_display);

imshow(result_window, result);



return;

}

更多内容关注微信公众号:ML_Study

猜你喜欢

转载自blog.csdn.net/qq_34106574/article/details/93773224