如何使用OpenCV和Python从图像中仅保留特定颜色的文本?

3
我有一些发票图像,其中一些文字重叠在一起,这对后续处理造成了一些麻烦,我只需要黑色文字。我想删除其他颜色的文字。请问有什么方法可以实现吗?示例图像已附上。我已经尝试使用opencv解决,但是我仍然无法解决这个问题。
import numpy as np import cv2
img = cv2.imread('11.png')

lower = np.array([150,150,150]) 

upper = np.array([200,200,200])

mask = cv2.inRange(img, lower, upper) 
res = cv2.bitwise_and(img, img, mask=mask) 
cv2.imwrite('22.png',res)

[多色彩图片][1]

[1]: https://istack.dev59.com/nWQrV.webpstrong 文字

2个回答

6
文本变得更暗,饱和度降低。正如@J.D.所建议的那样,HSV颜色空间是不错的选择。但他的范围是错误的。
在OpenCV中,H范围为[0, 180],而S/V范围为[0, 255]。
这是我去年制作的一张色标图,我认为它很有帮助。 (1) 使用cv2.inRange
(2) 只需对V(HSV)通道进行阈值处理:
th, threshed = cv2.threshold(v, 150, 255, cv2.THRESH_BINARY_INV)

(3) 只需对 S(HSV) 通道进行阈值处理:

th, threshed2 = cv2.threshold(s, 30, 255, cv2.THRESH_BINARY_INV)

结果:

在此输入图像描述


演示代码:
# 2018/12/30 22:21 
# 2018/12/30 23:25 

import cv2 

img = cv2.imread("test.png")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)

mask = cv2.inRange(hsv, (0,0,0), (180, 50, 130))
dst1 = cv2.bitwise_and(img, img, mask=mask)

th, threshed = cv2.threshold(v, 150, 255, cv2.THRESH_BINARY_INV)
dst2 = cv2.bitwise_and(img, img, mask=threshed)

th, threshed2 = cv2.threshold(s, 30, 255, cv2.THRESH_BINARY_INV)
dst3 = cv2.bitwise_and(img, img, mask=threshed2)

cv2.imwrite("dst1.png", dst1)
cv2.imwrite("dst2.png", dst2)
cv2.imwrite("dst3.png", dst3)

  1. 如何使用OpenCV检测图像中的彩色块?

  2. 如何定义阈值来仅检测图像中的绿色物体:Opencv


我认为我应该让我的问题更具体和完整,我想只保留特定颜色(黑色/红色)的文本的原因是图像中有几种颜色重叠的文本,这使得OCR无法识别那些重叠的文本。你的解决方案可以找出黑色文本,但图像质量大大降低,这使得后续OCR识别变得困难。 - jianhua zhou

3
转换为HSV颜色空间可以更轻松地选择颜色。
以下代码可实现您的要求。 结果: enter image description here
import numpy as np 
import cv2

kernel = np.ones((2,2),np.uint8)
# load image
img = cv2.imread("image.png")

# Convert BGR to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# define range of black color in HSV
lower_val = np.array([0,0,0])
upper_val = np.array([179,100,130])

# Threshold the HSV image to get only black colors
mask = cv2.inRange(hsv, lower_val, upper_val)

# Bitwise-AND mask and original image
res = cv2.bitwise_and(img,img, mask= mask)
# invert the mask to get black letters on white background
res2 = cv2.bitwise_not(mask)

# display image
cv2.imshow("img", res)
cv2.imshow("img2", res2)
cv2.waitKey(0)
cv2.destroyAllWindows()

要更改所选黑色的级别,请从当前设置为130的upper_val进行微调。更高=允许较浅的色调(称为值)。还有当前值为100:较低=允许较少的颜色(实际上是饱和度)。 了解有关HSV颜色空间的更多信息请点击此处
我始终发现下面的图像非常有帮助。底部的“圆盘”全部是黑色的。随着值的增加,也会选择较浅的像素。低饱和度的像素保持灰色色调直到白色(中心),高饱和度的像素变为彩色(边缘)。这就是为什么要微调这些值的原因。 enter image description here 编辑:正如@Silencer指出的那样,我的范围错误。已修复。

我认为我应该让我的问题更具体和完整,我想只保留特定颜色(黑色/红色)的文本的原因是图像中有几种颜色重叠的文本,这使得OCR无法识别那些重叠的文本。你的解决方案可以找出黑色文本,但图像质量大大降低,这使得后续OCR识别变得困难。 - jianhua zhou
如果你放大图像左上角的字母,你会发现这很困难。有太多浅灰色的像素。我尝试增加对比度,但效果不大。获得均匀、高对比度的图像,并增加更多像素,将提高结果的质量... - J.D.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接