几何不变矩--Hu矩

た 入场券 2023-08-17 16:15 259阅读 0赞

【图像算法】图像特征:


一 原理

  1. 几何矩是由Hu(Visual pattern recognition by moment invariants)在1962年提出的,具有平移、旋转和尺度不变性。 定义如下:

① (p+q)阶不变矩定义

2011071909102486.png

② 对于数字图像,离散化,定义为

2011071909105531.png

③ 归一化中心矩定义

2011071909121175.png

④Hu矩定义

2011071909130059.png

2011071909131361.png


二 实现(源码)

①自编函数模块C++

  1. //#################################################################################//
  2. double M[7] = {0}; //HU不变矩
  3. bool HuMoment(IplImage* img)
  4. {
  5. int bmpWidth = img->width;
  6. int bmpHeight = img->height;
  7. int bmpStep = img->widthStep;
  8. int bmpChannels = img->nChannels;
  9. uchar*pBmpBuf = (uchar*)img->imageData;
  10. double m00=0,m11=0,m20=0,m02=0,m30=0,m03=0,m12=0,m21=0; //中心矩
  11. double x0=0,y0=0; //计算中心距时所使用的临时变量(x-x')
  12. double u20=0,u02=0,u11=0,u30=0,u03=0,u12=0,u21=0;//规范化后的中心矩
  13. //double M[7]; //HU不变矩
  14. double t1=0,t2=0,t3=0,t4=0,t5=0;//临时变量,
  15. //double Center_x=0,Center_y=0;//重心
  16. int Center_x=0,Center_y=0;//重心
  17. int i,j; //循环变量
  18. // 获得图像的区域重心(普通矩)
  19. double s10=0,s01=0,s00=0; //0阶矩和1阶矩
  20. for(j=0;j<bmpHeight;j++)//y
  21. {
  22. for(i=0;i<bmpWidth;i++)//x
  23. {
  24. s10+=i*pBmpBuf[j*bmpStep+i];
  25. s01+=j*pBmpBuf[j*bmpStep+i];
  26. s00+=pBmpBuf[j*bmpStep+i];
  27. }
  28. }
  29. Center_x=(int)(s10/s00+0.5);
  30. Center_y=(int)(s01/s00+0.5);
  31. // 计算二阶、三阶矩(中心矩)
  32. m00=s00;
  33. for(j=0;j<bmpHeight;j++)
  34. {
  35. for(i=0;i<bmpWidth;i++)//x
  36. {
  37. x0=(i-Center_x);
  38. y0=(j-Center_y);
  39. m11+=x0*y0*pBmpBuf[j*bmpStep+i];
  40. m20+=x0*x0*pBmpBuf[j*bmpStep+i];
  41. m02+=y0*y0*pBmpBuf[j*bmpStep+i];
  42. m03+=y0*y0*y0*pBmpBuf[j*bmpStep+i];
  43. m30+=x0*x0*x0*pBmpBuf[j*bmpStep+i];
  44. m12+=x0*y0*y0*pBmpBuf[j*bmpStep+i];
  45. m21+=x0*x0*y0*pBmpBuf[j*bmpStep+i];
  46. }
  47. }
  48. // 计算规范化后的中心矩: mij/pow(m00,((i+j+2)/2)
  49. u20=m20/pow(m00,2);
  50. u02=m02/pow(m00,2);
  51. u11=m11/pow(m00,2);
  52. u30=m30/pow(m00,2.5);
  53. u03=m03/pow(m00,2.5);
  54. u12=m12/pow(m00,2.5);
  55. u21=m21/pow(m00,2.5);
  56. // 计算中间变量
  57. t1=(u20-u02);
  58. t2=(u30-3*u12);
  59. t3=(3*u21-u03);
  60. t4=(u30+u12);
  61. t5=(u21+u03);
  62. // 计算不变矩
  63. M[0]=u20+u02;
  64. M[1]=t1*t1+4*u11*u11;
  65. M[2]=t2*t2+t3*t3;
  66. M[3]=t4*t4+t5*t5;
  67. M[4]=t2*t4*(t4*t4-3*t5*t5)+t3*t5*(3*t4*t4-t5*t5);
  68. M[5]=t1*(t4*t4-t5*t5)+4*u11*t4*t5;
  69. M[6]=t3*t4*(t4*t4-3*t5*t5)-t2*t5*(3*t4*t4-t5*t5);
  70. returntrue;
  71. }

  

②调用OpenCV方法

复制代码

  1. 1 // 利用OpenCV函数求7个Hu矩
  2. 2 CvMoments moments;
  3. 3 CvHuMoments hu;
  4. 4 cvMoments(bkImgEdge,&moments,0);
  5. 5 cvGetHuMoments(&moments, &hu);
  6. 6 cout<<hu.hu1<<"/"<<hu.hu2<<"/"<<hu.hu3<<"/"<<hu.hu4<<"/"<<hu.hu5<<"/"<<hu.hu6<<"/"<<hu.hu7<<"/"<<"/"<<endl;
  7. 7 cvMoments(testImgEdge,&moments,0);
  8. 8 cvGetHuMoments(&moments, &hu);
  9. 9 cout<<hu.hu1<<"/"<<hu.hu2<<"/"<<hu.hu3<<"/"<<hu.hu4<<"/"<<hu.hu5<<"/"<<hu.hu6<<"/"<<hu.hu7<<"/"<<"/"<<endl;

复制代码

Python调用OpenCV:

  1. #-*-coding:utf-8-*-
  2. import cv2
  3. from datetime import datetime
  4. import numpy as np
  5. def test(img):
  6. moments = cv2.moments(img)
  7. humoments = cv2.HuMoments(moments)
  8. # humoments = no.log(np.abs(humoments)) # 同样建议取对数
  9. print(humoments)
  10. if __name__ == '__main__':
  11. t1 = datetime.now()
  12. fp = '/home/mamq/images/3.jpg'
  13. img = cv2.imread(fp)
  14. img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  15. test(img_gray)
  16. print datetime.now() - t1

  

Python方法:

  1. #-*-coding:utf-8-*-
  2. import cv2
  3. from datetime import datetime
  4. import numpy as np
  5. np.set_printoptions(suppress=True)
  6. def humoments(img_gray):
  7. '''
  8. 由于7个不变矩的变化范围很大,为了便于比较,可利用取对数的方法进行数据压缩;同时考虑到不变矩有可能出现负值的情况,因此,在取对数之前先取绝对值
  9. 经修正后的不变矩特征具有平移 、旋转和比例不变性
  10. '''
  11. # 标准矩定义为m_pq = sumsum(x^p * y^q * f(x, y))
  12. row, col = img_gray.shape
  13. #计算图像的0阶几何矩
  14. m00 = img_gray.sum()
  15. m10 = m01 = 0
  16. # 计算图像的二阶、三阶几何矩
  17. m11 = m20 = m02 = m12 = m21 = m30 = m03 = 0
  18. for i in range(row):
  19. m10 += (i * img_gray[i]).sum()
  20. m20 += (i ** 2 * img_gray[i]).sum()
  21. m30 += (i ** 3 * img_gray[i]).sum()
  22. for j in range(col):
  23. m11 += i * j * img_gray[i][j]
  24. m12 += i * j ** 2 * img_gray[i][j]
  25. m21 += i ** 2 * j * img_gray[i][j]
  26. for j in range(col):
  27. m01 += (j * img_gray[:, j]).sum()
  28. m02 += (j ** 2 * img_gray[:, j]).sum()
  29. m30 += (j ** 3 * img_gray[:, j]).sum()
  30. # 由标准矩我们可以得到图像的"重心"
  31. u10 = m10 / m00
  32. u01 = m01 / m00
  33. # 计算图像的二阶中心矩、三阶中心矩
  34. y00 = m00
  35. y10 = y01 = 0
  36. y11 = m11 - u01 * m10
  37. y20 = m20 - u10 * m10
  38. y02 = m02 - u01 * m01
  39. y30 = m30 - 3 * u10 * m20 + 2 * u10 ** 2 * m10
  40. y12 = m12 - 2 * u01 * m11 - u10 * m02 + 2 * u01 ** 2 * m10
  41. y21 = m21 - 2 * u10 * m11 - u01 * m20 + 2 * u10 ** 2 * m01
  42. y03 = m03 - 3 * u01 * m02 + 2 * u01 ** 2 * m01
  43. # 计算图像的归格化中心矩
  44. n20 = y20 / m00 ** 2
  45. n02 = y02 / m00 ** 2
  46. n11 = y11 / m00 ** 2
  47. n30 = y30 / m00 ** 2.5
  48. n03 = y03 / m00 ** 2.5
  49. n12 = y12 / m00 ** 2.5
  50. n21 = y21 / m00 ** 2.5
  51. # 计算图像的七个不变矩
  52. h1 = n20 + n02
  53. h2 = (n20 - n02) ** 2 + 4 * n11 ** 2
  54. h3 = (n30 - 3 * n12) ** 2 + (3 * n21 - n03) ** 2
  55. h4 = (n30 + n12) ** 2 + (n21 + n03) ** 2
  56. h5 = (n30 - 3 * n12) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n21 - n03) * (n21 + n03) \
  57. * (3 * (n30 + n12) ** 2 - (n21 + n03) ** 2)
  58. h6 = (n20 - n02) * ((n30 + n12) ** 2 - (n21 + n03) ** 2) + 4 * n11 * (n30 + n12) * (n21 + n03)
  59. h7 = (3 * n21 - n03) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n12 - n30) * (n21 + n03) \
  60. * (3 * (n30 + n12) ** 2 - (n21 + n03) ** 2)
  61. inv_m7 = [h1, h2, h3, h4, h5, h6, h7]
  62. inv_m7 = np.log(np.abs(inv_m7))
  63. return inv_m7
  64. if __name__ == '__main__':
  65. t1 = datetime.now()
  66. fp = '/home/mamq/images/3.jpg'
  67. img = cv2.imread(fp)
  68. img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  69. print humoments(img_gray)
  70. print datetime.now() - t1

  

  

MATLAB方法:

  1. invariable_moment(imread('lena.jpg'));
  2. function inv_m7 = invariable_moment(in_image)
  3. % 功能:计算图像的Hu的七个不变矩
  4. % 输入:in_image-RGB图像
  5. % 输出:inv_m7-七个不变矩
  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. inv_m7= [h1 h2 h3 h4 h5 h6 h7];

  


三 相似性准则

①法一

  1. // 计算相似度1
  2. double dbR =0; //相似度
  3. double dSigmaST =0;
  4. double dSigmaS =0;
  5. double dSigmaT =0;
  6. double temp =0;
  7. {for(int i=0;i<7;i++)
  8. {
  9. temp = fabs(Sa[i]*Ta[i]);
  10. dSigmaST+=temp;
  11. dSigmaS+=pow(Sa[i],2);
  12. dSigmaT+=pow(Ta[i],2);
  13. }}
  14. dbR = dSigmaST/(sqrt(dSigmaS)*sqrt(dSigmaT));

  

②法二

  1. 1 // 计算相似度2
  2. 2 double dbR2 =0; //相似度
  3. 3 double temp2 =0;
  4. 4 double temp3 =0;
  5. 5 {for(int i=0;i<7;i++)
  6. 6 {
  7. 7 temp2 += fabs(Sa[i]-Ta[i]);
  8. 8 temp3 += fabs(Sa[i]+Ta[i]);
  9. 9 }}
  10. 10 dbR2 =1- (temp2*1.0)/(temp3);

Author: SKySeraph

Email/GTalk: zgzhaobo@gmail.com QQ:452728574

From: http://www.cnblogs.com/skyseraph/


作者:skyseraph
出处:http://www.cnblogs.com/skyseraph/
更多精彩请直接访问SkySeraph个人站点:http://skyseraph.com//
Email/GTalk: zgzhaobo@gmail.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

wechat_sk.jpg

转载于:https://www.cnblogs.com/sddai/p/11430732.html

发表评论

表情:
评论列表 (有 0 条评论,259人围观)

还没有评论,来说两句吧...

相关阅读

    相关 MATLAB特征数字验证码识别∗

    摘 要 网络给人们提供丰富资源和极大便利,同时,互联网的安全性问题也随之而来。验证码正是加强网络系统安全性的常用手段。不变矩方法在目标识别领域的应用较为广泛,但在验证码识别方面

    相关

    扭矩和功率一样,是汽车发动机的主要指数之一,它反映在汽车性能上,包括加速度、爬坡能力等。它的准确定义是:活塞在汽缸里的往复运动,往复一次就会做一定的功,它的国际标准单位是牛顿。

    相关 图像变性特征—hu

    图像的hu矩是一种具有平移、旋转和尺度不变性的图像特征。 普通矩的计算: f(x,y)的p+q阶原点矩可以表示为: ![这里写图片描述][aHR0cDovL2ltZy