【问题标题】:OpenInventor to PCD: cannot convert RGB to decimalOpenInventor 到 PCD:无法将 RGB 转换为十进制
【发布时间】:2012-07-23 20:53:37
【问题描述】:

我正在编写一个小程序来将 OpenInventor 文件转换为 PCD 文件。为此,我输入了两个文件,即 OpenInventor 文件和 JPEG 图像。纹理坐标是介于 0.0 和 1.0 之间的浮点值。

我使用OpenCV提取RGB值并以十进制格式返回,但是下面的函数好像不能正常工作...

float get_color(cv::Mat img, float x, float y) {

    int i = x*img.cols;
    int j = y*img.rows;

    unsigned char R = img.ptr<unsigned char>(j)[3*i];
    unsigned char G = img.ptr<unsigned char>(j)[3*i+1];
    unsigned char B = img.ptr<unsigned char>(j)[3*i+2];

    return  R*pow(16,4) +
            G*pow(16,2) +
            B;
}

我加载图像

 cv::imread("filename.jpg", CV_LOAD_IMAGE_COLOR).

【问题讨论】:

  • 你怎么可能用一个float来表示一种RGB颜色?
  • @DesmondHume:完全是我的想法。
  • 你想用那个浮动做什么?您是否可能想要一个平均值以获得灰度图像?
  • 其实一个浮点数可以存储3个字节。浮点数为 32 位,尾数为 24 位。其中只有 23 个被实际存储,但这并不重要,因为由于浮点数的原因,第一位总是 1。所以,如果你用 8 位值表示 R、G 和 B,只需使用类似 256 的值*256*R+256*G+B 可以解决问题,并且应该是完全可逆的。不过,为什么有人会使用浮点数而不是 int 我无法理解
  • @DesmondHume,是的,我想我在计算 B 时打错了。无论如何,B 是 150。我的意思是,反过来很简单,我不明白你的反对意见是什么!

标签: c++ opencv rgb point-cloud-library openinventor


【解决方案1】:

您的意思是将其作为 32 位整数返回吗?

unsigned int get_color(cv::Mat img, float x, float y) 
{

    int i = x*img.cols;
    int j = y*img.rows;

    unsigned char R = img.ptr<unsigned char>(j)[3*i];
    unsigned char G = img.ptr<unsigned char>(j)[3*i+1];
    unsigned char B = img.ptr<unsigned char>(j)[3*i+2];

    return  (R << 16) |
            (G << 8) |
            B;
}

或者您可能希望将其作为浮点数返回,在这种情况下您需要执行以下操作

struct FloatColour
{
    float r;
    float g;
    float b;
};

float get_color(cv::Mat img, float x, float y) 
{

    int i = x*img.cols;
    int j = y*img.rows;

    unsigned char R = img.ptr<unsigned char>(j)[3*i];
    unsigned char G = img.ptr<unsigned char>(j)[3*i+1];
    unsigned char B = img.ptr<unsigned char>(j)[3*i+2];

    FloatColour retCol;
    retCol.r = R / 255.0f;
    retCol.g = G / 255.0f;
    retCol.b = B / 255.0f;
    return retCol;
}

【讨论】:

  • 另外 img.at(i,j)[0] "or [1] or[2]" 可能是访问像素的首选方式
  • @Goz 谢谢好友,但我不需要它!
【解决方案2】:

我在 PCL 标题“point_types.hpp”(PCL 版本:1.5.1)中的评论中找到了我自己问题的答案:

由于历史原因(PCL最初是作为ROS包开发的), RGB 信息被打包成一个整数并转换为一个浮点数。 这是我们希望在不久的将来删除的东西,但在 同时,以下代码 sn-p 应该可以帮助您打包和解包 PointXYZRGB 结构中的 RGB 颜色:

uint8_t r = 255, g = 0, b = 0;
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
p.rgb = *reinterpret_cast<float*>(&rgb);

经过重构和一些其他错误修复后,功能变为:

float get_color(cv::Mat img, float s, float t){

        int j = (1.0 - s)*(float)img.cols;
        int i = (1.0 - t)*(float)img.rows;

        uint8_t R = img.at<cv::Vec3b>(i,j)[2];
        uint8_t G = img.at<cv::Vec3b>(i,j)[1];
        uint8_t B = img.at<cv::Vec3b>(i,j)[0];

        uint32_t rgb_32 = ((uint32_t)R << 16 | (uint32_t)G << 8 | (uint32_t)B);

        return *reinterpret_cast<float*>(&rgb_32);
}

【讨论】:

    猜你喜欢
    • 2020-11-14
    • 2015-01-31
    • 2015-05-09
    • 2012-07-25
    • 2012-01-18
    • 2011-05-14
    • 2011-08-09
    相关资源
    最近更新 更多