您的位置:首页 > 其它

几何不变矩 Hu 矩

2016-02-29 17:58 316 查看

版权声明:本文为博主原创文章,未经博主允许不得转载。

几何不变矩 Hu 矩

【原文部分转载】:http://blog.csdn.net/wrj19860202/archive/2011/04/16/6327094.aspx

在连续情况下,图像函数为

,那么图像的p+q阶几何矩(标准矩)定义为:





p+q阶中心距定义为:





其中



代表图像的重心,





对于离散的数字图像,采用求和号代替积分:












分别是图像的高度和宽度;

归一化的中心距定义为:


;其中


(PS_yang: 此处的 ρ 的取值有争议,不同文献 [不变矩算法研究.丁明跃.华科] 给了不同的公式。

主要争议在于ρ后是否要加1。个人编程实践发现,加1应该是正确的选择。

个人在Hu矩原著:Visual Pattern Recognition by Moment Invariants 中没能找到原始公式。手头也没有相关书籍的详细解释,所以,暂留做疑问。还望各位读者指点。)

利用二阶和三阶归一化中心矩构造了7个不变矩















这7个不变矩构成一组特征量,Hu.M.K在1962年证明了他们具有旋转,缩放和平移不变性。

实际上,在对图片中物体的识别过程中,只有



不变性保持的比较好,其他的几个不变矩带来的误差比较大,有学者认为只有基于二阶矩的不变矩对二维物体的描述才是真正的具有旋转、缩放和平移不变性(



刚好都是由二阶矩组成的)。不过我没有证明是否是真的事这样的。

由Hu矩组成的特征量对图片进行识别,优点就是速度很快,缺点是识别率比较低,我做过手势识别,对于已经分割好的手势轮廓图,识别率也就30%左右,对于纹理比较丰富的图片,识别率更是不堪入眼,只有10%左右。这一部分原因是由于Hu不变矩只用到低阶矩(最多也就用到三阶矩),对于图像的细节未能很好的描述出来,导致对图像的描述不够完整。

Hu不变矩一般用来识别图像中大的物体,对于物体的形状描述得比较好,图像的纹理特征不能太复杂,像识别水果的形状,或者对于车牌中的简单字符的识别效果会相对好一些。

由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矩变化还是很大的。

附上个人代码:
//*****************************//

//***yangxin_szu 2013_03_24***//

//经验证,第一、第二矩特征能较好地保持不变特性//

//*****************************//

//计算矩不变纹理特征

void My_Texture::Calculate_Moment_Fea(unsigned char* Img_Data ,int Img_H ,int Img_W)

{

int i=0 ,j=0;

unsigned char temp = 0;

double m_00 =0 ,m_01 =0 ,m_10 =0;

double X_c =0 ,Y_c =0 ,Center_x =0 ,Center_y =0;

double H_00=0,H_02=0,H_03=0,H_11=0,H_12=0,H_20=0,H_21=0,H_30=0;

float eta_02=0,eta_03=0,eta_11=0,eta_12=0,eta_20=0,eta_21=0,eta_30=0;

//阶矩

for (i=0;i<Img_H;i++)

{

for (j=0;j<Img_W;j++)

{

temp = Img_Data[i*Img_W + j];

m_00 = m_00 + (powf(i,0)*powf(j,0)*temp);

m_01 = m_01 + (powf(i,0)*powf(j,1)*temp);

m_10 = m_10 + (powf(i,1)*powf(j,0)*temp);

}

}

X_c = m_10/m_00;

Y_c = m_01/m_00;

//中心矩

for (i=0;i<Img_H;i++)

{

for (j=0;j<Img_W;j++)

{

temp = Img_Data[i*Img_W + j];

Center_x = i - X_c;

Center_y = j - Y_c;

H_00 = H_00 + pow(Center_x,0)*pow(Center_y,0)*temp;

H_02 = H_02 + pow(Center_x,0)*pow(Center_y,2)*temp;

H_03 = H_03 + pow(Center_x,0)*pow(Center_y,3)*temp;

H_11 = H_11 + pow(Center_x,1)*pow(Center_y,1)*temp;

H_12 = H_12 + pow(Center_x,1)*pow(Center_y,2)*temp;

H_20 = H_20 + pow(Center_x,2)*pow(Center_y,0)*temp;

H_21 = H_21 + pow(Center_x,2)*pow(Center_y,1)*temp;

H_30 = H_30 + pow(Center_x,3)*pow(Center_y,0)*temp;

}

}

//矩的归一化

eta_02 = H_02/pow(H_00 ,2);

eta_03 = H_03/pow(H_00 ,2.5);

eta_11 = H_11/pow(H_00 ,2);

eta_12 = H_12/pow(H_00 ,2.5);

eta_20 = H_20/pow(H_00 ,2);

eta_21 = H_21/pow(H_00 ,2.5);

eta_30 = H_30/pow(H_00 ,2.5);

//矩不变特征

m_mo_1 = eta_20 + eta_02;

m_mo_2 = pow(eta_20 - eta_02,2) + 4*pow(eta_11,2);

m_mo_3 = pow(eta_30 - 3*eta_12,2) + pow(3*eta_21 - eta_03,2);

m_mo_4 = pow(eta_30 + eta_12,2) + pow(eta_21 + eta_03,2);

m_mo_5 = (eta_30 - 3*eta_12)*(eta_03 + eta_21)*(pow(eta_30+eta_12,2) - 3*pow(eta_21+eta_03,2)) +

(3*eta_12 - eta_03)*(eta_21+eta_30)*(3*pow(eta_30+eta_12,2)-pow(eta_21+eta_03,2));

m_mo_6 = (eta_20 - eta_02)*(pow(eta_30+eta_12,2) - pow(eta_21+eta_03,2))+

4*eta_11*(eta_30+eta_12)*(eta_03+eta_21);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: