在matlab中检测线

detecting lines in matlab

我正在尝试检测此图像中的白线数量:

我已尝试使用以下 link 中的代码:

RGB = imread('test image.jpg');
GSC = rgb2gray(RGB);
BW = imbinarize(GSC);
figure
imshowpair(GSC,BW,'montage')
se = strel('line',size(BW,2),0);
out = imdilate(BW,se);
[~,num] = bwlabel(out);

但是,我检测到的白线数量不正确。我得到的总行数的值为 1.

我是您所引用的 post 的原作者。请注意,问题和后续答案旨在检测图像中的行文本。您的图像不包含文本,因此显然无法开箱即用。以后您在使用代码时,请仔细阅读并确保按照预期的方式使用它。

具体来说,当你对你的图像使用我的方法开箱即用时,整个背景都是白色的,所以你需要消除背景。如果不这样做,那么线条和背景将计为一个对象,因此这就是为什么您只计算 1 个对象的原因。例如,这是在不进行任何处理的情况下对图像进行二值化时得到的结果:

这不是图像的良好表示。请注意,在您提供的 link 中,背景和文字非常简单。文本是完全白色的,文本是完全黑色的。你的背景有点复杂。背景是灰色的,而一些对象是黑色的,整个对象都有一些白线。我发现对解决您的问题有用的一件事是使用图像的阈值。我选择 0.9 来移除背景以及对象的背景以保持线条完好无损。我使用 im2bw from versions before MATLAB R2016a. imbinarize 是 R2016a 及更高版本的一部分,但您应该能够在这两种方法之间切换。我将直接从 Stack Overflow 中引用您的图片以使其可重现:

im = imread('https://i.stack.imgur.com/yKd4V.jpg');
BW = im2bw(rgb2gray(im), 0.9); % or BW = imbinarize(rgb2gray(im), 0.9);
figure; imshow(BW);

我们现在得到这张图片:

好多了。因为图像中已经有线条,所以问题变得非常简单。您 linked 的 post 查找文本中的总行数,这就是为什么需要使用跨越图像宽度的线元素进行扩展的原因。您已经有了线条,因此不需要进行这种扩张。因此,只需计算此图像中有多少个非零区域即可:

[~,num] = bwlabel(BW);

我们看到有:

>> num

num =

     9

虽然您没有指定,但如果需要连接左侧和右侧的线(即在您的情况下,有 5 条线而不是 9 条线),您当然可以使用 link 您提供的是将这些行合并在一起。在这种情况下,您需要使结构元素的垂直范围更粗。原因是因为左侧和右侧的线条有轻微的垂直偏移,所以指定更大的垂直范围将确保在您扩张时线条连接起来。因此,代替一条线,制作一个横跨图像宽度的矩形框。我在这里随意选择了5像素的高度:

se = strel('rectangle', [5, size(BW, 2)]);
out = imdilate(BW, se);

我们现在得到这张图片:

看起来不错....现在如果你数一数有多少行:

>> [~,num] = bwlabel(out)

num = 

     5