Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LUT for different channels in C++, opencv2

I've been playing around with opencv2 implemented in C++ for a couple of days and noticed that the lookup tables are the fastest way to apply changes to an image. However, I've been having some troubles with using them for my purposes.

The code below shows an example of inverting pixels' values:

bool apply(Image& img) {
   int dim(256);
   Mat lut(1, &dim, CV_8U);
   for (int i=0; i<256; i++)
      lut.at<uchar>(i)= 255-i;
   LUT(img.final,lut,img.final);
   return true;
}

class Image {
public:
   const Mat& original;
   Mat final;
...
};

As it's very efficient, much more efficient than changing each pixel by one (verified by my own tests), I'd like to use this method for other operations. However to do this, I have to access each layer (each color, the picture is in BGR) separately. So for example, I'd like to change blue to 255-i, green to 255-i/2 and red to 255-i/3.

I've been searching the net for a while, but couldn't come up with a correct solution. As far as I know, it's possible (documentation) but I can't find a way to implement it.

like image 729
Michal B Avatar asked Jul 16 '12 11:07

Michal B


1 Answers

The key is this paragraph in the docs:

the table should either have a single channel (in this case the same table is used for all channels) or the same number of channels as in the source array

So, you must create a multichannel LUT:

bool apply(Image& img) {
   int dim(256);

   Mat lut(1, &dim, CV_8UC(img.final.channels()));

   if( img.final.channels() == 1)
   {
      for (int i=0; i<256; i++)
         lut.at<uchar>(i)= 255-i;
   }
   else // stupid idea that all the images are either mono either multichannel
   {
      for (int i=0; i<256; i++)
      {
         lut.at<Vec3b>(i)[0]= 255-i;   // first channel  (B)
         lut.at<Vec3b>(i)[1]= 255-i/2; // second channel (G)
         lut.at<Vec3b>(i)[2]= 255-i/3; // ...            (R)
      }
   }

   LUT(img.final,lut,img.final); // are you sure you are doing final->final? 
   // if yes, correct the LUT allocation part

   return true;
}
like image 103
Sam Avatar answered Oct 10 '22 06:10

Sam