【图形图像】几何不变矩---Hu矩

2023-10-24 01:40
文章标签 几何 不变 hu 图形图像

本文主要是介绍【图形图像】几何不变矩---Hu矩,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在连续情况下,图像函数为 ,那么图像的p+q阶几何矩(标准矩)定义为:

 

p+q阶中心距定义为:

 

其中 和 代表图像的重心,

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

 

 

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

归一化的中心距定义为:

 ;其中

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

 

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

实际上,在对图片中物体的识别过程中,只有 和 不变性保持的比较好,其他的几个不变矩带来的误差比较大,有学者认为只有基于二阶矩的不变矩对二维物体的描述才是真正的具有旋转、缩放和平移不变性( 和 刚好都是由二阶矩组成的)。不过我没有证明是否是真的事这样的。

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

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

C++代码:

[cpp]  view plain copy
  1. // 图像位数对齐   
  2.   
  3. #define bpl(imwidth, deep) ((imwidth*deep*8+31)/32*4)   
  4.   
  5. /* 获取像素值  
  6.  
  7. psrcBmp: 图像数据指针  
  8.  
  9. nsrcBmpWidth: 图像宽度,以像素为单位  
  10.  
  11. x,y: 像素点  
  12.  
  13. deep: 图像的位数深度,(表示位的灰度图,表示位的 RGB 位图)  
  14.  
  15. */   
  16.   
  17. COLORREF J_getpixel( const BYTE *psrcBmp, const int nsrcBmpWidth, const int x, const int y, int deep = 3)   
  18.   
  19. {   
  20.   
  21.     if (deep == 3)   
  22.   
  23.     {   
  24.   
  25.         return RGB(*(psrcBmp + x*3 + y*bpl(nsrcBmpWidth, deep) + 2 ) ,   
  26.   
  27.             *(psrcBmp + x*3 + y*bpl(nsrcBmpWidth, deep) + 1 ) ,   
  28.   
  29.             *(psrcBmp + x*3 + y*bpl(nsrcBmpWidth, deep) +0 ));   
  30.   
  31.     }   
  32.   
  33.     else if (deep == 1)   
  34.   
  35.     {   
  36.   
  37.         return *(psrcBmp + x + y*bpl(nsrcBmpWidth, deep));   
  38.   
  39.     }   
  40.   
  41. }   
  42.   
  43. // 获取标准矩 ( 只支持位灰度图 )   
  44.   
  45. void GetStdMoment (BYTE *psrcBmp ,   
  46.   
  47.                  int nsrcBmpWidth ,   
  48.   
  49.                  int nsrcBmpHeight ,   
  50.   
  51.                  double *m )   
  52.   
  53. {   
  54.   
  55.     for ( int p = 0 ; p < 2 ; p ++ )   
  56.   
  57.         for ( int q = 0 ; q < 2 ; q ++ )   
  58.   
  59.         {   
  60.   
  61.             if ( p == 1 && q == 1)   
  62.   
  63.                 break ;   
  64.   
  65.             for ( int y = 0 ; y < nsrcBmpHeight ; y ++ )   
  66.   
  67.                 for ( int x = 0 ; x < nsrcBmpWidth ; x ++ )   
  68.   
  69.                     m [p *2+q ] += (pow ( (double )x , p ) * pow ( (double )y , q ) * J_getpixel (psrcBmp , nsrcBmpWidth , x ,y , 1));   
  70.   
  71.         }   
  72.   
  73. }   
  74.   
  75. //hu 不变矩 ( 只支持位灰度图 )   
  76.   
  77. void J_GetHuMoment (BYTE *psrcBmp ,   
  78.   
  79.                 int nsrcBmpWidth ,   
  80.   
  81.                 int nsrcBmpHeight ,   
  82.   
  83.                 double *H )   
  84.   
  85. {   
  86.   
  87.    
  88.   
  89.     double m [4] = {0.0};   
  90.   
  91.    
  92.   
  93.     GetStdMoment (psrcBmp ,   
  94.   
  95.          nsrcBmpWidth ,   
  96.   
  97.          nsrcBmpHeight ,   
  98.   
  99.          m );   
  100.   
  101.    
  102.   
  103.     int x0 = (int )(m [2]/m [0] + 0.5);   
  104.   
  105.     int y0 = (int )(m [1]/m [0] + 0.5);   
  106.   
  107.    
  108.   
  109.     double u [4][4] = {0.0};   
  110.   
  111.     for ( int p = 0 ; p < 4 ; p ++ )   
  112.   
  113.         for ( int q = 0 ; q < 4 ; q ++ )   
  114.   
  115.         {   
  116.   
  117.             // 优化<a href="http://lib.csdn.net/base/31" class='replace_word' title="算法与数据结构知识库" target='_blank' style='color:#df3434; font-weight:bold;'>算法</a>,以下介数不用计算   
  118.   
  119.             if ( (p == 0 && q == 1) ||   
  120.   
  121.                 (p == 1 && q == 0) ||   
  122.   
  123.                 (p == 1 && q == 3) ||   
  124.   
  125.                 (p == 2 && q == 2) ||   
  126.   
  127.                 (p == 2 && q == 3) ||   
  128.   
  129.                 (p == 3 && q == 1) ||   
  130.   
  131.                 (p == 3 && q == 2) ||   
  132.   
  133.                 (p == 3 && q == 3))   
  134.   
  135.             {   
  136.   
  137.                 break ;   
  138.   
  139.             }   
  140.   
  141.             for ( int y = 0 ; y < nsrcBmpHeight ; y ++ )   
  142.   
  143.                 for ( int x = 0 ; x < nsrcBmpWidth ; x ++ )   
  144.   
  145.                     u [p ][q ] += (pow ( double (x - x0 ) , p ) * pow ( double (y - y0 ), q ) * J_getpixel (psrcBmp , nsrcBmpWidth , x , y , 1));   
  146.   
  147.         }   
  148.   
  149.                
  150.   
  151.     double n [4][4] = {0.0};   
  152.   
  153.     for ( int p = 0 ; p < 4 ; p ++ )   
  154.   
  155.         for ( int q = 0 ; q < 4 ; q ++ )   
  156.   
  157.         {   
  158.   
  159.             // 优化算法,以下介数不用计算   
  160.   
  161.             if ( (p == 0 && q == 0) ||   
  162.   
  163.                 (p == 0 && q == 1) ||   
  164.   
  165.                 (p == 1 && q == 0) ||   
  166.   
  167.                 (p == 1 && q == 3) ||   
  168.   
  169.                 (p == 2 && q == 2) ||   
  170.   
  171.                 (p == 2 && q == 3) ||   
  172.   
  173.                 (p == 3 && q == 1) ||   
  174.   
  175.                 (p == 3 && q == 2) ||   
  176.   
  177.                 (p == 3 && q == 3))   
  178.   
  179.             {   
  180.   
  181.                 break ;   
  182.   
  183.             }   
  184.   
  185.             n [p ][q ] = u [p ][q ]/( pow ( u [0][0] , (p +q )/2.0 + 1 ) );   
  186.   
  187.         }   
  188.   
  189.    
  190.   
  191.     *(H ) = n [2][0] + n [0][2];   
  192.   
  193.     *(H + 1) = pow (n [2][0]-n [0][2] , 2.0) + 4*pow (n [1][1],2.0);   
  194.   
  195.     *(H + 2) = pow (n [3][0]-3*n [1][2] , 2) + pow (3*n [2][1] - n [0][3] , 2);   
  196.   
  197.     *(H + 3) = pow (n [3][0]+n [1][2] , 2)+ pow (n [2][1]+n [0][3],2);   
  198.   
  199.     *(H + 4) = (n [3][0]-3*n [1][2])*(n [3][0] + n [1][2])*(pow (n [3][0]+n [1][2],2)-3*pow (n [2][1]+n [0][3],2))+(3*n [2][1]-n [0][3])*(n [2][1]+n [0][3])*(3*pow (n [3][0]+n [1][2],2)-pow (n [2][1]+n [0][3],2));   
  200.   
  201.     *(H + 5) = (n [2][0]-n [0][2])*(pow (n [3][0]+n [1][2],2)-pow (n [2][1]+n [0][3],2))+4*n [1][1]*(n [3][0]+n [1][2])*(n [2][1]+n [0][3]);   
  202.   
  203.     *(H + 6) = (3*n [2][1]-n [0][3])*(n [3][0] + n [1][2])*(pow (n [3][0]+n [1][2],2)-3*pow (n [2][1]+n [0][3],2))+( 3*n [1][2] - n [3][0] )*(n [2][1]+n [0][3])*(3*pow (n [3][0]+n [1][2],2)-pow (n [2][1]+n [0][3],2));   
  204.   
  205. }   

这篇关于【图形图像】几何不变矩---Hu矩的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/271855

相关文章

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

poj 3304 几何

题目大意:给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出No!。 解题思路:如果存在这样的直线,过投影相交点(或投影相交区域中的点)作直线的垂线,该垂线(也是直线)必定与每条线段相交,问题转化为问是否存在一条直线和所有线段相交。 若存在一条直线与所有线段相交,此时该直线必定经过这些线段的某两个端点,所以枚举任意两个端点即可。

POJ 2318 几何 POJ 2398

给出0 , 1 , 2 ... n 个盒子, 和m个点, 统计每个盒子里面的点的个数。 const double eps = 1e-10 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;}struct Point{double x , y

poj 2653 几何

按顺序给一系列的线段,问最终哪些线段处在顶端(俯视图是完整的)。 const double eps = 1e-10 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;}struct Point{double x , y ;Point(){}Po

三维布尔运算对不规范几何数据的兼容处理

1.前言 上一篇文章谈过八叉树布尔运算,对于规范几何数据的情况是没有问题的。 在实际情况中,由于几何数据来源不一,处理和生成方式不一,我们无法保证进行布尔运算的几何数据都是规范的,对于不规范情况有时候也有需求,这就需要兼容不规范数据情况,当然这种兼容不是一味的让步,而是对于存在有限的不规范数据的兼容处理。 2.原始数据示例 下图是一个大坝模型和之上要对其进行布尔运算的立方体。 大坝模型由

CF#284 (Div. 2) C.(几何规律)

题目链接:http://codeforces.com/contest/499/problem/C 解题思路: 把两个点的坐标分别带入方程组,如果最后两个值相乘为负,即异号,计数器++。其中有一个有趣的现象,从A到B的最短步数,可以变化为求A和B之间夹了多少条直线,那么最后只要求出直线数,即可求出最小步数。 如果一条直线夹在A和B中间,那么把A和B的坐标带入后,所得值相乘一定为负。数据很

百度之星初赛1006(计算几何:能包含凸包的最小矩形面积)

矩形面积    Accepts: 717    Submissions: 1619  Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些