我正在尝试检测此图片中的白线数量:
我尝试使用以下链接中的代码:How to calculate the number of lines of text in an image in MATLAB
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。
答案 0 :(得分:4)
我是您引用的帖子的原作者。请注意,问题和后续答案旨在检测图像中的文本行。您的图片不包含文字,因此显然不会开箱即用。将来当您使用代码时,请阅读并确保您按照预期的方式使用它。
具体来说,当您在图像中使用我的方法时,整个背景都是白色的,因此您需要消除背景。如果不这样做,则行和背景将计为一个对象,这就是为什么只计算1个对象的原因。例如,这是在没有任何处理的情况下对图像进行二值化时得到的结果:
这不是图像的良好表现。请注意,在您提供的链接中,背景和文字非常简单。文字完全是白色,文字全黑。你有一个更复杂的背景。背景是灰色的,而一些物体是黑色的,整个物体上有一些白线。我发现解决你的问题有用的一件事是玩弄图像的阈值。我选择0.9来删除背景以及对象的背景以保持线条完好无损。我在MATLAB R2016a之前的版本中使用了im2bw
。 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);
我们现在得到这张图片:
那好多了。因为图像中已经有线条,所以这个问题非常简单。您链接的帖子会查找文本中的总行数,这就是为什么需要使用跨越图像宽度的线元素进行扩张的原因。你已经有线,所以这种扩张是不必要的。因此,只需计算此图像中有多少非零区域,您就完成了:
[~,num] = bwlabel(BW);
我们看到有:
>> num
num =
9
虽然您没有指定,但如果左侧和右侧的线需要连接(即在您的情况下,有5行而不是9行),您当然可以使用您提供的链接中的扩张逻辑将线合并在一起。在这种情况下,您将希望使结构元素的垂直范围更粗。原因是因为左侧和右侧的线条具有轻微的垂直偏移,因此指定较大的垂直范围将确保在扩张时线条连接。因此,而不是一条线使一个矩形框跨越图像的宽度。我在这里任意选择了5个像素的高度:
se = strel('rectangle', [5, size(BW, 2)]);
out = imdilate(BW, se);
我们现在得到这张图片:
看起来很漂亮....现在如果算上有多少行:
>> [~,num] = bwlabel(out)
num =
5