Reputation: 58
i want to edit the hsv value of a certain area The picture I want to change color of
I to change all the purple parts of the image to green. Here is the result I made in an image editing software just to show a example.The Result Yeah i made it darker for no reason but i just wanna make the blade green but not the handle
Upvotes: 2
Views: 10286
Reputation: 53182
Here is a way to do that in Python/OpenCV by shifting hues.
Input:
import cv2
import numpy as np
# load image with alpha channel
img = cv2.imread('sword_purple.png', cv2.IMREAD_UNCHANGED)
# extract alpha channel
alpha = img[:,:,3]
# extract bgr channels
bgr = img[:,:,0:3]
# convert to HSV
hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
#h = hsv[:,:,0]
#s = hsv[:,:,1]
#v = hsv[:,:,2]
h,s,v = cv2.split(hsv)
# purple is 276 in range 0 to 360; so half in OpenCV
# green is 120 in range 0 to 360; so half in OpenCV
purple = 138
green = 60
# diff color (green - hue)
diff_color = green - purple
# modify hue channel by adding difference and modulo 180
hnew = np.mod(h + diff_color, 180).astype(np.uint8)
# recombine channels
hsv_new = cv2.merge([hnew,s,v])
# convert back to bgr
bgr_new = cv2.cvtColor(hsv_new, cv2.COLOR_HSV2BGR)
# put alpha back into bgr_new
bgra = cv2.cvtColor(bgr_new, cv2.COLOR_BGR2BGRA)
bgra[:,:,3] = alpha
# save output
cv2.imwrite('sword_alpha.png', alpha)
cv2.imwrite('sword_bgr.png', bgr)
cv2.imwrite('sword_bgr_new.png', bgr_new)
cv2.imwrite('sword_green.png', bgra)
# Display various images to see the steps
cv2.imshow('alpha',alpha)
cv2.imshow('bgr',bgr)
cv2.imshow('bgr_new',bgr_new)
cv2.imshow('bgra',bgra)
cv2.waitKey(0)
cv2.destroyAllWindows()
Upvotes: 4
Reputation: 53182
The simple way in Python/OpenCV is to create a mask where the image is purple using inRange() and then change the image to green where the mask is white using Numpy.
Input:
import cv2
import numpy as np
# load image with alpha channel
img = cv2.imread('sword_purple.png', cv2.IMREAD_UNCHANGED)
# extract alpha channel
alpha = img[:,:,3]
# extract bgr channels
bgr = img[:,:,0:3]
# select purple
lower_purple = (140,40,110)
upper_purple = (170,60,130)
mask = cv2.inRange(bgr, lower_purple, upper_purple)
# change the image to make it green where the mask is white
bgr_new = bgr.copy()
bgr_new[mask==255] = (0,255,0)
# put alpha back into rgb_new
bgra = cv2.cvtColor(bgr_new, cv2.COLOR_BGR2BGRA)
bgra[:,:,3] = alpha
# save output
cv2.imwrite('sword_alpha.png', alpha)
cv2.imwrite('sword_bgr.png', bgr)
cv2.imwrite('sword_mask.png', mask)
cv2.imwrite('sword_masked_green.png', bgr_new)
cv2.imwrite('sword_green.png', bgra)
# Display various images to see the steps
cv2.imshow('alpha',alpha)
cv2.imshow('mask',mask)
cv2.imshow('bgr_new',bgr_new)
cv2.imshow('bgra',bgra)
cv2.waitKey(0)
cv2.destroyAllWindows()
BGR channels:
Mask:
Recolored BGR channels:
Result with alpha channel put back:
Alternately, you can do the same by converting BGR to HSV and changing the purple to green the same way. Then convert back to BGR and put the alpha channel back.
Upvotes: 1