使用PyOpenCL在OpenCL中快速2d直方图

时间:2016-03-04 01:43:13

标签: python performance opencv numpy opencl

我试图在HSV图像上用Python做二维直方图,但即使使用numpy和opencv它也不够快(我实际上是用视频做的,但是考虑每个框架只是一个图像)。

我正在寻找最饱和的Hue值。目前我有以下代码,它可以正常工作,但速度太慢了。

hist, xbins, ybins = np.histogram2d(hsv_channels[0].ravel(), saturation_channel.ravel(), [180,256],[[0,180],[0,256]])

我希望希望使用PyOpenCL来实现这一点,并将计算推送到GPU,但除了OpenCL中的hello world程序之外。我发现了一些关于这样做的文章,但我不确定从哪里开始。

我将如何开始这个?

编辑:

我已经考虑过这个了。我认为我想要做的GPU步骤大致如下:

  1. 将图像转换为1d阵列(如果是10x10,则转为100长阵列)
  2. 将图片上传到GPU
  3. 将图像分割成n个切片以进行处理,其中n是并行计算单元的数量。或者每个都可以引用此阵列上的特定范围。
  4. (地图)对于每个计算单元,分配180''每个可以包含256个其他箱。每个最里面的内容只是一个用于计数的整数。
  5. 对于每个色调(180个分档中的一个),计算每个饱和度级别(其他256个分档)的色调数量。对可以计数的数组的子部分执行此操作。
  6. 创建一组新的空箱。
  7. (Reduce)对于所有这些bin计数,然后将它们合并在一起(添加值)。我不确定是否需要等到它们全部完成,或者只是按顺序将它们与上面的空箱合并。
  8. (确定最终答案)对于最后一组箱,循环遍历它们并找到该色调的最大饱和度值,并存储它。现在找到具有最大饱和度的色调。作为最终答案,返回此色调#和此最大饱和度#。
  9. 尽管如此,我还是对PyOpenCL(或整个OpenCL)的GPU知识不够了解,无法正确完成这项工作。

1 个答案:

答案 0 :(得分:6)

如果采用不同的方法,可以将计算时间减少到histogram2d所用时间的2%左右。在3143x2095图像上,此方法花费约5毫秒,而histogram2d浪费约280毫秒。

import cv2
import numpy as np
from numpy import unravel_index
import time

img = cv2.imread('ducks.jpg')

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

print hsv.shape
hue = hsv[:, :, 0]
sat = hsv[:, :, 1]

start = time.time()
max_index = unravel_index(sat.argmax(), sat.shape)
end = time.time()
print 'argmax time:', end - start
print sat[max_index]
print hue[max_index]

start = time.time()
hist, xbins, ybins = np.histogram2d(hue.ravel(), sat.ravel(), [180, 256], [[0, 180], [0, 256]])
end = time.time()
print 'histogram2d time:', end - start

输出:

(2095, 3143, 3)
argmax time: 0.00526285171509
255
39
histogram2d time: 0.288522958755

很容易处理具有多个饱和度值的像素的情况。