从图像中删除线条:用于数字检测Python笔记本

4
我需要从下面这张图中的数字上移除线条,而不会使数字变形。如果不这样做,我的数字检测算法就会失败,因为在感兴趣区域有纸张规则线的痕迹。
以下是原图:https://www.dropbox.com/s/mjtnldwme4qqc4v/Issue_file.jpeg?dl=0 "Issue Image" 以下是没有任何痕迹的更清晰的版本:Cleaner version of file
3个回答

5

傅里叶变换的经典任务。

  1. 执行傅里叶变换:

import numpy as np from scipy.misc import imshow, imsave, imread img = imread("10XIn.jpg")[:,:,:3] imggray = np.mean(img, -1) imfft = np.fft.fft2(imggray) mags = np.abs(np.fft.fftshift(imfft)) angles = np.angle(np.fft.fftshift(imfft)) visual = np.log(mags) visual2 = (visual - visual.min()) / (visual.max() - visual.min())*255

visual2看起来像这样: enter image description here

注意中心的对角线 - 它代表了你的线条。

现在,我手动创建了这条线的掩模,但理想情况下,你可以通过程序过滤它。 enter image description here

然后,我们读取掩模并把线擦除: mask = imread("fftimg4_mask.jpg")[:,:,:3] mask = (np.mean(mask,-1) > 20) visual[mask] = np.mean(visual)

然后反向傅里叶变换: newmagsshift = np.exp(visual) newffts = newmagsshift * np.exp(1j*angles) newfft = np.fft.ifftshift(newffts) imrev = np.fft.ifft2(newfft) newim2 = 255 - np.abs(imrev).astype(np.uint8) imsave("fftimg2.jpg", newim2 )

这是newim2enter image description here

当然,你可以在傅里叶空间中进行更精确的修补,并将结果应用回原始图像以保持颜色,但我认为这篇文章阐述了这个想法。


这很棒,我会尝试一下。在另一个网站上有一个类似问题的赏金任务,你应该试试看。https://www.freelancer.com/contest/Digit-Detection-on-ruled-paper-188586.html - Dev Roy
谢谢,我会尝试的。 - vzaguskin
嗨,我尝试使用霍夫线来检测线条,但由于返回了太多线条而无法正常工作,是否有其他方法?但在某种程度上,它确实可以工作。 - Dev Roy
适当的阈值然后霍夫线应该可以工作。实际上,只需要一个阈值加上将不相关区域清零就足够了。 - vzaguskin

1

好的,这可能有点复杂,因为笔记本线条的颜色与数字的颜色非常接近,从您的示例中看来是这样。我猜想,绿色框框是您的添加部分,而不是数据本身的一部分。

您没有说明使用哪个框架,因此我将仅提供一些通用提示来解决此问题。

第一步是进行一些阈值处理。您可以使用二进制阈值处理或更好的自适应阈值处理,并使用正确大小的窗口。您需要进行实验。阈值处理的结果将是二进制图像。仍带有线条。

第二步将是使用形态学操作清除图像。如果您不确定形态学是什么,请查看此 morphology tutorial

在中间的位置,有一些从图像中删除线条的示例。最大的问题是,某些数字也包含水平线。因此,一种选择将是使用相当小的形态学核(可能是3行和1列),因为笔记本线条更细。并更新识别器,以便识别扭曲的数字。这应该是可行的,因为所有数字都会以相同的方式扭曲。


不幸的是,失真可能有无限的可能性,因此数字检测将失败。 - Dev Roy

0

另一种方法是利用已知结构。

  1. 矫正图像(可以在OpenCV中使用Hough变换找到倾斜)
  2. 定位行求和的高峰
  3. 在线条上方和下方物理克隆像素

我刚刚为另一个数据集实现了这个,附上示例。这可以进一步调整。

Sample result


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接