Как применить матрицу к изображению

я сделал несколько поисков, но не нашел точных вопросов – и решения, которые я нашел, не были адаптированы.

У меня есть изображение, представленное массивом numpy формы (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 ..!

Благодаря !

Вы уменьшаете последнюю ось на двух входах Image и P Итак, вы можете использовать np.tensordot , как и так –

 np.tensordot(Image,P,axes=(-1,-1)) 

Это также может быть выражено как np.dot с некоторой перестройкой до и после него, например,

 Image.reshape(-1,3).dot(PT).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(PT).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(PT).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