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

Python 根据饱和度和图像numpy数组中的值的色调值计算颜色可见性,python,opencv,numpy,hsv,Python,Opencv,Numpy,Hsv,对于一个有趣的项目,我想分析一些图像,特别是哪些颜色(色调)比其他颜色更明显。由于我想考虑到颜色的“可见性”,仅计算像素的色调是不够的(例如,完美黑色的色调为0°时会计算为红色)。我想出了一个公式,对我的项目来说已经足够好了 目前我做了以下工作: 使用opencv读取图像(结果在BGR numpy数组中) 将图像转换为HSV 对于每个像素,计算其色调的可见性(根据饱和度和值),并将其相加为一个色调的dict 公式是color\u visibility=sqrt(饱和度*值)。因此,一个完整的

对于一个有趣的项目,我想分析一些图像,特别是哪些颜色(色调)比其他颜色更明显。由于我想考虑到颜色的“可见性”,仅计算像素的色调是不够的(例如,完美黑色的色调为0°时会计算为红色)。我想出了一个公式,对我的项目来说已经足够好了

目前我做了以下工作:

  • 使用opencv读取图像(结果在BGR numpy数组中)
  • 将图像转换为HSV
  • 对于每个像素,计算其色调的可见性(根据饱和度和值),并将其相加为一个色调的dict
公式是
color\u visibility=sqrt(饱和度*值)
。因此,一个完整的红色
RGB=255,0,0;HSV=0,1,1
将导致
1
,而例如,淡红色
RGB=255128128;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?

您正在寻找的魔法就在其中,因为它使用
h
值作为存储箱直接转换为循环版本-

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

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

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