【问题标题】:Measure image sharpness with opencv using gpu使用gpu使用opencv测量图像清晰度
【发布时间】:2022-01-13 09:46:30
【问题描述】:

我创建了一个小脚本,它使用拉普拉斯算子从一组图像中提取最清晰的图像:

sharpness = cv2.Laplacian(cv2.imread(path), cv2.CV_64F).var()

但是代码有点慢,而且似乎只使用 CPU,然后我想知道是否有一种方法使用 gpu 来计算该值,但只找到示例来锐化图像。

【问题讨论】:

  • 当你说慢 - 有多慢,以及图像属性和图像数量?它是如何扩展的?
  • 一切都是相对的,不是吗?我正在处理几千张 4K 图像,每张图像需要半秒,还不错,我只是想看看是否可以更快。

标签: python opencv gpu gpgpu


【解决方案1】:

在您了解需要时间之前不要进行优化。

大部分时间都花在加载图像上。时间吧,你会看到的。这涉及访问大容量存储和解码图像格式。 PNG 并不是最复杂的,所以它可能会更糟。

拉普拉斯计算使用a specific kernel。用任意 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

【讨论】:

  • 是的,这不是错误的,读取时间接近 0.25 秒,计算时间接近 0.3 秒,但这仍然是一些余量。我将尝试找到如何使用 gpu,不确定您所说的“将 numpy 数组包装在 cv.UMat 中”是什么意思...
  • 当然,确切的数字取决于处理器和具体图片。我碰巧从一个随机文件夹中挑选了几张图片,这些图片的加载时间比处理时间要多。我又试了几次,加载时间比计算要少。 -- 这只是cv.Laplacian(cv.UMat(cv.imread(...)), cv.CV_32F).get().var() 单浮点数是个好主意,因为即使 CPU 对双精度数只有 1:2 的惩罚,许多 GPU 的惩罚也会更差
  • cv.Laplacian(cv.UMat(cv.imread(...)), cv.CV_32F).get().var() 工作并且计算时间现在是 0.08 !我接受了您的 awser,也许您可​​以将您的评论添加到 anwser。谢谢
猜你喜欢
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
相关资源
最近更新 更多