5

这是关于在 pcl 文件中解压缩编码的 rgb 值。我使用 pcl 文档中描述的过程执行此操作,但我得到的解压 rgb 值并不完全正确。当我用 R 绘制它们时,给出的表示与实际设置中的颜色不对应(我在一定程度上确定问题不在于它用 R 绘制的方式)。

例如,在附加的图像中,划定的区域应该有灰色和蓝色(两把椅子和一张桌子)。使用 R 中的 rgl 库绘制的未打包 pcl 数据

源 pcl 文件可在以下位置找到:https ://docs.google.com/open?id=0Bz5-HVcDiF6SanBZU0JWVmJwWHM ,解压后颜色值的文件位于: https ://docs.google.com/open?id=0Bz5 -HVcDiF6SV2pYQ0xUbTAwVmM。以下是用于在 ac plus plus 设置中解压缩颜色值的代码:

uint32_t rgbD = *reinterpret_cast<int*>(&kinectValue);

    uint16_t rD = (rgbD >> 16) & 0x0000ff;
    uint16_t gD = (rgbD >> 8)  & 0x0000ff;
    uint16_t bD = (rgbD)       & 0x0000ff;

如果您能告诉我哪里出错了,我将不胜感激。

更新:

以下是我在绘制 3D 值时使用的 R 代码片段:

library(rgl)
pcd <- read.table(file.choose(),sep="")
names(pcd) <- c("x","y","z","r","g","b")
plot3d(pcd$x,pcd$y,pcd$z,col=rgb(pcd$r,pcd$g,pcd$b,maxColorValue=255))

更新:

以下是我用 C++ 读取数据的代码:

/*
Reads in a file from Kinect with unpacked color values, filter the color value component and
sends it to be unpacked
*/
int fileRead(){

  string line;
  int lineNum = 0;

  ifstream myfile ("res/OnePerson4.pcd");

  if (myfile.is_open())
  {
    while ( myfile.good() )
    {
      lineNum++;
      getline (myfile,line);

       // Exclude the header information in the kinect file from the unpacking process
      //if(lineNum > 10 && lineNum <20){//This for loop is activated when testing
      if(lineNum > 10){
        //Test code to extract the x,y,z values
        string xyzvalFromKinectStr = line.substr(0,line.find_last_of(' '));
        //cout<<xyzvalFromKinectStr<<"\n";
        //Extract the packed rgb value
        string valFromKinectStr = line.substr(line.find_last_of(' '));
        double kinectVal = ::atof(valFromKinectStr.c_str());
        kinectToRgb(kinectVal, xyzvalFromKinectStr);

      }
    }
    myfile.close();
  }
  else
  {
      cout << "Unable to open file";
  }

  return 0;
}
4

1 回答 1

9

这是我的工作解决方案。首先,我运行您的输入grep以过滤掉坐标中的 NAN:

$ grep -v nan OnePerson4.pcd > OnePerson4.pcd.filtered

然后我通过 C++ 代码提取数据,如下所示:

#include <stdio.h>

int main()
{
    if (FILE *f = fopen("OnePerson4.pcd.filtered", "rt"))
    {
        for (;;)
        {
            float x = 0;
            float y = 0;
            float z = 0;
            float color_float = 0;
            if (fscanf(f, "%f %f %f %f", &x, &y, &z, &color_float) != 4)
            {
                break;
            }

            unsigned color = *(unsigned const *)&color_float;
            unsigned r = color & 0xff;
            unsigned g = (color >> 8) & 0xff;
            unsigned b = (color >> 16) & 0xff;
            printf("%f,%f,%f,%d,%d,%d\n", x, y, z, r, g, b);
        }

        fclose(f);
    }

    return 0;
}

我不知道 RGB 以哪个字节顺序存储,因此您可能必须交换 R 和 B。它通常是 RGB 或 BGR。

然后我用你的代码来绘制点(我改为read.tableread.csv

library(rgl)
pcd <- read.csv(file.choose())
names(pcd) <- c("x","y","z","r","g","b")
plot3d(pcd$x,pcd$y,pcd$z,col=rgb(pcd$r,pcd$g,pcd$b,maxColorValue=255))

这就是我得到的:

在此处输入图像描述

所以我假设问题出在您从 pcd 文件中读取颜色的代码上。其余的对我来说都很好。

更新:你的问题是double类型。将其更改为float,它应该可以工作。尽管unsigned int按原样存储float至少是有问题的。这很脆弱,并不能保证在您阅读后颜色是正确的。有些位可能已关闭。

另一个注意事项:您可以使用>>流运算符从文件中提取数字。这比使用string方法手动解析要容易得多。例如,您可以在此处阅读相关内容。

于 2012-04-12T15:17:02.617 回答