1. 使用Matlab 的imfill進行填充圖像在Matlab中簡單的幾行代碼就能實現(xiàn):
| 1 2 3 4 5 6 7 8 | clc; clear; BW=im2bw(imread('imfilltest.tif')); imshow(BW); holes=imfill(BW,'holes'); BW(~holes)=1; figure,imshow(holes); |
2.用opencv來實現(xiàn)imfill(bw, 'holes')opencv在這里不像matlab那么好用了,matlab調(diào)用下。C++ Code
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include #include #include usingnamespacestd; usingnamespacecv; voidmy_imfillholes(Mat&src) { //detectexternalcontours // vector>contours; vectorhierarchy; findContours(src,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE); // //fillexternalcontours // if(!contours.empty()&&!hierarchy.empty()) { for(intidx=0;idx<contours.size();idx++) { drawContours(src,contours,idx,Scalar::all(255),CV_FILLED,8); } } } voidtest_my_imfillholes() { Matm=imread(filltestName,IMREAD_GRAYSCALE); //threshold,(i,j)>100-->255 Matth_m; threshold(m,th_m,100,255,THRESH_BINARY); my_imfillholes(th_m); namedWindow(WinName,CV_WINDOW_AUTOSIZE); imshow(WinName,th_m); waitKey(0); } voidmain() { test_my_imfillholes(); system("pause"); } |
3. imfill和opencv實現(xiàn)的imfill 對矩陣進行操作的對比我仍有點不放心,覺得盡管2幅圖看起來差不多,但是是不是完全一樣呢,然后我覺得用個矩陣試一下。m = [1, 1, 1, 0, 0, 0,0, 0; 1, 0, 1, 0, 1, 1, 0, 0; 1, 0, 1, 0, 1, 1, 0, 0; 1, 1, 1, 0, 1, 0, 1, 0; 1, 0, 1, 0, 1, 0, 1, 0; 1, 1, 1, 0, 1, 0, 1, 0; 1, 0, 1, 0, 0, 1, 1, 0; 1, 1, 1, 0, 0, 0, 0, 0];without_holes =imfill(m, 'holes')
得到結(jié)果:without_holes=
11100000
11101100
11101100
11101110
11101110
11101110
11100110
11100000然后用第2部分所說的opencv的方法也試一下,結(jié)果發(fā)現(xiàn)是這樣的:without_holes=
00000000
0 1101100
01101100
0 1101110
01101110
01101110
01100110
00000000是不一樣的。這個問題折騰了我一個晚上,終于,我在http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontours中的findContours找到了這樣的一個note:Note:Source image is modified by this function. Also,the function does not take into account1-pixel border of the image (it’s filled with 0’s andused for neighbor analysis in the algorithm), therefore thecontours touching the image border will be clipped.它的意思是,findCountours是不會包含1-pixel的邊界的。所以這就是為啥opencv計算的結(jié)果中邊界的1都消失的原因。我想,既然邊界不被包含,那么我給它上下左右加一個1-pixel的框,這樣邊界點就變成了內(nèi)部點,就能成功的用findCountours了。于是乎:我寫了下面的code:C++ Code
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include #include #include usingnamespacestd; usingnamespacecv; voidmy_imfillholes_v2() { //step1:makeaborder Matm(8,8,CV_8UC1,data); Matm_with_border; copyMakeBorder(m,m_with_border,1,1,1,1,BORDER_CONSTANT,Scalar()); cout<<m_with_border<<endl; //setp2:findthecontourfillholes vector>contours; vectorhierarchy; ![]() findContours(m_with_border,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_NONE); // //fillexternalcontours // if(!contours.empty()&&!hierarchy.empty()) { for(intidx=0;idx<contours.size();idx++) { drawContours(m_with_border,contours,idx,Scalar::all(1),CV_FILLED,8); } } //cout<<m_with_border<<endl; //step3:removetheborder m_with_border=m_with_border.rowRange(Range(1,m_with_border.rows-1)); //cout<<m_with_border<<endl; m_with_border=m_with_border.colRange(Range(1,m_with_border.cols-1)); cout<<m_with_border<<endl; } voidmain() { my_imfillholes_v2(); system("pause"); } |
先加一個全0的1-pixel的框,然后在findCountours填充,最后把框給去了。這樣結(jié)果就完全和matlab中的imfill一致了。result= 1 1 1 0 0 0 0 0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 0 1 1 0 1 1 1 0 0 0 0 0
愛華網(wǎng)![[原]imfill的openCV實現(xiàn) opencv實現(xiàn)杯子識別](http://img.aihuau.com/images/02111102/02062747t01c19ab5e88744d2ff.jpg)




