框架填充墙砌筑规范_opencv二值化图像

框架填充墙砌筑规范_opencv二值化图像http://bbs.csdn.net/topics/391542633?page=1

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

opencv 孔洞填充,方案1: 

http://bbs.csdn.net/topics/391542633?page=1

opencv 孔洞填充,方案1: 

其实主要是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);

左图为填充前的图像,右图是填充后的图像:
 
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 

using 

namespace 
std;


using 

namespace 
cv;

void 
my_imfillholes(Mat 
&src)

{

 
 
 

// detect external contours
 
 
 

//
 
 
 
vector 

contours;

 
 
 
vector 
hierarchy;

 
 
 
findContours(src, 
contours, 
hierarchy, 
CV_RETR_EXTERNAL, 
CV_CHAIN_APPROX_SIMPLE);

 
 
 

//
 
 
 

// fill external contours
 
 
 

//
 
 
 

if
!contours.empty() 
&& 
!hierarchy.empty() 
)

 
 
 
{

 
 
 
 
 
 

for 
(
int 
idx=
0;idx 

contours.size();idx++)

 
 
 
 
 
 
{

 
 
 
 
 
 
 
 
 
drawContours(src,contours,idx,Scalar::all(
255),CV_FILLED,
8);

 
 
 
 
 
 
}

 
 
 
}

}

void 
test_my_imfillholes()

{

 
 
 
Mat 


imread(filltestName,IMREAD_GRAYSCALE);

 
 
 

//threshold, (i,j)>100 –>255
 
 
 
Mat 
th_m;

 
 
 
threshold(m, 
th_m, 

100

255
THRESH_BINARY);

 
 
 
my_imfillholes(th_m);

 
 
 
namedWindow(WinName, 
CV_WINDOW_AUTOSIZE);

 
 
 
imshow(WinName, 
th_m);

 
 
 
waitKey(
0); 


}

void 
main()

{

 
 
 
test_my_imfillholes();

 
 
 
system(
“pause”);

}

框架填充墙砌筑规范_opencv二值化图像 3. imfill 和opencv实现的imfill 对矩阵进行操作的对比

without_holes =
     0     0     0     0     0     0     0     0
     0     1     1     0     1     1     0     0
     0     1     1     0     1     1     0     0
     0     1     1     0     1     1     1     0
     0     1     1     0     1     1     1     0
     0     1     1     0     1     1     1     0
     0     1     1     0     0     1     1     0
     0     0     0     0     0     0     0     0
是不一样的。这个问题折腾了我一个晚上,终于,我在
中的 findContours找到了这样的一个note:
Note:
Source image is modified by this function. Also, the function does not take into account 1-pixel border of the image (it’s filled with 0’s and used for neighbor analysis in the algorithm), therefore the contours 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 

using 

namespace 
std;


using 

namespace 
cv;

void 
my_imfillholes_v2()

{

 
 
 

//step 1: make border
 
 
 
Mat 
m(
8

8
CV_8UC1, 
data);

 
 
 
Mat 
m_with_border;

 
 
 
copyMakeBorder(m, 
m_with_border, 

1

1

1

1
BORDER_CONSTANT, 
Scalar());

 
 
 
cout<<m_with_border<<endl;

 
 
 

//setp 2: find the contour fill holes
 
 
 
vector 

contours;

 
 
 
vector 
hierarchy;

 
 
 
findContours(m_with_border, 
contours, 
hierarchy, 
CV_RETR_CCOMP, 
CV_CHAIN_APPROX_NONE);

 
 
 

//
 
 
 

// fill external contours
 
 
 

// 
 
 
 

if
!contours.empty() 
&& 
!hierarchy.empty() 
)

 
 
 
{

 
 
 
 
 
 

for 
(
int 
idx=
0;idx 

contours.size();idx++)

 
 
 
 
 
 
{

 
 
 
 
 
 
 
 
 
drawContours(m_with_border,contours,idx,Scalar::all(
1),CV_FILLED,
8);

 
 
 
 
 
 
}

 
 
 
}

 
 
 

//cout<<m_with_border<<endl;
 
 
 

//step 3: remove the border
 
 
 
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;

}

void 
main()

{

 
 
 
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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/197691.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号