添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

从图像中去除颜色,只保留文本

0 人关注

像下面这样的白色背景图片,在(额外的)红色背景下的一些文字是黑色的,一些文字是红色的。文字的位置(无论是否有背景)是不固定的。

我想复制一个只有文字的图像。

我想到的一个办法是把红色背景换成白色,但不可避免的是,红色文字也会消失。

以下是我所尝试的。

from PIL import Image
import numpy as np
orig_color = (255,0,0)
replacement_color = (255,255,255)
img = Image.open("C:\\TEM\\AB.png").convert('RGB')
data = np.array(img)
data[(data == orig_color).all(axis = -1)] = replacement_color
img2 = Image.fromarray(data, mode='RGB')
img2.show()

结果如下。

有什么办法可以只保留图片的所有文字?(理想状态如下)

5 个评论
它总是黑色和红色吗?还是可能有其他颜色?
@Mark Setchell,总是只有黑色和红色。
如何获得左上角像素的颜色。如果是红色,就把红色像素变成白色,把(假定的)黑字保留为黑色。如果是黑色,就把黑色像素变成白色,红色像素变成黑色。这个策略假定你的字母不接触角落--也就是说,左上角的像素是背景色。
@MarkSetchell, 忘了告诉大家图片是白色背景的。所以左上角的康纳是白色的...
如果你能检测到包含黑色文本的红色矩形区域,你可以在该区域内删除它们周围的红色。之后,你可以用黑色替换图像中剩余的所有红色(即红色文本)。
python
image
numpy
colors
python-imaging-library
Mark K
Mark K
发布于 2019-12-05
1 个回答
Jonathan Feenstra
Jonathan Feenstra
发布于 2019-12-05
已采纳
0 人赞同

下面是我的方法,只使用图像的红色和绿色通道(使用OpenCV,解释见我在代码中的注释)。

import cv2
import imageio
import numpy as np
# extract red and green channel from the image
r, g = cv2.split(imageio.imread('https://i.stack.imgur.com/bMSzZ.png'))[:2]
imageio.imsave('r-channel.png', r)
imageio.imsave('g-channel.png', g)
# white image as canvas for drawing contours
canvas = np.ones(r.shape, np.uint8) * 255
# find contours in the inverted green channel 
# change [0] to [1] when using OpenCV 3, in which contours are returned secondly
contours = cv2.findContours(255 - g, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]
# filter out contours that are too large and have length 4 (rectangular)
contours = [
    cnt for cnt in contours
    if cv2.contourArea(cnt) <= 500 and len(cnt) == 4
# fill kept contours with black on the canvas
cv2.drawContours(canvas, contours, -1, 0, -1)
imageio.imsave('filtered-contours.png', canvas)
# combine kept contours with red channel using '&' to bring back the "AAA"
# use '|' with the green channel to remove contour edges around the "BBB"
result = canvas & r | g
imageio.imsave('result.png', result)

r-channel.png

g-channel.png

filtered-contours.png

result.png

result = np.ones(img.shape[:2], np.uint8) * 255 for channel in cv2.split(img): canvas = np.ones(img.shape[:2], np.uint8) * 255 contours = cv2.findContours(255 - channel, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0] # size threshold may vary per image contours = [cnt for cnt in contours if cv2.contourArea(cnt) <= 100] cv2.drawContours(canvas, contours, -1, 0, -1) result = result & (canvas | channel)