【问题标题】:how to change the text layout color to white and text to black using python?如何使用python将文本布局颜色更改为白色并将文本更改为黑色?
【发布时间】:2021-06-01 10:50:03
【问题描述】:

我有这张图片。

我想将所有彩色标题设为白色,将其中的文本设为黑色。

我尝试在下面使图像全黑。

img_grey = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)
thresh = 170
img_binary = cv2.threshold(img_grey, thresh, 250, cv2.THRESH_BINARY)[1]
cv2.imwrite('bw_img.jpg',img_binary) 

现在这些标题是黑色的,其中的文本是白色的。但我想让文本变黑,标题布局变白。那么,谁能帮我解决这个问题?

【问题讨论】:

  • cv2.THRESH_BINARY 替换为cv2.THRESH_BINARY_INV
  • 它适用于标题,但它也会使整个图像背景变黑。我只想更改那些粉红色的标题。

标签: python python-3.x opencv image-processing


【解决方案1】:

您可以将图像转换为 HSV,应用阈值来查找彩色区域,并将 cv2.thresholdcv2.THRESH_BINARY_INV 的结果仅复制到彩色区域。

建议解决方案的主要阶段:

  • 从 BGR 转换为 HSV 颜色空间,并获得饱和颜色通道。
    所有黑色和白色都为零,彩色像素高于零。
  • 对饱和通道应用阈值。
  • 在二值化饱和度通道上查找轮廓。
  • 在黑色背景上将轮廓绘制为白色(255 个值)以形成蒙版。
  • 应用形态闭合来闭合一些黑色间隙。
  • 仅从img_binary_inv 获取掩码内的区域(您的代码使用cv2.THRESH_BINARY_INV 的结果)。
  • 仅将蒙版的img_binary_inv 复制到img_grey,以蒙版为白色的像素为单位。

完整的代码示例:

import numpy as np
import cv2

img_bgr = cv2.imread('img.jpg')  # Read image as BGR

img_grey = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)  # Convert from BGR to grayscale.

thresh = 170
img_binary_inv = cv2.threshold(img_grey, thresh, 255, cv2.THRESH_BINARY_INV)[1]  # Apply threshold and invert black/white

# Convert from BGR to HSV color space.
hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)

# Get the saturation color channel - all black and white are zero, and colored pixels are above zero.
s = hsv[:, :, 1]

thresh = 100
s_binary = cv2.threshold(s, thresh, 255, cv2.THRESH_BINARY)[1]  # Apply threshold to the saturation channel.

# Find contours on s_binary
cnts = cv2.findContours(s_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]  # Use index [-2] to be compatible to OpenCV 3 and 4

# Draw the contours as white (255 values) on black background.
mask = np.zeros_like(s_binary)
cv2.drawContours(mask, cnts, -1, 255, -1)

# Apply morphological closing for closing some black gaps.
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((3, 3)))

# Get only the area inside the mask from img_binary_inv
masked_binary_inv = cv2.bitwise_or(img_binary_inv, img_binary_inv, mask=mask)

# Copy masked_binary_inv to img_grey only in pixels that mask is white.
cv2.copyTo(masked_binary_inv, mask, img_grey)

cv2.imwrite('img_grey.png', img_grey)  # Save result (as PNG and not JPEG for better quality).

# Show images
cv2.imshow('img_bgr', img_bgr)
cv2.imshow('s_binary', s_binary)
cv2.imshow('mask', mask)
cv2.imshow('masked_binary_inv', masked_binary_inv)
cv2.imshow('img_grey', img_grey)
cv2.waitKey()
cv2.destroyAllWindows()

结果(img_grey):

由于输入图像的质量相对较低,结果看起来不太好。


中间结果:

s_binary:

mask:

masked_binary_inv:

【讨论】:

  • 感谢您的帮助。它工作得非常好,但它也使一些标题完全白色,一些标题半部分。那么,该如何处理呢?
  • 1. 尝试获得质量更好的图像样本(至少是 PNG 无损格式,而不是 JPEG)。 2. 黄色区域内的红色文本是白色的,因为该解决方案不处理彩色区域内的彩色文本。您可以使用 HSV 的色调颜色通道的信息来解决它(看起来很复杂)。彩色区域不会覆盖所有方向的文本。您可以通过扩大mask 来改进它。 3. 降低您对 Stack Overflow 中答案的期望 - 答案只是指导,而不是处理所有情况的完美解决方案。
猜你喜欢
  • 1970-01-01
  • 2023-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多