简体   繁体   中英

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.

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). 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.

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. If you use COLOR_BGR2HSV_FULL for the "forward conversion", you need to use COLOR_HSV2BGR_FULL for the "backward conversion". 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.

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.

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"; image had mostly values 171 , and temp_image mostly values 170 . The main result after converting to BGR was identical, but for the sake of completeness, I wanted to mention that.

Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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