【问题标题】:Eliminating various backgrounds from image and segmenting object?从图像和分割对象中消除各种背景?
【发布时间】:2014-11-09 18:51:17
【问题描述】:

假设我有这个输入图像,带有任意数量的框。我想分割这些盒子,所以我最终可以把它们提取出来。 输入图片:

背景可以是任何连续的东西,例如彩绘墙、木桌、地毯。 我的想法是渐变在整个背景中是相同的,并且具有恒定的渐变。我可以把梯度大致相同的地方变成图像中的零。

通过边缘检测,我会扩大并填充检测到边缘的区域。基本上我的目标是在盒子所在的区域制作一个斑点。有了这些斑点,我就可以知道盒子的确切位置,从而能够从输入图像中裁剪出盒子。 所以在这种情况下,我应该可以有四个 blob,然后我就可以从输入图像中裁剪出四个图像。

这是我走了多远: 分割图像:

query = imread('AllFour.jpg');
gray = rgb2gray(query);
[~, threshold] = edge(gray, 'sobel');
weightedFactor = 1.5;
BWs = edge(gray,'roberts');
%figure, imshow(BWs), title('binary gradient mask');

se90 = strel('disk', 30);
se0 = strel('square', 3);

BWsdil = imdilate(BWs, [se90]);
%figure, imshow(BWsdil), title('dilated gradient mask');

BWdfill = imfill(BWsdil, 'holes');
figure, imshow(BWdfill);
title('binary image with filled holes');

【问题讨论】:

  • 我什至没有通过使用imgradient(query)来使用渐变的大小。我标准化了幅度。如果背景是连续的,我应该能够将对象与前景分开。有什么帮助吗?

标签: image-processing matlab matlab-cvst


【解决方案1】:

多么有趣的问题啊!这是我的解决方案,试图为您解决这个问题。这是假设背景始终具有相同的颜色分布。首先,使用rgb2hsv 将图像从RGB 转换为HSV 颜色空间。 HSV 颜色空间是分析颜色的理想转换。在此之后,我会查看饱和度和价值平面。饱和度与颜色的“纯”程度有关,而值是颜色本身的强度或亮度。如果您查看图像的饱和度和值平面,则会显示以下内容:

im = imread('http://i.stack.imgur.com/1SGVm.jpg');
out = rgb2hsv(im);
figure;
subplot(2,1,1);
imshow(out(:,:,2));
subplot(2,1,2);
imshow(out(:,:,3));

这是我得到的:

通过查看灰色背景中的某些位置,看起来大部分饱和度小于 0.2,而值平面中的元素大于 0.3。因此,我们希望找到这些像素的相反来获取我们的对象。因此,我们找到那些饱和度大于 0.2 的像素那些值小于 0.3 的像素:

seg = out(:,:,2) > 0.2 | out(:,:,3) < 0.3;

这是我们得到的:

快到了!有一些虚假的单个像素,所以我将使用带有线条结构元素的imopen 进行开口。

在此之后,我将使用imdilate 执行膨胀以关闭任何间隙,然后使用imfill'holes' 选项来填充间隙,然后使用带有imerode 的侵蚀来缩小形状到他们原来的形式。因此:

se = strel('line', 3, 90);
pre = imopen(seg, c);
se = strel('square', 20);
pre2 = imdilate(pre, se);
pre3 = imfill(pre2, 'holes');
final = imerode(pre3, se);
figure;
imshow(final);

final 包含带有 4 个糖果盒的分段图像。这是我得到的:

【讨论】:

  • 非常感谢。我会更深入地研究。我注意到您没有采取边缘检测方法?我正在考虑在检测到边缘后使用霍夫变换来连接边缘。我还没有实现它——但你怎么看?
  • 1.为什么你决定使用垂直线结构元素来打开像素,为什么不使用水平线?
  • @Kayla - 嗨!我没有采用边缘检测方法,因为之前的海报已经这样做了。我决定尝试变得独一无二,并完全使用颜色信息和形态来做到这一点。霍夫变换可以工作,然后您可以应用填充操作来获得正确的结果。你必须尝试一下,因为我不确定会发生什么。图片右侧似乎有一个闪光可能会弄乱您的结果
  • @Kayla - 垂直或水平线之间的选择非常随意。您可以使用水平线或垂直线来消除图像中的单个点。您可以使用其中任何一种来获得结果。我随意选择了垂直。
  • 我最终无法使用这种方法。我的目标是分割查询图像并使用 knn 来匹配 SURF 特征。事实证明,由于光照和阴影,当您查询其他图像时,变化太大。也许我可以习惯一些噪声过滤器来获得那种照明效果
【解决方案2】:

尝试调整图像大小。当你把它变小时,连接边缘会更容易。我尝试了下面显示的内容。您可能需要根据背景的性质对其进行调整。

close all;
clear all;

im = imread('1SGVm.jpg');
small = imresize(im, .25); % resize
grad = (double(imdilate(small, ones(3))) - double(small)); % extract edges
gradSum = sum(grad, 3);
bw = edge(gradSum, 'Canny');
joined = imdilate(bw, ones(3)); % join edges
filled = imfill(joined, 'holes');
filled = imerode(filled, ones(3));
imshow(label2rgb(bwlabel(filled))) % label the regions and show

【讨论】:

  • 感谢您的回复。我必须调整什么?为什么?
  • gradSum = sum(grad, 3); 是做什么的?
  • 有时您可能不得不尝试不同的结构元素来连接边缘。这里使用大小为 3 的矩形元素就足够了。 sum(grad, 3) 对 grad 的所有三个通道的像素求和。我不是从 RGB 转换为灰色,而是对像素求和,因为这样所有通道的权重相同,所以我不会丢失通道中的边缘信息。
【解决方案3】:

如果您有最新版本的 MATLAB,请尝试图像处理工具箱中的 Color Thresholder 应用程序。它可以让您以交互方式使用不同的色彩空间,看看哪一个可以给您最好的分割。

【讨论】:

    【解决方案4】:

    如果您的糖果封面是固定的,或者您知道所有进入场景的封面,那么 模板匹配 是最适合的。因为它独立于图像中的背景。

    http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html

    【讨论】:

    • -1。从问题的上下文来看,没有模板,模板也不知道。我相信这是在统一背景上使用任意数量对象的一般对象提取。当这是一个 MATLAB 问题时,您还向 OpenCV 放置了文档。请在发布答案之前仔细阅读标签。
    猜你喜欢
    • 2015-07-16
    • 2021-09-18
    • 2016-06-03
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    相关资源
    最近更新 更多