如何使用python将图像中方形标题的背景从黑色反转为白色?

如何使用python将图像中方形标题的背景从黑色反转为白色?,python,image,opencv,image-processing,computer-vision,Python,Image,Opencv,Image Processing,Computer Vision,我试图将方形标题(包含PONUMBER项目术语的黑色条)的背景设置为白色,并将其中的文本设置为黑色 我曾尝试使用findContours方法来查找轮廓,然后裁剪并反转它们,以便以黑色文本和白色背景的形式获得它们。但问题是我不知道如何继续前进,或者有没有更好的方法来解决这个问题 image =cv2.imread("default.jpg") gray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) th, thresh = cv2.threshold(gray

我试图将方形标题(包含PONUMBER项目术语的黑色条)的背景设置为白色,并将其中的文本设置为黑色

我曾尝试使用findContours方法来查找轮廓,然后裁剪并反转它们,以便以黑色文本和白色背景的形式获得它们。但问题是我不知道如何继续前进,或者有没有更好的方法来解决这个问题

image =cv2.imread("default.jpg")
gray=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

th, thresh = cv2.threshold(gray,1, 255, cv2.THRESH_BINARY_INV)

kernel = cv2.getStructuringElemnt(cv2.MORPH_ELLIPSE,(7,7))
morp_image = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

contours = cv2.findContours(morp_image, 
cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]
cnts = sorted(contours,key=cv2.contourArea)[-1]
上面的代码确实会逐个查找每个这样的轮廓,比如如果我将代码最后一行中的[-1]更改为[-2],它将查找下一个轮廓,但我希望一次查找图像中的所有这样的区域,并在将文本更改为黑色的同时将这些区域的背景设置为白色


谢谢这里有一个简单的方法

  • 将图像转换为灰度和高斯模糊
  • 大津阈值法获取二值图像
  • 寻找轮廓
  • 使用角数和轮廓面积进行过滤
  • 提取ROI,反转ROI,并替换为原始图像

其思想是,如果轮廓有4个角,那么它必须是正方形/矩形。此外,我们使用最小轮廓面积来忽略噪声。如果轮廓通过我们的过滤器,那么我们就有一个想要反转的ROI。检测到的roi

现在,我们使用Numpy切片提取每个ROI。这是反转前后的每个ROI

现在,我们只需将每个反转的ROI替换回原始图像即可得到结果


如果该表上的任何信息是PII,我建议对其进行编辑并重新发布图像。您也可以尝试使用
teseract ocr
提取所需的文本区域,并相应更改相邻像素值。另一种方法是在水平方向上使用
Hough行
来隔离标题,并找到彼此接近的行对。这是一个令人惊讶的解释!!非常感谢@Nathany,它解决了我的问题。如果方形标题有白色背景,此算法将使其变为黑色,这不是目的。它不应该反转带有白色背景的标题。我们怎么能做到呢@唯一的方法是使用
cv2.countNonZero()
检查ROI以确定大多数像素的颜色。此函数将检查灰度图像上有多少白色像素。如果大部分像素为黑色,则反转,如果为白色,则不做任何操作
import cv2

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.015 * peri, True)
    area = cv2.contourArea(c)
    if len(approx) == 4 and area > 1000:
        x,y,w,h = cv2.boundingRect(c)
        ROI = 255 - image[y:y+h,x:x+w]
        image[y:y+h, x:x+w] = ROI

cv2.imshow('image', image)
cv2.imwrite('image.png', image)
cv2.waitKey()