繁体   English   中英

使用 Python OpenCV 删除图像的黑色标题部分

[英]Remove black header section of image using Python OpenCV

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

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

在此处输入图片说明

任何人都可以帮助我选择正确的库或解决方案来克服这个问题吗?

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

让我们看看选项 2。噪音有一个非常独特的模式。 如果您使用所有 blob 都涂成白色的二进制图像,则您要查找的图案是一个白色像素(1)被 8 个黑色像素(0)包围:

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

命中和未命中操作可用于定位和隔离像素模式。 如果您想了解更多信息,这里有一个很好的帖子。 现在,让我们处理代码:

//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 方法的修改版本,该方法使用 Python 中目标像素的形态命中或未命中操作来过滤点状图案。 不同之处在于,我们不是用降低文本质量的二值图像减去掩码,而是先对二值图像进行膨胀,然后按位扩展,以保持文本质量。

  1. 获取二值图像。 加载图像、灰度、 大津阈值

  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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM