图像的七个不变矩 可用于图像的匹配
矩特征主要表征了圖像區域的幾何特征,又稱為幾何矩, 由于其具有旋轉、平移、尺度等特性的不變特征,所以又稱其為不變矩。在圖像處理中,幾何不變矩可以作為一個重要的特征來表示物體,可以據此特征來對圖像進行分類等操作。
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:rowfor j=1:colm10=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:rowfor j=1:colm20=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; }
其他幾種矩的比較可以參考這篇文章:
點擊打開鏈接
總結
以上是生活随笔為你收集整理的图像的七个不变矩 可用于图像的匹配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像的多分辨率金字塔详解
- 下一篇: susan算子的运用