How to save an image in Intel RealSense(Visual C++)
Asked Answered
S

2

15

I'm working on Intel RealSense SDK (R2). I want to save the image from Camera_viewer. I have worked till saving the frame to specific buffers and retrieving from the same. I want to know how to save those frames/images to a specified location/folder.

Here's my code:

PXCImage *colorIm, *depthIm;
for (int i=0; i<MAX_FRAMES; i++) {

    // This function blocks until all streams are ready (depth and color)
    // if false streams will be unaligned
    if (psm->AcquireFrame(true)<PXC_STATUS_NO_ERROR) break; 

    // retrieve all available image samples
    PXCCapture::Sample *sample = psm->QuerySample();

    // retrieve the image or frame by type from the sample
    colorIm = sample->color;
    depthIm = sample->depth;

    // render the frame
    if (!renderColor->RenderFrame(colorIm)) break;
    if (!renderDepth->RenderFrame(depthIm)) break;

    // release or unlock the current frame to fetch the next frame
    psm->ReleaseFrame();
}

I'm able to retrieve the frames/images successfully, but I want to save those files for further use. So I want to know how to save those files in a folder.

Thanks in advance

Skiff answered 24/8, 2015 at 3:29 Comment(2)
Can you solve your problem?Bristletail
There is an answer to this question on #32351713. In short: use PXCImage::AcquireAccess() to get the image data, then set up (e.g.) a Gdiplus::Bitmap instance with that data, and save that to disk.Flick
M
4

Same question was asked here and the answer that was posted solved the initial question. However there was a follow-up question on how to save the images to specific folder.

If you have that specific question, then answer would be the same SetFileName() only. According to this link, pxcCHAR *file is the full path of the file to playback or to be recorded. . That being said, you can create a custom folder and point your path to that custom folder followed by a valid file name to save your image.

Monometallic answered 10/1, 2016 at 18:32 Comment(1)
And how can you load an extern image (BMP, JPG, PNG, etc) into a PXCImage?Bristletail
C
3

To save the data I would create a Bitmap from the image data as ThorngardSO said and use the code from http://www.runicsoft.com/bmp.cpp to save it -

#include <windows.h>
#include <stdio.h>       // for memset

bool SaveBMP ( BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile )
{
    // declare bmp structures 
    BITMAPFILEHEADER bmfh;
    BITMAPINFOHEADER info;

    // andinitialize them to zero
    memset ( &bmfh, 0, sizeof (BITMAPFILEHEADER ) );
    memset ( &info, 0, sizeof (BITMAPINFOHEADER ) );

    // fill the fileheader with data
    bmfh.bfType = 0x4d42;       // 0x4d42 = 'BM'
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
    bmfh.bfOffBits = 0x36;      // number of bytes to start of bitmap bits

    // fill the infoheader

    info.biSize = sizeof(BITMAPINFOHEADER);
    info.biWidth = width;
    info.biHeight = height;
    info.biPlanes = 1;          // we only have one bitplane
    info.biBitCount = 24;       // RGB mode is 24 bits
    info.biCompression = BI_RGB;    
    info.biSizeImage = 0;       // can be 0 for 24 bit images
    info.biXPelsPerMeter = 0x0ec4;     // paint and PSP use this values
    info.biYPelsPerMeter = 0x0ec4;     
    info.biClrUsed = 0;         // we are in RGB mode and have no palette
    info.biClrImportant = 0;    // all colors are important

    // now we open the file to write to
    HANDLE file = CreateFile ( bmpfile , GENERIC_WRITE, FILE_SHARE_READ,
         NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
    if ( file == NULL )
    {
        CloseHandle ( file );
        return false;
    }

    // write file header
    unsigned long bwritten;
    if ( WriteFile ( file, &bmfh, sizeof ( BITMAPFILEHEADER ), &bwritten, NULL ) == false )
    {   
        CloseHandle ( file );
        return false;
    }
    // write infoheader
    if ( WriteFile ( file, &info, sizeof ( BITMAPINFOHEADER ), &bwritten, NULL ) == false )
    {   
        CloseHandle ( file );
        return false;
    }
    // write image data
    if ( WriteFile ( file, Buffer, paddedsize, &bwritten, NULL ) == false )
    {   
        CloseHandle ( file );
        return false;
    }

    // and close file
    CloseHandle ( file );

    return true;
}

This can then be subsequently loaded using more code from the same link -

/*******************************************************************
BYTE* LoadBMP ( int* width, int* height, long* size 
        LPCTSTR bmpfile )

The function loads a 24 bit bitmap from bmpfile, 
stores it's width and height in the supplied variables
and the whole size of the data (padded) in <size>
and returns a buffer of the image data 

On error the return value is NULL. 

  NOTE: make sure you [] delete the returned array at end of 
        program!!!
*******************************************************************/

BYTE* LoadBMP ( int* width, int* height, long* size, LPCTSTR bmpfile )
{
    // declare bitmap structures
    BITMAPFILEHEADER bmpheader;
    BITMAPINFOHEADER bmpinfo;
    // value to be used in ReadFile funcs
    DWORD bytesread;
    // open file to read from
    HANDLE file = CreateFile ( bmpfile , GENERIC_READ, FILE_SHARE_READ,
         NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
    if ( NULL == file )
        return NULL; // coudn't open file


    // read file header
    if ( ReadFile ( file, &bmpheader, sizeof ( BITMAPFILEHEADER ), &bytesread, NULL ) == false )
    {
        CloseHandle ( file );
        return NULL;
    }

    //read bitmap info

    if ( ReadFile ( file, &bmpinfo, sizeof ( BITMAPINFOHEADER ), &bytesread, NULL ) == false )
    {
        CloseHandle ( file );
        return NULL;
    }

    // check if file is actually a bmp
    if ( bmpheader.bfType != 'MB' )
    {
        CloseHandle ( file );
        return NULL;
    }

    // get image measurements
    *width   = bmpinfo.biWidth;
    *height  = abs ( bmpinfo.biHeight );

    // check if bmp is uncompressed
    if ( bmpinfo.biCompression != BI_RGB )
    {
        CloseHandle ( file );
        return NULL;
    }

    // check if we have 24 bit bmp
    if ( bmpinfo.biBitCount != 24 )
    {
        CloseHandle ( file );
        return NULL;
    }


    // create buffer to hold the data
    *size = bmpheader.bfSize - bmpheader.bfOffBits;
    BYTE* Buffer = new BYTE[ *size ];
    // move file pointer to start of bitmap data
    SetFilePointer ( file, bmpheader.bfOffBits, NULL, FILE_BEGIN );
    // read bmp data
    if ( ReadFile ( file, Buffer, *size, &bytesread, NULL ) == false )
    {
        delete [] Buffer;
        CloseHandle ( file );
        return NULL;
    }

    // everything successful here: close file and return buffer

    CloseHandle ( file );

    return Buffer;
}

You can then load those bitmap files at a later date using the code from Intel https://software.intel.com/sites/landingpage/realsense/camera-sdk/v1.1/documentation/html/manuals_image_and_audio_data.html -

// Image info
PXCImage::ImageInfo info={};
info.format=PXCImage::PIXEL_FORMAT_RGB32;
info.width=image_width;
info.height=image_height;

// Create the image instance
PXCImage image=session->CreateImage(&info);

// Write data
PXCImage::ImageData data;
image->AcquireAccess(PXCImage::ACCESS_WRITE,&data);
... // copy the imported image to data.planes[0]
image->ReleaseAccess(&data); 

Using these three sets of code you should easily be able to save Bitmaps in any specified folder using WriteFile then, once loaded you can convert the bitmap back into ImageData.

Let me know how it goes.

Choate answered 13/1, 2016 at 10:45 Comment(6)
That looks very good!, I can see you are very good in this :D , can you help me with this please?Bristletail
I am afraid that I don't use the Intel image processing suite so I can only quote code that other people have written. The steps should be 1. Convert to Bitmap using PXCImage tools found in the final link 2. Once you have the Bitmap format save it to your desired file using the runicsoft method. (as a Bitmap it can also be accessed by other programs) 3. At a later date you can load it back in using the second runicsoft code. 4. Load the Bitmap data back into ImageInfo using the quoted Intel code. I wish I could be more helpful!Choate
Is the first time that I heard about the runicsoft method. Do you have a link about that? Thank'sBristletail
Its runicsoft.com/bmp.cpp - That will open in any browser that can open text files.Choate
@AlexanderLeonVI - Did you manage to write something that worked? I see the question has received positive interest and I bet that a lot of people would love to see the final product you put together.Choate
Well, I have to say that I haven't found how to figure it outBristletail

© 2022 - 2024 — McMap. All rights reserved.