2

请查看下面的图片,以更清楚地了解我要问的内容。

在此处输入图像描述

相信大家都能看到这张图的书本数,也就是3本。我试过按照强度、分水岭来分割。由于噪音,即使使用 Canny 也不是很成功。但总而言之,除了canny,图像总是这样(见左图): 在此处输入图像描述

所有的书都聚集在一起。我的目标是最终将它们分开并使用 bwboundaries 来计算书籍的数量。我也在尝试使用 label2rgb 来进一步区分这些书,但是,所有发生的事情都是它只有一种颜色,这意味着 MatLab 认为它是因为所有 3 本书都是相同的。

我在精装书上做到了这一点并取得了巨大成功,但是由于这本书不是精装书,因此没有明确的界限将它们分开。

几天来,我一直试图分割这张图片,但没有成功。有任何想法吗?欢迎任何建议或想法。

4

3 回答 3

1

Shai 建议沿图像的每个水平行计算平均值有助于识别书籍。如果书不是平的、不是水平的或有相似的颜色,那么这种方法会有一定的局限性。但是,与其关注亮度相似的块,不如考虑使用水平平均值/中值等作为检测书籍之间可能存在的气隙的方法。

我不会为处理二进制图像而烦恼。太繁琐,而且不是很健壮。您可以为某些图像找到解决方案,但可能会花费大量时间来尝试为所有图像找到解决方案。该图像的灰度强度聚类非常重要,您不想丢弃这些数据。在二值化之前设置阈值可能是一件混乱且令人不满意的事情。

您熟悉均值偏移算法吗?它是一种类似于 k-means 聚类的聚类算法,但不需要事先知道项目数 (k)。这可以帮助您对原始灰度图像中的数据进行聚类,并发现存在三个具有合理一致灰度值的不同大块。

使用 Mean Shift 进行图像分割解释

http://docs.opencv.org/trunk/doc/py_tutorials/py_video/py_meanshift/py_meanshift.html

http://saravananthirumuruganathan.wordpress.com/2010/04/01/introduction-to-mean-shift-algorithm/

于 2013-11-09T01:13:22.130 回答
1

对我来说,这是形态过滤中的经典问题。我们可以看到,随着我们提高阈值,我们可以看到书籍的不同部分。

阈值为 100 阈值 150阈值 172

现在一些基于灰度分量的面积/大小的灰度过滤可以提供一些很好的分割。这被称为形态过滤中的区域开口:http: //www.mathworks.fr/fr/help/images/ref/bwareaopen.html

这基本上删除了大小/面积小于某个参数的连接组件。因此,要在此处看到这一点,这里有一些上述阈值的过滤图像。

区域开闭

另一个灰度

    x150 = I>150;
    x100 = I>100;
    x172 = I>172;
    x150_op = bwareaopen(x150,80);
    x172_op = bwareaopen(x172,300);
    figure, imshow(~bwareaopen(x150_op,150); %area closing
    figure, imshow(~bwareaopen(x172_op,300); %area closing

因此,正如我们所见,我们需要一个连接区域开口滤波器,它计算具有特定区域的连接灰度组件。我想你可以为这些书调整这个!

另一个提供相同运算符的库和一些示例:http ://www.mmorph.com/mxmorph/html/morph/mmareaopen.html

祝你好运!

于 2013-10-29T18:02:49.733 回答
1

在 x 值处沿 y 轴进行切片,这样您就有了很好的边界。然后使用“conv”找到该一维向量(包含 0 和 1)与奇数高斯函数的中心部分的卷积。这就像一个边缘滤波器,但对噪声具有鲁棒性。该卷积将为您提供一堆不规则间隔的峰。找到峰,数一数。每一个山峰都是两本书之间的分界线。(抱歉,如果没有白板,这个简单的过程很难解释。)

“奇数高斯函数的中心部分”= 想象一个正弦函数,在正/负 pi 处截断。但是从正到负的变化更接近阶跃函数。我认为你可以通过卷积高斯和阶跃函数得到你想要的。(再次,抱歉没有白板。)

edit2:这是一些 Matlab 代码,可以交互运行,以便您了解我的意思:

x=[-9.5:1:9.5];
y=[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 1]; plot(x,y,'.');
g=exp(-x.*x/8); plot(x,g,'.');
odd_g=conv(y,g);plot([-19:19],odd_g,'.')

因此,odd_g(或类似的东西)是您想要与给定 x 处的图像切片进行卷积的东西。

peaks=conv(image_slice,odd_g);

编辑3:假设你有

image_slice=[1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1 1];

并注意到我已经加入了嘈杂的边缘。对于所选值,当您绘制卷积时,

plot(conv(image_slice,odd_g)

您会看到一个边缘的噪声有一个轻微的峰值,但它没有真正的边缘那么大。因此,您会找到峰值并丢弃小于某个截止值的任何值。当然,为odd_g 选择最适合您的数据的参数。

于 2013-10-28T20:36:47.460 回答