简体   繁体   English

如何将颜色从 HSV 更改回 RGB

[英]How to change color back from HSV to RGB

I am doing a little experiment to debug my project.我正在做一个小实验来调试我的项目。 I am trying to manipulate the hue value on HSV colorspace to see the effect on it when I change it back to RGB.我正在尝试操纵 HSV 颜色空间上的色调值,以查看当我将其更改回 RGB 时对它的影响。

I have a simple image with whole blue background and a single red circle inside of it.我有一个带有整个蓝色背景的简单图像,里面有一个红色圆圈。 I convert it from RGB to HSV and then change one of the values, and then revert it back to the previous value (please see the code, I can't explain it well by using just words).我将其从 RGB 转换为 HSV,然后更改其中一个值,然后将其恢复为以前的值(请参阅代码,我无法仅用文字来很好地解释它)。 I was expecting the image to remain the same but to my surprise, when I changed it back from HSV to RGB it gives different image.我期待图像保持不变,但令我惊讶的是,当我将其从 HSV 更改回 RGB 时,它会给出不同的图像。

import cv2
import sys
import numpy as np
from matplotlib import pyplot as plt
from bqplot import pyplot as bq
import math
import os

ori_image = cv2.imread('../test.png')
image = np.float32(ori_image)
image = cv2.cvtColor(ori_image,cv2.COLOR_BGR2HSV_FULL)
hues=np.round(image[:,:,0]/255*360)
np.place(hues,hues==229,50)
np.place(hues,hues==50,229)
hues=hues/360*255
temp_image = image.copy()
temp_image[:,:,0]=hues
temp_image=cv2.cvtColor(temp_image,cv2.COLOR_HSV2RGB)
plt.imshow(temp_image)
plt.show()

Can someone give an explanation for this?有人可以对此做出解释吗?

Basically, you just used the wrong ColorConversionCode for your second conversion.基本上,您只是在第二次转换中使用了错误的ColorConversionCode If you use COLOR_BGR2HSV_FULL for the "forward conversion", you need to use COLOR_HSV2BGR_FULL for the "backward conversion".如果使用COLOR_BGR2HSV_FULL进行“前向转换”,则需要使用COLOR_HSV2BGR_FULL进行“后向转换”。 You used COLOR_HSV2RGB , which is indeed wrong in two ways: (1) You convert to RGB instead of BGR, and (2) you don't use the full conversion for the H channel.您使用COLOR_HSV2RGB ,这在两个方面确实是错误的:(1)您转换为 RGB 而不是 BGR,以及(2)您没有对 H 通道使用完全转换。

import cv2
import numpy as np
from matplotlib import pyplot as plt

orig_image = np.ones((400, 400, 3), np.uint8)
orig_image[:, :, 0] *= 255
orig_image[:, :, 1:3] = 0
cv2.circle(orig_image, (100, 100), 50, (0, 0, 255), cv2.FILLED)

image = np.float32(orig_image)                                  # this line is ignored either way
image = cv2.cvtColor(orig_image, cv2.COLOR_BGR2HSV_FULL)
hues = np.round(image[:, :, 0] / 255 * 360)
np.place(hues, hues == 229, 50)
np.place(hues, hues == 50, 229)
hues = np.round(hues / 360 * 255)                               # Use np.round here, too, to prevent integer cutting
temp_image = image.copy()
temp_image[:, :, 0] = hues
temp_image = cv2.cvtColor(temp_image,  cv2.COLOR_HSV2BGR_FULL)  # You need to use the proper color conversion code here

plt.figure(1)
plt.subplot(1, 2, 1), plt.imshow(orig_image), plt.title('Original image')
plt.subplot(1, 2, 2), plt.imshow(temp_image), plt.title('Modified image')
plt.savefig('C:/Users/c.wilde/Desktop/output.png')
plt.show()

输出

Note: Matplotlib uses RGB ordering, OpenCV BGR ordering, that's why the blue and red in the plots are inverted.注意:Matplotlib 使用 RGB 排序,OpenCV BGR 排序,这就是图中蓝色和红色反转的原因。

Also, please notice: I added a rounding at hues = np.round(hues / 360 * 255) , because image and temp_image (before converting to BGR) were slightly different due to "integer cutting";另外,请注意:我在hues = np.round(hues / 360 * 255)处添加了舍入,因为imagetemp_image (在转换为 BGR 之前)由于“整数切割”而略有不同; image had mostly values 171 , and temp_image mostly values 170 . image的主要值是171 ,而temp_image主要值是170 The main result after converting to BGR was identical, but for the sake of completeness, I wanted to mention that.转换为 BGR 后的主要结果是相同的,但为了完整起见,我想提一下。

Hope that helps!希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM