根据图像 numpy 数组中饱和度和值的色调值计算颜色可见性
Calculate color visibility from hue values respecting saturation and value in image numpy array
为了一个有趣的项目,我想分析一些图像,尤其是哪些颜色(色调)比其他颜色更明显。由于我想考虑颜色的 "visibility",仅计算像素的色调是不够的(例如,完美的黑色会被视为红色,因为它的色调为 0°)。我想出了一个 IMO 对我的项目来说足够好的公式。
目前我在做以下事情:
- 用opencv读取图片(结果为BGR numpy数组)
- 将图像翻译成 HSV
- 对于每个像素,计算其色调的可见性(根据饱和度和值)并将其求和到色调字典中。
公式为color_visibility = sqrt(saturation * value)
。所以全红 RGB=255,0,0; HSV=0,1,1
会导致 1
而例如浅红色 RGB=255,128,128; HSV=0,0.5,1
会导致 0.70
.
这是我使用的(完整工作)代码:
import urllib
import cv2
import numpy as np
url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Leuchtturm_in_Westerheversand_crop.jpg/299px-Leuchtturm_in_Westerheversand_crop.jpg'
image = np.asarray(bytearray(urllib.urlopen(url).read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
d = {}
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
pixels = hsv.reshape((hsv.shape[0] * hsv.shape[1], 3))
for h,s,v in pixels:
d[h] = d.get(h, 0.) + (s/255. * v/255.) ** 0.5
您可能猜到了,当图像具有更多像素时,代码会变得非常慢。
我的问题是,如果没有 dict 和 for 循环,我该如何计算我的公式?也许直接用 numpy?
您正在寻找的魔法在 np.bincount
中,因为它使用 h
值作为 bins -
非常直接地转换为循环版本
H,S,V = pixels.T
d_arr = np.bincount(H, ((S/255.0) * (V/255.0))**0.5 )
请注意,结果数组的元素计数可能为零
为了一个有趣的项目,我想分析一些图像,尤其是哪些颜色(色调)比其他颜色更明显。由于我想考虑颜色的 "visibility",仅计算像素的色调是不够的(例如,完美的黑色会被视为红色,因为它的色调为 0°)。我想出了一个 IMO 对我的项目来说足够好的公式。
目前我在做以下事情:
- 用opencv读取图片(结果为BGR numpy数组)
- 将图像翻译成 HSV
- 对于每个像素,计算其色调的可见性(根据饱和度和值)并将其求和到色调字典中。
公式为color_visibility = sqrt(saturation * value)
。所以全红 RGB=255,0,0; HSV=0,1,1
会导致 1
而例如浅红色 RGB=255,128,128; HSV=0,0.5,1
会导致 0.70
.
这是我使用的(完整工作)代码:
import urllib
import cv2
import numpy as np
url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Leuchtturm_in_Westerheversand_crop.jpg/299px-Leuchtturm_in_Westerheversand_crop.jpg'
image = np.asarray(bytearray(urllib.urlopen(url).read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
d = {}
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
pixels = hsv.reshape((hsv.shape[0] * hsv.shape[1], 3))
for h,s,v in pixels:
d[h] = d.get(h, 0.) + (s/255. * v/255.) ** 0.5
您可能猜到了,当图像具有更多像素时,代码会变得非常慢。
我的问题是,如果没有 dict 和 for 循环,我该如何计算我的公式?也许直接用 numpy?
您正在寻找的魔法在 np.bincount
中,因为它使用 h
值作为 bins -
H,S,V = pixels.T
d_arr = np.bincount(H, ((S/255.0) * (V/255.0))**0.5 )
请注意,结果数组的元素计数可能为零