2014-11-10 4 views
1

Мне нужно сгенерировать oni-файл с изображения rgb и глубины. Я использовал образец NiRecordSynthetic от openni. Он работает правильно для моего изображения глубины, но когда я добавляю функцию transformImageMD для своего изображения RGB, я получаю ошибку сегментации в imageMap (x, y) = imagePixel. Я не знаю почему.конвертировать изображение rgb depth в файл oni

вот мой код:

void transformDepthMD(Mat FrameDepth,DepthMetaData& depthMD) 
{ 
    DepthMap& depthMap = depthMD.WritableDepthMap(); 
    for (XnUInt32 y = 0; y < depthMap.YRes(); y++) 
    { 
     for (XnUInt32 x = 0; x < depthMap.XRes(); x++) 
     { 
      //Punch vertical cut lines in the depth image 
      if ((x % 2) == 0) 
      { 

       depthMap(x,y) = FrameDepth.at<XnUInt16>(y,x); 
      } 
     } 
    } 
} 
void transformImageMD(Mat FrameImage,ImageMetaData& imageMD) 
{ 
    RGB24Map& imageMap = imageMD.WritableRGB24Map(); 
    for (XnUInt32 y = 0; y < imageMD.YRes(); y++) 
    { 
    for (XnUInt32 x = 0; x <imageMD.XRes(); x++) 
     { 
      XnRGB24Pixel imagePixel; 
      imagePixel.nBlue=FrameImage.at<Vec3b>(y,x)[0]; 
      imagePixel.nGreen=FrameImage.at<Vec3b>(y,x)[1]; 
      imagePixel.nRed=FrameImage.at<Vec3b>(y,x)[2]; 
      imageMap(x,y) = imagePixel; 
     } 
    } 

} 

int main(int argc, char* argv[]) 
{ 
    XnStatus nRetVal = XN_STATUS_OK; 
    nRetVal = xnLogInitFromXmlFile(SAMPLE_XML_PATH); 
    if (nRetVal != XN_STATUS_OK) 
    { 
     printf("Log couldn't be opened: %s. Running without log", xnGetStatusString(nRetVal)); 
    } 
    if (argc < 3) 
    { 
     printf("usage: %s <inputFile> <outputFile>\n", argv[0]); 
     return -1; 
    } 
    const char* strInputFile = argv[1]; 
    const char* strOutputFile = argv[2]; 
    Context context; 
    nRetVal = context.Init(); 
    CHECK_RC(nRetVal, "Init"); 
    // open input file 
    Player player; 
    nRetVal = context.OpenFileRecording(strInputFile, player); 
    CHECK_RC(nRetVal, "Open input file"); 
    // Get depth node from recording 
    DepthGenerator depth; 
    nRetVal = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth); 
    CHECK_RC(nRetVal, "Find depth generator"); 
    // Create mock node based on depth node from recording 
    MockDepthGenerator mockDepth; 
    nRetVal = mockDepth.CreateBasedOn(depth); 
    CHECK_RC(nRetVal, "Create mock depth node"); 

    ImageGenerator image; 
    nRetVal = context.FindExistingNode(XN_NODE_TYPE_IMAGE, image); 
    CHECK_RC(nRetVal, "Find depth generator"); 
    // Create mock node based on depth node from recording 
    MockImageGenerator mockImage; 
    nRetVal = mockImage.CreateBasedOn(image); 
    CHECK_RC(nRetVal, "Create mock depth node"); 
    // create recorder 
    Recorder recorder; 
    nRetVal = recorder.Create(context); 
    CHECK_RC(nRetVal, "Create recorder"); 
    nRetVal = recorder.SetDestination(XN_RECORD_MEDIUM_FILE, strOutputFile); 
    CHECK_RC(nRetVal, "Set recorder destination file"); 
    // add depth node to recorder 
    nRetVal = recorder.AddNodeToRecording(mockDepth); 
    CHECK_RC(nRetVal, "Add node to recording"); 
    nRetVal = recorder.AddNodeToRecording(mockImage); 
    CHECK_RC(nRetVal, "Add node to recording"); 

    nRetVal = player.SetRepeat(FALSE); 
    XN_IS_STATUS_OK(nRetVal); 
    XnUInt32 nNumFrames = 0; 
    nRetVal = player.GetNumFrames(image.GetName(), nNumFrames); 
    CHECK_RC(nRetVal, "Get player number of frames"); 
    DepthMetaData depthMD; 
    ImageMetaData imageMD; 
    int frameNum = 0; 
    String path = "myData"; 
    while ((nRetVal = depth.WaitAndUpdateData()) != XN_STATUS_EOF) 
    { 
     ++frameNum; 
     CHECK_RC(nRetVal, "Read next frame"); 
     // Get depth meta data 
     depth.GetMetaData(depthMD); 
     image.GetMetaData(imageMD); 

     nRetVal = depthMD.MakeDataWritable(); 
     CHECK_RC(nRetVal, "Make depth data writable"); 

     nRetVal = imageMD.MakeDataWritable(); 
     CHECK_RC(nRetVal, "Make depth data writable"); 

     String ficheroActualRGB; 
     ficheroActualRGB = path +"RGB_" + boost::to_string(frameNum) + ".png"; 
     String ficheroActualDepth = path +"Depth_"+ boost::to_string(frameNum) + ".png"; 

     Mat matFrameImage = imread(ficheroActualRGB, 1); 
     resize(matFrameImage, matFrameImage, Size(640, 480), 0, 0, INTER_CUBIC); 
     Mat matFrameDepth = imread(ficheroActualDepth,1); 
     resize(matFrameDepth, matFrameDepth, Size(640, 480), 0, 0, INTER_CUBIC); 

     transformDepthMD(matFrameDepth,depthMD); 
     transformImageMD(matFrameImage,imageMD); 
//   Pass the transformed data to the mock depth generator 
     nRetVal = mockDepth.SetData(depthMD); 
     CHECK_RC(nRetVal, "Set mock node new data"); 

     nRetVal = mockImage.SetData(imageMD); 
     CHECK_RC(nRetVal, "Set mock node new data"); 

     /* We need to call recorder.Record explicitly because we're not using WaitAndUpdateAll(). */ 
     nRetVal = recorder.Record(); 
     CHECK_RC(nRetVal, "Record"); 
     printf("Recorded: frame %u out of %u\r", depthMD.FrameID(), nNumFrames); 
    } 
    printf("\n"); 
    return 0; 
} 

Спасибо,

+0

Возможно, проверьте, имеют ли 'FrameImage' и' depthMD' и/или 'imageMD' одинаковые размеры? – Galik

+0

да, оба они имеют одинаковые размеры. Кажется, что imageMap имеет значение null, потому что он не может поместить imagePixel в imageMap, но когда я показываю imageMD.Yres и imageMD.Xres, он показывает 640 и 480 одинакового размера моего изображения. –

ответ

1

С странной причине я не могу получить какие-либо данные из imageMD. Но вы можете использовать собственный стиль для преобразования изображения RGB-D в файл .oni. Я использовал OpenCV и OpenNI для этого.

Вот пример кода.

string color_dir="your_color_dir/", depth_dir="your_depth_dir/"; 
int frame_num = 100; 

XnStatus nRetVal = XN_STATUS_OK; 
Context context; 
nRetVal = context.Init(); 
CHECK_RC(nRetVal, "Init"); 

Player player; 
nRetVal = context.OpenFileRecording("input.oni", player); // we use existence .oni file to simulate a oni context environment. 
CHECK_RC(nRetVal, "Open input file"); 

DepthGenerator depth; 
ImageGenerator color; 
nRetVal = context.FindExistingNode(XN_NODE_TYPE_IMAGE, color); 
CHECK_RC(nRetVal, "Find color generator"); 

nRetVal = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth); 
CHECK_RC(nRetVal, "Find depth generator"); 

MockDepthGenerator mockDepth; 
nRetVal = mockDepth.CreateBasedOn(depth); 
CHECK_RC(nRetVal, "Create mock depth node"); 
MockImageGenerator mockColor; 
mockColor.CreateBasedOn(color); 
CHECK_RC(nRetVal, "Create mock color node"); 

Recorder recorder; 
nRetVal = recorder.Create(context); 
CHECK_RC(nRetVal, "Create recorder"); 

nRetVal = recorder.SetDestination(XN_RECORD_MEDIUM_FILE, "dst.oni"); 
CHECK_RC(nRetVal, "Set recorder destination file"); 

nRetVal = recorder.AddNodeToRecording(mockDepth); 
CHECK_RC(nRetVal, "Add node to recording"); 
nRetVal = recorder.AddNodeToRecording(mockColor); 
CHECK_RC(nRetVal, "Add node to recording"); 

for (int i = 0; i < frame_num;++i) 
{ 
    std::stringstream ss; 
    ss << depth_dir << i << ".png"; 
    std::string filepath_depth = ss.str(); 

    std::stringstream sss; 
    sss << color_dir << i << ".png"; 
    std::string filepath_color = sss.str(); 

    cv::Mat depth_img = cv::imread(filepath_depth, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH); 
    depth_img.convertTo(depth_img, CV_16U); 

    cv::Mat color_img = cv::imread(filepath_color, CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH); 
    color_img.convertTo(color_img, CV_8UC3); 

    //depth 
    DepthMetaData depthMD; 
    XnUInt32& di = depthMD.FrameID(); 
    di = i;      // set frame id. 
    XnUInt64& dt = depthMD.Timestamp(); 
    dt = i*30000+1;    // set a proper timestamp. 

    depthMD.AllocateData(depth_img.cols, depth_img.rows); 
    DepthMap& depthMap = depthMD.WritableDepthMap(); 
    for (XnUInt32 y = 0; y < depthMap.YRes(); y++) 
    { 
     for (XnUInt32 x = 0; x < depthMap.XRes(); x++) 
     { 
      depthMap(x, y) = depth_img.at<ushort>(y, x); 
     } 
    } 
    nRetVal = mockDepth.SetData(depthMD); 
    CHECK_RC(nRetVal, "Set mock node new data"); 

    //color 
    ImageMetaData colorMD; 
    XnUInt32& ci = colorMD.FrameID(); 
    ci = i; 
    XnUInt64& ct = colorMD.Timestamp(); 
    ct = i*30000+1; 

    colorMD.AllocateData(color_img.cols, color_img.rows, XN_PIXEL_FORMAT_RGB24); 
    RGB24Map& imageMap = colorMD.WritableRGB24Map(); 
    for (XnUInt32 y = 0; y < imageMap.YRes(); y++) 
    { 
     for (XnUInt32 x = 0; x < imageMap.XRes(); x++) 
     { 
      cv::Vec3b intensity = color_img.at<cv::Vec3b>(y, x); 
      imageMap(x, y).nBlue = (XnUInt8)intensity.val[0]; 
      imageMap(x, y).nGreen = (XnUInt8)intensity.val[1]; 
      imageMap(x, y).nRed = (XnUInt8)intensity.val[2]; 
     } 
    } 
    nRetVal = mockColor.SetData(colorMD); 
    CHECK_RC(nRetVal, "Set mock node new data"); 


    recorder.Record(); 
    printf("Recorded: frame %u out of %u\r", depthMD.FrameID(), frame_num); 
} 
+0

Большое спасибо за ваш ответ –

Смежные вопросы