【问题标题】:Opencv color mapping with direct pixel access具有直接像素访问的 Opencv 颜色映射
【发布时间】:2013-10-14 20:45:21
【问题描述】:

我有一个灰度图像,我想通过使用调色板(如 Matlab 中的颜色图)映射灰度值来以彩色显示。

我设法通过使用 OpenCV cvSet2D 函数来做到这一点,但出于性能原因,我想直接访问像素。

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

这是我的代码:

    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);
        }
    }
}

将 if (true) 更改为 if (false) 以进行不同的像素访问。

正确的结果是 cvSet2D:

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

感谢您的帮助

【问题讨论】:

  • 目前看不到任何错误。正确的字节顺序应该是imageData 内的 BGR。如果更改字节顺序,图像会如何变化?它应该改变,否则你做错了什么。尝试只渲染一种颜色(将其他通道保留为 0/黑色)。看看他们是否合适。对齐似乎是正确的,但我对角落周围的强烈对比有点困惑。
  • 我发现了我的错误...事实上它是 RGB 但这不是问题,我的颜色值是 256 而不是 255...真的很抱歉...我想问这个问题帮我找到了答案。
  • 啊……好吧。这就解释了强烈的对比(由于溢出等)。 :)
  • 没有 iplImage 是 openCV 的一部分,但它现在已被 CV::Mat 取代。
  • 那么请关闭问题。人们花时间解决它。

标签: c++ opencv


【解决方案1】:

我已经为 Microsoft Kinect 传感器的深度图着色做了类似的事情。我用于将灰度深度图转换为彩色图像的代码将适用于您正在尝试做的事情。您可能需要稍作修改,因为在我的情况下,深度值在 500 到 2000 之间,我不得不重新调整它们。

将灰度图像着色为彩色图像的函数是:

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

        }
        }
}

对于如下所示的输入图像:

这段代码的输出是:

【讨论】:

    【解决方案2】:

    我发布这个是为了结束我在问题的 cmets 中提出的问题。

    答案是:

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

    谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-19
      相关资源
      最近更新 更多