【发布时间】:2015-05-05 21:49:21
【问题描述】:
对于我的一个图像处理项目,我需要使用关键点。为了计算它们,我发现 OpenCV 使用起来非常快速和方便。但是,当使用例如 FAST 算法计算图像的关键点时,我们会收到一个 KeyPoint objects 数组。
当我得到这些关键点时,我只想获取它们的坐标,而不是附加信息(角度等)。这些坐标将用于使用 numpy 进行多次计算。问题是从 KeyPoint 数组到 numpy 数组的转换时间。它大约需要总执行时间的 60%。有什么建议可以改善下面的循环吗?
import cv2
import numpy as np
image_cv2 = cv2.imread("sample.jpg")
fast = cv2.FastFeatureDetector(threshold=25)
keypoints = fast.detect(image_cv2)
n = len(keypoints)
cd_x = np.zeros(n, dtype=np.int)
cd_y = np.zeros(n, dtype=np.int)
for i in xrange(0, n):
cd_x[i] = keypoints[i].pt[0]
cd_y[i] = keypoints[i].pt[1]
PS:我尝试使用 np.vectorize 但没有发现任何改进。作为信息,按图像的关键点数量通常在 5 000 左右。
更新: 正如一些人指出的那样,从关键点到 numpy 数组的简单分配应该非常快。经过一些测试,确实非常快。比如一个275张图片的数据集,1个线程,完整的执行时间是22.9s,keypoints->numpy的执行时间只有0.2s,而cv2.imread()用了20s左右。
我的错误是同时使用了太多线程,因为每个内核至少没有使用 80%,我不断增加它们的数量直到这个任意限制,这减慢了循环执行。谢谢大家让我看到代码中其他地方的愚蠢错误!
【问题讨论】:
-
keypoints是对象列表,还是带有dtype=object的numpy数组?vectorize是什么意思?使用np.vectorize函数,还是别的什么? -
有时理解更快:
cd_x=np.array([k.pt[0] for k in keypoints]) -
@hpaulj keypoints 是对象列表,而不是 numpy 数组。我已经更新了标题和正文,我在谈论 np.vectorize 因为我不知道如何在 python 中真正矢量化。
-
当你说它需要 60% 的执行时间时,我们说的是秒还是分钟?从 5000 个对象中取出 2 个整数并将它们粘贴到 numpy 数组中肯定不会花费太长时间,并且会随着更多对象线性缩放。
-
np.vectorize只是在你的函数周围包裹了一个循环。这是一个方便的工具,而不是加速代码的方法。
标签: python opencv image-processing numpy