【问题标题】:How to remove extra whitespace from image in opencv? [duplicate]如何从opencv中的图像中删除多余的空格? [复制]
【发布时间】:2020-04-25 10:16:02
【问题描述】:

我有以下图像,它是一张收据图像,并且收据周围有很多空白区域。我想裁剪空白区域。我不能手动裁剪它,所以我正在寻找一种可以做到的方法。

裁剪一个:

从以下帖子中尝试了此代码:How to remove whitespace from an image in OpenCV?

gray = load_image(IMG_FILE) # image file
gray = 255*(gray < 128).astype(np.uint8)
coords = cv2.findNonZero(gray) # Find all non-zero points (text)
x, y, w, h = cv2.boundingRect(coords) # Find minimum spanning bounding box
rect = load_image(IMG_FILE)[y:y+h, x:x+w] # Crop the image - note we do this on the original image

它正在裁剪一小部分空白区域。

【问题讨论】:

  • @TanyaGupta 但那是一个密集的文本,等距且逐行。在我的情况下,它是一张收据图像,它的间距(或)不完全相等。它对我不起作用。我尝试过的上述代码取自该答案。
  • 我是您提到的帖子的原作者。您的代码确实可以进行非常轻微的修复。我已经写了一个自我控制的答案。顺便说一句,为了披露您没有正确使用整个解决方案。您删除了进行噪声过滤的答案的形态部分 - 检查我的答案中链接的代码的第二个版本。这是它没有按预期工作的主要原因。

标签: python image opencv image-processing computer-vision


【解决方案1】:

我是您尝试的代码的原作者。它不起作用的原因是因为文本周围有一些嘈杂的像素,这些像素会影响算法。如果你用一个简单的开放形态学操作去除噪声,你会得到你需要的结果。这实际上是在我的答案的第二个版本中完成的,不幸的是您没有尝试:

import cv2
import numpy as np

gray = load_image(IMG_FILE) # image file

# Threshold the image so that black text is white
gray = 255*(gray < 128).astype(np.uint8)

# Additionally do an opening operation with a 2 x 2 kernel
O = np.ones(2, dtype=np.uint8)
gray_morph = cv2.morphologyEx(gray, cv2.MORPH_OPEN, O)

# Continue where we left off
coords = cv2.findNonZero(gray_morph) # Find all non-zero points (text)
x, y, w, h = cv2.boundingRect(coords) # Find minimum spanning bounding box
rect = load_image(IMG_FILE)[y:y+h, x:x+w] # Crop the image

因此我们得到:

【讨论】:

  • 你能告诉我这条线在做什么255*(gray &lt; 128).astype(np.uint8)吗?
  • 它对图像进行阈值处理,将其转换为 uint8 并将非零像素设置为 255。您可以使用 cv2.threshold 实现相同的操作,但我喜欢明确地这样做,因为它向我展示了我的身份实际上在做。
  • 对我的问题还有一个小疑问,对于第一个未裁剪的图像,我得到了边界框(注释),但是当我执行这些步骤时,我得到了一个裁剪的图像和旧的边界框注释不起作用。 有什么方法可以使用裁剪比例来调整边界框以适应这个裁剪的图像?
  • @user_12 一些代码会有所帮助。我不太明白你想问什么。
  • 这是我之前问过的问题,一旦我认为您可以理解我在上述评论中要问的内容,请看一下:stackoverflow.com/questions/59652250/…
【解决方案2】:

这是一个简单的方法:

  1. 获取二值图像。加载图像,转换为灰度,应用大的高斯模糊,然后是 Otsu 的阈值

  2. 执行形态学操作。我们首先用一个小核变形打开以去除噪声,然后用一个大核变形关闭以组合轮廓

  3. 找到封闭的边界框并裁剪 ROI。 我们找到所有非零点的坐标,找到边界矩形,然后裁剪 ROI。


这是检测到的要裁剪的 ROI,以绿色突出显示

裁剪的投资回报率

import cv2

# Load image, grayscale, Gaussian blur, Otsu's threshold
image = cv2.imread('1.jpg')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (25,25), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Perform morph operations, first open to remove noise, then close to combine
noise_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, noise_kernel, iterations=2)
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, close_kernel, iterations=3)

# Find enclosing boundingbox and crop ROI
coords = cv2.findNonZero(close)
x,y,w,h = cv2.boundingRect(coords)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
crop = original[y:y+h, x:x+w]

cv2.imshow('thresh', thresh)
cv2.imshow('close', close)
cv2.imshow('image', image)
cv2.imshow('crop', crop)
cv2.waitKey()

【讨论】:

  • 谢谢你:)。只是一个简单的问题,如果背景并不总是白色,这会起作用吗...只是我有一些收据,背景有点灰色,浅灰色带有一些点(即干扰)?
  • 是的,它应该可以工作,Otsu 的阈值会自动计算一个阈值,因此如果照明条件或背景发生变化,它应该仍然可以。大的高斯模糊和变形开放操作的原因是为了平滑和去除噪声。根据图像,您可能需要修改这些值。你能添加一些背景有点灰的例子吗?
  • 一个人如何在职业生涯中达到一个点,他们知道在图像处理中应用哪些操作以达到预期的效果。这对我来说太神奇了。
  • @MikanPotatos 在我创建这个 stackoverflow 帐户的同一天,我开始学习图像处理,没有任何经验。你只是做了很多问题,当你看到情况时,你最终会立即看到要应用的模式
猜你喜欢
  • 2018-09-29
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
相关资源
最近更新 更多