• 图像处理中,几何不变矩可以作为一重要的特征来表示物体,可以据此特征来对图像进行分类等操作。 1. HU矩 几何矩是由Hu(Visual pattern recognition by moment invariants)在1962年提出
    图像的几何不变矩 

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

    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=

    invariable_moment(imread('lena.jpg'));

    function inv_m7 = invariable_moment(in_image)
    % 功能:计算图像的Hu的七个不变矩
    % 输入:in_image-RGB图像
    % 输出:inv_m7-七个不变矩
    
    % 将输入的RGB图像转换为灰度图像   
    image=rgb2gray(in_image);     
    %将图像矩阵的数据类型转换成双精度型
    image=double(image);      
    %%%=================计算 、 、 =========================
    %计算灰度图像的零阶几何矩 
    m00=sum(sum(image));     
    m10=0;
    m01=0;
    [row,col]=size(image);
    for i=1:row
        for j=1:col
            m10=m10+i*image(i,j);
            m01=m01+j*image(i,j);
        end
    end
    %%%=================计算 、 ================================
    u10=m10/m00;
    u01=m01/m00;
    %%%=================计算图像的二阶几何矩、三阶几何矩============
    m20 = 0;m02 = 0;m11 = 0;m30 = 0;m12 = 0;m21 = 0;m03 = 0;
    for i=1:row
        for j=1:col
            m20=m20+i^2*image(i,j);
            m02=m02+j^2*image(i,j);
            m11=m11+i*j*image(i,j);
            m30=m30+i^3*image(i,j);
            m03=m03+j^3*image(i,j);
            m12=m12+i*j^2*image(i,j);
            m21=m21+i^2*j*image(i,j);
        end
    end
    %%%=================计算图像的二阶中心矩、三阶中心矩============
    y00=m00;
    y10=0;
    y01=0;
    y11=m11-u01*m10;
    y20=m20-u10*m10;
    y02=m02-u01*m01;
    y30=m30-3*u10*m20+2*u10^2*m10;
    y12=m12-2*u01*m11-u10*m02+2*u01^2*m10;
    y21=m21-2*u10*m11-u01*m20+2*u10^2*m01;
    y03=m03-3*u01*m02+2*u01^2*m01;
    %%%=================计算图像的归格化中心矩====================
            n20=y20/m00^2;
            n02=y02/m00^2;
            n11=y11/m00^2;
            n30=y30/m00^2.5;
            n03=y03/m00^2.5;
            n12=y12/m00^2.5;
            n21=y21/m00^2.5;
    %%%=================计算图像的七个不变矩======================
    h1 = n20 + n02;                      
    h2 = (n20-n02)^2 + 4*(n11)^2;
    h3 = (n30-3*n12)^2 + (3*n21-n03)^2;  
    h4 = (n30+n12)^2 + (n21+n03)^2;
    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);
    h6 = (n20-n02)*((n30+n12)^2-(n21+n03)^2)+4*n11*(n30+n12)*(n21+n03);
      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);
     
    inv_m7= [h1 h2 h3 h4 h5 h6 h7];   
    
    c++代码:

    /*===============================================//
    功能:不变矩匹配
    时间:3/28/2011 SkySeraph HQU
    参考:
    //===============================================*/
    #include "iostream"
     usingnamespace std;
    
    #include "cv.h"
    #include "highgui.h"
    
    #include "math.h"
    
    #pragma comment(lib,"highgui.lib")
    #pragma comment(lib,"cv.lib")
    #pragma comment(lib,"cvaux.lib")
    #pragma comment(lib,"cxcore.lib")
    
    constchar* filename ="D:\\My Documents\\My Pictures\\Images\\1.bmp";
    constchar* filename2 ="D:\\My Documents\\My Pictures\\Images\\2.bmp";
    
    /*=============================================*/
    double M[7] = {0}; //HU不变矩
    
    bool HuMoment(IplImage* img)
    {
    
    int bmpWidth = img->width;
    int bmpHeight = img->height;
    int bmpStep = img->widthStep;
    int bmpChannels = img->nChannels;
    uchar*pBmpBuf = (uchar*)img->imageData;
    
    double m00=0,m11=0,m20=0,m02=0,m30=0,m03=0,m12=0,m21=0; //中心矩
    double x0=0,y0=0; //计算中心距时所使用的临时变量(x-x')
    double u20=0,u02=0,u11=0,u30=0,u03=0,u12=0,u21=0;//规范化后的中心矩
    //double M[7]; //HU不变矩
    double t1=0,t2=0,t3=0,t4=0,t5=0;//临时变量,
    //double Center_x=0,Center_y=0;//重心
    int Center_x=0,Center_y=0;//重心
    int i,j; //循环变量
    
    // 获得图像的区域重心
    double s10=0,s01=0,s00=0; //0阶矩和1阶矩 //注:二值图像的0阶矩表示面积
    for(j=0;j<bmpHeight;j++)//y
    {
    for(i=0;i<bmpWidth;i++)//x
    {
    s10+=i*pBmpBuf[j*bmpStep+i];
    s01+=j*pBmpBuf[j*bmpStep+i];
    s00+=pBmpBuf[j*bmpStep+i];
    }
    }
    Center_x=(int)(s10/s00+0.5);
    Center_y=(int)(s01/s00+0.5);
    
    // 计算二阶、三阶矩
    m00=s00;
    for(j=0;j<bmpHeight;j++)
    {
    for(i=0;i<bmpWidth;i++)//x
    {
    x0=(i-Center_x);
    y0=(j-Center_y);
    m11+=x0*y0*pBmpBuf[j*bmpStep+i];
    m20+=x0*x0*pBmpBuf[j*bmpStep+i];
    m02+=y0*y0*pBmpBuf[j*bmpStep+i];
    m03+=y0*y0*y0*pBmpBuf[j*bmpStep+i];
    m30+=x0*x0*x0*pBmpBuf[j*bmpStep+i];
    m12+=x0*y0*y0*pBmpBuf[j*bmpStep+i];
    m21+=x0*x0*y0*pBmpBuf[j*bmpStep+i];
    }
    } 
    
    // 计算规范化后的中心矩
    u20=m20/pow(m00,2);
    u02=m02/pow(m00,2);
    u11=m11/pow(m00,2);
    u30=m30/pow(m00,2.5);
    u03=m03/pow(m00,2.5);
    u12=m12/pow(m00,2.5);
    u21=m21/pow(m00,2.5);
    
    // 计算中间变量。
    t1=(u20-u02);
    t2=(u30-3*u12);
    t3=(3*u21-u03);
    t4=(u30+u12);
    t5=(u21+u03);
    
    // 计算不变矩
    M[0]=u20+u02;
    M[1]=t1*t1+4*u11*u11;
    M[2]=t2*t2+t3*t3;
    M[3]=t4*t4+t5*t5;
    M[4]=t2*t4*(t4*t4-3*t5*t5)+t3*t5*(3*t4*t4-t5*t5);
    M[5]=t1*(t4*t4-t5*t5)+4*u11*t4*t5;
    M[6]=t3*t4*(t4*t4-3*t5*t5)-t2*t5*(3*t4*t4-t5*t5);
    
    
    /*cout<<M[0]<<endl;//<<二"<<M[0]<<"三"<<M[0]<<"四"<<M[0]<<"五"<<M[0]<<"六"<<M[0]<<"七"<<M[0]<<endl;
    cout<<M[1]<<endl;
    cout<<M[2]<<endl;
    cout<<M[3]<<endl;
    cout<<M[4]<<endl;
    cout<<M[5]<<endl;
    cout<<M[6]<<endl;
    cout<<endl;*/
    returntrue;
    }
    
    
    int main(char argc,char** argv)
    {
    int i;
    double Sa[7] = {0},Ta[7] ={0};
    
    ///*源图像
    IplImage*img = cvLoadImage(filename,0);//灰度
    HuMoment(img);
    for(i=0;i<7;i++)
    {
    Sa[i] = M[i];
    M[i] =0;
    }
    cout<<Sa[0]<<endl;
    cout<<Sa[1]<<endl;
    cout<<Sa[2]<<endl;
    cout<<Sa[3]<<endl;
    cout<<Sa[4]<<endl;
    cout<<Sa[5]<<endl;
    cout<<Sa[6]<<endl;
    cout<<endl;
    //*/
    
    
    ///*模板图
    IplImage*tpl = cvLoadImage(filename2,0);//灰度
    HuMoment(tpl);
    for(i=0;i<7;i++)
    {
    Ta[i] = M[i];
    M[i] =0;
    }
    cout<<Ta[0]<<endl;
    cout<<Ta[1]<<endl;
    cout<<Ta[2]<<endl;
    cout<<Ta[3]<<endl;
    cout<<Ta[4]<<endl;
    cout<<Ta[5]<<endl;
    cout<<Ta[6]<<endl;
    cout<<endl;
    
    
    // 计算相似度
    double dbR =0; //相似度
    double dSigmaST =0;
    double dSigmaS =0;
    double dSigmaT =0;
    double temp =0; 
    
    for(i=0;i<7;i++)
    {
    temp = Sa[i]*Ta[i];
    dSigmaST+=temp;
    dSigmaS+=pow(Sa[i],2);
    dSigmaT+=pow(Ta[i],2);
    }
    dbR = dSigmaST/(sqrt(dSigmaS)*sqrt(dSigmaT));
    printf("%lf\n",dbR);
    //cout<<dbR<<endl;
    
    cvReleaseImage(&img);
    cvReleaseImage(&tpl);
    
    return0;
    }

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

    点击打开链接

    展开全文
  • 图像不变矩

    2019-08-23 21:19:44
    由二阶矩和三阶矩可以导出一组共七个不变矩不变矩图像的统计特性,满足平移、伸缩、旋转均不变的不变性,在图像识别领域得到了广泛的应用。 1.矩的定义 矩本身是概率与统计中的概念,其本质是数学期望。 对二维...

    图像的矩可以反应,一阶矩与形状有关,二阶矩显示曲线围绕直线平均值的扩展程度,三阶矩则是关于平均值的对称性的测量。由二阶矩和三阶矩可以导出一组共七个不变矩。不变矩是图像的统计特性,满足平移、伸缩、旋转均不变的不变性,在图像识别领域得到了广泛的应用。
    1.矩的定义
    矩本身是概率与统计中的概念,其本质是数学期望。在这里插入图片描述
    对二维离散函数f(x,y),其(j+k)阶矩可以表示为:m(j,k)=x=0N1y=0M1xjykf(x,y)m\left ( j,k \right )=\sum_{x=0}^{N-1}\sum_{y=0}^{M-1}x^{j}y^{k}f\left ( x,y \right )。其中参数(j+k)为矩的阶次,如果只关心目标形状,可是目标区域为1,背景区域为0,这样零阶矩就可以表示目标的面积。
    2.质心坐标及中心矩
    m10指的是目标区域上所有x坐标的总和,m01指的是目标区域上所有y坐标的总和,这样二值图像中的质心坐标为:
    在这里插入图片描述
    在这里插入图片描述
    为了消除原点矩对平移旋转的变化,把坐标原点平移到质心坐标位置,从而得到中心矩为:
    在这里插入图片描述
    中心矩和原点矩之间有一定的关系,其三阶以内的关系如下:
    在这里插入图片描述
    3.不变矩
    利用三阶以内的归一化中心矩可以得到不变矩。
    在这里插入图片描述

    其MATLAB实现代码如下:

    function inv_m7 = invariable_moment(in_image)
    % 功能:计算图像的Hu的七个不变矩
    % 输入:in_image-RGB图像
    % 输出:inv_m7-七个不变矩
    
    % 将输入的RGB图像转换为灰度图像   
    % image=rgb2gray(in_image);
    %将图像矩阵的数据类型转换成双精度型
    image=double(in_image);
    %%%=================计算 、 、 =========================
    %计算灰度图像的零阶几何矩 
    m00=sum(sum(image));     
    m10=0;
    m01=0;
    [row,col]=size(image);
    for i=1:row
        for j=1:col
            m10=m10+i*image(i,j);
            m01=m01+j*image(i,j);
        end
    end
    %%%=================计算 、 ================================
    u10=m10/m00;
    u01=m01/m00;
    %%%=================计算图像的二阶几何矩、三阶几何矩============
    m20 = 0;m02 = 0;m11 = 0;m30 = 0;m12 = 0;m21 = 0;m03 = 0;
    for i=1:row
        for j=1:col
            m20=m20+i^2*image(i,j);
            m02=m02+j^2*image(i,j);
            m11=m11+i*j*image(i,j);
            m30=m30+i^3*image(i,j);
            m03=m03+j^3*image(i,j);
            m12=m12+i*j^2*image(i,j);
            m21=m21+i^2*j*image(i,j);
        end
    end
    %%%=================计算图像的二阶中心矩、三阶中心矩============
    y00=m00;
    y10=0;
    y01=0;
    y11=m11-u01*m10;
    y20=m20-u10*m10;
    y02=m02-u01*m01;
    y30=m30-3*u10*m20+2*u10^2*m10;
    y12=m12-2*u01*m11-u10*m02+2*u01^2*m10;
    y21=m21-2*u10*m11-u01*m20+2*u10^2*m01;
    y03=m03-3*u01*m02+2*u01^2*m01;
    %%%=================计算图像的归格化中心矩====================
            n20=y20/m00^2;
            n02=y02/m00^2;
            n11=y11/m00^2;
            n30=y30/m00^2.5;
            n03=y03/m00^2.5;
            n12=y12/m00^2.5;
            n21=y21/m00^2.5;
    %%%=================计算图像的七个不变矩======================
    h1 = n20 + n02;                      
    h2 = (n20-n02)^2 + 4*(n11)^2;
    h3 = (n30-3*n12)^2 + (3*n21-n03)^2;  
    h4 = (n30+n12)^2 + (n21+n03)^2;
    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);
    h6 = (n20-n02)*((n30+n12)^2-(n21+n03)^2)+4*n11*(n30+n12)*(n21+n03);
    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);
     
    inv_m7= [h1 h2 h3 h4 h5 h6 h7]; 
    
    展开全文
  • 1、定义:图像矩:一个从数字图形中计算出来的矩集...不变矩:由二阶矩和三阶矩可以导出一组共七个不变矩不变矩是图像的统计特征,满足平移、伸缩、旋转均不变的不变形,在图像处理中,几何不变矩可以作为一个重要...

    1、定义:

    图像矩:一个从数字图形中计算出来的矩集,通常描述了该图像的全局特征,并提供了大量的关于该图像不同类型的几何特征信息,比如大小、位置、方向及形状等。

    一阶矩与形状有关,二阶矩显示了曲线围绕直线平均值的扩展程度,三阶矩则是关于平均值的对称性测量。

    不变矩:由二阶矩和三阶矩可以导出一组共七个不变矩。不变矩是图像的统计特征,满足平移、伸缩、旋转均不变的不变形,在图像处理中,几何不变矩可以作为一个重要的特征来表示物体,可以据此特征来对图像进行分类等操作。

    对于图像(单通道图像)来说,图像可以看成是一个平板物体,其一阶矩和零阶矩就可以拿来计算某个形状的重心,而二阶矩就可以拿来计算形状的方向。

    2、公式:

            

                           

    图像的重心坐标:

                              

    物体形状的方向:

                             

    其中

                       



    这 7 个不变矩构成一组特征量, Hu.M.K 在 1962 年证明了他们具有旋转,缩放和平移不变性。实际上,在对图片中物体的识别过程中,只有 M1 和 M2 不变性保持的比较好,其他的几个不变矩带来的误差比较大,有学者认为只有基于二阶矩的不变矩对二维物体的描述才是真正的具有旋转、缩放和平移不变性(M1 和M2 刚好都是由二阶矩组成的)。

    由 Hu 矩组成的特征量对图片进行识别,优点就是速度很快,缺点是识别率比较低。 Hu 不变矩一般用来识别图像中大的物体,对于物体的形状描述得比较好,图像的纹理特征不能太复杂,像识别水果的形状,或者对于车牌中的简单字符的识别效果会相对好一些。



    参考文献:

    [1]百度文库-图像矩:https://wenku.baidu.com/view/4a7e4ce890c69ec3d4bb75b4.html

    [2]https://wenku.baidu.com/view/af5a202c657d27284b73f242336c1eb91a373384.html?rec_flag=default&mark_pay_doc=2&mark_rec_page=1&mark_rec_position=1&mark_rec=view_r_1&clear_uda_param=1&sxts=1527581671468

    展开全文
  • 一 原理  几何矩是由Hu(Visual pattern recognition by moment ...① (p+q)阶不变矩定义: ② 对于数字图像,离散化,定义为:   ③ 归一化中心矩定义: ④Hu矩定义  

    一 原理

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

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

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

     

    ③ 归一化中心矩定义

    ④Hu矩定义

     



    //#################################################################################//
    double M[7] = {0};        //HU不变矩
    bool HuMoment(IplImage* img)
    {
    int bmpWidth = img->width;
    int bmpHeight = img->height;
    int bmpStep = img->widthStep; 
    int bmpChannels = img->nChannels;
        uchar*pBmpBuf = (uchar*)img->imageData;
    
    double m00=0,m11=0,m20=0,m02=0,m30=0,m03=0,m12=0,m21=0;  //中心矩 
    double x0=0,y0=0;    //计算中心距时所使用的临时变量(x-x') 
    double u20=0,u02=0,u11=0,u30=0,u03=0,u12=0,u21=0;//规范化后的中心矩
    //double M[7];    //HU不变矩 
    double t1=0,t2=0,t3=0,t4=0,t5=0;//临时变量, 
    //double Center_x=0,Center_y=0;//重心 
    int Center_x=0,Center_y=0;//重心 
    int i,j;            //循环变量
    
    //  获得图像的区域重心(普通矩)
    double s10=0,s01=0,s00=0;  //0阶矩和1阶矩  
    for(j=0;j<bmpHeight;j++)//y
        {
    for(i=0;i<bmpWidth;i++)//x
            {
                s10+=i*pBmpBuf[j*bmpStep+i];
                s01+=j*pBmpBuf[j*bmpStep+i];
                s00+=pBmpBuf[j*bmpStep+i];
            }
        }
        Center_x=(int)(s10/s00+0.5);
        Center_y=(int)(s01/s00+0.5);
    
    //  计算二阶、三阶矩(中心矩)
        m00=s00; 
    for(j=0;j<bmpHeight;j++) 
        {
    for(i=0;i<bmpWidth;i++)//x 
            { 
                x0=(i-Center_x); 
                y0=(j-Center_y); 
                m11+=x0*y0*pBmpBuf[j*bmpStep+i]; 
                m20+=x0*x0*pBmpBuf[j*bmpStep+i]; 
                m02+=y0*y0*pBmpBuf[j*bmpStep+i]; 
                m03+=y0*y0*y0*pBmpBuf[j*bmpStep+i];
                m30+=x0*x0*x0*pBmpBuf[j*bmpStep+i]; 
                m12+=x0*y0*y0*pBmpBuf[j*bmpStep+i]; 
                m21+=x0*x0*y0*pBmpBuf[j*bmpStep+i]; 
            } 
        } 
    
    //  计算规范化后的中心矩: mij/pow(m00,((i+j+2)/2)
        u20=m20/pow(m00,2); 
        u02=m02/pow(m00,2); 
        u11=m11/pow(m00,2);
        u30=m30/pow(m00,2.5); 
        u03=m03/pow(m00,2.5);
        u12=m12/pow(m00,2.5); 
        u21=m21/pow(m00,2.5);
    
    //  计算中间变量
        t1=(u20-u02); 
        t2=(u30-3*u12); 
        t3=(3*u21-u03); 
        t4=(u30+u12);
        t5=(u21+u03);
    
    //  计算不变矩 
        M[0]=u20+u02; 
        M[1]=t1*t1+4*u11*u11; 
        M[2]=t2*t2+t3*t3; 
        M[3]=t4*t4+t5*t5;
        M[4]=t2*t4*(t4*t4-3*t5*t5)+t3*t5*(3*t4*t4-t5*t5); 
        M[5]=t1*(t4*t4-t5*t5)+4*u11*t4*t5;
        M[6]=t3*t4*(t4*t4-3*t5*t5)-t2*t5*(3*t4*t4-t5*t5);
    
    returntrue;
    }

    下面的代码计算轮廓的矩,并根据1阶中心矩得到轮廓的质心,代码如下:

    src = imread( "../star1.jpg" ,1 );
    
    /// Convert image to gray and blur it
    cvtColor( src, src_gray, CV_BGR2GRAY );
    blur( src_gray, src_gray, Size(3,3) );
    
    namedWindow( "image", CV_WINDOW_AUTOSIZE );
    imshow( "image", src );
    
    Mat canny_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    
    //利用canny算法检测边缘
    Canny( src_gray, canny_output, thresh, thresh*2, 3 );
    namedWindow( "canny", CV_WINDOW_AUTOSIZE );
    imshow( "canny", canny_output );
    //查找轮廓
    findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    
    //计算轮廓矩
    vector<Moments> mu(contours.size() );
    for( int i = 0; i < contours.size(); i++ )
        { mu[i] = moments( contours[i], false ); }
    
    //计算轮廓的质心
    vector<Point2f> mc( contours.size() );
    for( int i = 0; i < contours.size(); i++ )
        { mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }
    
    //画轮廓及其质心
    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
    for( int i = 0; i< contours.size(); i++ )
        {
        Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
        drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
        circle( drawing, mc[i], 4, color, -1, 8, 0 );
        }
    
    namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
    imshow( "Contours", drawing );
    
    //打印轮廓面积和轮廓长度
    printf("\t Info: Area and Contour Length \n");
    for( int i = 0; i< contours.size(); i++ )
        {
        printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );
        Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
        drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
        circle( drawing, mc[i], 4, color, -1, 8, 0 );
        }


    展开全文
  • 图像-不变矩

    2011-01-04 11:07:00
    不变矩的主要思想是使用对变换...在图像处理中,几何不变矩可以作为一重要的特征来表示物体,可以据此特征来对图像进行分类等操作。 1.HU矩 几何矩是由Hu(Visual pattern recognition by moment invariants)在1962

    不变矩的主要思想是使用对变换不敏感的基于区域的几个矩作为形状特征,Hu提出了7个这样的矩,在他工作的基础上出现了很多改进的版本。

     

    图像的几何不变矩 

     

      矩特征主要表征了图像区域的几何特征,又称为几何矩, 由于其具有旋转、平移、尺度等特性的不变特征,所以又称其为不变矩。

    在图像处理中,几何不变矩可以作为一个重要的特征来表示物体,可以据此特征来对图像进行分类等操作。 

    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;......      

     

      2.Zernike矩        在模式识别中,一个重要的问题是对目标的方向性变化也能进行识别。Zernike 矩是一组正交矩,具有旋转不变性的特性,即旋转目标并不改变其模值。。由于Zernike 矩可以构造任意高阶矩,所以Zernike 矩的识别效果优于其他方法.

    Zernike 提出了一组多项式{ V nm ( x , y) } 。这组多项式在单位圆{ x2 + y2 ≤1} 内是正交的,具有如下形式: V nm ( x , y) = V nm (ρ,θ) = Rnm (ρ) exp ( jmθ) ,并且满足   ∫∫ x^2+y^2 <= 1 [( V nm ( x , y) 的共轭]* V pq ( x , y) d x d y.      = [pi/(n+1)]*δnpδmq .

    if(a==b) δab = 1 else δab = 0,n 表示正整数或是0;m是正整数或是负整数它表示满足m的绝对值<=n 而且n-m的绝对值是偶数这两个条件;ρ 表示原点到象素(x,y)的向量的距离;θ 表示向量ρ 跟x 轴之间的夹角(逆时针方向).

          对于一幅数字图象,积分用求和代替,即A nm =∑x∑y f(x,y) *[( V nm (ρ,θ) 的共轭],x^2+y^2 <=1,实际计算一幅给定图象的Zernike 矩时,必须将图象的重心移到坐标圆点,将图象象素点映射到单位圆内。由以上可知,使[ V nm (ρ,θ) 的共轭]可提取图象的特征,低频特性由n 值小的[( V nm (ρ,θ) 的共轭]来提取,高频特性由n 值大的来提取。Zernike 矩可以任意构造高价矩, 而高阶矩包含更多的图象信息, 所以Zernike 矩识别效果更好。,Zernike 矩仅仅具有相位的移动。它的模值保持不变。所以可以将| A nm | 作为目标的旋转不变性特征。因为| A nm | =| A n , - m | ,所以只需计算m ≥0 的情况。

     

     

    以下转自http://blog.csdn.net/byxdaz/archive/2009/12/28/5089448.aspx

    图像的几何不变矩

    矩特征主要表征了图像区域的几何特征,又称为几何矩, 由于其具有旋转、平移、尺度等特性的不变特征,所以又称其为不变矩。在图像处理中,几何不变矩可以作为一个重要的特征来表示物体,可以据此特征来对图像进行分类等操作。如果想详细了解不变矩的概念、公式等请参考下面的论文:

    不变矩方法研究

    一种实用的不变矩计算方法

     

    http://download.csdn.net/source/1943495

    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幅图作比较就好了。而对于其他的矩来说,由于一般是多维的关系,一般不好排序,只能顺序查找,自然速度有巨大的差别.所以。虽然几何矩不太能选出最像的,但可以快速排除不像的,提高搜索效率。

     

    几种简单的几何矩:

     

    令平面上点坐标为P(x,y),重心为C(x!,y!),

    二阶行距:rowMoment = [∑(x- x!)*(x- x!)]/A

    二阶列距:colMoment = [∑(y- y!)*(y- y!)]/A

    A为点的个数。

    由以上两个信息可以算出图形的圆度:circleDisgree = rowMoment /colMoment .如果图形的circleDisgree 越小于1,则它越趋向于长轴为y方向的椭圆。如果图形的circleDisgree 越大于1,则它越趋向于长轴为x方向的椭圆.如果图形的circleDisgree 越接近于1,则它越趋向于圆。

    所以我们可以使用圆度这种几何矩,对其进行索引,实现快速过滤。

     

    //代码实例

     

    double* Getsquare(int **Array1,int Width,int Height//Array1图像灰度矩阵

     

    {

     

      int x,y;

     

      double pSum,dx,dy;

     

      int xmax,xmin,ymax,ymin,xSum,ySum,PointSum;

     

      double dd,n1,n2,xAve,yAve;

     

      pSum=Height*Width;

     

      xSum=0;ySum=0;PointSum=0;

     

      xmin=10000;ymin=10000;xmax=-1;ymax=-1;

     

     

     

      for (y=0 ;y<Height; y++)

     

      {

     

        for (x=0; x<Width; x++)

     

        {

     

          if (Array1[x][y]==255)

     

          {

     

           continue;

     

          }

     

          xSum=xSum+x;ySum=ySum+y;++PointSum;

     

          if (x<xmin)

     

           {

     

              xmin=x;

     

           }

     

          if (x>xmax)

     

          {

     

             xmax=x;

     

          }

     

        }

     

        if (y<ymin)

     

        {

     

           ymin=y;

     

        }

     

        if (y>ymax)

     

        {

     

          ymax=y;

     

        }

     

      }

     

    if (pSum==0)

     

    {

     

     goto Loop;

     

    }

     

    xAve=xSum/pSum;

     

    yAve=ySum/pSum;

     

    ///////////////////////////////////////////上面为计算x,y平均值

     

    for (x=1; x<16; x++)

     

    {

     

     SqureNumber[x]=0;

     

    }

     

    // 11 20 02 21+ 21- 12+ 12- 30+ 30- 03+ 02-

     

    for (y=0; y<Height; y++)

     

    {

     

        for (x=0; x<Width; x++)

     

        {

     

          if (Array1[x][y]==255)

     

          {

     

           continue;

     

          }

     

          dx=x-xAve;dy=y-yAve;

     

          SqureNumber[1]=SqureNumber[1]+dx*dx;      // 计算 u(11) 11

     

          SqureNumber[2]=SqureNumber[2]+dx*dx;      // 计算 u(20) 20

     

          SqureNumber[3]=SqureNumber[3]+dy*dy;      // 计算 u(02) 02

     

          if (dy>0)

     

          {

     

            SqureNumber[4]=SqureNumber[4]+dx*dx*dy; // 计算 u(21)+ 21+

     

          }

     

          else

     

          {

     

            SqureNumber[5]=SqureNumber[5]+dx*dx*dy; // 计算 u(21)- 21-

     

          }

     

          if( dx>0 )

     

          {

     

            SqureNumber[6]=SqureNumber[6]+dx*dy*dy; // 计算 u(12)+ 12+

     

          }

     

          else

     

          {

     

            SqureNumber[7]=SqureNumber[7]+dx*dy*dy; // 计算 u(12}- 12-

     

          }

     

          if (dx>0 )

     

          {

     

            SqureNumber[8]=SqureNumber[8]+dx*dx*dx ;// 计算 u(30)+ 30+

     

          }

     

          else

     

          {

     

            SqureNumber[9]=SqureNumber[9]+dx*dx*dx; // 计算 u(30)- 30-

     

          }

     

          if (dy>0)

     

          {

     

            SqureNumber[10]=SqureNumber[10]+dy*dy*dy ;// 计算 u(03)+ 03+

     

          }

     

          else

     

          {

     

            SqureNumber[11]=SqureNumber[11]+dy*dy*dy;// 计算 u(03)- 03-

     

          }

     

        }//end for x

     

    }// end for y;

     

    for (x=1; x<12; x++)

     

    {

     

     SqureNumber[x]=SqureNumber[x]/pSum;

     

    }

     

    ///////////////////////////////////////////////////////计算图像的各阶矩

     

    for (x=12; x<21; x++)

     

    {

     

     SqureNumber[x]=0;

     

    }

     

    SqureNumber[12]=((SqureNumber[2]-SqureNumber[3])/(SqureNumber[2]+SqureNumber[3]))/2; //长宽比特征

     

     

     

    dd=sqrt((SqureNumber[2]-SqureNumber[3])*(SqureNumber[2]-SqureNumber[3])+4*SqureNumber[1]*SqureNumber[1]);

     

    dd=dd+(SqureNumber[2]-SqureNumber[3]);

     

    SqureNumber[16]=2*atan(dd/(2*SqureNumber[1]))/M_PI; ///字型倾斜度

     

     

     

    dd=sqrt((SqureNumber[2]-SqureNumber[3])*(SqureNumber[2]-SqureNumber[3])+4*SqureNumber[1]*SqureNumber[1]);

     

    n1=((SqureNumber[2]+SqureNumber[3])+dd)/2;

     

    n2=((SqureNumber[2]+SqureNumber[3])-dd)/2;

     

    SqureNumber[14]=(n1-n2)/(n1+n2);                   //拉长度

     

     

     

    n1=sqrt((ymax-ymin)*(xmax-xmin));

     

    dd=sqrt((SqureNumber[2]+SqureNumber[3])/PointSum);

     

    SqureNumber[15]=dd/n1;                             //伸展度

     

     

     

    dd=(SqureNumber[8]-SqureNumber[9])/(SqureNumber[8]+SqureNumber[9]);

     

    SqureNumber[16]=(dd+1)/2;                          //水平偏移度

     

     

     

    dd=(SqureNumber[10]-SqureNumber[11])/(SqureNumber[10]+SqureNumber[11]);

     

    SqureNumber[17]=(dd+1)/2;                          //垂直偏移度

     

     

     

    dd=(SqureNumber[4]-SqureNumber[5])/(SqureNumber[4]+SqureNumber[5]);

     

    SqureNumber[18]=(dd+1)/2;                          //水平伸展度度

     

     

     

    dd=(SqureNumber[6]-SqureNumber[7])/(SqureNumber[6]+SqureNumber[7]);

     

    SqureNumber[19]=(dd+1)/2;                          //垂直伸展度

     

    Loop:;

     

    }

     

    2.Zernike矩

     

    在模式识别中,一个重要的问题是对目标的方向性变化也能进行识别。Zernike 矩是一组正交矩,具有旋转不变性的特性,即旋转目标并不改变其模值。。由于Zernike 矩可以构造任意高阶矩,所以Zernike 矩的识别效果优于其他方法.

     

    Zernike 提出了一组多项式{ V nm ( x , y) } 。这组多项式在单位圆{ x2 + y2 ≤1} 内是正交的,具有如下形式: V nm ( x , y) = V nm (ρ,θ) = Rnm (ρ) exp ( jmθ) ,并且满足   ∫∫ x^2+y^2 <= 1  [( V nm ( x , y) 的共轭]* V pq ( x , y) d x d y.      = [pi/(n+1)]*δnpδmq .

     

    if(a==b)  δab = 1 else  δab = 0,n 表示正整数或是0;m是正整数或是负整数它表示满足m的绝对值<=n 而且n-m的绝对值是偶数这两个条件;ρ 表示原点到象素(x,y)的向量的距离;θ 表示向量ρ 跟x 轴之间的夹角(逆时针方向).

     

    对于一幅数字图象,积分用求和代替,即A nm =∑x∑y f(x,y) *[( V nm (ρ,θ) 的共轭],x^2+y^2 <=1

     

    实际计算一幅给定图象的Zernike 矩时,必须将图象的重心移到坐标圆点,将图象象素点映射到单位圆内。由以上可知,使[ V nm (ρ,θ) 的共轭]可提取图象的特征,低频特性由n 值小的[( V nm (ρ,θ) 的共轭]来提取,高频特性由n 值大的来提取。Zernike 矩可以任意构造高价矩, 而高阶矩包含更多的图象信息, 所以Zernike 矩识别效果更好。,Zernike 矩仅仅具有相位的移动。

     

    它的模值保持不变。所以可以将| A nm | 作为目标的旋转不变性特征。因为| A nm | =| A n , - m | ,所以只需计算m ≥0 的情况。

     

    不变矩的应用过程一般包括:1)选择合适的不变矩类型;2)选择分类器(如神经网络、最短距离等);3)如果是神经网络分类器,则需要计算学习样例的不变矩去训练神经网络;4)计算待识别对象的不变矩,输入神经网络就可得到待识别对象的类型,或者计算待识别对象不变矩与类别对象不变矩之间的距离,选择最短距离的类别作为待识别对象的类别。

    可以看出,不变矩作用主要目的是描述事物(图像)的特征。人眼识别图像的特征往往又表现为“求和”的形式,因此不变矩是对图像元素进行了积分操作。

    不变矩能够描述图像整体特征就是因为它具有平移不变形、比例不变性和旋转不变性等性质。

    然而,另一方面图像的各阶不变矩究竟代表的什么特征很难进行直观的物理解释。

    展开全文
  • 图像的几何不变矩

    2015-10-29 20:48:52
    图像处理中,几何不变矩可以作为一重要的特征来表示物体,可以据此特征来对图像进行分类等操作。  1. HU矩 几何矩是由Hu(Visual pattern recognition by moment invariants)在1962年提出的,图像f(x,y)
  • 数字图像是一二维的离散信号,对上述公式进行离散化之后: 其中C与R分别表示图像的列与行。各阶的物理意义: 0阶(m00):目标区域的质量 1阶(m01,m10):目标区域的质心 2阶(m02,m11,m20):...
  • 获取图像的Hu不变矩

    2019-04-23 09:31:29
    使用C++、opencv获取图像的Hu不变矩 矩函数在图像分析中有着广泛的应用,如模式识别、目标分类、目标识别与方位估计、图像编码与重构等。一从一幅数字图形中计算出来的矩集,通常描述了该图像形状的全局特征,并...
  • 图像处理中,几何不变矩可以作为一重要的特征来表示物体,可以据此特征来对图像进行分类等操作。 1.HU矩 几何矩是由Hu(Visual pattern recognition by moment invariants)在1962年提出的,图像f(x,y)的(p...
  • 图像不变矩

    2012-09-13 19:30:49
    #include #include using namespace std; using namespace cv; /*====================================... 功能:不变矩匹配 时间:3/28/2011 SkySeraph HQU 参考: //===========================================
  • 不变矩的主要思想是使用对变换不敏感的基于区域的几矩作为形状特征,Hu提出了7个这样的矩,在他工作的基础上出现了很多改进的版本。   图像的几何不变矩     矩特征主要表征了图像区域
  • 数字图像处理》书上说这7个矩是旋转、缩放、平移不变的,因此用这7个矩就可以代表一图像了。我只试验了缩放的,这几数几乎是不变的,也许做图像检索的时候可以用到。 代码: main.m clear all; close ...
  • 毕设选题【Matlab数字图像类】 ★图像检索 ★学生成绩管理系统,图书借阅管理系统 ★水果分类系统 ★基于图像的考勤监控系统 ★人民币面值识别 ★图像雾霾去雾系统 ★验证码识别 ★车牌识别【国内全国车牌...
1 2 3 4 5 ... 20
收藏数 1,211
精华内容 484