RGB image rendering from ImageData

RGB image rendering from ImageData

I'm trying to render RGB image from PXCImage::ImageData, and see some issues:

Step 1. set RGB resolution to 320x240, I get pitch: 640, and data layout of each pixel is RGBA. The rendered image is wrong(see attached image)

EnableImage(PXCImage::COLOR_FORMAT_RGB32,320,240);

two questions here:

1. why the pitch is 640?  640 bytes means 160 words in this case(32bit RGB), but the image width is 320 words,

I guess the pitch should be higher or equal to image width(unit: bytes)?

2. according to the comment, COLOR_FORMAT_RGB32 data layout on little endian machine is BGRA, but it's different from

what I really see: RGBA.

 

Step 2: change resolution to 640x480, now the pitch becomes 1920(480*4, not 640*4), and the color order is wrong.

Step 3: I try depth image, resolution is 320x240, and I got pitch 640(320*2, knowing 2 bytes for each pixel). So depth image is correct.

 

The Capture viewer tool works well, so there is something wrong with the way I render it.

When I turned to help from documents, I realized that the description about ImageData on local document is out date than the one online.

Is there any sample showing how to render color image from ImageData(planes[0], specifically)? Or anyone knows what's wrong with it?

Thank you very much!

 

AttachmentSize
Downloadimage/jpeg rgb-qvga.jpg16.37 KB
4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hi Len,

Hopefully I can shed some light on a few things from what I have learned over the past few weeks:

  1. I have no idea why your pitch is 640 when you ask for 320x240, the pitch does indeed relate to the number of bytes per row. I know the SDK uses the color format bit-depth as a suggestion so perhaps instead of returning you 32-bit data, it is only returning 5-6-5-bit data.
  2. I think there is some under-the-hood translation that the computer does, so if it is little endian, it may translate the values automatically to RGB unless you are accessing the values manually byte-by-byte.
  3. I ran into the same confusion earlier when I specified 640x480 resolution and 32-bit depth and got returned a pitch of 1920. This is another example of the SDK ignoring your 32-bit depth request, so you are actually only getting 24-bit data (640*3 = 1920)

Here is my color-image-related code in case that helps. I'm working in openFrameworks:

//in setup
mPXC.EnableImage(PXCImage::COLOR_FORMAT_RGB24, 1280, 720);//I only request 24-bit, since when I request 32-bit I get 24-bit anyway (and really, what would the Alpha be besides 255?)
mPXC.QueryImageSize(PXCImage::IMAGE_TYPE_COLOR, mDimsRgb[0], mDimsRgb[1]);//to get the _actual_ res that the camera decides to return
mTexRgb.allocate(mDimsRgb[0], mDimsRgb[1], GL_RGB);

//in update
mTexRgb.loadData(cData.planes[0],mDimsRgb[0],mDimsRgb[1],GL_BGR);

//in draw
mTexRgb.draw(100,0,320,240);//yes, the aspect ratio is messed up, but this is just for debugging

 

Thanks Quin! You did shed some light! Now color image rendering works well.

Indeed, COLOR_FORMAT_RGB32 works like COLOR_FORMAT_RGB24, so just change it to RGB24 or treat it as RGB24.

lessons learnt:

1. verify the color format you get, not expecting by what you set.

2. read online document, not the local one.

3. it's good to come here before jumping into the water. :)

working C++ code for those who need it:

    UtilPipeline pp;
    pp.EnableImage(PXCImage::COLOR_FORMAT_RGB32,640,480);
    pp.Init();

    PXCImage::ImageData data;
    for (;;)
    {
        if (pp.IsDisconnected()) break;
        if (!pp.AcquireFrame(true)) break;
        
        PXCImage* image = pp.QueryImage(PXCImage::IMAGE_TYPE_COLOR);
        if (image != NULL)
        {
            pxcStatus sts = image->AcquireAccess(PXCImage::ACCESS_READ,&data);
            if (sts >= PXC_STATUS_NO_ERROR)
            {
                pxcBYTE* baseAddr = data.planes[0];
                int stride = data.pitches[0] / sizeof(pxcU8);

                for (int y = 0; y < 480; y++)
                {
                    for (int x = 0; x < 640; x++)
                    {
                        pxcBYTE nBlue = (baseAddr + y * stride)[3 * x + 0];
                        pxcBYTE nGreen = (baseAddr + y * stride)[3 * x + 1];
                        pxcBYTE nRed = (baseAddr + y * stride)[3 * x + 2];
                    }
                }
                // Rendering code
            }
            image->ReleaseAccess(&data);
        }

        pp.ReleaseFrame();
    }

Thanks Quin K. You did shed some light!

Now color image rendering works well.

Enabling COLOR_FORMAT_RGB32 actually returns COLOR_FORMAT_RGB24.

It seems it's better to verify with ImageData::ColorFormat rather than expecting from what you set.

Leave a Comment

Please sign in to add a comment. Not a member? Join today