python - 从图像中删除网格

标签 python opencv image-processing scikit-image

我正在开展一个项目,让用户可以为手写公式拍照并将其发送到我的服务器。我只想留下与数学相关的符号,而不是表格网格。

示例照片:

(1) 原始RGB照片 Original photo (RGB

(2) 模糊灰度 Blurred grayscale photo

(3) 应用自适应阈值后 After applying Adaptive Threshold

注意: 我希望我的算法能够处理任何颜色的网格。

任何代码片段将不胜感激。 提前致谢。

最佳答案

Result

这是一个具有挑战性的问题,要在不知道确切的纸张/线条和墨水组合类型以及输出的确切用途的情况下进行概括。我以为我会尝试一下,也许会学到一些东西。

我看到了解决这个问题的两种方法:

  1. 聪明的方法:识别网格、它的颜色、方向、大小来找到它占据的图像区域,以便忽略它。这里有一些需要解决的重要警告。例如页面可能不是平面和方形照片(必须考虑扭曲、扭曲、旋转)。还会有一些我们不想删除的行。

  2. 简单的方法:应用一般的图像操作,除了假设笔总是比网格暗,并且输出是二进制的(黑笔/白页)之外,对问题知之甚少。

我更喜欢第二个,因为它更容易实现并且概括性更好。

我们首先注意到页面的“白色”实际上是一种不均匀的灰色阴影(如果我们转换为灰度)。 CV 自适应阈值处理很好地解决了这个问题。它几乎让我们到达那里。

下面的代码以 50x50 像素 block 处理图像,以解决光照不均匀的问题。在每个 block 中,我们在应用阈值之前减去中值。一个简单的解决方案,但也许是您所需要的。我没有在很多图像上测试它,阈值和预处理和后处理可能需要调整。如果输入图像差异很大,或者如果网格相对于墨水太暗,它将不起作用。

import cv2
import numpy
import sys

BLOCK_SIZE = 50
THRESHOLD = 25


def preprocess(image):
    image = cv2.medianBlur(image, 3)
    image = cv2.GaussianBlur(image, (3, 3), 0)
    return 255 - image


def postprocess(image):
    image = cv2.medianBlur(image, 5)
    # image = cv2.medianBlur(image, 5)
    # kernel = numpy.ones((3,3), numpy.uint8)
    # image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)
    return image


def get_block_index(image_shape, yx, block_size): 
    y = numpy.arange(max(0, yx[0]-block_size), min(image_shape[0], yx[0]+block_size))
    x = numpy.arange(max(0, yx[1]-block_size), min(image_shape[1], yx[1]+block_size))
    return numpy.meshgrid(y, x)


def adaptive_median_threshold(img_in):
    med = numpy.median(img_in)
    img_out = numpy.zeros_like(img_in)
    img_out[img_in - med < THRESHOLD] = 255
    return img_out


def block_image_process(image, block_size):
    out_image = numpy.zeros_like(image)
    for row in range(0, image.shape[0], block_size):
        for col in range(0, image.shape[1], block_size):
            idx = (row, col)
            block_idx = get_block_index(image.shape, idx, block_size)
            out_image[block_idx] = adaptive_median_threshold(image[block_idx])

    return out_image


def process_image_file(filename):
    image_in = cv2.cvtColor(cv2.imread(filename), cv2.COLOR_BGR2GRAY)

    image_in = preprocess(image_in)
    image_out = block_image_process(image_in, BLOCK_SIZE)
    image_out = postprocess(image_out)

    cv2.imwrite('bin_' + filename, image_out)


if __name__ == "__main__":
    process_image_file(sys.argv[1])

关于python - 从图像中删除网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48491217/

相关文章:

python - 我在 python 速成类(class)书中学习文件和异常。无法弄清楚为什么它说 votes = Judge.read() 没有可写的属性

python - 一个表达式如何与括号化的不同?

c++ - pyrDown 错误

machine-learning - 从图像中提取主要/最常用的颜色

windows - 帧到视频 - Windows 8 中的图像处理(仅限 WinRT)

python - SQLAlchemy中如何删除多个表

python - 如何让word2vec模型的加载时间和内存使用更加高效?

python - 从精巧的边缘获取边界并删除图像的背景

python - cv2.VideoCapture 无法在 Mac 主机上的 docker 容器中工作

python - 使图像边缘平滑