Как применить матрицу к изображению
Я провел некоторый поиск, но не нашел те же самые вопросы - и решения, которые я нашел, не были адаптированы.
У меня есть изображение, представленное массивом фигуры (l1,l2,3)
где l1,l2 - целые числа и три, потому что RGB.
И по причинам, я хочу изменить базис, это означает применение матрицы P ко всем векторам RGB. Обратите внимание, что P
имеет форму (3,3)
,
Я написал это:
def change_base(Image,P):
Image_copie=np.zeros(Image.shape)
for i in range(Image_copie.shape[0]):
for j in range(Image_copie.shape[1]):
Image_copie[i,j]=np.dot(P,Image[i,j])
return Image_copie
Это работает, очевидно, но это ужасно и очень медленно.
Ребята, у вас есть какое-нибудь решение, возможно, с использованием numPy Я не использую opencv ..!
Спасибо!
1 ответ
Вы уменьшаете последнюю ось на двух входах Image
а также P
, Итак, вы можете использовать np.tensordot
, вот так -
np.tensordot(Image,P,axes=(-1,-1))
Это также может быть выражено как np.dot
с некоторым изменением формы до и после него, вот так -
Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
Можно также использовать np.einsum
для такой операции сокращения, например, так
np.einsum('ijk,lk->ijl',Image,P)
Для производительности, являющейся исключительно операцией сокращения, без требования выравнивания осей, dot-based
решения будут быстрее для больших массивов, но для небольших и приличных массивов, einsum
может быть лучше.
Испытание во время выполнения
Случай 1:
In [46]: # Inputs
...: Image = np.random.randint(0,255,(256,256,3))
...: P = np.random.randint(0,255,(3,3))
...:
In [47]: %timeit change_base(Image,P)
...: %timeit np.tensordot(Image,P,axes=(-1,-1))
...: %timeit Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
...: %timeit np.einsum('ijk,lk->ijl',Image,P)
...:
1 loops, best of 3: 206 ms per loop
100 loops, best of 3: 3.28 ms per loop
100 loops, best of 3: 3.22 ms per loop
100 loops, best of 3: 3.06 ms per loop
Дело № 2:
In [48]: # Inputs
...: Image = np.random.randint(0,255,(512,512,3))
...: P = np.random.randint(0,255,(3,3))
...:
In [49]: %timeit change_base(Image,P)
...: %timeit np.tensordot(Image,P,axes=(-1,-1))
...: %timeit Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
...: %timeit np.einsum('ijk,lk->ijl',Image,P)
...:
1 loops, best of 3: 845 ms per loop
100 loops, best of 3: 12.8 ms per loop
100 loops, best of 3: 12.7 ms per loop
100 loops, best of 3: 13.4 ms per loop