【问题标题】:Detecting and removing blank area in image检测和去除图像中的空白区域
【发布时间】:2021-03-21 15:29:40
【问题描述】:

我收集了 35.000 份不同纸质表格的灰度扫描图。有些纸质表格是横向的,有些是纵向的。一些横向表格被错误地以纵向模式扫描。这会导致扫描,在较低的三分之二(大约)中有空格。当然,空白中有一些噪音。

我需要做的是从纵向扫描中删除空白并将其转换为横向扫描。这应该很简单,但我显然是图像处理的新手。

因此,我们将不胜感激任何帮助。很抱歉无法发布示例,因为扫描包含个人医疗数据。

编辑:

from skimage import io
from skimage.util import crop
import numpy as np

image = io.imread(convert_image_path + filename)
crop_image = crop(image, ( image.shape[0]/5, image.shape[0]), ((0, image.shape[1])), (0,image.shape[2]))

结果是:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-21-6cc7c0d534bf> in <module>
      4 
      5 image = io.imread(convert_image_path + filename)
----> 6 crop_image = crop(image, ( image.shape[0]/5, image.shape[0]), ((0, image.shape[1])), (0,image.shape[2]))

/usr/local/lib/python3.7/site-packages/skimage/util/arraycrop.py in crop(ar, crop_width, copy, order)
     58                    for i, (a, b) in enumerate(crops))
     59     if copy:
---> 60         cropped = np.array(ar[slices], order=order, copy=True)
     61     else:
     62         cropped = ar[slices]

ValueError: Non-string object detected for the array ordering. Please pass in 'C', 'F', 'A', or 'K' instead

【问题讨论】:

  • 到目前为止您尝试过什么,或者您正在为什么苦苦挣扎?
  • 我尝试了一些我发现的代码示例,但似乎无法按照我想要的方式对图像进行切片 - 以错误结束或什么也不做。必须有一种简单的方法来实现这一点,但到目前为止没有任何效果。更困难的是,我无法在我的 Jupiter 笔记本中显示图像。但这是一个不同的问题。我编辑了问题以证明我的失败之一。
  • 您的问题对您想要什么仍然很模糊,您知道哪些图像是横向的吗?您是否希望图像从所有图像中删除空白,图像的其他部分有多少白色?你想对底部区域有空格的图像做什么?

标签: python-3.x orientation scikit-image


【解决方案1】:

我将尝试回答您的三个主要问题。

  1. 如何对图像进行切片
  2. 如何将图像旋转 90 度。
  3. 如何检测大面积的白色区域。

输入

我生成了以下输入

使用:

import numpy as np

from skimage import io

portrait = np.full(shape=(250, 150), fill_value=255, dtype=np.uint8)
portrait[:200, :] = 0

io.imsave("portrait.png", portrait)

如何切片

我们可以直接使用numpy进行切片,它的坐标系从左上角开始,依次为rowcolumnyx)。

为了分割图像的底部,我们必须选择顶部,使用[:200],它会取走所有高于 200 的行。(删除最后 50 个白色行)。

from skimage import io

portrait = io.imread("portrait.png")
sliced = portrait[:200]
io.imsave("portrait slice.png", sliced)


如何旋转

对于旋转,numpy 中有一个内置方法 rot90

import numpy as np
from skimage import io

portrait = io.imread("portrait.png")
rotated = np.rot90(portrait, k=-1)  # Rotate clockwise, k=1, rotate counter clockwise
io.imsave("portrait rotated.png", rotated)


如何检测白色区域

为了检测大的白色区域,您可以查看一行和一列的平均值。基于此,您可以决定是否有足够的白色将其指示为空白区域。

import numpy as np
from itertools import groupby, count
from skimage import io

portrait = io.imread("portrait.png")

# We take the average value for every row.
rows = np.average(portrait, axis=1)

# This returns the row indices that have a gray value higher than 240
white_rows = np.squeeze(np.argwhere(rows > 240), axis=-1)

# This locates the groups of consecutive rows that are largely white
groups = groupby(white_rows, key=lambda item, c=count(): item - next(c))
for index, group in groups:
    white_region = list(group)
    
    # Only slice regions that contains at least so many largely white rows. 
    if len(white_region) > 30:
        slicing = [white_region[0], white_region[-1]]
        print(slicing)

示例输出:

[200, 249]

所以现在我们知道图像中哪里有一个大的白色区域。在您的情况下,您可能想要验证该区域是否仅位于图像的底部。这可以通过过滤低值的白色行来完成。

white_rows = white_rows[white_rows > 150]

这意味着白色行必须超过第 150 个像素行。

额外

要检测图像是否为纵向,您可以使用图像形状

portrait = image.shape[0] > image.shape[1]

【讨论】:

  • 非常感谢你,百里香
猜你喜欢
  • 1970-01-01
  • 2011-05-06
  • 2017-06-22
  • 2011-03-19
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
相关资源
最近更新 更多