【问题标题】:How to identify boundaries of a binary image to crop in matlab?如何识别二进制图像的边界以在matlab中裁剪?
【发布时间】:2014-06-05 05:12:21
【问题描述】:

如何识别二进制图像的边界以在 matlab 中进行裁剪? IE。输入二值图像没有噪声。白色背景中只有一个黑色物体。

【问题讨论】:

标签: matlab image-processing


【解决方案1】:

您可以在 MATLAB 中使用edge 命令。

E = edge(I);

I 将是输入灰度或二值图像。这将返回只有边缘的二值图像。

这可以提供进一步的帮助:

http://www.mathworks.com/help/images/ref/edge.html

【讨论】:

  • 我可以看到使用边缘检测的唯一好处是它减少了在找到最小跨越边界框时要搜索的像素数量。找到边界框时的核心算法本身就是 OP 正在寻找的。​​span>
【解决方案2】:

如果您的图像只是黑白且只有一个对象,您可以使用 Flood fill 算法,Matlab 已内置支持该算法!

试试imfill函数(ref)。

这应该给你对象的范围,这将允许你随意裁剪。

【讨论】:

  • 我的输入图像有一个填充图像。假设,白色背景中有一个黑色实心圆圈。我想找到可以包含圆的最小正方形的边界。
  • 洪水填充的好主意,但是找到简单对象的边界是多余的。
【解决方案3】:

您还可以反转图像,然后执行regionprops 以提取单独对象的所有属性。您需要反转图像,因为regionprops 假定对象是白色,而背景是黑色。这种方法的一个好处是它可以泛化多个对象,您只需要几行代码即可。

例如,让我们按照您的建议,在一张白底黑字的图像中心人为地创建一个圆圈。假设这也是一个二值图像。

im = true(200, 200);
[X,Y] = meshgrid(1:200, 1:200);
ind = (X-100).^2 + (Y-100).^2 <= 1000;
im(ind) = false;
imshow(im);

这就是你的圈子的样子:

现在让我们将其反转,使其成为黑色背景上的白色圆圈:

imInvert = ~im;
imshow(imInvert);

这就是你的倒圆的样子:

现在,调用regionprops 来查找图像中所有对象的属性。在这种情况下,应该只有一个。

s = regionProps(imInvert, 'BoundingBox');

因此,s 包含一个长度为 1 个元素的结构,并且有一个名为 BoundingBox 的字段。该字段是一个 4 元素数组,其结构如下:

[x y w h]

x 表示列/垂直坐标,y 表示边界框左上角的行/水平坐标。 w,h 是矩形的宽度和高度。我们上面代码的输出是:

s = 

BoundingBox: [68.5000 68.5000 63 63]

这意味着我们的边界框的左上角位于(x,y) = (68.5,68.5),宽度和高度各为 63。因此,我们的边界框的跨度从行(68.5,131.5) 和列(68.5,131.5) 开始。为了确保我们有正确的边界框,您可以使用 rectangle 命令在我们的形状周围绘制一个矩形。

imshow(im);
rectangle('Position', s.BoundingBox);

这就是您的图像在对象周围画一个矩形时的样子。如您所见,regionprops 给出的边界框是完全封装对象所需的最小跨度边界框。

如果要裁剪对象,可以执行以下操作:

 imCrop = imcrop(imInvert, s.BoundingBox);

这应该会为您提供由我们之前讨论过的边界框定义的裁剪图像。

希望这是您正在寻找的。祝你好运!

【讨论】:

  • 我用你说的这段代码。它只生成原始的 n 个倒置图像。没有种植。你能解释一下为什么吗?
  • im = imread('22.JPG');子图(3,3,1);显示(我); title('原创'); imInvert = ~im;子图(3,3,2); imshow(imInvert); s = regionprops(imInvert, 'BoundingBox');子图(3,3,3);显示(S); a = rectangle('位置', s.BoundingBox);子图(3,3,4);显示(一); b = imcrop(im,s);子图(3,3,5); imshow(b);
  • @user2234446 你没有正确调用imcrop。你需要做b = imcrop(im,s.BoundingBox);。第二个参数接受 4 个数字的数组。您传入的是包含信息的 结构,而不是数组本身。我还编辑了我的帖子,让您查看正确的语法。祝你好运。
  • 另外:确保图像是黑白。它可能是 RGB 图像,即使它只有两种强度。在您继续阅读图像之后,请执行im = im2bw(im);
  • ALSO #2imshow(s) 完全是一派胡言。它是一个包含与图像像素数据无关的数据的结构。因此,您需要摆脱该呼叫。另外,您需要在完成imshow(im);之后致电rectangle
猜你喜欢
  • 1970-01-01
  • 2018-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
相关资源
最近更新 更多