我想改变颜色的推土机,以特定的十六进制颜色(在这种情况下为红色)
,同时保持强度(推土机上的光线效果).我想只改变它的黄色部分,到目前为止,我已经创建了一个面具,为浅色和深色的黄色色调设置了下限和上限,并提取了那个面具,然而,我不知道如何应用红色的面具,并保持相对强度的颜色,而不仅仅是所有相同的红色色调。
像下面这样的图像将是伟大的(更好的质量,如果可能的话,因为似乎有一些颜色没有正确设置)
我已经看到了一些使用HSV的变通方法,但没有什么真正做的工作。
到目前为止,我的代码涉及到创建一个掩码来提取我想要改变的颜色,并将该掩码转换为HSV颜色以保留颜色的强度,之后我试图修改HSV以实现所需的颜色,但它并不精确,没有确切的方法将HSV更改为我想要的十六进制或RGB颜色?
import cv2
import numpy as np
import os
import math
from numpy import inf
# set the bounds for the light and dark shade of color you want to mask
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])
all_images = sorted(os.listdir('data/audi_a6'))
for i, image in enumerate(all_images):
print(image, end='\r')
img = cv2.imread(f'data/lego/{image}')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
yellow_mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
inv_mask = cv2.bitwise_not(yellow_mask)
h, s, v = cv2.split(hsv)
h = np.mod(h - h + 182, 180)
s = np.clip(s + 120, 0, 255)
v = np.clip(v, 0, 255)
hsv = cv2.merge([h, s, v])
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
result = cv2.bitwise_or(cv2.bitwise_and(img, img, mask=inv_mask), cv2.bitwise_and(bgr, bgr, mask=yellow_mask))
# Save the result
cv2.imwrite(f'output_change_color/lego/frame_{i:03}.jpg', result)
字符串
2条答案
按热度按时间k7fdbhmy1#
你似乎很难区分黄色的机器和它下面的“泥泞的轨道”。解决这些问题的一种方法是查看不同的色彩空间,看看哪一个是好的判别式。所以,我将你的图像转换为许多不同的色彩空间,并为你并排拆分出各个通道:
的数据
因此,您可以查看每个色彩空间的每个通道,看看哪一个最适合您。例如,
CIELab
的第三个通道,或HCL
的第二个通道。kjthegm62#
我只需要做一件事就可以让你的代码产生预期的结果。对于黄色像素,H通道大约是25。我们希望它是0。所以我们需要减去25:
H - H_yellow + H_red
。但是由于
h
是一个uint8
数组,减去25会导致一些像素绕回255,这不是H的有效值(OpenCV将其定义为8位图像的0-180范围)。因此,如果加上0,我们加上180,那么np.mod()
操作可以做正确的事情:字符串
这显然不是通用的。为了更通用地做到这一点,我们最好使用浮点运算进行算术运算,因为没有溢出或 Package 需要担心。这还有另一个优点:OpenCV不会将HSV空间转换为整数值,这允许更精确的重建。但是请记住,H现在在0-360的范围内,S和V在0-1的范围内。
型
[Note我们不碰V。