for Robot Artificial Inteligence

IMAGE, Pointcloud save and read Parser(데이터 포맷만 알고 있으면 어떤 것이든 할 수 있음)

|

Usually, depth data is represented by integers, ranging from 0 to 65535, and the type is UINT16, i.e. unsigned short, unsigned 2 bytes.

therefore, when we save file we need to use UINIT16 data type to read depth image

즉 data SIZE와 format만 알고 있으면 어느 무엇이든 데이터를 저장할 수 있고 불러올 수 있다!

READ stream data and save !


// create pointer to read Depth image
void imgcb(const sensor_msgs::ImageConstPtr& img)
{
  // can be any data format that we want to read.
  const uinit16_t * image_data = reinterprete_cast<const uinit16_t * >(&img->data[0]); // pointer always pointing referece if not initialized as int* point = nullptr.
  // and pointer showing value by "*" in front of member variable like int k = *point;

  int width  = img->width;
  int height = img->height;
  std::string fname = "file_name.raw";
  auto file = std::fstream(fname, std::ios::out | std::ios::binary) // ready to write data as binary type

  // const char* is like all round of reading data(float, int, double, char, string...)
  // rule of write of fstream is ("data that we want to read" here is pointer will read data in function, therefore reference, and size of data within data type)
  file.write((const char* )&(image_data[0]), sizeof(uinit16_t) * width * hegith);
  file close();
}

Read file data and use

// in small and simple task we do not use boost, instead, use dirent.h, it is available as a standard header in Unix
std::string image_path = "";
DIR* dir;
// http://pchero21.com/?p=3323
struct dirent *env;
char *ptr1. *ptr2, *ptr3; // we use this truce sentence into word
dir = opendir(path.c_str()) // read directory

// supported image type : jpg, jpeg, bmp, png
std::sting data_format = "raw";
sensor_msgs::ImagePtr image_data;

int width = 480;
int height = 640;

// Step 1: check Directory Exist
if(dir)
{
  // Step 2 : env can read Director then keep reading data.
  while(env = readdir(dir) !== NULL)
  {
    char file_name[100]; // number of alphabet
    strcpy(file_name, image_path.c_str()); // copy string
    strcat(file_name, "/") // 맨뒷쪽에 "/" 이어 붙이는 것이다. ex) /home/chan + "/";
    strcat(file_name, ent->d_name); // "ent->d_name" read file name and put it later

    ptr1 = strtok(ent->d_name, "."); // 문자열 자르기, 자른 문자열 출력
    ptr2 = strtok(NULL, "."); // "ptr == raw"
    ptr3 = strtok(NULL, "."); // "." 자르기.
    int _return = 1;

    // read a file after truce
    if(ptr2 != NULL)
    {
      // check same name in dir
      int ret = strcmp(ptr2,data_format.c_str()); // 만약 raw이면 0이 되고 pop하여 아래쪽 리딩
      if(ret == 0)
      {
        retn = 0;
        break;
      }
    }
    if(retn == 0 && ptr3 = NULL)
    {
      // make size of image data
      uinit16_t* img_data = new uinit16_t(sizeof(uinit16_t)width * height);
      FILE* file = nullptr; // ready to instance to write data
      file = fopen(file_name, "rb"); // read binary
      fread(img_data, sizeof(uinit16_t), width * height, file);

      sensor_msgs::ImagePtr image;
      image.reset(new sensor_msgs::Image());
      image->data.resize(sizeof(uinit16_t) * width * height);

      // pointer occupancy data copy
      memcpy(image->data.data(), img_data, sizeof(unint16_t) * width * height);

      image->height = height;
      image->width = width;
      image->setp = image->width * sizeof(unint16_t);
      image->encoding = sensor_msgs::image_encoding::TYPE_16UC1;
      image->header.frame_id = "/camera";
      image->header.stamp = ros::Time(0);
      image->is_bigendian = 0;
    }  


  }// while done
  closedir(dir);
}
else
{
  std::cout << " Invalid Path Given" << std::endl;
  return false;
}
return true;

위와 같은 식으로 data format, 크기만 안다면 쉽게 파일을 만들고 읽어 올수 있다.

Comments