I have a gray scale image that I want to display in color by mapping the gray scale values with a color palette (like colormap in Matlab).
I managed to do it by using OpenCV cvSet2D function, but I would like to access to the pixels directly for performance reasons.
But when I do that the image has strange colors. I tried to set the colors in different orders (RGB, BGR,…) but can’t seem to get around it.
There is my code:
IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), IPL_DEPTH_8U, 3 );
for (int y=0; y<temp->height; y++)
{
uchar* ptr1 = (uchar*) ( temp->imageData + y * temp->widthStep );
uchar* ptr2 = (uchar*) ( img->imageData + y * img->widthStep );
for (int x=0; x<temp->width; x++)
{
CvScalar v1;
int intensity = (int)ptr2[x];
int b=0, g=0, r=0;
r = colormap[intensity][0];
g = colormap[intensity][1];
b = colormap[intensity][2];
if (true)
{
ptr1[3*x] = b;
ptr1[3*x+1] = g;
ptr1[3*x+2] = r;
}
else
{
v1.val[0] = r;
v1.val[1] = g;
v1.val[2] = b;
cvSet2D(temp, y, x, v1);
}
}
}
Change the if (true) to if (false) for different pixel access.
The correct result is with cvSet2D:
The wrong result with the direct memory access:
Thank you for your help
I have done something similar for coloring depth maps from Microsoft Kinect Sensor. The code I used for converting a grayscale depth map into color image will work for what you are trying to do. You may require slight modifications as in my case the depth values were in the range 500 to 2000, and I had to rescale them.
The function for colouring a grayscale image into colour image is:
void colorizeDepth( const Mat& gray, Mat& rgb)
{
double maxDisp= 255;
float S=1.f;
float V=1.f ;
rgb.create( gray.size(), CV_8UC3 );
rgb = Scalar::all(0);
if( maxDisp < 1 )
return;
for( int y = 0; y < gray.rows; y++ )
{
for( int x = 0; x < gray.cols; x++ )
{
uchar d = gray.at<uchar>(y,x);
unsigned int H = 255 - ((uchar)maxDisp - d) * 280/ (uchar)maxDisp;
unsigned int hi = (H/60) % 6;
float f = H/60.f - H/60;
float p = V * (1 - S);
float q = V * (1 - f * S);
float t = V * (1 - (1 - f) * S);
Point3f res;
if( hi == 0 ) //R = V, G = t, B = p
res = Point3f( p, t, V );
if( hi == 1 ) // R = q, G = V, B = p
res = Point3f( p, V, q );
if( hi == 2 ) // R = p, G = V, B = t
res = Point3f( t, V, p );
if( hi == 3 ) // R = p, G = q, B = V
res = Point3f( V, q, p );
if( hi == 4 ) // R = t, G = p, B = V
res = Point3f( V, p, t );
if( hi == 5 ) // R = V, G = p, B = q
res = Point3f( q, p, V );
uchar b = (uchar)(std::max(0.f, std::min (res.x, 1.f)) * 255.f);
uchar g = (uchar)(std::max(0.f, std::min (res.y, 1.f)) * 255.f);
uchar r = (uchar)(std::max(0.f, std::min (res.z, 1.f)) * 255.f);
rgb.at<Point3_<uchar> >(y,x) = Point3_<uchar>(b, g, r);
}
}
}
For an input image which looks like this:
Output of this code is:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With