圖像的矩:Hu矩

參考

  • 【圖像算法】圖像特徵:幾何不變矩–Hu矩 - SkySeraph - 博客園: https://www.cnblogs.com/skyseraph/archive/2011/07/19/2110183.html
  • 圖像的矩特徵 - ☆Ronny丶 - 博客園: https://www.cnblogs.com/ronny/p/3985810.html
  • 《圖像處理、分析與機器視覺》
  • 《數字圖像處理》岡薩雷斯–第十一章-不變矩

一、矩的概念

圖像識別的一個核心問題是圖像的特徵提取,簡單描述即爲用一組簡單的數據(圖像描述量)來描述整個圖像,這組數據越簡單越有代表性越好。良好的特徵不受光線、噪點、幾何形變的干擾。圖像識別發展幾十年,不斷有新的特徵提出,而圖像不變矩就是其中一個。

針對於一幅圖像,我們把像素的座標看成是一個二維隨機變量(X,Y)(X,Y),那麼一幅灰度圖像可以用二維灰度密度函數來表示,因此可以用矩來描述灰度圖像的特徵。

不變矩(Invariant Moments)是一處高度濃縮的圖像特徵,具有平移、灰度、尺度、旋轉不變性。M.K.Hu在1961年首先提出了不變矩的概念。1979年M.R.Teague根據正交多項式理論提出了Zernike矩。下面主要介紹這兩種矩特徵的算法原理與實現。

二、Hu矩

2.1 (p+q)階不變矩的定義

對於灰度分佈爲f(x,y)f(x,y)的圖像,其(p+q)(p+q)階矩定義爲:

mpq=xpyqf(x,y)dxdyp,q=0,1,2,m_{pq}=\iint x^py^qf(x,y)dxdy\qquad p,q=0,1,2,\cdots

(p+q)(p+q)階中心矩定義爲:

μpq=(xx0)p(y=y0)qf(x,y)dxdy\mu_{pq}=\iint(x-x_0)^p(y=y_0)^qf(x,y)dxdy

其中,矩心爲:

x0=m10m00,y0=m01m00x_0=\frac {m_{10}}{m_{00}},y_0=\frac {m_{01}}{m_{00}}

由於數字圖像屬於離散化數據,離散狀態下,f(x,y)f(x,y)(p+q)(p+q)階普通矩和中心矩的公式如下:

mpq=x=1My=1Nxpyqf(x,y)m_{pq}=\sum_{x=1}^M\sum_{y=1}^Nx^py^qf(x,y)

μpq=x=1My=1N(xx0)p(yy0)qf(x,y)其中p,q=0,1,2,\mu_{pq}=\sum_{x=1}^M\sum_{y=1}^N(x-x_0)^p(y-y_0)^qf(x,y)\quad\text{其中}\quad p,q=0,1,2,\cdots

離散化後的矩心x0與y0的計算方法同連續狀態下的計算公式。

p、q即在x、y這兩個像素位置上的多少次方。在p、q不爲0時,求mpqm_{pq}可以看作 x的p次方 與 y的q次方 作爲權重疊加到當前x、y位置上的灰度值,然後累加。當求m00m_{00}時,可知僅爲圖像的灰度值進行累加。

2.2 歸一化中心距

當圖像發生變化,如平移、旋轉等,mpqm_{pq}也發生變化。而由於μpq\mu_{pq}式與中心有關,其對平移不敏感,但依舊對旋轉敏感。爲了解決這個問題,這裏提出歸一化中心矩

ypq=μpqμ00ry_{pq}=\frac {\mu_{pq}}{\mu_{00}^r}

式中:r=p+q+22p+q=2,3,r=\frac {p+q+2}{2} \quad p+q=2,3,\cdots

歸一化中心矩使用的是中心矩進行的計算。可以注意到,歸一化中心矩計算ypqy_{pq}時使用的μ00\mu_{00}從數值上來看,就等同於m00m_{00}

2.3 Hu矩定義

Hu利用二階和三階中心矩(即p+q=2,3p+q = 2,3)構造了7個不變矩I1I7I_1\sim I_7,這7個不變矩構成一組特徵量,Hu.M.K在1962年證明了他們具有旋轉,縮放和平移不變性,它們在連續圖像條件下可以保持平移、縮放和旋轉不變。具體定義如下:

{I1=y20+y02I2=(y20y02)2+4y112I3=(y303y12)2+(3y21y03)2I4=(y30+y12)2+(y21+y03)2I5=(y303y12)(y30+y12)[(y30+y12)23(y21+y03)2]+(3y21y03)(y21+y03)[3(y30+y12)2(y21+y03)2]I6=(y20y02)[(y30+y12)2(y21+y03)2]+4y11(y30+y12)(y21+y03)I7=(3y21y03)(y30+y12)[(y30+y12)23(y21+y03)2](y303y12)(y21+y03)[3(y30+y12)2(y21+y03)2] \begin{cases} I_1 = y_{20}+y_{02}\\\\ I_2 = (y_{20}-y_{02})^2+4y_{11}^2\\\\ I_3 = (y_{30}-3y_{12})^2+(3y_{21}-y_{03})^2\\\\ I_4 = (y_{30}+y_{12})^2+(y_{21}+y_{03})^2\\\\ I_5=(y_{30}-3y_{12})(y_{30}+y_{12})[(y_{30}+y_{12})^2-3(y_{21}+y_{03})^2]+(3y_{21}-y_{03})(y_{21}+y_{03})[3(y_{30}+y_{12})^2-(y_{21}+y_{03})^2]\\\\ I_6=(y_{20}-y_{02})[(y_{30}+y_{12})^2-(y_{21}+y_{03})^2]+4y_{11}(y_{30}+y_{12})(y_{21}+y_{03})\\\\ I_7=(3y_{21}-y_{03})(y_{30}+y_{12})[(y_{30}+y_{12})^2-3(y_{21}+y_{03})^2]-(y_{30}-3y_{12})(y_{21}+y_{03})[3(y_{30}+y_{12})^2-(y_{21}+y_{03})^2] \end{cases}

2.4 Hu矩計算代碼

參考自:【圖像算法】圖像特徵:幾何不變矩–Hu矩 - SkySeraph - 博客園,修正了部分格式問題與變量名,方便對照上面進行查看。

double I[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 u00=0,u11=0,u20=0,u02=0,u30=0,u03=0,u12=0,u21=0;     //中心矩 
    double x0=0,y0=0;                                           //計算中心距時所使用的臨時變量(x-x') 
    double y20=0,y02=0,y11=0,y30=0,y03=0,y12=0,y21=0;           //規範化後的中心矩
    double t1=0,t2=0,t3=0,t4=0,t5=0;                            //臨時變量, 
    int center_x0=0,center_y0=0;                                //矩心 
    int i,j;                                                    //循環變量

    //  獲得圖像的區域重心(普通矩)
    double m10=0,m01=0,m00=0;                                   //0階矩和1階矩  
    for(j=0;j<bmpHeight;j++)//y
    {
        for(i=0;i<bmpWidth;i++)//x
        {
            m10+=i*pBmpBuf[j*bmpStep+i];
            m01+=j*pBmpBuf[j*bmpStep+i];
            m00+=pBmpBuf[j*bmpStep+i];
        }
    }
    center_x0=(int)(m10/m00+0.5);
    center_y0=(int)(m01/m00+0.5);

    //  計算二階、三階矩(中心矩)
    u00=m00;                        //歸一化中心矩計算時使用的u00從數值上來看,就等同於m00。
    for(j=0;j<bmpHeight;j++) 
    {
        for(i=0;i<bmpWidth;i++)//x 
        { 
            x0=(i-center_x0); 
            y0=(j-center_x0); 
            u11+=x0*y0*pBmpBuf[j*bmpStep+i]; 
            u20+=x0*x0*pBmpBuf[j*bmpStep+i]; 
            u02+=y0*y0*pBmpBuf[j*bmpStep+i]; 
            u03+=y0*y0*y0*pBmpBuf[j*bmpStep+i];
            u30+=x0*x0*x0*pBmpBuf[j*bmpStep+i]; 
            u12+=x0*y0*y0*pBmpBuf[j*bmpStep+i]; 
            u21+=x0*x0*y0*pBmpBuf[j*bmpStep+i]; 
        } 
    } 

    //  計算規範化後的中心矩: uij/pow(u00,((i+j+2)/2) , 而u00 = m00,故直接用m00
    y20=u20/pow(m00,2); 
    y02=u02/pow(m00,2); 
    y11=u11/pow(m00,2);
    y30=u30/pow(m00,2.5); 
    y03=u03/pow(m00,2.5);
    y12=u12/pow(m00,2.5); 
    y21=u21/pow(m00,2.5);

    //  計算中間變量
    t1=(y20-y02); 
    t2=(y30-3*y12); 
    t3=(3*y21-y03); 
    t4=(y30+y12);
    t5=(y21+y03);

    //  計算不變矩 
    I[0]=y20+y02; 
    I[1]=t1*t1+4*y11*y11; 
    I[2]=t2*t2+t3*t3; 
    I[3]=t4*t4+t5*t5;
    I[4]=t2*t4*(t4*t4-3*t5*t5)+t3*t5*(3*t4*t4-t5*t5); 
    I[5]=t1*(t4*t4-t5*t5)+4*y11*t4*t5;
    I[6]=t3*t4*(t4*t4-3*t5*t5)-t2*t5*(3*t4*t4-t5*t5);

    return true;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章