A list comprehension could be helpful here. You can try something like:
hex_values = ['#b4a795', '#e7e0d6', '#d7cfc8']
hsv_values = [rgb2hsv(*hex2rgb(hex_val)) for hex_val in hex_values]
Answer from jprebys on Stack OverflowA list comprehension could be helpful here. You can try something like:
hex_values = ['#b4a795', '#e7e0d6', '#d7cfc8']
hsv_values = [rgb2hsv(*hex2rgb(hex_val)) for hex_val in hex_values]
put your hex values in a list, then iterate it.
hexValues = ["#b4a795", "#e7e0d6", "#d7cfc8"]
hsvValues = []
for i in hexValues:
hsvValues.append(rgb2hsv(*hex2rgb(i)))
print(hsvValues)
hex <-> RGB <-> HSV Color space conversion with Python - Stack Overflow
python - Converting hsl to hex in python3 - Stack Overflow
Convert hsl to hsv color codes and vice versa in Python - Stack Overflow
How to convert HSL color into HSV color in python (no external library)? - Stack Overflow
I would use regular expressions:
regex = r'hsl\(\s*(\d+),\s*(\d+)%,\s*(\d+)%\s*\);'
lines = [re.findall(regex,line) for line in one_dark_syn.split('\n')]
rgbs = [colorsys.hsv_to_rgb(int(line[0][0])/360,
int(line[0][1])/100,
int(line[0][2])/100) for line in lines if line]
# [(0.2915, 0.519842, 0.55), (0.1188, 0.41646, 0.66), (0.5762, 0.268, 0.67),
# (0.48257, 0.62, 0.3844), (0.65, 0.2275, 0.2627), (0.51, 0.2856, 0.2652),
# (0.61, 0.43981, 0.2806), (0.69, 0.528195, 0.2277)]
Finally, convert RGB triplets to a HEX string:
rgbhex = ["".join("%02X" % round(i*255) for i in rgb) for rgb in rgbs]
# ['1D3437', '0C2A42', '3A1B43', '303E26', '41171A', '331D1B', '3D2C1C', '453517']
Thank you, @DYZ:
import re
import colorsys
json = '''
```json
{
"variables":
{
"blue": "hsl(210, 50%, 60%)",
"blue2": "hsl(180, 36%, 54%)",
"green": "hsl(114, 31%, 68%)",
"grey": "hsl(0, 0%, 73%)",
"grey2": "hsl(0, 0%, 60%)",
"grey3": "hsl(0, 0%, 20%)",
"orange": "hsl(32, 93%, 66%)",
"orange2": "hsl(32, 85%, 55%)",
"orange3": "hsl(40, 94%, 68%)",
"pink": "hsl(300, 30%, 68%)",
"red": "hsl(357, 79%, 65%)",
"red2": "hsl(13, 93%, 66%)",
"red3": "hsl(16, 29%, 54%)",
"white": "hsl(0, 0%, 97%)",
"white2": "hsl(210, 11%, 85%)",
"white3": "hsl(204, 10%, 90%)",
"white4": "hsl(195, 11%, 93%)",
"white5": "hsl(180, 9%, 98%)"
}
}
'''
regex = r'hsl\(\s*(\d+),\s*(\d+)%,\s*(\d+)%\s*\)'
lines = re.findall(regex,json)
rgbs = [colorsys.hls_to_rgb(int(line[0])/360,int(line[2])/100,int(line[1])/100) for line in lines]
hexs = ['#%02x%02x%02x'%(round(rgb[0]*255),round(rgb[1]*255),round(rgb[2]*255)) for rgb in rgbs]
print(hexs)
You need to make sure to normalize the values according to the matching ranges. According to your values (and the range hints in this website), it seems you're using values of H in the range [0, 360] ; S and V in the range [0, 100]. On the other hand, the built-in library colorsys uses all [0, 1] ranges. So a bit of normalization will give you the required results:
import colorsys
def hsv_to_hsl(hsv):
h, s, v = hsv
rgb = colorsys.hsv_to_rgb(h/360, s/100, v/100)
r, g, b = rgb
h, l, s = colorsys.rgb_to_hls(r, g, b)
return h*360, s*100, l*100
hsv = (300, 65, 40)
print(hsv)
print(hsv_to_hsl(hsv))
Now gives the expected:
(300, 65, 40)
(300.0, 48.148148148148145, 27.0)
If you are looking for a manual implementation, you can use the algorithm described here (now the values are: H in range [0, 360] and S,V and L are in [0, 1]):
def hsv_to_hsl(hsv):
h, s, v = hsv
l = v * (1 - s/2)
s = 0 if l in (0, 1) else (v - l)/min(l, 1-l)
return h, s, l
def hsl_to_hsv(hsl):
h, s, l = hsl
v = l + s * min(l, 1-l)
s = 0 if v == 0 else 2*(1 - l/v)
return h, s, v
To compare the result with colorsys:
h, s, l = (300, 48.148, 27)
custom = hsl_to_hsv((h, s/100, l/100))
print("Custom function: ", custom[0], custom[1]*100, custom[2]*100)
expected = colorsys.rgb_to_hsv(*colorsys.hls_to_rgb(h/360, l/100, s/100))
print("Expected result: ", expected[0]*360, expected[1]*100, expected[2]*100)
Indeed gives:
Custom function: 300 64.99986499986498 39.99996
Expected result: 300.0 64.999864999865 39.99996
Not a native Python coder so this is pretty simplistic, but is based on the formula on Wikipedia and returns accurate values according to colorizer.org:
def hsl_to_hsv(hsl):
hue,sat,lum = hsl
if hue < 0 or hue > 360 or sat < 0 or sat > 1 or lum < 0 or lum > 1:
exit
h = hue
v = lum + sat * min(lum, 1 - lum)
if v == 0:
s = 0
else:
s = 2 * (1 - lum / v)
return h,s,v
def hsv_to_hsl(hsv):
hue,sat,val = hsv
if hue < 0 or hue > 360 or sat < 0 or sat > 1 or val < 0 or val > 1:
exit
h = hue
l = val * (1 - sat / 2)
if l == 0 or l == 1:
s = 0
else:
s = (val - l) / min(l, 1 - l)
return h,s,l
print (hsl_to_hsv((36.9,0.5118,0.751)))
print (hsv_to_hsl((36.9,0.2902,0.8784)))
Output:
(36.9, 0.29014721809684496, 0.8784382)
(36.9, 0.5117560784762163, 0.75094416)
Note that hue is a float with values 0 to 360, the other values are floats with values from 0 to 1, often expressed as percentages. Your problem using the colorsys library may have been that you were passing larger values like 29 instead of 0.29.
Use python std colorsys as HSL -> RGB -> HSV:
import colorsys
c = {'h': 300, 's': 67.0, 'l': 80.0}
r, g, b = colorsys.hls_to_rgb(c["h"], c["l"], c["s"])
h, s, v = colorsys.rgb_to_hsv(r, g, b)
Resu
Try using python's builtin colorsys module
like this:
import colorsys
def HSL2HSV(h,s,l):
rgb=colorsys.hls_to_rgb(h,l,s)
hsv=colorsys.rgb_to_hsv(*rgb)
return hsv
Converting HSV to RGB requires a formula -
Python, actually has had it in its standard library since the dawn of time - there is the colorsys module in the stdlib.
However, it works with floating point values in the 0.0-1.0 range - so, some code is needed if you want to convert your component values as integers.
Of course, just import colorsys does nothing - although possible, almost no package will have a global side-effect just by being imported (except from __future__ import .... statements which affect the way the Python code itself is compiled). You have to call the functions inside it.
That said, I think this could be your function (give or take "1" at the extreme boundaries:
import colorsys
def hsv_to_hex(h,s,v):
r, g, b = (int(255 * component) for component in colorsys.hsv_to_rgb(h / 255, s / 255, v / 255))
return f"#{r:02x}{g:02x}{b:02x}"
I am assuming the values you have for the HSV components are normalized in the 0-255 range. There is another, more usual convention, where they are 0-360 for H and 0-100 for S and V - change the divisors accordingly in the function above. (You have 172 for S, so it can´t be in the 0-100 range)
No, the hexcode is a representation of RGB, not HSV. You'll need to convert HSV to RGB with a formula like this first (or use a library).
Also your data does not look like typical HSV numbers, especially with saturations of "172". If they do actually represent HSV you would need to normalise to a 0 - 1 range before conversion.
I have a data science experiment I am trying to replicate. This experiment involves classifying images into 1 of 4 possible categories. I have been given a dataset of RGB pixel values for 400,000 28x28 images in the form of a 28 x 28 x 4 x 400,000 tensor. The third dimension is 4 because the 4 values of every pixel of the image are the RGB values as well as NIR (near-infrared) value. The paper recommends that to improve your model, you should convert the RGB values into HSV before training the classifier (while continuing to use the NIR values). A little bit of digging has told me that I can train a fairly good classifier by using only the mean and standard deviations of the HSV values as well as the NIR values for every image. I am using an SVM from scikit_learn ie the sklearn.SVC (with possibly rbf kernel) to classify this dataset. So I have two questions. Firstly, how can I flatten this tensor into a 2d matrix (of dimensions 400k x 3136) (where 3136 = 28 x 28 x 4) that my SVM can use to classify the data? And secondly how can I convert these RGB values to HSV in Python? (Sorry for the long question. It is my first time handling Data Science and Machine Learning so I am a bit unaware of how to do things. Also sorry for incorrect English)
(In case some detail is a bit vague/ not understandable please feel free to ask me for clarifications) Thanks in advance