【问题标题】:Remove black header section of image using Python OpenCV使用 Python OpenCV 删除图像的黑色标题部分
【发布时间】:2020-05-28 17:11:32
【问题描述】:

我需要使用 Python CV 删除图像多个部分中的变黑部分。 我尝试了去噪,但效果不佳。

例如。我需要删除表头(下图)中的黑色部分,并将表头背景转换为白色,内容为黑色。

谁能帮我选择正确的库或解决方案来克服这个问题?

【问题讨论】:

  • 这太宽泛/模糊了,可能离题了。请参阅:tourHow to Askhelp center
  • 什么是“黑化部分”?您是指列线划分吗?行?看看这篇文章:stackoverflow.com/questions/60163725/…
  • 黑化部分是背景图像具有不同虚线图案的列标题。我需要删除虚线图案,并且需要提供白色作为背景。
  • 发布问题时,请提供您迄今为止尝试过的内容以及您受到打击的地方

标签: python opencv image-processing deep-learning python-imaging-library


【解决方案1】:

如您所见,虚线图案很难过滤。它显然与文本重叠。我看到至少有两种选择:1)利用模式的周期性特性并执行频率过滤。 2) 尝试一种更简单的方法,对目标像素使用形态命中或未命中操作,旨在隔离它们。

让我们看看选项 2。噪声具有非常独特的模式。如果您使用所有斑点都以白色着色的二进制图像,您正在寻找的图案是一个白色像素 (1) 被 8 个黑色像素 (0) 包围>:

[ 0, 0, 0 ]
[ 0, 1, 0 ]
[ 0, 0, 0 ]

命中和未命中操作可用于定位和隔离像素模式。 Here's 如果您想了解更多信息,这是一篇好文章。现在,让我们处理代码:

//Read the input image, as normal:
std::string imagePath = "C://opencvImages//tableTest.png";
cv::Mat testImage = cv::readImage( imagePath );

//Convert the image to grayscale:
cv::Mat grayImage;
cv::cvtColor( testImage, grayImage, cv::COLOR_BGR2GRAY );

//Get the binary image via otsu:
cv::Mat binaryImage;
cv::threshold( grayImage, binaryImage, 0, 255,cv::THRESH_OTSU );

//Invert the image, as we will be working on white blobs:
binaryImage = 255 - binaryImage;

//Prepare the target kernel. This is where you define the pattern of 
//pixels you are looking for
//Keep in mind that -1 -> black and 1 -> white

cv::Mat kernel = ( cv::Mat_<int>(3, 3) <<
    -1, -1, -1,
    -1, 1, -1,
    -1, -1, -1
);

//perform the hit or miss operation:
cv::Mat hitMissMask;
cv::morphologyEx( binaryImage, hitMissMask, cv::MORPH_HITMISS, kernel );

这是你得到的面具:

现在,只需将此蒙版减去原始(二进制)图像即可得到:

如您所见,部分列标题妨碍了操作。如果您想要白色背景和黑色斑点,只需反转图像:

【讨论】:

  • 这是一个很好的方法。我有一个可能的改进,而不是减去蒙版,您可以在蒙版上找到轮廓,然后将轮廓绘制到白色的输入图像上。这样,文本看起来不会失真。目前,通过反转图像会损坏文本像素(文本质量略有下降)
  • 感谢 Eldesgraciado 的及时回复!
【解决方案2】:

这是@eldesgraciado 方法的修改版本,该方法在 Python 中使用对目标像素的形态命中或未命中操作来过滤虚线图案。不同之处在于,我们不是用降低文本质量的二值图像减去掩码,而是按位扩展二值图像并保留文本质量。

  1. 获取二值图像。加载图像,灰度,Otsu's threshold

  2. 执行形态学命中或未命中操作。我们使用cv2.getStructuringElement 创建一个点模式内核,然后使用cv2.filter2D 对图像进行卷积

  3. 去除点。我们cv2.bitwise-xor带有二值图像的蒙版

  4. 修复损坏的文本像素。我们cv2.dilate 然后cv2.bitwise_and 将输入图像和背景像素设置为白色的最终蒙版


二值图像

点掩码

去除点

扩张以修复阈值处理过程中损坏的文本像素

结果

代码

import cv2
import numpy as np

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

# Perform morphological hit or miss operation
kernel = np.array([[-1,-1,-1], [-1,1,-1], [-1,-1,-1]])
dot_mask = cv2.filter2D(thresh, -1, kernel)

# Bitwise-xor mask with binary image to remove dots
result = cv2.bitwise_xor(thresh, dot_mask)

# Dilate to fix damaged text pixels
# since the text quality has decreased from thresholding
# then bitwise-and with input image
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
dilate = cv2.dilate(result, kernel, iterations=1)
result = cv2.bitwise_and(image, image, mask=dilate)
result[dilate==0] = [255,255,255]

cv2.imshow('dot_mask', dot_mask)
cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.imshow('dilate', dilate)
cv2.waitKey()

【讨论】:

    猜你喜欢
    • 2018-02-08
    • 2018-06-18
    • 2018-11-16
    • 1970-01-01
    • 2020-05-04
    • 2019-10-29
    • 2021-06-05
    • 2020-12-05
    • 1970-01-01
    相关资源
    最近更新 更多