Оптимизация функции numpy
Ниже приведена реализация функции по заполнению аккумуляторного массива (пространства Хафа). Возможно ли её подвергнуть ещё большей оптимизации? Больше всего времени эта функция проводит вот в этой строчке:
accum += index * np.apply_along_axis(np.bincount, axis=0, arr=ro_calc, minlength=accum.shape[0])
Необходим оптимальный по времени переход от текущего шага:
>>>ro_calc = (point @ sin_cos + img_diagonal).astype(np.int32)
>>>ro_calc
array([[4, 4, 4, 4, 4, 4, 4, 4, 4, 5],
[4, 4, 4, 4, 4, 4, 4, 5, 5, 5],
[3, 3, 3, 3, 3, 3, 3, 3, 3, 4],
[3, 3, 3, 3, 3, 3, 4, 4, 4, 4],
[2, 2, 2, 2, 2, 2, 3, 3, 3, 3]])
к
>>>accum += index * np.apply_along_axis(np.bincount, axis=0, arr=ro_calc, minlength=accum.shape[0])
>>>accum
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1., 1., 0., 0., 0., 0.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 1.],
[2., 2., 2., 2., 2., 2., 3., 2., 2., 2.],
[0., 0., 0., 0., 0., 0., 0., 1., 1., 2.]])
Ниже представлена полная реализация текущей функции.
def hough_transform(processed_image, mark, accum, sin_cos, img_diagonal, index=1) -> None:
"""
:param processed_image: входное маркированное изображение (каждой области соответствует целое число)
:param mark: метка, соответствующая исследуемой области
:param accum: аккумуляторный массив Хафа, пространство Хафа
:param sin_cos: вычисленные значения sin и cos
:param img_diagonal: длина диагонали прямоугольника, ограничивающего исследуемую область
:param index: 1 - для увеличения значения в аккумуляторном массиве, -1 - для уменьшения
:return: None, изменение массива происходит на месте
>>>point = np.array([[1, 2],[1, 3],[2, 2],[2, 3],[3, 3]])
>>>sin_cos = [[-1.0, -0.9986, -0.9945, -0.9877, -0.9781, -0.9659, -0.9511, -0.9336, -0.9135, -0.891],
... [0.0, 0.0523, 0.1045, 0.1564, 0.2079, 0.2588, 0.309, 0.3584, 0.4067, 0.454]]
>>>img_diagonal = 5
>>>ro_calc = (point @ sin_cos + img_diagonal).astype(np.int32)
>>>ro_calc
array([[4, 4, 4, 4, 4, 4, 4, 4, 4, 5],
[4, 4, 4, 4, 4, 4, 4, 5, 5, 5],
[3, 3, 3, 3, 3, 3, 3, 3, 3, 4],
[3, 3, 3, 3, 3, 3, 4, 4, 4, 4],
[2, 2, 2, 2, 2, 2, 3, 3, 3, 3]])
>>>accum = np.zeros((6, 10))
>>>accum += index * np.apply_along_axis(np.bincount, axis=0, arr=ro_calc, minlength=accum.shape[0])
>>>accum
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1., 1., 0., 0., 0., 0.],
[2., 2., 2., 2., 2., 2., 2., 2., 2., 1.],
[2., 2., 2., 2., 2., 2., 3., 2., 2., 2.],
[0., 0., 0., 0., 0., 0., 0., 1., 1., 2.]])
"""
points = np.argwhere(processed_image == mark)
ro_calc = (points @ sin_cos + img_diagonal).astype(np.int32)
accum += index * np.apply_along_axis(np.bincount, axis=0, arr=ro_calc, minlength=accum.shape[0])