0

I would like to implement some white balance algorithms from wiki http://en.wikipedia.org/wiki/Color_balance

They are just some simple matrix manipulation Do openCV offer any functions to do some multiplication on a group of pixels like following?

example, 2 x 2, 3 channels Mat A =

0 0 0 1 1 1
2 2 2 3 3 3

3 x 3, 1 channels Mat B =

1 0 0
0 2 0
0 0 3

A x B = C and C =

0 0 0 1 2 3
2 4 6 3 6 9

I have wrote some generic functions to deal with pixel transformation but I would prefer the build in function of openCV if it exist since the functions of openCV may do some optimization

template<typename T, typename UnaryFunctor>
void transform_channel(cv::Mat &src, int channel, UnaryFunctor functor)
{
    int const channels = src.channels();
    if(channels == 1 && src.isContinuous()){
        return transform_continuous_channel<T>(src, functor);
    }

    for(int row = 0; row != src.rows; ++row)
    {
        auto dst_ptr = get_pointer<T>(src, row, channel);
        for(int col = 0; col != src.cols; ++col){
            *dst_ptr = functor(*dst_ptr);
            dst_ptr += channels;
        }
    }
}
StereoMatching
  • 4,971
  • 6
  • 38
  • 70

2 Answers2

1

Matrix multiplication is implementend in OpenCV with the * operator. If you want to make it work though, you should reshape your RGB images into 1-channel matrices using cv::Mat::reshape() (documentation here).

Hint: cv::Mat::reshape() returns a reference to the new matrix without copying the data (unnecessary and slow). Hence, it is usually a good idea to use it like this:

cv::Mat someMatrix;
someMatrix = someMatrix.reshape(1);

Or this way (using another matrix variable):

cv::Mat rgbMatrix, myMatrix;
myMatrix = rgbMatrix.reshape(1);

Again, I emphasize that this does not copy the data, so you are not losing any memory.

sansuiso
  • 9,259
  • 1
  • 40
  • 58
  • * need to satisfy the condition of mxn * nxl, the col of the first matrix and the row of the second matrix must have the same dimension,but I would like to do element wise multiplication like .mul() did.Any, thanks – StereoMatching Apr 13 '13 at 02:52
  • Element-wise multiplication is done via cv::multiply(mat1,mat2). – sansuiso Apr 13 '13 at 09:02
1

You will notice that color-balance operations consist only of diagonal matrices, which corresponds to an element-wise multiplication by a scalar. Thus, the transform in your example would be:

image = image.mul(cv::Scalar(1,2,3));

for a 3-channel image. I do not know of a function to apply arbitrary pixel-wise matrix transformations.

Aurelius
  • 11,111
  • 3
  • 52
  • 69
  • Thanks, this work, but it would be better if it alter the image itself directly rather than create a temporary object – StereoMatching Apr 13 '13 at 02:50
  • Is your concern about memory footprint or extra copies? The "temporary object" is a `MatExpr`, which ensures no data is copied. – Aurelius Apr 15 '13 at 15:18