一、概述
我们在实际中如何应用这些轮廓呢?比如,有两个轮廓如何进行比较匹配,或者如何比较一个轮廓和一个抽象模板。比较两个轮廓最简洁的方式是比较它们的轮廓矩。矩是通过对轮廓上所有点进行积分运算(或者认为是求和运算)而得到的一个粗略特征。
二、矩及Hu矩的结构体
typedef struct CvMoments
{
double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; /* spatial moments */
double mu20, mu11, mu02, mu30, mu21, mu12, mu03; /* central moments */
double inv_sqrt_m00; /* m00 != 0 ? 1/sqrt(m00) : 0 */
}CvMoments;
//Hu矩
typedef struct CvHuMoments
{
double hu1, hu2, hu3, hu4, hu5, hu6, hu7; /* Hu invariants */
}
CvHuMoments;
三、相关函数
1、计算轮廓矩
void cvContoursMoments(CvSeq* contour, CvMoments* moments)
contour
要处理的轮廓
moments
指向一个结构,该结构用于保存生成的结果。
在二值图像的情况下,M00表示区域的面积。令Xc,Yc表示区域重心的坐标,则:Xc = M10/M00;
Yc = M01/M00;
2、计算7 Hu 不变量
void cvGetHuMoments( CvMoments* moments, CvHuMoments* hu_moments );
moments
矩状态结构的指针
hu_moments
Hu 矩结构的指针.
函数 cvGetHuMoments 计算 7 个 Hu 不变量,它们的定义是:
h1=η20+η02
h2=(η20-η02)2+4η112
h3=(η30-3η12)2+ (3η21-η03)2
h4=(η30+η12)2+ (η21+η03)2
h5=(η30-3η12)(η30+η12)[(η30+η12)2-3(η21+η03)2]+(3η21-η03)(η21+η03)[3(η30+η12)2-(η21+η03)2]
h6=(η20-η02)[(η30+η12)2- (η21+η03)2]+4η11(η30+η12)(η21+η03)
h7=(3η21-η03)(η21+η03)[3(η30+η12)2-(η21+η03)2]-(η30-3η12)(η21+η03)[3(η30+η12)2-(η21+η03)2]
这些值被证明为对图像缩放、旋转和反射的不变量。对反射,第7个除外,因为它的符号会因为反射而改变。
3、使用Hu矩进行匹配
double cvMatchShapes( const void* object1, const void* object2, int method, double parameter=0 );
object1
第一个轮廓或灰度图像
object2
第二个轮廓或灰度图像
method
比较方法,其中之一 CV_CONTOUR_MATCH_I1, CV_CONTOURS_MATCH_I2 or CV_CONTOURS_MATCH_I3.
parameter
比较方法的参数 (目前不用).
函数 cvMatchShapes 比较两个形状。 三个实现方法全部使用 Hu 矩
method=CV_CONTOUR_MATCH_I1:
method=CV_CONTOUR_MATCH_I2:
method=CV_CONTOUR_MATCH_I3: