[英]Vectorizing python code to numpy
I have the following code snippet (for Hough circle transform): 我有以下代码片段(用于霍夫圆变换):
for r in range(1, 11):
for t in range(0, 360):
trad = np.deg2rad(t)
b = x - r * np.cos(trad)
a = y - r * np.sin(trad)
b = np.floor(b).astype('int')
a = np.floor(a).astype('int')
A[a, b, r-1] += 1
Where A
is a 3D array of shape (height, width, 10)
, and height
and width
represent the size of a given image. 其中
A
是形状(height, width, 10)
的3D数组, height
和width
表示给定图像的大小。 My goal is to convert the snippet exclusively to numpy code. 我的目标是将代码段专门转换为numpy代码。
My attempt is this: 我的尝试是这样的:
arr_r = np.arange(1, 11)
arr_t = np.deg2rad(np.arange(0, 360))
arr_cos_t = np.cos(arr_t)
arr_sin_t = np.sin(arr_t)
arr_rcos = arr_r[..., np.newaxis] * arr_cos_t[np.newaxis, ...]
arr_rsin = arr_r[..., np.newaxis] * arr_sin_t[np.newaxis, ...]
arr_a = (y - arr_rsin).flatten().astype('int')
arr_b = (x - arr_rcos).flatten().astype('int')
Where x
and y
are two scalar values. 其中
x
和y
是两个标量值。
I am having trouble at converting the increment part: A[a,b,r] += 1
. 我在转换增量部分时遇到麻烦:
A[a,b,r] += 1
。 I thought of this: A[a,b,r]
counts the number of occurrences of the pair (a,b,r)
, so a clue was to use a Cartesian product (but the arrays are too large). 我想到了这一点:
A[a,b,r]
计算该对(a,b,r)
的出现次数,因此线索是使用笛卡尔积(但是数组太大)。
Any tips or tricks I can use? 我可以使用任何提示或技巧吗?
Thank you very much! 非常感谢你!
Edit: after filling A
, I need (a,b,r)
as argmax(A)
. 编辑:填充
A
,我需要(a,b,r)
作为argmax(A)
。 The tuple (a,b,r)
identifies a circle and its value in A
represents the confidence value. 元组
(a,b,r)
标识一个圆,其在A
的值表示置信度值。 So I want that tuple with the highest value in A
. 所以我想要
A
具有最高值的元组。 This is part of the voting algorithm from Hough circle transform: find circle parameter with unknown radius . 这是霍夫圆变换投票算法的一部分: 查找半径未知的圆参数 。
Method #1 方法1
Here's one way leveraging broadcasting
to get the counts and update A
(this assumes the a
and b
values computed in the intermediate steps are positive ones) - 这是利用
broadcasting
获取计数并更新A
(这假设在中间步骤中计算出的a
和b
值为正数)-
d0,d1,d2 = A.shape
arr_r = np.arange(1, 11)
arr_t = np.deg2rad(np.arange(0, 360))
arr_b = np.floor(x - arr_r[:,None] * np.cos(arr_t)).astype('int')
arr_a = np.floor(y - arr_r[:,None] * np.sin(arr_t)).astype('int')
idx = (arr_a*d1*d2) + (arr_b * d2) + (arr_r-1)[:,None]
A.flat[:idx.max()+1] += np.bincount(idx.ravel())
# OR A.flat += np.bincount(idx.ravel(), minlength=A.size)
Method #2 方法#2
Alternatively, we could avoid bincount
to replace the last step in approach #1
, like so - 另外,我们可以避免
bincount
代替approach #1
的最后一步,就像这样-
idx.ravel().sort()
idx.shape = (-1)
grp_idx = np.flatnonzero(np.concatenate(([True], idx[1:]!=idx[:-1],[True])))
A.flat[idx[grp_idx[:-1]]] += np.diff(grp_idx)
Improvement with numexpr
numexpr
改进
We could also leverage numexpr
module for faster sine, cosine computations, like so - 我们还可以利用
numexpr
模块更快地进行正弦,余弦计算,如下所示-
import numexpr as ne
arr_r2D = arr_r[:,None]
arr_b = ne.evaluate('floor(x - arr_r2D * cos(arr_t))').astype(int)
arr_a = ne.evaluate('floor(y - arr_r2D * sin(arr_t))').astype(int)
np.add(np.array([arr_a,arr_b,10]),1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.