原 imfill的openCV实现 opencv实现杯子识别

其实主要是imfill(matrix,'holes'); 的openCV/C++ 实现。Overview:imfill是matlab的一个函数,在http://www.mathworks.cn/cn/help/images/ref/imfill.html中有详细的讲解。这个函数有好几种不同的签名。在这里我的侧重点是imfill(m,'holes'),以及如何用openCV来实现imfill一样的功能。本文有三部分组成。
1. 使用Matlab 的imfill进行填充图像在Matlab中简单的几行代码就能实现:
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来实现imfill(bw, 'holes')opencv在这里不像matlab那么好用了,matlab调用下。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实现的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')
得到结果:without_holes=
11100000
11101100
11101100
11101110
11101110
11101110
11100110
11100000然后用第2部分所说的opencv的方法也试一下,结果发现是这样的: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计算的结果中边界的1都消失的原因。我想,既然边界不被包含,那么我给它上下左右加一个1-pixel的框,这样边界点就变成了内部点,就能成功的用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;
[原]imfill的openCV实现 opencv实现杯子识别
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填充,最后把框给去了。这样结果就完全和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

  

爱华网本文地址 » http://www.413yy.cn/a/25101018/369908.html

更多阅读

胶原蛋白的功效与作用史上最全 胶原蛋白功效与作用

胶原蛋白的功效与作用(史上最全)——简介 胶原蛋白是一种生物性高分子物质,英文学名Collagen。在动物细胞中扮演结合组织的角色。为生物科技产业最具关键性的原材料之一,也是需求量十分庞大的最佳生医材料。其应用领域包括生医材料、化

胶原蛋白的副作用量大人体不易吸收 胶原蛋白的副作用

  最近一段时间,胶原蛋白好像风靡了各大论坛,大家都在讨论胶原蛋白的品牌、效果。看到很多姐妹都讲服用胶原蛋白效果如何如何地好,但是赞美声同时也伴随着众说纷纭的,甚至有一部分MM用了某些品牌的胶原蛋白竟然产生了副作用!  认识

55度杯子的工作原理 55摄氏度杯子原理

55度杯子的工作原理——简介最近网上出现了一个55度杯子,此款杯子有“快速降温”和“快速升温”的功能,将100摄氏度的开水倒入杯中,摇一摇(约1分钟),就可以快速降温至人体可饮用的55度温水。同样,将冷水倒入杯中,摇一摇 (约1分钟),就可以快速升

声明:《原 imfill的openCV实现 opencv实现杯子识别》为网友西红柿小生分享!如侵犯到您的合法权益请联系我们删除