5

これは、エンコードされた RGB 値を pcl ファイルに展開することに関するものです。pcl のドキュメントに記載されている手順でこれを行いましたが、取得したアンパックされた RGB 値は正確ではありません。Rでそれらをプロットすると、与えられた表現は実際の設定の色に対応しません(Rでプロットされた方法に問題がないことはある程度確信しています)。

たとえば、添付の画像では、区切られた領域の色はグレーとブルー (椅子 2 脚とテーブル 1 脚) である必要があります。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.tableしましたread.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 intfloatはいえ、少なくとも疑問です。これは壊れやすく、読んだ後に色が正しいことを保証するものではありません. 一部のビットがオフになっている可能性があります。

別の注意:>>ストリーム演算子を使用して、ファイルから数値を抽出できます。stringメソッドを使用して手動で解析するよりもはるかに簡単です。たとえば、ここでそれについて読むことができます。

于 2012-04-12T15:17:02.617 に答える