沿着几乎连接的组件的路径进行线跟踪

信息处理 图像处理 matlab 周期性的 ocr
2022-02-18 16:19:59

假设我们有一张像下面这样的二值图像

我想提取每条黑线,即使它几乎没有连接

我在这里用红色标记了与要提取的行相对应的行示例

**这里的目的是提取手写文本的行!**

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

有什么建议么 !!谢谢

2个回答

这是一个可能的解决方案:

  • 使用 FFT2 查找文本的角度和行间的近似间距
  • 将图像旋转到 0 角
  • 按列对图像求和
  • 查找将文本行与非文本行分开的阈值
  • 在旋转图像上显示线条。

可以通过找到更复杂的曲线(而不是直线)来改进它。

结果如下:

原来的 在此处输入图像描述

旋转后 在此处输入图像描述

逐列旋转图像的总和 在此处输入图像描述

最终结果 在此处输入图像描述

代码是:

%% 1) Read image
im = imread('http://i.stack.imgur.com/zbHTp.jpg');
im = im(:,:,2);
im = double(im < 100);
im = padarray(im,[40 0]);
figure();imshow(im);

%% 2) Find approximate line spacing
F = fftshift(fft2(im));
% figure;imagesc(log(abs(fftshift(fft2(im)))));
[~,iMax] = max(F(:));
[r1,c1] = ind2sub(size(F),iMax);
F(iMax) = 0;
[~,iMax2] = max(F(:));
[r2,c2] = ind2sub(size(F),iMax2);
lineSpaceY = size(im,1)/ abs(r2-r1);
lineSpaceX = size(im,2)/ abs(c2-c1);
angleDeg = abs(90-rad2deg( atan2(lineSpaceX,lineSpaceY)));
imr = imrotate(im,angleDeg);
figure;imshow(imr);

%% 3) Take a look at 1D signal
S = mean(imr,2);
isText = S > max(S)/2;
isText = imclose(isText,strel('line',lineSpaceY/10,90));
% figure(); plot(isText,'o-');
rp = regionprops(isText,'Centroid');
centerY = cat(1,rp.Centroid);
centerY = centerY(:,2);

%% 4) Show final results
figure();imshow(imr);
for i=1:numel(centerY);
    hold on;
    plot( [0,size(im,2)],[centerY(i) centerY(i)],'g','LineWidth',2);
end

首先,如果线没有连接,应用形态学打开操作使它们连接起来(参见 OpenCV 中的morphologyEx)。

现在,假设您有一个连接的黑色区域,您可以应用迭代细化来获得骨架。或参考已有的想法,例如this onethis one