zoukankan      html  css  js  c++  java
  • 【图像算法OpenCV】几何不变矩--Hu矩

    原文地址  http://blog.csdn.NET/daijucug/article/details/7535370


    【图像算法OpenCV】几何不变矩--Hu矩  

    一 原理

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

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

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

     

    ③ 归一化中心矩定义

     

    ④Hu矩定义

     

     

     

    -------------------------------------------------------------------------------------------------------------------------------

    二 实现(源码)

    自编函数模块

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

    ②调用OpenCV方法

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

    -------------------------------------------------------------------------------------------------------------------------------

    三 相似性准则

    ①法一

    //  计算相似度1
    double dbR =0; //相似度
    double dSigmaST =0;
        double dSigmaS =0;
        double dSigmaT =0;
        double temp =0;  
        {for(int i=0;i<8;i++)
        {
            temp = fabs(Sa[i]*Ta[i]);
            dSigmaST+=temp;
            dSigmaS+=pow(Sa[i],2);
            dSigmaT+=pow(Ta[i],2);
        }}
        dbR = dSigmaST/(sqrt(dSigmaS)*sqrt(dSigmaT));

    ②法二 

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

  • 相关阅读:
    alkhaser学习笔记(一)Anti Debug
    8086 汇编指令手册查询(转)
    QueryUserAPC Ring3下 APC注入
    内存分配(malloc,new,VirtualAlloc,HeapAlloc,GlobalAlloc,LocalAlloc)区别与注意
    error C2220: 警告被视为错误 没有生成“object”文件 (转)
    消息队列
    分页存储过程(对有主键的表效率极高)
    asp.net vs2010 设计报表rdlc时,未能加载文件或程序集
    【翻译】创建ViewState特征的自动ViewState属性
    中英文字符的截取
  • 原文地址:https://www.cnblogs.com/huty/p/8517707.html
Copyright © 2011-2022 走看看