我创建了一个小脚本,使用像Laplacian这样的方法从一组图像中提取最清晰的图像:
sharpness = cv2.Laplacian(cv2.imread(path), cv2.CV_64F).var()
然而,这段代码执行速度有点慢,并且似乎只使用了CPU,所以我想知道是否有一种方法可以使用GPU计算该值,但是我只找到了关于图像处理的示例。
我创建了一个小脚本,使用像Laplacian这样的方法从一组图像中提取最清晰的图像:
sharpness = cv2.Laplacian(cv2.imread(path), cv2.CV_64F).var()
然而,这段代码执行速度有点慢,并且似乎只使用了CPU,所以我想知道是否有一种方法可以使用GPU计算该值,但是我只找到了关于图像处理的示例。
在了解耗时点之前,请勿进行优化。
大多数时间都花在加载图像上。计时一下,你就会发现这牵涉到访问大规模存储和解码图像格式。PNG并不是最复杂的,所以情况可能更糟。
拉普拉斯计算使用特定的内核。将图片与任意3x3内核卷积需要9次乘法和9次加法。而这个内核只需要一次移位和五次加减法。CPU的SIMD轻松应对。
GPU毫无帮助。将数据传输到GPU需要时间。然后启动GPU上的任何计算还有其他固定成本(延迟,“预热”)。而CPU已经完成了计算。如果有很多图片,至少可以将传输进行流水线处理,并且只需要上传内核代码一次。
在整个操作中,GPU和CPU都可能受到内存限制,这意味着计算能力远未受到挑战。
如果您真的想让GPU参与其中,最简单的方法是将numpy数组封装到cv.UMat
中,然后传递UMat对象。然后OpenCV将使用OpenCL。结果将再次是UMat,因此您需要查看OpenCV函数可以为您计算方差。
h_im = cv.imread(...) # hostside data
d_im = cv.UMat(im) # usable on "device"
d_lap = cv.Laplacian(d_im, cv.CV_32F) # single floats are usually faster than doubles
h_lap = d_lap.get() # retrieve data
# numpy functions unavailable on UMat, hence hostside calculation
var = h_lap.var()
# try cv.meanStdDev, calculates for each channel
cv.Laplacian(cv.UMat(cv.imread(...)), cv.CV_32F).get().var()
。单精度浮点数是个好主意,因为即使CPU仅对双精度有1:2的惩罚,许多GPU的惩罚更严重。 - Christoph Rackwitzcv.Laplacian(cv.UMat(cv.imread(...)), cv.CV_32F).get().var()
可以正常工作,计算时间现在为0.08秒!我接受了你的答案,也许你可以在答案中添加你的评论。谢谢。 - Entretoize