Opencv颜色映射与直接像素访问。

时间:2021-11-21 23:45:39

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).

我有一个灰度图像,我想用颜色来显示颜色,用一个颜色调色板(如Matlab中的colormap)来绘制灰度值。

I managed to do it by using OpenCV cvSet2D function, but I would like to access to the pixels directly for performance reasons.

我成功地使用了OpenCV cvSet2D函数,但是我想直接访问像素,因为性能原因。

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.

但是当我这样做的时候,图像有奇怪的颜色。我试着把颜色设置成不同的顺序(RGB, BGR,…),但似乎无法绕过它。

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.

将if (true)改为if (false),以获得不同的像素访问。

The correct result is with cvSet2D:

正确的结果是cvSet2D:

Opencv颜色映射与直接像素访问。

The wrong result with the direct memory access:

直接内存访问错误的结果:

Opencv颜色映射与直接像素访问。

Thank you for your help

谢谢你的帮助。

2 个解决方案

#1


4  

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.

我做了一些类似于从微软Kinect传感器着色深度图。我用于将灰度深度图转换成彩色图像的代码将为您正在尝试做的工作而工作。您可能需要稍微修改一下,因为在我的情况下,深度值在500到2000之间,我必须重新调整它们。

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:

对于一个像这样的输入图像:

Opencv颜色映射与直接像素访问。

Output of this code is:

该代码的输出为:

Opencv颜色映射与直接像素访问。

#2


0  

I'm posting this to close the question like asked in the comments of my question.

我把这篇文章贴在了我的问题的评论里。

The answer was:

答案是:

I found out my error... In fact it's RGB but that wasn't the problem, I had color values at 256 instead of 255... Really sorry... I guess asking the question helped me found the answer

我发现了我的错误……实际上是RGB,但这不是问题,我的颜色值是256而不是255…真的很抱歉……我想问这个问题帮助我找到了答案。

Thank you

谢谢你!

#1


4  

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.

我做了一些类似于从微软Kinect传感器着色深度图。我用于将灰度深度图转换成彩色图像的代码将为您正在尝试做的工作而工作。您可能需要稍微修改一下,因为在我的情况下,深度值在500到2000之间,我必须重新调整它们。

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:

对于一个像这样的输入图像:

Opencv颜色映射与直接像素访问。

Output of this code is:

该代码的输出为:

Opencv颜色映射与直接像素访问。

#2


0  

I'm posting this to close the question like asked in the comments of my question.

我把这篇文章贴在了我的问题的评论里。

The answer was:

答案是:

I found out my error... In fact it's RGB but that wasn't the problem, I had color values at 256 instead of 255... Really sorry... I guess asking the question helped me found the answer

我发现了我的错误……实际上是RGB,但这不是问题,我的颜色值是256而不是255…真的很抱歉……我想问这个问题帮助我找到了答案。

Thank you

谢谢你!