Fastest way to apply color matrix to RGB image using OpenCV 3.0?

后端 未结 2 845
栀梦
栀梦 2020-12-18 06:43

I have a color image represented as an OpenCV Mat object (C++, image type CV_32FC3). I have a color correction matrix that I want to apply to each pixel of the RGB color im

相关标签:
2条回答
  • 2020-12-18 07:23

    Here's the code that worked using cv::reshape. It was fast enough for my application:

    #define WIDTH 2048
    #define HEIGHT 2048
    ...
    
    Mat orig_img = Mat(HEIGHT, WIDTH, CV_32FC3);
    //put some data in orig_img somehow ...
    
    /*The color matrix
    Red:RGB; Green:RGB; Blue:RGB
    1.8786   -0.8786    0.0061
    -0.2277    1.5779   -0.3313
    0.0393   -0.6964    1.6321
    */
    
    float m[3][3] = {{1.6321, -0.6964, 0.0393},
                    {-0.3313, 1.5779, -0.2277}, 
                    {0.0061, -0.8786, 1.8786 }};
    Mat M = Mat(3, 3, CV_32FC1, m).t();
    
    Mat orig_img_linear = orig_img.reshape(1, HEIGHT*WIDTH);
    Mat color_matrixed_linear = orig_img_linear*M;
    Mat final_color_matrixed = color_matrixed_linear.reshape(3, HEIGHT);
    

    A few things to note from the above: The color matrix in the comment block is the one I would ordinarily apply to an RGB image. In defining the float array m, I switched rows 1 and 3, and columns 1 and 3 for OpenCV's BGR ordering. The color matrix also must be transposed. Usually a color matrix is applied as M* v = v_new, where M is 3x3 and v is 3x1 but here we are doing vT *MT = v_newT to avoid having to transpose each 3-channel pixel.

    0 讨论(0)
  • 2020-12-18 07:31

    Basically the linked answer uses reshape to convert your CV_32FC3 mat of size m x n to a CV_32F mat of size (mn) x 3. After that, each row of the matrix contains exactly color channels of one pixel. You can then apply usual matrix multiplication to obtain a new mat and reshape it back to the original shape with three channels.

    Note: It may be worth noticing that the default color space of opencv is BGR, not RGB.

    0 讨论(0)
提交回复
热议问题