矩是概率统计里的概念,然而他在轮廓分析里也很有用,其中比较著名要数Hu矩了。下面我们来看矩的定义:
定义一个轮廓x为p阶,y为q阶的公式为:
OPENCV提供计算各阶的函数为
void cvContoursMoments(CvSeq*contour, CvMoments*moments)
其中矩的结构体为:
typedef struct CvMoments{
//spatial moments
double m00,m10,m01,m20,m11,m02,m30,m21,m12,m03;
//central moments
double mu20,mu11,mu02,mu30,mu21,mu12,mu03;
//m00!=0?1/sqrt(m00):0
double inv_sqrt_m00;
}CvMoments;
从这个结构体中获得各阶矩的函数为:
double cvGetSpatialMoment(CvMoments*moments, Int x_order, int y_order);
然而在轮廓相似性比较的时候,仅仅有矩是不够的,还需要进行坐标系的统一,以及值的归一化,这就有了Hu不变矩(Hu invariant moments)即七个由归一化中心矩组合成的矩:
其中中心矩和归一化中心矩的定义为:
由OPENCV提供计算中心距、归一化中心距和hu矩的函数为:
void cvMoments(const CvArr*image, CvMoments*moments,int isBinary=0)
double cvGetCentralMoment(CvMoments*moments,int x_order,int y_order)
double cvGetNormalizedCentralMoment(CvMoments*moments,int x_order,int y_order);
void cvGetHuMoments(CvMoments*moments,CvHuMoments*HuMoments);
其中cvMoments和上面的cvContourMoments是同一个函数。
同时OPENCV还提供了输入图像直接进行hu矩匹配的函数是
double cvMatchShapes(const void*object1,const void*object2,int method,double parameter=0); 因此可以帮助省掉中间的步骤。
我尝试了下,HU矩的效果并不是很好,字母旋转后的hu矩变化还是很大的,有时候会比两个不同的字母的距离还大!