• 图像的七个不变矩 可用于图像的匹配


    http://blog.csdn.net/qq_18343569/article/details/46913501

    图像的几何不变矩 

    矩特征主要表征了图像区域的几何特征,又称为几何矩, 由于其具有旋转、平移、尺度等特性的不变特征,所以又称其为不变矩。在图像处理中,几何不变矩可以作为一个重要的特征来表示物体,可以据此特征来对图像进行分类等操作。

    1.     HU矩

    几何矩是由Hu(Visual pattern recognition by moment invariants)在1962年提出的,图像f(x,y)的(p+q)阶几何矩定义为

            Mpq =∫∫(x^p)*(y^q)f(x,y)dxdy(p,q = 0,1,……∞)

            矩在统计学中被用来反映随机变量的分布情况,推广到力学中,它被用作刻画空间物体的质量分布。同样的道理,如果我们将图像的灰度值看作是一个二维或三维的密度分布函数,那么矩方法即可用于图像分析领域并用作图像特征的提取。最常用的,物体的零阶矩表示了图像的“质量”:

                      Moo= ∫∫f(x,y )dxdy

            一阶矩(M01,M10)用于确定图像质心( Xc,Yc):

                  Xc = M10/M00;Yc = M01/M00;

             若将坐标原点移至 Xc和 Yc处,就得到了对于图像位移不变的中心矩。如

                Upq =∫∫[(x-Xc)^p]*[(y-Yc)^q]f(x,y)dxdy。

    Hu在文中提出了7个几何矩的不变量,这些不变量满足于图像平移、伸缩和旋转不变。如果定义

    Zpq=Upq/(U20 + U02)^(p+q+2),

    Hu 的7种矩为:

                       H1=Z20+Z02;H1=(Z20+Z02)^2+4Z11^2;......

    矩是描述图像特征的算子,它在模式识别与图像分析领域中有重要的应用.迄今为止,常见的矩描述子可以分为以下几种:几何矩、正交矩、复数矩和旋转矩.其中几何矩提出的时间最早且形式简单,对它的研究最为充分。几何矩对简单图像有一定的描述能力,他虽然在区分度上不如其他三种矩,但与其他几种算子比较起来,他极其的简单,一般只需用一个数字就可表达。所以,一般我们是用来做大粒度的区分,用来过滤显然不相关的文档。

    比如在图形库中,可能有100万幅图,也许只有200幅图是我们想要的。使用一维的几何矩的话,就可以对几何矩进行排序,建立索引,然后选出与目标图的几何矩最近的2000幅图作比较就好了。而对于其他的矩来说,由于一般是多维的关系,一般不好排序,只能顺序查找,自然速度有巨大的差别.所以。虽然几何矩不太能选出最像的,但可以快速排除不像的,提高搜索效率。

    MATLAB代码:

    img=

    [html] view plain copy
     
    1. invariable_moment(imread('lena.jpg'));  
    [html] view plain copy
     
    1. function inv_m7 = invariable_moment(in_image)  
    2. % 功能:计算图像的Hu的七个不变矩  
    3. % 输入:in_image-RGB图像  
    4. % 输出:inv_m7-七个不变矩  
    5.   
    6. % 将输入的RGB图像转换为灰度图像     
    7. image=rgb2gray(in_image);       
    8. %将图像矩阵的数据类型转换成双精度型  
    9. image=double(image);        
    10. %%%=================计算 、 、 =========================  
    11. %计算灰度图像的零阶几何矩   
    12. m00=sum(sum(image));       
    13. m10=0;  
    14. m01=0;  
    15. [row,col]=size(image);  
    16. for i=1:row  
    17.     for j=1:col  
    18.         m10=m10+i*image(i,j);  
    19.         m01=m01+j*image(i,j);  
    20.     end  
    21. end  
    22. %%%=================计算 、 ================================  
    23. u10=m10/m00;  
    24. u01=m01/m00;  
    25. %%%=================计算图像的二阶几何矩、三阶几何矩============  
    26. m20 = 0;m02 = 0;m11 = 0;m30 = 0;m12 = 0;m21 = 0;m03 = 0;  
    27. for i=1:row  
    28.     for j=1:col  
    29.         m20=m20+i^2*image(i,j);  
    30.         m02=m02+j^2*image(i,j);  
    31.         m11=m11+i*j*image(i,j);  
    32.         m30=m30+i^3*image(i,j);  
    33.         m03=m03+j^3*image(i,j);  
    34.         m12=m12+i*j^2*image(i,j);  
    35.         m21=m21+i^2*j*image(i,j);  
    36.     end  
    37. end  
    38. %%%=================计算图像的二阶中心矩、三阶中心矩============  
    39. y00=m00;  
    40. y10=0;  
    41. y01=0;  
    42. y11=m11-u01*m10;  
    43. y20=m20-u10*m10;  
    44. y02=m02-u01*m01;  
    45. y30=m30-3*u10*m20+2*u10^2*m10;  
    46. y12=m12-2*u01*m11-u10*m02+2*u01^2*m10;  
    47. y21=m21-2*u10*m11-u01*m20+2*u10^2*m01;  
    48. y03=m03-3*u01*m02+2*u01^2*m01;  
    49. %%%=================计算图像的归格化中心矩====================  
    50.         n20=y20/m00^2;  
    51.         n02=y02/m00^2;  
    52.         n11=y11/m00^2;  
    53.         n30=y30/m00^2.5;  
    54.         n03=y03/m00^2.5;  
    55.         n12=y12/m00^2.5;  
    56.         n21=y21/m00^2.5;  
    57. %%%=================计算图像的七个不变矩======================  
    58. h1 = n20 + n02;                        
    59. h2 = (n20-n02)^2 + 4*(n11)^2;  
    60. h3 = (n30-3*n12)^2 + (3*n21-n03)^2;    
    61. h4 = (n30+n12)^2 + (n21+n03)^2;  
    62. h5 = (n30-3*n12)*(n30+n12)*((n30+n12)^2-3*(n21+n03)^2)+(3*n21-n03)*(n21+n03)*(3*(n30+n12)^2-(n21+n03)^2);  
    63. h6 = (n20-n02)*((n30+n12)^2-(n21+n03)^2)+4*n11*(n30+n12)*(n21+n03);  
    64.   h7 = (3*n21-n03)*(n30+n12)*((n30+n12)^2-3*(n21+n03)^2)+(3*n12-n30)*(n21+n03)*(3*(n30+n12)^2-(n21+n03)^2);  
    65.    
    66. inv_m7= [h1 h2 h3 h4 h5 h6 h7];     
    c++代码:
    [html] view plain copy
     
    1. /*===============================================//  
    2. 功能:不变矩匹配  
    3. 时间:3/28/2011 SkySeraph HQU  
    4. 参考:  
    5. //===============================================*/  
    6. #include "iostream"  
    7.  usingnamespace std;  
    8.   
    9. #include "cv.h"  
    10. #include "highgui.h"  
    11.   
    12. #include "math.h"  
    13.   
    14. #pragma comment(lib,"highgui.lib")  
    15. #pragma comment(lib,"cv.lib")  
    16. #pragma comment(lib,"cvaux.lib")  
    17. #pragma comment(lib,"cxcore.lib")  
    18.   
    19. constchar* filename ="D:\My Documents\My Pictures\Images\1.bmp";  
    20. constchar* filename2 ="D:\My Documents\My Pictures\Images\2.bmp";  
    21.   
    22. /*=============================================*/  
    23. double M[7] = {0}; //HU不变矩  
    24.   
    25. bool HuMoment(IplImage* img)  
    26. {  
    27.   
    28. int bmpWidth = img->width;  
    29. int bmpHeight = img->height;  
    30. int bmpStep = img->widthStep;  
    31. int bmpChannels = img->nChannels;  
    32. uchar*pBmpBuf = (uchar*)img->imageData;  
    33.   
    34. double m00=0,m11=0,m20=0,m02=0,m30=0,m03=0,m12=0,m21=0; //中心矩  
    35. double x0=0,y0=0; //计算中心距时所使用的临时变量(x-x')  
    36. double u20=0,u02=0,u11=0,u30=0,u03=0,u12=0,u21=0;//规范化后的中心矩  
    37. //double M[7]; //HU不变矩  
    38. double t1=0,t2=0,t3=0,t4=0,t5=0;//临时变量,  
    39. //double Center_x=0,Center_y=0;//重心  
    40. int Center_x=0,Center_y=0;//重心  
    41. int i,j; //循环变量  
    42.   
    43. // 获得图像的区域重心  
    44. double s10=0,s01=0,s00=0; //0阶矩和1阶矩 //注:二值图像的0阶矩表示面积  
    45. for(j=0;j<bmpHeight;j++)//y  
    46. {  
    47. for(i=0;i<bmpWidth;i++)//x  
    48. {  
    49. s10+=i*pBmpBuf[j*bmpStep+i];  
    50. s01+=j*pBmpBuf[j*bmpStep+i];  
    51. s00+=pBmpBuf[j*bmpStep+i];  
    52. }  
    53. }  
    54. Center_x=(int)(s10/s00+0.5);  
    55. Center_y=(int)(s01/s00+0.5);  
    56.   
    57. // 计算二阶、三阶矩  
    58. m00=s00;  
    59. for(j=0;j<bmpHeight;j++)  
    60. {  
    61. for(i=0;i<bmpWidth;i++)//x  
    62. {  
    63. x0=(i-Center_x);  
    64. y0=(j-Center_y);  
    65. m11+=x0*y0*pBmpBuf[j*bmpStep+i];  
    66. m20+=x0*x0*pBmpBuf[j*bmpStep+i];  
    67. m02+=y0*y0*pBmpBuf[j*bmpStep+i];  
    68. m03+=y0*y0*y0*pBmpBuf[j*bmpStep+i];  
    69. m30+=x0*x0*x0*pBmpBuf[j*bmpStep+i];  
    70. m12+=x0*y0*y0*pBmpBuf[j*bmpStep+i];  
    71. m21+=x0*x0*y0*pBmpBuf[j*bmpStep+i];  
    72. }  
    73. }   
    74.   
    75. // 计算规范化后的中心矩  
    76. u20=m20/pow(m00,2);  
    77. u02=m02/pow(m00,2);  
    78. u11=m11/pow(m00,2);  
    79. u30=m30/pow(m00,2.5);  
    80. u03=m03/pow(m00,2.5);  
    81. u12=m12/pow(m00,2.5);  
    82. u21=m21/pow(m00,2.5);  
    83.   
    84. // 计算中间变量。  
    85. t1=(u20-u02);  
    86. t2=(u30-3*u12);  
    87. t3=(3*u21-u03);  
    88. t4=(u30+u12);  
    89. t5=(u21+u03);  
    90.   
    91. // 计算不变矩  
    92. M[0]=u20+u02;  
    93. M[1]=t1*t1+4*u11*u11;  
    94. M[2]=t2*t2+t3*t3;  
    95. M[3]=t4*t4+t5*t5;  
    96. M[4]=t2*t4*(t4*t4-3*t5*t5)+t3*t5*(3*t4*t4-t5*t5);  
    97. M[5]=t1*(t4*t4-t5*t5)+4*u11*t4*t5;  
    98. M[6]=t3*t4*(t4*t4-3*t5*t5)-t2*t5*(3*t4*t4-t5*t5);  
    99.   
    100.   
    101. /*cout<<M[0]<<endl;//<<二"<<M[0]<<"三"<<M[0]<<"四"<<M[0]<<"五"<<M[0]<<"六"<<M[0]<<"七"<<M[0]<<endl;  
    102. cout<<M[1]<<endl;  
    103. cout<<M[2]<<endl;  
    104. cout<<M[3]<<endl;  
    105. cout<<M[4]<<endl;  
    106. cout<<M[5]<<endl;  
    107. cout<<M[6]<<endl;  
    108. cout<<endl;*/  
    109. returntrue;  
    110. }  
    111.   
    112.   
    113. int main(char argc,char** argv)  
    114. {  
    115. int i;  
    116. double Sa[7] = {0},Ta[7] ={0};  
    117.   
    118. ///*源图像  
    119. IplImage*img = cvLoadImage(filename,0);//灰度  
    120. HuMoment(img);  
    121. for(i=0;i<7;i++)  
    122. {  
    123. Sa[i] = M[i];  
    124. M[i] =0;  
    125. }  
    126. cout<<Sa[0]<<endl;  
    127. cout<<Sa[1]<<endl;  
    128. cout<<Sa[2]<<endl;  
    129. cout<<Sa[3]<<endl;  
    130. cout<<Sa[4]<<endl;  
    131. cout<<Sa[5]<<endl;  
    132. cout<<Sa[6]<<endl;  
    133. cout<<endl;  
    134. //*/  
    135.   
    136.   
    137. ///*模板图  
    138. IplImage*tpl = cvLoadImage(filename2,0);//灰度  
    139. HuMoment(tpl);  
    140. for(i=0;i<7;i++)  
    141. {  
    142. Ta[i] = M[i];  
    143. M[i] =0;  
    144. }  
    145. cout<<Ta[0]<<endl;  
    146. cout<<Ta[1]<<endl;  
    147. cout<<Ta[2]<<endl;  
    148. cout<<Ta[3]<<endl;  
    149. cout<<Ta[4]<<endl;  
    150. cout<<Ta[5]<<endl;  
    151. cout<<Ta[6]<<endl;  
    152. cout<<endl;  
    153.   
    154.   
    155. // 计算相似度  
    156. double dbR =0; //相似度  
    157. double dSigmaST =0;  
    158. double dSigmaS =0;  
    159. double dSigmaT =0;  
    160. double temp =0;   
    161.   
    162. for(i=0;i<7;i++)  
    163. {  
    164. temp = Sa[i]*Ta[i];  
    165. dSigmaST+=temp;  
    166. dSigmaS+=pow(Sa[i],2);  
    167. dSigmaT+=pow(Ta[i],2);  
    168. }  
    169. dbR = dSigmaST/(sqrt(dSigmaS)*sqrt(dSigmaT));  
    170. printf("%lf ",dbR);  
    171. //cout<<dbR<<endl;  
    172.   
    173. cvReleaseImage(&img);  
    174. cvReleaseImage(&tpl);  
    175.   
    176. return0;  
    177. }  

    其他几种矩的比较可以参考这篇文章:

    点击打开链接

  • 相关阅读:
    基于jquery. cookie 防刷新重复点击获取验证码
    Mysql常用命令详解
    20种常用的DOS命令小结
    php 常用正则表达式
    VBA Excel 常用 自定义函数
    VBA Mysql 类
    VBA Excel 引用 API,以实现“透明”
    VBA Excel 打印
    VBA Excel 单元格操作
    php上传常见文件类型对应的$_FILES["file"]["type"](转)
  • 原文地址:https://www.cnblogs.com/zkwarrior/p/5701200.html
Copyright © 2020-2023  润新知