Can someone explain me why there is the need of the LUT to have the same number of channels as the input image?
I don't even understand, which elements will be chosen...
For example if I have a BGR input image and a 1D LUT with 256 elements (each element is a cv::Vec3b
).
Now for each pixel i
of the input image: Output(i) = LUT(Input(i))
.
But Input(i)
is a cv::Vec3b
element. So what will Output(i)
be? LUT(Input(i)[0])
??
In my opinion, LUT could have any number of channels, except if there are any algorithmic needs for optimization (I know that LUT is highly optimized).
Initially I wanted to create a Color image from Grayscale image with a single LUT call, but I had to use CV_GRAY2BGR in the beginning...
Here's some sample code:
cv::Mat input = cv::Mat(512,512,CV_8UC1, cv::Scalar(0));
for(int j=0; j<input.rows; ++j)
for(int i=0; i<input.cols; ++i)
{
input.at<unsigned char>(j,i) = i/2;
}
// unfortunately, we have to convert to grayscale, because OpenCV doesnt allow LUT from single channel to 3 channel directly. (LUT must have same number of channels as input)
cv::Mat input_3channels;
cv::cvtColor(input, input_3channels, CV_GRAY2BGR);
// create replacement look-up-table:
// 1. basic => gray values of given intensity
cv::Mat lookUpTable(1, 256, CV_8UC3);
for( int i = 0; i < 256; ++i)
lookUpTable.at<cv::Vec3b>(0,i) = cv::Vec3b(i,i,i);
// 2. replace whatever you want:
lookUpTable.at<cv::Vec3b>(0,25) = cv::Vec3b(25,0,0);
lookUpTable.at<cv::Vec3b>(0,100) = cv::Vec3b(0,255,0);
lookUpTable.at<cv::Vec3b>(0,115) = cv::Vec3b(255,0,0);
lookUpTable.at<cv::Vec3b>(0,200) = cv::Vec3b(0,100,255);
// LUT will fail if used this way: cv::LUT(input, lookUpTable, output); - with assertion failed: (lutcn == cn || lutcn == 1) because LUT has 3 channels but input only has 1 channel.
cv::Mat output;
cv::LUT(input_3channels, lookUpTable, output);
cv::imshow("output", output);
cv::imshow("input", input);
cv::waitKey(0);