根据图像numpy数组中关于饱和度和值的色调值计算颜色可见性

Posted

技术标签:

【中文标题】根据图像numpy数组中关于饱和度和值的色调值计算颜色可见性【英文标题】:Calculate color visibility from hue values respecting saturation and value in image numpy array 【发布时间】:2017-05-24 22:03:53 【问题描述】:

对于一个有趣的项目,我想分析一些图像,尤其是哪些颜色(色调)比其他颜色更明显。由于我想考虑颜色的“可见性”,仅计算像素的色调是不够的(例如,完美的黑色将算作红色,因为它的色调为 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?

【问题讨论】:

【参考方案1】:

您正在寻找的魔法在np.bincount 中,因为它使用h 值作为垃圾箱非常直接地转换为循环版本-

H,S,V = pixels.T
d_arr = np.bincount(H, ((S/255.0) * (V/255.0))**0.5 )

请注意,结果数组中的元素可能具有零值计数

【讨论】:

谢谢,是的,我是 numpy 的新手,不知道要搜索什么。非常感谢:) @sphere 应该提到bincount 超级快。所以,准备好被吹走:) 确实,与 numpy 一样。即使在阅读了bincount 的文档之后,我也不知道它可以这样使用......

以上是关于根据图像numpy数组中关于饱和度和值的色调值计算颜色可见性的主要内容,如果未能解决你的问题,请参考以下文章

numpy数组元素值的高效查表映射机制

如何使用NumPy字符串格式化程序打印输出字符串依赖于数组值的NumPy数组?

计算机视觉图像预处理

灰度梯度

如何使用 OpenCV Python 检测颜色

如何计算RGB数字图像处理 亮度的亮度值