金字塔分割算法由cvPrySegmentation所實現,該函數的使用很簡單;需要注意的是圖像的尺寸以及金字塔的層數,圖像的寬度和高度必須能被2整除,能夠被2整除的次數決定了金字塔的最大層數。
PyrSegmentation 用金字塔實現圖像分割 void cvPyrSegmentation( IplImage* src, IplImage* dst, CvMemStorage* storage, CvSeq** comp, int level, double threshold1, double threshold2 ); src 輸入圖像. dst 輸出圖像. storage Storage: 存儲連通部件的序列結果 comp 分割部件的輸出序列指針 components. level 建立金字塔的最大層數 threshold1 建立連接的錯誤閾值 threshold2 分割簇的錯誤閾值 函數 cvPyrSegmentation 實現了金字塔方法的圖像分割。金字塔建立到 level 指定的最大層數。如果 p(c(a),c(b))<threshold1,則在層 i 的象素點 a 和它的相鄰層的父親象素 b 之間的連接被建立起來, 定義好連接部件後,它們被加入到某些簇中。如果p(c(A),c(B))<threshold2,則任何兩個分割 A 和 B 屬於同一簇。 如果輸入圖像只有一個通道,那麼 p(c1,c2)=|c1-c2|. 如果輸入圖像有單個通道(紅、綠、蘭),那麼p(c1,c2)=0,3·(c1r-c2r)+0,59·(c1g-c2g)+0,11·(c1b-c2b) . 每一個簇可以有多個連接部件。圖像 src 和 dst 應該是 8-比特、單通道 或 3-通道圖像,且大小一樣 。 |
//學習OpenCV中的介紹:
圖像分割需要先建立一個圖像金字塔,然後在Gi的像素和Gi+1的像素直接依照對應關係,建立起"父-子"關係,通過這種方式,快速初始分割可以先在金字塔高層的低分辨率圖像上完成,然後逐層對分割加以優化;
在程序寫好後,VS總是編譯不通過,提示cvPyrSegmentation是未標示的函數。在網上找了好久,才找到解決辦法。問題是缺少了legacy這個庫文件。只要將這個庫放進來即可。
具體是 項目屬性-——VC++ Directories——Include Directories——加入編輯的路徑(D:\OPENCV\opencv\build\include\opencv2\legacy),這是相對於本人的安裝路徑,主要是有\opencv\build\include\opencv2\legacy。加入後,即可正常使用函數了。
附:
在Ubuntu 10.04上安裝openCV很方便:
#apt-get install opencv-doc libcv4 libhighgui4 libcvaux4 libcv-dev libcvaux-dev libhighgui-dev
同時最好順便把ffmpeg的開發文件也裝上。
然後編譯《Learning OpenCV》一書的例子試一把,理論上把Makefile.txt改爲Makefile然後make就行,但在我機子上有錯誤:
1. 'cvPyrSegmentation' undeclared identifier
定義在 /usr/local/include/opencv2/legacy/legacy.hpp中,默認沒include進來,把該頭文件包含進來即可。
2. 'cvCalcOpticalFlowHS' undeclared identifier
原因同上,也在legacy.hpp中。
3. cvRand,cvRandInit,cvRandSetRange等函數undeclred identifier
這些函數在 legacy/compat.hpp中,包含進來即可,然後鏈接時還要鏈接libopencv_legacy.so(-lopencv_legacy)。
4. 'CvDTreeParams::CvDTreeParams(...)' undefined reference
鏈接時加-lopencv_ml去鏈接libopencv_ml庫。
void CdialogCVDlg::OnBnClickedBtnpyrsegment()
{
// TODO: Add your control notification handler code here
cvNamedWindow("src",CV_WINDOW_AUTOSIZE);
cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);
img=cvLoadImage("D:\KK.jpg",-1);
cvShowImage("src",img);
img1=cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
CvMemStorage * stoage = cvCreateMemStorage(0) ;
CvSeq* comp=NULL;
int level = 2 ; //進行n層採樣
double threshold1 = 150 ;
double threshold2 = 30 ;
cvPyrSegmentation(img,img1,stoage,&comp,level,threshold1,threshold2);
cvShowImage("dst",img1);
}