在OpenCV中更改颜色并保持原始颜色强度

ogsagwnx  于 2023-11-22  发布在  其他
关注(0)|答案(2)|浏览(115)

我想改变颜色的推土机,以特定的十六进制颜色(在这种情况下为红色)

,同时保持强度(推土机上的光线效果).我想只改变它的黄色部分,到目前为止,我已经创建了一个面具,为浅色和深色的黄色色调设置了下限和上限,并提取了那个面具,然而,我不知道如何应用红色的面具,并保持相对强度的颜色,而不仅仅是所有相同的红色色调。
像下面这样的图像将是伟大的(更好的质量,如果可能的话,因为似乎有一些颜色没有正确设置)

我已经看到了一些使用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)

字符串

k7fdbhmy

k7fdbhmy1#

你似乎很难区分黄色的机器和它下面的“泥泞的轨道”。解决这些问题的一种方法是查看不同的色彩空间,看看哪一个是好的判别式。所以,我将你的图像转换为许多不同的色彩空间,并为你并排拆分出各个通道:


的数据
因此,您可以查看每个色彩空间的每个通道,看看哪一个最适合您。例如,CIELab的第三个通道,或HCL的第二个通道。

kjthegm6

kjthegm62#

我只需要做一件事就可以让你的代码产生预期的结果。对于黄色像素,H通道大约是25。我们希望它是0。所以我们需要减去25:H - H_yellow + H_red
但是由于h是一个uint8数组,减去25会导致一些像素绕回255,这不是H的有效值(OpenCV将其定义为8位图像的0-180范围)。因此,如果加上0,我们加上180,那么np.mod()操作可以做正确的事情:

h = np.mod(h + 180 - 25, 180)

字符串
这显然不是通用的。为了更通用地做到这一点,我们最好使用浮点运算进行算术运算,因为没有溢出或 Package 需要担心。这还有另一个优点:OpenCV不会将HSV空间转换为整数值,这允许更精确的重建。但是请记住,H现在在0-360的范围内,S和V在0-1的范围内。

img = cv2.imread(image)

imgf = img.astype(np.float32) / 255
hsv = cv2.cvtColor(imgf, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)

h = np.mod(h + h_target - h_source, 360)
s = np.clip(s + s_taget - s_source, 0, 1)

hsv = cv2.merge([h, s, v])
imgf = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
bgr = (imgf * 255).astype(np.uint8)


[Note我们不碰V。

相关问题