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

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

    【图像算法】图像特征:几何不变矩--Hu矩

          SkySeraph July 19th 2011  HQU

    Email:zgzhaobo@gmail.com    QQ:452728574

    Latest Modified Date:July 19th 2011 HQU

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

    一 原理

        几何矩是由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<7;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);

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

    Author:         SKySeraph

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

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

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

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

  • 相关阅读:
    CentOS重启与关机
    VIM打开文件与保存文件
    sql Split
    JS获取URL参数
    C#后台调用公网接口(GET, POST)
    鼠标右击.exe的程序出现闪退(桌面重启)怎么办
    JS判断有无网络(移动端)
    TFS API : 四、工作项查询
    TFS API:三、TFS WorkItem添加和修改、保存
    TFS API:二、TFS 代码查询工作项
  • 原文地址:https://www.cnblogs.com/skyseraph/p/2110183.html
Copyright © 2011-2022 走看看