【发布时间】:2022-01-19 02:40:12
【问题描述】:
我已经编译了最新的可用 OpenCV 4.5.4 版本,以与最新的 CUDA 11.5 一起使用,并在配备 GeForce RTX 2070 Super 显卡(7.5 拱门)的 Windows 10 机器上运行启用了快速数学。我正在使用 Python 3.8.5。
运行时结果:
- CPU 性能优于 GPU(匹配 300x300 源图像中的 70x70 针图像)
- 最大的 GPU 瓶颈是需要在模板匹配之前将文件上传到 GPU
- CPU 大约需要 0.005 秒,而 GPU 大约需要 0.42 秒
- 这两种方法最终都找到了 100% 匹配
使用的图片:
使用 CPU 的 Python 代码:
import cv2
import time
start_time = time.time()
src = cv2.imread("cat.png", cv2.IMREAD_GRAYSCALE)
needle = cv2.imread("needle.png", 0)
result = cv2.matchTemplate(src, needle, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
print("CPU --- %s seconds ---" % (time.time() - start_time))
使用 GPU 的 Python 代码:
import cv2
import time
start_time = time.time()
src = cv2.imread("cat.png", cv2.IMREAD_GRAYSCALE)
needle = cv2.imread("needle.png", 0)
gsrc = cv2.cuda_GpuMat()
gtmpl = cv2.cuda_GpuMat()
gresult = cv2.cuda_GpuMat()
upload_time = time.time()
gsrc.upload(src)
gtmpl.upload(needle)
print("GPU Upload time --- %s seconds ---" % (time.time() - upload_time))
match_time = time.time()
matcher = cv2.cuda.createTemplateMatching(cv2.CV_8UC1, cv2.TM_CCOEFF_NORMED)
gresult = matcher.match(gsrc, gtmpl)
print("GPU Match time --- %s seconds ---" % (time.time() - match_time))
result_time = time.time()
resultg = gresult.download()
min_valg, max_valg, min_locg, max_locg = cv2.minMaxLoc(resultg)
print("GPU Result time --- %s seconds ---" % (time.time() - result_time))
print("GPU --- %s seconds ---" % (time.time() - start_time))
即使我不考虑将文件上传到 GPU 所花费的时间,仅匹配时间就需要 CPU 上整个过程的 10 倍以上。我的 CUDA 安装正确,我已经运行了其他测试,其中 GPU 的性能远远优于 CPU,但到目前为止,模板匹配的结果确实令人失望。
为什么 GPU 性能这么差?
【问题讨论】:
-
CPU 和 GPU 可能使用不同的模板匹配方法。我知道 CPU 使用 DFT 和其他优化,并且对 CPU 的速度进行了非常优化。我不知道GPU使用什么方法。
-
GPU 有延迟。这是 GPU 编程中众所周知的事实。
-
从时间测量中排除匹配器的初始化,如果可能的话,在没有时间测量的情况下运行一次匹配,然后使用 tine measurent 确保没有更多的即时编译活动(这可能发生第一次通话)。如果可能:测量大量运行的总时间。
-
谢谢@Micka 我已经这样做了。我只循环匹配线超过 100 次,没有进一步初始化并取平均值,CPU 最终还是快了 10 倍。
-
您提供的代码混合了
cv2.cuda.createTemplateMatching和matcher.match。将时间移出 个。 -- OpenCV 代码可能并不完美。即使在单个“匹配”调用中,它也可能会进行复制等等。
标签: python opencv gpu template-matching