1. 程式人生 > >OpenCV入門(二十九) -- 輪廓匹配

OpenCV入門(二十九) -- 輪廓匹配

MatchShapes

比較兩個形狀

double cvMatchShapes( const void* object1, const void* object2,
                      int method, double parameter=0 );
object1
第一個輪廓或灰度影象
object2
第二個輪廓或灰度影象
method
比較方法,其中之一 CV_CONTOURS_MATCH_I1, CV_CONTOURS_MATCH_I2 or CV_CONTOURS_MATCH_I3.
parameter
比較方法的引數 (目前不用).

函式 cvMatchShapes 比較兩個形狀。 三個實現方法全部使用 Hu 矩 (見 cvGetHuMoments) (A ~ object1, B - object2):

method=CV_CONTOUR_MATCH_I1:
I_1(A,B)=\sum_{i=1}^7 |\frac{1}{m^{A_i}} - \frac{1}{m^{B_i}}|
method=CV_CONTOUR_MATCH_I2:
I_2(A,B)=\sum_{i=1}^7 | m^{A_i} - m^{B_i}|
method=CV_CONTOUR_MATCH_I3:
I_3(A,B)=\sum_{i=1}^7 \frac{|m^{A_i} - m^{B_i}|}{|m^{A_i}|}

其中

m^{A_i}=sign(h^{A_i}) \cdot \log(h^{A_i}),
m^{B_i}=sign(h^{B_i}) \cdot \log(h^{B_i}),
h^{A_i},h^{B_i} 是A 和 B的Hu矩.

實現程式碼, 接著上一節的程式碼,我們度量不用對變形逼近和用多邊形逼近找到的輪廓的匹配程度:
/*
輪廓匹配
*/

#include "highgui.h"
#include "cv.h"
#include<iostream>

using namespace std;

void doMatchCon(IplImage* img)
{
	IplImage* s =cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
	IplImage* dst = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
	IplImage* dst2 = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
	cvZero(dst);
	cvZero(dst2);
	CvMemStorage* storage = cvCreateMemStorage(0); 
	CvMemStorage* storage1 = cvCreateMemStorage(0);
	CvSeq* contour = 0;
	CvSeq* con ;
	CvSeq* mcon = NULL;
	
	cvCvtColor(img, s, CV_BGR2GRAY);
	cvThreshold(s, s, 100, 200, CV_THRESH_BINARY);
	cvFindContours(s,storage,&contour,sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
	// 不使用多邊形逼近的輪廓
	cvDrawContours(dst2, contour, CV_RGB(0,0,255), CV_RGB(0,0,255), 2,2,8, cvPoint(0,0));
	cvNamedWindow("cont",1);
	cvShowImage("cont",dst2);
	con = contour;
	while(contour != 0)
	{
		// 使用多變形逼近
		mcon = cvApproxPoly(contour, sizeof(CvContour), storage1, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0);
		cvDrawContours(dst, mcon, CV_RGB(0,0,255), CV_RGB(0,255,0), 2,2,8,cvPoint(0,0));
		contour = contour->h_next;
	}
	cvNamedWindow("contour",1);
	cvShowImage("contour",dst);

	double r = cvMatchShapes(con, mcon, 1);
	cout<<r<<endl;
}

結果: