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:
-
-
method=CV_CONTOUR_MATCH_I2:
-
-
method=CV_CONTOUR_MATCH_I3:
-
其中
-
,
-
,
-
是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;
}
结果: