[已解决] 请问,如何提取感兴趣的轮廓?

[复制链接]
ad0dwaa 发表于 2021-6-29 15:17:30
我的目的是想提取孔洞的轮廓,但是经Canny算子算出来的图像边缘有很多,我用连通域的bwareaopen函数消去了许多小的轮廓,得到如下结果:但我只想要中间的孔洞轮廓,我的想法是根据孔洞的形状(例如,长和宽的大小)来进行筛选,但实在不知道怎么写,求各位大神帮帮忙。

代码如下:
src_img_name = '1.jpg';  
img = imread(src_img_name);  

% get binary image  
gray_img = rgb2gray(img);  
T = graythresh(gray_img);  
bw_img = im2bw(gray_img, T);  

I_med = medfilt2(gray_img, [11 11]);
sigma = 0.8;
gausFilter = fspecial('gaussian', [3 3], sigma);
I_gaus= imfilter(I_med, gausFilter, 'replicate');
BW1 = edge(I_gaus,'Canny');

%从二值图像中删除小对象
BW2 = bwareaopen(BW1,200,8);

% find the connected region  
img_reg = regionprops(BW2,  'Area', 'boundingbox');  

areas = [img_reg.Area];  
rects = cat(1,  img_reg.BoundingBox);  

% show all the connected region  
figure(1),  
imshow(BW2);  
for i = 1:size(rects, 1)  
    rectangle('position', rects(i, :), 'EdgeColor', 'r');  
end  

[~, max_id] = max(areas);  
max_rect = rects(max_id, :);  

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

最佳答案


lyqmath 发表于 2021-6-30 12:01:50


可以

参考书籍《计算机视觉与深度学习实战——以MATLAB、Python 为工具》[刘衍琦等]


  1. clc; clear all; close all;
  2. src_img_name = 'ceshi.jpg';  
  3. img = imread(src_img_name);  

  4. % get binary image  
  5. gray_img = rgb2gray(img);  
  6. T = graythresh(gray_img);  
  7. bw_img = im2bw(gray_img, T);  

  8. I_med = medfilt2(gray_img, [11 11]);
  9. sigma = 0.8;
  10. gausFilter = fspecial('gaussian', [3 3], sigma);
  11. I_gaus= imfilter(I_med, gausFilter, 'replicate');
  12. BW1 = edge(I_gaus,'Canny');

  13. %从二值图像中删除小对象
  14. BW2 = bwareaopen(BW1,100,8);

  15. % find the connected region  
  16. [L,num] = bwlabel(BW2);
  17. img_reg = regionprops(L,  'Area', 'boundingbox');  

  18. areas = [img_reg.Area];  
  19. rects = cat(1,  img_reg.BoundingBox);  

  20. % show all the connected region  
  21. figure(1),  
  22. imshow(BW2);  
  23. for i = 1:size(rects, 1)  
  24.     rectangle('position', rects(i, :), 'EdgeColor', 'r');  
  25. end  

  26. % 条件筛选
  27. for i = 1:size(rects, 1)  
  28.     % 小、闭合的矩形框
  29.     recti = rects(i, :);
  30.     if recti(3)/size(img,2) > 0.3 || recti(4)/size(img,1) > 0.3 || max(recti(3:4))/min(recti(3:4)) > 2
  31.         % 大小筛选
  32.         continue;
  33.     end
  34.     bwi = BW2;
  35.     bwi(L ~= i ) = 0;
  36.     bwi2 = imfill(bwi, 'holes');
  37.     if length(find(bwi2(:)))/length(find(bwi(:))) < 2
  38.         % 孔洞筛选
  39.         continue;
  40.     end
  41.     if recti(1) < size(img,2)*0.15 || recti(2) < size(img,1)*0.15 || recti(1)+recti(3) > size(img,2)*0.85 || recti(2)+recti(4) > size(img,1)*0.85
  42.         % 周边筛选
  43.         continue;
  44.     end
  45.     rectangle('position', recti, 'EdgeColor', 'c', 'LineWidth', 2);  
  46. end  


复制代码




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

8 条回复


lyqmath 发表于 2021-6-30 09:04:41


可以

参考书籍《计算机视觉与深度学习实战——以MATLAB、Python 为工具》[刘衍琦等]


  1. clc; clear all; close all;
  2. src_img_name = 'ceshi.png';  
  3. img = imread(src_img_name);  

  4. % get binary image  
  5. gray_img = rgb2gray(img);  
  6. T = graythresh(gray_img);  
  7. bw_img = im2bw(gray_img,T);  
  8. bw_img = imclearborder(bw_img);
  9. bw2 = imfill(bw_img, 'holes');
  10. bw2 = imopen(bw2, strel('disk', 3));
  11. bw2 = imdilate(bw2, strel('disk', 5));
  12. stats = regionprops(bw2);
  13. rects = cat(1, stats.BoundingBox);

  14. figure(1),  
  15. imshow(img, []);  
  16. for i = 1:size(rects, 1)  
  17.     rectangle('position', rects(i, :), 'EdgeColor', 'c', 'LineWidth', 2);  
  18. end  
复制代码




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

ad0dwaa 发表于 2021-6-30 10:27:39
lyqmath 发表于 2021-6-30 09:04
可以

参考书籍《计算机视觉与深度学习实战——以MATLAB、Python 为工具》[刘衍琦等][/backc ...

您好,感谢您的帮助,但这个程序我换一张图像就还会提取好多边框,例如:
所以我想能不能根据rects矩阵里第3列和第4列的w和h来具体限制一下我所感兴趣的区域的大小?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

lyqmath 发表于 2021-6-30 12:01:50


可以

参考书籍《计算机视觉与深度学习实战——以MATLAB、Python 为工具》[刘衍琦等]


  1. clc; clear all; close all;
  2. src_img_name = 'ceshi.jpg';  
  3. img = imread(src_img_name);  

  4. % get binary image  
  5. gray_img = rgb2gray(img);  
  6. T = graythresh(gray_img);  
  7. bw_img = im2bw(gray_img, T);  

  8. I_med = medfilt2(gray_img, [11 11]);
  9. sigma = 0.8;
  10. gausFilter = fspecial('gaussian', [3 3], sigma);
  11. I_gaus= imfilter(I_med, gausFilter, 'replicate');
  12. BW1 = edge(I_gaus,'Canny');

  13. %从二值图像中删除小对象
  14. BW2 = bwareaopen(BW1,100,8);

  15. % find the connected region  
  16. [L,num] = bwlabel(BW2);
  17. img_reg = regionprops(L,  'Area', 'boundingbox');  

  18. areas = [img_reg.Area];  
  19. rects = cat(1,  img_reg.BoundingBox);  

  20. % show all the connected region  
  21. figure(1),  
  22. imshow(BW2);  
  23. for i = 1:size(rects, 1)  
  24.     rectangle('position', rects(i, :), 'EdgeColor', 'r');  
  25. end  

  26. % 条件筛选
  27. for i = 1:size(rects, 1)  
  28.     % 小、闭合的矩形框
  29.     recti = rects(i, :);
  30.     if recti(3)/size(img,2) > 0.3 || recti(4)/size(img,1) > 0.3 || max(recti(3:4))/min(recti(3:4)) > 2
  31.         % 大小筛选
  32.         continue;
  33.     end
  34.     bwi = BW2;
  35.     bwi(L ~= i ) = 0;
  36.     bwi2 = imfill(bwi, 'holes');
  37.     if length(find(bwi2(:)))/length(find(bwi(:))) < 2
  38.         % 孔洞筛选
  39.         continue;
  40.     end
  41.     if recti(1) < size(img,2)*0.15 || recti(2) < size(img,1)*0.15 || recti(1)+recti(3) > size(img,2)*0.85 || recti(2)+recti(4) > size(img,1)*0.85
  42.         % 周边筛选
  43.         continue;
  44.     end
  45.     rectangle('position', recti, 'EdgeColor', 'c', 'LineWidth', 2);  
  46. end  


复制代码




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复此楼

ad0dwaa 发表于 2021-6-30 12:44:31

非常感谢您的帮忙,大部分图像都可以准确的识别出孔洞了,太感谢您了!您程序厘面的这三句话我有点没看懂,您能大概告诉我一下什么意思吗?我好根据具体图像进行参数修改,麻烦您了。

if recti(3)/size(img,2) > 0.4 || recti(4)/size(img,1) > 0.4 || max(recti(3:4))/min(recti(3:4)) > 2


if length(find(bwi2(:)))/length(find(bwi(:))) < 5
if recti(1) < size(img,2)*0.15 || recti(2) < size(img,1)*0.15 || recti(1)+recti(3) > size(img,2)*0.85 || recti(2)+recti(4) > size(img,1)*0.85

lyqmath 发表于 2021-6-30 13:26:04
if recti(3)/size(img,2) > 0.4 || recti(4)/size(img,1) > 0.4 || max(recti(3:4))/min(recti(3:4)) > 2
就是这个区域的宽度和高度不能过大,长宽比阈值也不能过大


if length(find(bwi2(:)))/length(find(bwi(:))) < 5
if recti(1) < size(img,2)*0.15 || recti(2) < size(img,1)*0.15 || recti(1)+recti(3) > size(img,2)*0.85 || recti(2)+recti(4) > size(img,1)*0.85

这是区域不能在在周边区域出现

ad0dwaa 发表于 2021-6-30 13:56:38
lyqmath 发表于 2021-6-30 13:26
if recti(3)/size(img,2) > 0.4 || recti(4)/size(img,1) > 0.4 || max(recti(3:4))/min(recti(3:4)) > 2
...

好的好的,非常感谢您!

lyqmath 发表于 2021-7-1 10:57:31

休幹賴xd12377 发表于 2021-9-1 23:10:58
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则

相关帖子
相关文章
热门教程
站长推荐
快速回复 返回顶部 返回列表