对于我的图像处理项目之一,我需要使用关键点。为了计算它们,我发现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,但我没有注意到任何改进。有关信息,图像的关键点数通常约为5000。
更新 正如一些人所指出的那样,从关键点到numpy数组的简单分配应该非常快。经过一些测试,它确实非常快。例如,对于具有1个线程的275个图像的数据集,完整的执行时间为22.9s,关键点仅为0.2s-&n;执行numpy,cv2.imread()花费大约20s。
我的错误是同时使用太多线程,因为每个核心至少没有使用80%我一直在增加它们的数量,直到这个任意限制,这减慢了循环执行速度。谢谢大家让我睁开眼睛看看代码中其他地方的一个愚蠢的错误!
答案 0 :(得分:0)
试用案例:
In [765]: class Keypoints(object):
def __init__(self):
self.pt=[1.,2.]
.....:
In [766]: keypoints=[Keypoints() for i in xrange(1000)]
In [767]: cd=np.array([k.pt for k in keypoints])
In [768]: cd
Out[768]:
array([[ 1., 2.],
[ 1., 2.],
[ 1., 2.],
...,
[ 1., 2.],
[ 1., 2.],
[ 1., 2.]])
In [769]: cd_x=cd[:,0]
在timeit测试中,keypoints
步骤与cd
计算一样长,1ms。
但是2个更简单的迭代
cd_x=np.array([k.pt[0] for k in keypoints])
cd_y=np.array([k.pt[1] for k in keypoints])
需要一半的时间。我期待单次迭代可以节省时间。但在这些简单的情况下,理解本身只占用了一半的时间,剩下的就是创建数组。
In [789]: timeit [k.pt[0] for k in keypoints]
10000 loops, best of 3: 136 us per loop
In [790]: timeit np.array([k.pt[0] for k in keypoints])
1000 loops, best of 3: 282 us per loop