Reputation: 429
I have an image and a color correction matrix (ccm).
import numpy as np
import cv2
img = cv2.imread('1.jpg') # shape = (512, 512, 3)
ccm = np.array([1.0234, -0.2969, -0.2266,
-0.5625, 1.6328, -0.0469,
-0.0703, 0.2188, 0.6406])
I write a function
def color_correction(img, ccm):
'''
Input:
img: H*W*3 numpy array, input image
ccm: 3*3 numpy array, color correction matrix
Output:
output: H*W*3 numpy array, output image after color correction
'''
output = np.matmul(ccm, img)
return output
i get a error as following:
ValueError: shapes (3,3) and (512,512,3) not aligned: 3 (dim 1) != 512 (dim 1)
How can I perform matrix multiplication using numpy? --> to get H*W*3 numpy array, output image after color correction
Upvotes: 0
Views: 4611
Reputation: 1475
In my opinion it's easy to use tensor product:
output = np.tensordot(img, cc.T, axes=1)
Another solution is to use einsum
:
output = np.einsum("ijk, mk -> ijm", img, cc)
Upvotes: 1
Reputation: 16796
This is a problem faced due to misinterpretation of how the matrices are stored by numpy
and also how the Color Correction process is supposed to work.
The color correction process works by performing matrix multiplication of a single RGB tuple with a color correction matrix (CCM). So basically its a matrix multiplication of 2 matrices of dimensions (1, 3)
and (3, 3)
. It works as follows:
RGB * CCM = RGB_Corrected
(1, 3) * ( 3, 3 ) = ( 1, 3 )
This process is applied individually on each RGB pixel.
Now that the color correction process is defined, we need to correctly define our variables i.e. validate their dimensions.
The CCM should be a (3 , 3)
numpy array, but currently it is defined as a (1 , 9)
array. It should be defined as follows to make it 2 dimensional (notice the additional square brackets):
ccm = np.array([ [ 1.0234, -0.2969, -0.2266],
[-0.5625, 1.6328, -0.0469],
[-0.0703, 0.2188, 0.6406] ])
Secondly, matrix multiplication should be performed among matrices of compatible dimensions. To achieve this, the image must be reshaped so that instead of a 3D matrix of dimensions (height, width, channels)
, it is a 2D matrix with dimensions ( width x height, channels )
. In your case, its shape should be ( 512 x 512, 3 )
.
It can be achieved using the numpy.ndarray.reshape
function as follows:
img2 = img.reshape((img.shape[0] * img.shape[1], 3))
This will allow us to perform multiplication of matrices with the following dimensions.
( 262144, 3 ) * (3, 3) = ( 262144, 3 )
output = np.matmul(img2, ccm)
Next, we will reshape the image back to the original dimensions and return the result.
reshaped_back = output.reshape(img.shape).astype(img.dtype)
The final color correction function may look like this:
def color_correction(img, ccm):
'''
Input:
img: H*W*3 numpy array, input image
ccm: 3*3 numpy array, color correction matrix
Output:
output: H*W*3 numpy array, output image after color correction
'''
img2 = img.reshape((img.shape[0] * img.shape[1], 3))
output = np.matmul(img2, ccm)
return output.reshape(img.shape).astype(img.dtype)
Upvotes: 3