1. 程式人生 > >opencv二值圖孔洞填充演算法(方法系轉載)

opencv二值圖孔洞填充演算法(方法系轉載)

方法原文見:http://geniusshare.i.sohu.com/blog/view/149854097.htm 作者:天才的自省

 孔洞者,不與大背景聯通卻具有大背景顏色的畫素也,所以思路如下:將大背景全部用前景色(白色)填充(cvFloodFill函式,一(0,0)為種子點即可),即得到孔洞圖(此時孔洞用為黑色),然後將此圖二值反轉,即得到用白色表示的孔洞圖,然後將此空洞圖與原二值圖相加(使用cvAdd函式即可)即可將孔洞填充掉,這個方法目前寂靜基本上可以填充孔洞,但是還有一點瑕疵,那就是用完cvFloodFill函式填充大背景後邊界卻保留下來了,即未填充,當然這個對孔洞填充來說的視覺效果上沒有什麼影響的,但是嚴格來講還是有一點問題的,我查閱了cvFloodFill函式的引數說明,卻未看出到底是什麼使得邊緣不被填充而被保留了下來,如果解決了這個問題,那這個填充演算法就完美了。


實現程式碼:

	IplImage* otst_test=cvLoadImage("f:\\S1212L06_ROI.jpg",CV_LOAD_IMAGE_GRAYSCALE);
	IplImage* fillHole=cvCreateImage(cvGetSize(otst_test),IPL_DEPTH_8U,1);
	CIrisLocalization  tt;
	double teet=tt.otsu((unsigned char*)otst_test->imageData,otst_test->height,otst_test->width,0,0,otst_test->width,otst_test->height,0);
	cvThreshold(otst_test,otst_test,teet,255,CV_THRESH_BINARY);

	cvNamedWindow("src");
	cvShowImage("src",otst_test);

	fillHole=cvCloneImage(otst_test);
	cvFloodFill(fillHole,cvPoint(0,0),cvScalarAll(1));
	cvNot(otst_test,otst_test);

	cvNamedWindow("not");
	cvShowImage("not",otst_test);
	cvAdd(otst_test,fillHole,otst_test,NULL);
	cvNamedWindow("fillHole");
	cvShowImage("fillHole",fillHole);
	cvNamedWindow("result");
	cvShowImage("result",otst_test);