生活随笔
收集整理的這篇文章主要介紹了
图像处理基本算法 形状特征
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
形狀特征
? (一)特點:各種基于形狀特征的檢索方法都可以比較有效地利用圖像中感興趣的目標來進行檢索,但它們也有一些共同的問題,包括:①目前基于形狀的檢索方法還缺乏比較完善的數學模型;②如果目標有變形時檢索結果往往不太可靠;③許多形狀特征僅描述了目標局部的性質,要全面描述目標常對計算時間和存儲量有較高的要求;④許多形狀特征所反映的目標形狀信息與人的直觀感覺不完全一致,或者說,特征空間的相似性與人視覺系統感受到的相似性有差別。另外,從 2-D 圖像中表現的 3-D 物體實際上只是物體在空間某一平面的投影,從 2-D 圖像中反映出來的形狀常不是 3-D 物體真實的形狀,由于視點的變化,可能會產生各種失真。
?
(二)常用的特征提取與匹配方法
?
Ⅰ幾種典型的形狀特征描述方法
?
通常情況下,形狀特征有兩類表示方法,一類是輪廓特征,另一類是區域特征。圖像的輪廓特征主要針對物體的外邊界,而圖像的區域特征則關系到整個形狀區域。
?
幾種典型的形狀特征描述方法:
?
(1)邊界特征法該方法通過對邊界特征的描述來獲取圖像的形狀參數。其中Hough 變換檢測平行直線方法和邊界方向直方圖方法是經典方法。Hough 變換是利用圖像全局特性而將邊緣像素連接起來組成區域封閉邊界的一種方法,其基本思想是點—線的對偶性;邊界方向直方圖法首先微分圖像求得圖像邊緣,然后,做出關于邊緣大小和方向的直方圖,通常的方法是構造圖像灰度梯度方向矩陣。
?
(2)傅里葉形狀描述符法
?
傅里葉形狀描述符(Fourier shape descriptors)基本思想是用物體邊界的傅里葉變換作為形狀描述,利用區域邊界的封閉性和周期性,將二維問題轉化為一維問題。
?
由邊界點導出三種形狀表達,分別是曲率函數、質心距離、復坐標函數。
?
(3)幾何參數法
?
形狀的表達和匹配采用更為簡單的區域特征描述方法,例如采用有關形狀定量測度(如矩、面積、周長等)的形狀參數法(shape factor)。在 QBIC 系統中,便是利用圓度、偏心率、主軸方向和代數不變矩等幾何參數,進行基于形狀特征的圖像檢索。
?
需要說明的是,形狀參數的提取,必須以圖像處理及圖像分割為前提,參數的準確性必然受到分割效果的影響,對分割效果很差的圖像,形狀參數甚至無法提取。
?
(4)形狀不變矩法
?
利用目標所占區域的矩作為形狀描述參數。
?
(5)其它方法
?
近年來,在形狀的表示和匹配方面的工作還包括有限元法(Finite Element Method 或 FEM)、旋轉函數(Turning Function)和小波描述符(Wavelet Descriptor)等方法。
?
實際上,只是提取物體的形狀,這并不難,最難的是這些特征該怎么用!
特征嘛,自然是講此物區分彼物的特點。
那么假如,給出了一系列不同形狀物體的輪廓該如何識別出他們呢?正方形,圓形,矩形,橢圓,不規則圖形,再進一步,這些圖形由于受到信號的干擾,有噪聲存在時,該如何去識別他們呢?
那就可以使用形狀的特征了,我們定義一些參數,來描述這些形狀。
1 矩形度:R = A0/A; A0為區域面積,A為區域最小外接矩形面積。
那么R = 1 時,為矩形的概率很大,R = PI/4時為圓的可能性最大
2 體態比 T = a/b;
a b 分別為區域最小外接矩形的長和寬。
T = 1 為正方形或者圓形,
T>1 為細長圖形
3 球狀性 S = Ri/Rc
Ri Rc分別為內切圓和外接圓半徑,圓心都在中心上
4 球狀性 C = Ur/Pr
Ur 為區域重心到輪廓點的平均距離
Pr 為區域重心到輪廓點的均方差
5 中心矩
這一特征,使用頗為頻繁,OpenCV有專門的函數求解(p,q)次矩
6 長軸 短軸
最小外接矩形的長軸和短軸
7面積
一般會作為閾值使用,判定某個區域的面積在兩個閾值之間才判定有效
?
?下面給出各個形狀特征的求法:
[cpp]?view plaincopy
?? #include?<cv.h>?? #include?<cxcore.h>?? #include?<highgui.h>?? #include?<iostream>?? using?namespace?std;?? ?? int?main()?? {?? ????IplImage?*src?=?cvLoadImage("E:\\image\\mapleleaf.tif",0);?? ????IplImage?*image?=?cvCreateImage(cvGetSize(src),8,3);??? ????image?=?cvCloneImage(src);?? ????cvNamedWindow("src",1);?? ????cvNamedWindow("dst",1);?? ????cvShowImage("src",src);?? ?? ????CvMemStorage?*storage?=?cvCreateMemStorage(0);?? ????CvSeq?*?seq?=?cvCreateSeq(CV_SEQ_ELTYPE_POINT,?sizeof(CvSeq),?sizeof(CvPoint),?storage);?? ????CvSeq?*?tempSeq?=?cvCreateSeq(CV_SEQ_ELTYPE_POINT,?sizeof(CvSeq),?sizeof(CvPoint),?storage);?? ?????? ????IplImage?*dst?=?cvCreateImage(cvGetSize(src),8,3);??? ????cvZero(dst);?? ????double?length,area;?? ?? ?????? ????int?cnt?=?cvFindContours(src,storage,&seq);?? ????cout<<"number?of?contours???"<<cnt<<endl;?? ?????? ?????? ?????? ????CvRect?rect;?? ????CvBox2D?box;?? ????double?axislong,axisShort;?? ????double?temp1=?0.0,temp2?=?0.0;?? ????double?Rectangle_degree;?? ????double?long2short;?? ????double?x0,y0;?? ????long?sumX??=?0?,sumY?=?0;?? ????double?sum?=0.0;?? ????int?i,j,m,n;?? ????unsigned?char*?ptr;?? ?? ????double?UR;?? ????double?PR;?? ????CvPoint?*?contourPoint;??? ????int?count?=?0;?? ????double?CDegree;?? ?? ????CvPoint?*A,*B,*C;?? ????double?AB,BC,AC;?? ????double?cosA,sinA;?? ????double?tempR,inscribedR;?? ?????? ????for?(tempSeq?=?seq;tempSeq?!=?NULL;?tempSeq?=?tempSeq->h_next)?? ????{?? ?????????? ????????length?=?cvArcLength(tempSeq);?? ????????area?=?cvContourArea(tempSeq);?? ????????cout<<"Length?=?"<<length<<endl;?? ????????cout<<"Area?=?"<<area<<endl;?? ????????cout<<"num?of?point?"<<tempSeq->total<<endl;?? ?????????? ????????rect?=?cvBoundingRect(tempSeq,1);?? ?????????? ?? ?????????? ????????cvDrawContours(dst,tempSeq,CV_RGB(255,0,0),CV_RGB(255,0,0),0);?? ????????cvRectangleR(dst,rect,CV_RGB(0,255,0));?? ????????cvShowImage("dst",dst);?? ?????????? ?? ?????????? ????????CvPoint2D32f?center;?? ????????float?radius;?? ????????cvMinEnclosingCircle(tempSeq,¢er,&radius);?? ????????cvCircle(dst,cvPointFrom32f(center),cvRound(radius),CV_RGB(100,100,100));?? ????????cvShowImage("dst",dst);?? ?????????? ?? ?????????? ????????CvBox2D?ellipse?=?cvFitEllipse2(tempSeq);?? ????????cvEllipseBox(dst,ellipse,CV_RGB(255,255,0));?? ????????cvShowImage("dst",dst);?? ?????????? ?? ?? ?????????? ????????CvPoint2D32f?pt[4];?? ????????box?=?cvMinAreaRect2(tempSeq,0);?? ????????cvBoxPoints(box,pt);?? ????????for(int?i?=?0;i<4;++i){?? ????????????cvLine(dst,cvPointFrom32f(pt[i]),cvPointFrom32f(pt[((i+1)%4)?(i+1):0]),CV_RGB(0,0,255));?? ????????}?? ????????cvShowImage("dst",dst);?? ?????????? ?? ?? ?????????? ?????????? ????????temp1?=?sqrt(pow(pt[1].x?-pt[0].x,2)?+?pow(pt[1].y?-pt[0].y,2));?? ????????temp2?=?sqrt(pow(pt[2].x?-pt[1].x,2)?+?pow(pt[2].y?-pt[1].y,2));?? ?? ????????if?(temp1?>?temp2)?? ????????{?? ????????????axislong?=?temp1;?? ????????????axisShort=temp2;?? ????????}??? ????????else?? ????????{?? ????????????axislong?=?temp2;?? ????????????axisShort=temp1;?? ????????}?? ?????????? ????????cout<<"long?axis:?"<<axislong<<endl;?? ????????cout<<"short?axis:?"<<axisShort<<endl;?? ?????????? ????????Rectangle_degree?=?(double)area/(axisShort*axislong);?? ?? ????????cout<<"Rectangle?degree?:"<<Rectangle_degree<<endl;?? ?????????? ????????long2short?=?axislong/axisShort;?? ????????cout<<"ratio?of?long?axis?to?short?axis:?"<<long2short<<endl;?? ?????????? ?????????? ?????????? ?????????? ????????? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ?????????? ?????????? ????????sumX?=?0;?? ????????sumY?=?0;?? ????????src?=?cvCloneImage(image);?? ????????for?(int?i?=?0?;?i<?src->height;i++)?? ????????{?? ????????????for?(int?j?=?0;?j<?src->width;j++)?? ????????????{?? ????????????????ptr?=?(unsigned?char?*)src->imageData?+?i*src->widthStep?+?j;?? ????????????????if?((*ptr)?>?128)?? ????????????????{?? ????????????????????sumX?+=?(long)j;?? ????????????????????sumY?+=?(long)i;?? ????????????????}?? ?? ????????????}?? ????????}?? ????????x0?=?sumX/area;?? ????????y0?=?sumY/area;?? ????????cout<<"center?of?gravity?"<<x0<<"???"<<y0<<endl;?? ??????? ????????sum?=?0;?? ????????count?=?0;?? ????????for?(m?=?0?;?m<?tempSeq->total;m++)?? ????????{?? ????????????contourPoint?=?(CvPoint*)cvGetSeqElem(tempSeq,m);?? ????????????sum?+=?sqrt(pow(contourPoint->x?-?x0,2)+?pow(contourPoint->y?-?y0,2));?? ????????????count++;?? ????????}?? ????????UR?=?sum/count;?? ????????cout<<"mean?distance?to?center?of?gravity"<<UR<<endl;?? ?????????? ????????sum?=?0;?? ????????for?(m?=?0?;?m<?tempSeq->total;m++)?? ????????{?? ????????????contourPoint?=?(CvPoint*)cvGetSeqElem(tempSeq,m);?? ????????????temp1?=?sqrt(pow(contourPoint->x?-?x0,2)+?pow(contourPoint->y?-?y0,2));?? ????????????sum?+=?pow(temp1?-?UR,2);?? ????????}?? ????????PR?=?sum/count;?? ????????cout<<"mean?square?error?of?distance?to?center?of?gravity"<<PR<<endl;?? ?????????? ????????CDegree=?UR/PR;?? ????????cout<<"degree?of?circle?"<<CDegree<<endl;?? ?????????? ?????????? ????????cvWaitKey(0);?? ????}?? ?????? ?????? ????cvReleaseImage(&src);?? ????cvReleaseImage(&dst);?? ????cvReleaseMemStorage(&storage);???? ?????? ????return?0;?? }??
?
總結
以上是生活随笔為你收集整理的图像处理基本算法 形状特征的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。