我要调查的色彩数据很少。它采用RGB数据列表的形式。
[(255, 255, 255), (124, 144, 231), ...]
图像使用了受限制的调色板,我想通过沿色轮进行绘制来查看这些颜色是如何“分布”的。另外,我尝试了单个通道的直方图,但这并没有给我我感兴趣的见识。
我搜索并了解到,HSL颜色可以更准确地映射到色轮。但是,转换为HSL后,我仍然感到困惑。颜色仍然由3个数据组成:色相,饱和度和亮度。您如何将3个数据映射到2d平面上?
我在这里了解极坐标:https://www.mathsisfun.com/polar-cartesian-coordinates.html。我尝试通过将HSL数据视为极坐标(色相=角度,饱和度=半径长度(由某些比例缩放))来忽略亮度和绘图。
def polar2cartesian(hsl):
color_circle_radius = 100
radius = hsl.saturation * color_circle_radius
x = radius * math.cos(math.radians(hsl.hue))
y = radius * math.sin(math.radians(hsl.hue))
return x, y
...
for hsl in colors:
x, y = polar2cartesian(hsl)
im.point(x, y, hsl.to_rgb())
这不是正确的结果。由于它在多个地方都显示相同的红色色调,例如本例:
从RGB转换到色轮上某个位置的正确方法是什么?
答案 0 :(得分:5)
将3D(H,S,V)颜色映射到2D平面上的问题很难客观地解决,因此我认为我应该对此加以解决,并得出令人愉悦的结果。
我的方法如下:
现在,在代码中:(Entire file)
创建一个表以在每个特定位置存储最大值
highest_value = numpy.zeros((image_size, image_size))
将RGB转换为HSV
def rgb_to_point(rgb):
hsv = colorsys.rgb_to_hsv(*rgb)
将其转换为向量
rads = math.tau * hsv[0] - math.pi
mag = hsv[1] * (image_size/2) - 1
将其转换为图像上的一个点
x = int(math.cos(rads) * mag + (image_size/2))
y = int(math.sin(rads) * mag + (image_size/2))
如果该值较大,则返回该点,否则返回None
if(hsv[2] > highest_value[x][y]):
highest_value[x][y] = hsv[2]
return (x, y)
我把所有rgb_to_point
函数都调用了,现在我们将它用于图像中的每个像素:
for pixel in img.getdata():
c = rgb_to_point(pixel)
if(c):
imgo.putpixel(c, pixel)
if(c)
确定该值是否更高,因为c并非{c}时为None
。
结果如下:
注意:我之所以要处理这样的价值,部分原因是因为我想到的替代方案并不那么好。完全忽略值会导致较暗的像素出现在输出图像上,这通常会导致轮子变丑。将每个输出像素的值都提高到1会导致非常普通的外观,实际上并不能很好地理解原始输入图像。