Python中利用NumPy ufunc加速HSV颜色空间量化与直方图提取
本文介绍在Python中如何对HSV颜色空间进行量化操作以提取颜色特征。通过对比双重for循环与NumPy的ufunc函数,展示了利用自定义ufunc加速颜色量化的方法。文章包含将RGB转换为HSV、基于人眼感知特性进行分量量化、合成72维矢量及绘制直方图的完整代码示例,并提供了性能优化前后的时间对比数据。
HSV颜色空间量化与特征提取
在图像处理中,提取颜色特征是常见需求。由于HSV颜色空间更符合人眼对颜色的感知方式,通常先将图像从RGB模型转换为HSV模型。为了降低矢量维度并有效提取颜色特征,需要对HSV空间进行量化处理。
量化策略基于人眼感知特性,对H、S、V三个分量分别设定阈值进行分段。最终,各颜色分量按特定公式合成为一个72维的一维矢量。这种量化方法不仅减少了数据维度,还保留了关键的颜色分布信息。


性能优化:从循环到ufunc
在处理图像时,直接使用双重for循环遍历像素点效率较低。例如,处理一张692*1024*3大小的测试图片,优化前的运行时间约为6.9秒。若处理388*500像素的照片,耗时约1.45秒。
为了提升性能,可以利用NumPy的ufunc(通用函数)机制。通过自定义ufunc函数替换双重for循环,可以避免Python层面的循环开销。优化后的代码未使用if-else判断语句进行逐像素处理,而是通过向量化操作实现,至少节省了1/3的运行时间。优化后,处理相同尺寸图片的时间缩短至0.8秒左右。
代码实现与步骤
1. 基础实现(双重循环)
首先,加载图像并转换为HSV格式。接着,定义量化函数 quantilize,该函数接收H、S、V值,根据预设阈值列表返回量化后的索引值。最后,遍历图像像素,应用量化函数并计算直方图。
#-*-coding:utf-8-*-
import cv2
import numpy as np
from datetime import datetime
from matplotlib import pyplot as plt
def colors(imagepath):
img = cv2.imread(imagepath)
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
nhsv = np.zeros(hsv.shape[:2], dtype=np.uint8)
t2 = datetime.now()
for i in range(hsv.shape[0]):
for j in range(hsv.shape[1]):
nhsv[i][j] = quantilize(hsv[i][j])
print datetime.now() - t2
hist = cv2.calcHist([nhsv], [0], None, [72], [0,71]) # 40x faster than np.histogramfaster than np.histogram
plt.plot(hist,color = 'r')
plt.xlim([0, 72])
plt.show()
def quantilize(value):
'''hsv直方图量化
value : [21, 144, 23] h, s, v
opencv中,h-[0,180], s-[0,255], v-[0,255]
'''
#
value[0] = value[0] * 2
hlist = [20, 40, 75, 155, 190, 270, 290, 316, 360]
svlist = [21, 178, 255]
for i in range(len(hlist)):
if value[0] <= hlist[i]:
h = i % 8
break
for i in range(len(svlist)):
if value[1] <= svlist[i]:
s = i
break
for i in range(len(svlist)):
if value[2] <= svlist[i]:
v = i
break
return 9 * h + 3 * s + v
2. 优化实现(NumPy ufunc)
优化方案的核心是将标量函数转换为ufunc。使用 np.frompyfunc 将自定义的 quantilize 函数转化为ufunc,该函数接受3个输入参数并返回1个输出。由于 frompyfunc 返回对象类型,需转换为 np.uint8。随后,直接对HSV图像的H、S、V通道进行向量化计算,并提取直方图。
#-*-coding:utf-8-*-
import cv2
import numpy as np
from datetime import datetime
from matplotlib import pyplot as plt
hlist = [20, 40, 75, 155, 190, 270, 290, 316, 360]
svlist = [21, 178, 255]
def quantilize(h, s, v):
'''hsv直方图量化'''
# value : [21, 144, 23] h, s, v
h = h * 2
for i in range(len(hlist)):
if h <= hlist[i]:
h = i % 8
break
for i in range(len(svlist)):
if s <= svlist[i]:
s = i
break
for i in range(len(svlist)):
if v <= svlist[i]:
v = i
break
return 9 * h + 3 * s + v
quantilize_ufunc = np.frompyfunc(quantilize, 3, 1) # 自定义ufunc函数,即将quantilize函数转化为ufunc函数,其输入参数为3个,输出参数为1个。
def colors(img):
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
nhsv = quantilize_ufunc(hsv[:,:,0], hsv[:,:,1], hsv[:,:,2]).astype(np.uint8) # 由于frompyfunc函数返回结果为对象,所以需要转换类型
hist = cv2.calcHist([nhsv], [0], None, [72], [0,71]) # 40x faster than np.histogram
hist = hist.reshape(1, hist.shape[0]).astype(np.int32).tolist()[0]
return hist
if __name__ == '__main__':
img_path = path + 'test.jpg'
img = cv2.imread(img_path)
colors(img)总结
通过上述步骤,我们实现了HSV颜色空间的量化与特征提取。利用NumPy的ufunc机制,显著提升了处理速度,从6.9秒优化至0.8秒。该方法适用于需要高效处理大量图像颜色特征的场景。
以上就是Python下对hsv颜色空间进行量化操作的详细内容,更多关于Python颜色处理、NumPy优化及图像特征提取的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













