how go get RGB values of ROI selected in depth stream - c++

I wrote an simple kinect application where I'm accessing the depth values to detect some objects. I use the following code to get the depth value
depth = NuiDepthPixelToDepth(pBufferRun);
this will give me the depth value for each pixel. Now I want to subselect a region of the image, and get the RGB camera values of this corresponding region.
What I'm not sure about:
do I need to open a color image stream?
or is it enough to just convert the depth into color?
how do I use NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution?
I'm fine with the simplest solution where I have a depth frame and a color frame, so that I can select a ROI with opencv and then crop the color frame accordingly.

do I need to open a color image stream?
Yes. You can get the coordinates in the colour frame without opening the stream, but you won't be able to do anything useful with them because you'll have no colour data to index into!
or is it enough to just convert the depth into color?
There's no meaningful conversion of distance into colour. You need two image streams, and a co-ordinate conversion function.
how do I use NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution?
That's a terribly documented function. Go take a look at NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution instead, because the function arguments and documentation actually make sense! Depth value and depth (x,y) coordinate in, RGB (x,y) coordinate out. Simple.
To get the RGB data at some given coordinates, you must first grab an RGB frame using NuiImageStreamGetNextFrame to get an INuiFrameTexture instance. Call LockRect on this to get a NUI_LOCKED_RECT. The pBits property of this object is a pointer to the first pixel of the raw XRGB image. This image is stored row wise, in top-to-bottom left-to-right order, with each pixel being represented by 4 sequential bytes representing a padding byte then R, G and B follwing it.
The pixel at position (100, 200) is therefore at
lockedRect->pBits[ ((200 * width * 4) + (100 * 4) ];
and the byte representing the red channel should be at
lockedRect->pBits[ ((200 * width * 4) + (100 * 4) + 1 ];
This is a standard 32bit RGB image format, and the buffer can be freely passed to your image manipulation library of choice... GDI, WIC, OpenCV, IPL, whatever.
(caveat... I'm not totally certain I have the pixel byte ordering correct. I think it is XRGB, but it could be XBGR or BGRX, for example. Testing for which one is actually being returned should be trivial)

Related

C++ OpenCV boundRect[].tl() unit of output

I was wondering what the unit is of my boundRect[].tl() output.
topleft = boundRect[largest_contour_index].tl();
My assumption is that it is in pixels.
If so, do I need to look at the pixels of my camera and the format it outputs to calculate the position of my object?
Or do the pixels that the function outputs change due to the fact that OpenCV converts the image to an 8-bit image? I can imagine that the amount of pixels where the image consists of becomes smaller when the image is converted to 8 bit.
Please correct me if I'm wrong.
Thank you!
First of all, the BoundingRect returns x,y coordinates, width and height. you can refer to its documentation: docs.opencv.org/2.4/modules/core/doc/basic_structures.html#rect
second, the 8-bit image conversion was based on pixel value of color and doesn't have a direct relation with pixel count. So converting a 100x100 image to 8-bit image will still be 100x100 px

YUV420 to grayscale in C++

I'm trying to write a function to convert a camera stream with a YUV420 pixel format to grayscale. To my understanding, I only need to extract the Y values since these are the luminance of the image frames.
I am using this page as a reference https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/pixfmt-yuv420.html, but I am having trouble understanding what a planar format is and how to essentially skip through the UV values. I think I would need to get the 2x2 Y values (e.g., Y00, Y01, Y10, Y11 in the above link) for every UV values, but I'm also not sure if I should just write them consecutively into my image frame's destination. That is, if I have a pointer to my destination and I have these for Y values, should I just write them in the order of Y00, Y01, Y10, Y11, Y02, etc?

How to get grayscale value of pixels from grayscale image in xCode

I was wondering how to determine the equivalent of RGB values for a grayscale image. The original image is grayscale and everything I have found online is converting an RGB image pixel values to the grayscale pixel values. I already can read in the image. Ideally, this would be for xCode.
I was wondering if there was a class which would do this for me. If so, and you could point me to it, that would be great. I will read on it.
Any help is greatly appreciated.
NOTE: I am a beginner in C++ and do not have time to learn everything formally; I have to learn all of my programming on the fly.
You need more information to transform from a simple Greyscale to RGB, when you do reverse operation, the color information is "lost", as the three channels are set to same value(depending on the algorithm each channel will have a different/same weight in the final color computation).
Digital cameras, usually store more information per pixel, 12 bits per channel in 35mm and 14 bits per channel in medium format (those bits number are the average, some products offer less or even more quality).
Thanks to those additional bits per channel, the camera can compute the "real" color, or what it thinks is the real color based on some parameters.
TL;DR: You can't without more data from your source, in this case the image.
You can convert a gray value to RGB by setting each component of the RGB value to the gray value:
ColorRGB myColorRGB = ColorRGBMake(myGrayValue, myGrayValue, myGrayValue);

Shifting color channels without drawing each channel separately?

I want to draw with Direct2D frames which color channels are shifted on x-axis. I know I could set the composition mode to D2D1_COMPOSITE_MODE_PLUS and draw each color channel separately so I can shift them manually. But I want to know if there is another (maybe more efficient) way of drawing shapes with shifted color channels?
I attached an image which shows what I mean.
(I suggest to open this image in a new tab and zoom in to see the effect better)
The way this is typically done is to sample 3 pixels from the input image at a time, each separated by some amount in the x direction, and combine the red from one, the green from another, and the blue from the third. Unfortunately, I don't know DX2D at all, so I don't know the specifics of how it works there. But if you have a bitmap and a pointer to the pixels, you can simply subtract one (or more) pixels from that pointer, and add one or more pixels to the that pointer and read from those memory locations (being careful to account for image edges). Then pull the channels from the values you've read. For example:
RGBA8* pixel = baseAddressOfImage;
RGBA8* pixelMinus1 = pixel - 1;
RGBA8* pixelPuls1 = pixel + 1;
for each pixel in the output
{
result.red = pixelMinus1->red;
result.green = pixel->green;
result.blue = pixelPlus1->blue;
pixelMinus1++;
pixel++;
pixelPlus1++;
}
Note that you can add or subtract more than 1, but as mentioned above, you have to handle what happens at the edges in those cases.

Conversion from YBR_FULL to RGB in c++?

Could you please explain the relationship between YBR_FULL and RGB so that I'm able to convert the YBR_FULL image to RGB in C++?
I'm getting the pixel data from a Dicom image as bytes in a buffer using DCMTK library. For some selected pixels I set the pixel values as 0, for RGB that works fine as when the images are Visualized the pixel values which are set to 0 are shown as black, but in case of YBR_FULL the those pixels are shown as green. I don't quite understand what the problem is. Could you please elaborate what mistake I'm doing?
this has been answered
Create BufferedImage from YBR_FULL Dicom Image
here's the link to the mathemetical formula
http://www.fourcc.org/fccyvrgb.php
If you are setting the YBR values to (0,0,0) your luminance (Y) is in the correct value, but the chroma (B and R) zero point is exactly in te middle of the range, so you should try with the value 128 (if B and R have one byte size). then you have YBR = (0, 128U, 128U)