将rgb深度图像转换为oni文件

时间:2014-11-10 09:00:17

标签: c++ openni

我需要从rgb和深度图像生成oni文件。我使用了来自openni的NiRecordSynthetic样本。它适用于我的深度图像但是当我为我的RGB图像添加transformImageMD函数时,我将在imageMap(x,y)= imagePixel中得到分段错误。 我不知道为什么。

这是我的代码:

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;
}

谢谢,

1 个答案:

答案 0 :(得分: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);
}