I'd like to know depth range data

I'd like to know depth range data

I have studied your example, camera_uvmap.

I knew that the type of depth data is short.However, when I see depth data using 'printf', It's range is 1byte.

I think that the module controls the depth data internally as 2 byte and displays the depth data as 1 byte. Is it right?

What I want to question to you is this.

-> Following is my code, which is for seeing depth data value. However, it doesn't look well like I want to see.

I want to control depth data from 0 to 255 as unsigned char type. So, I'd like to display the farest one as black and the nearest one as white,using opencv library.

Can I get your answer?

Thank you for your time.

short temp_p=(short *)(ddepth.planes[0][depth_render.m_mouse.y*pdepth.imageInfo.width+depth_render.m_mouse.x]);
unsigned short temp_s=temp_p;
unsigned char temp_c=temp_s/2;
printf("x=%d , y= %d ,value=%d\n",depth_render.m_mouse.x,depth_render.m_mouse.y,temp_c);

9 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项

Here is the code that I use to do what you want:

cv::Mat depthImage(240/*DepthSize.height*/, 320/*DepthSize.width*/, CV_16UC1, depthData.planes[0], depthData.pitches[0]);
double m, M;
cv::minMaxIdx(depthImage, &m, &M, 0, 0, depthImage < 32000);
cv::Mat dstImage(depthImage.size(), CV_8UC1);
depthImage.convertTo(dstImage, CV_8UC1, 255/(M-m), 1.0*(-m)/(M-m));
dstImage = 255 - dstImage;

The last parameter of minMaxIdx is a mask to remove unreliable depth values (32001 and 32002). And the last operation inverts the image, so that black is far and white is close.

Thank you for your reply. It works well a little. However, The image using your code is not same as the image using PCSDK example source.

Did you compare the image through your code with the image using PCSDK example source like camera_viewer??

I'd like to display the depth image the same as the image displayed through 'camera_viewer' code.

following is your code. And, last line is my one for converting cv::Mat to IplImage.

cv::Mat depthImage(240/*DepthSize.height*/, 320/*DepthSize.width*/, CV_16UC1, ddepth.planes[0], ddepth.pitches[0]);

double m, M;

cv::minMaxIdx(depthImage, &m, &M, 0, 0, depthImage < 32000);

cv::Mat dstImage(depthImage.size(), CV_8UC1);

depthImage.convertTo(dstImage, CV_8UC1, 255/(M-m), 1.0*(-m)/(M-m));

dstImage = 255 - dstImage;

 depth_img=&IplImage(dstImage);

Thank you for your time.

Sincerely.

Gabyong Park.

Another simple way to do what you want is to query an RGB32 image to your depth stream

pxcStatus sts = depthImage->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::COLOR_FORMAT_RGB32, &depthData);

This is what is used in the stream render of the SDK. I suggest you to look at the source code of the render, you may find what you want.

PS: Please answer to this post and not by private message, so that everyone could benefit from this discussion.

Sorry for not answering to the post. 

This is my question.

Sorry for one more question.

During experiment, I found the reason of the problem. If I put something near IR lens for depth data, The image through your code is the same as the image through the image through 'camera viewer' example code. However, if I don't put anything near IR lens for depth data, the image does flick! 

Why does this situation occur? Is it hardware problem? Or , will it be correct by changing source code?

I appreciate your reply. Thank you so much.

the two pictures of not correct image and ideal image are attached. (left one is the image from example source code)

And, this is my part code.

for (int f=0;f<(int)cmdl.m_nframes;f++) {
PXCSmartArray<PXCImage> images(2);
PXCSmartSP sp;

sts=capture.ReadStreamAsync(images, &sp);
if (sts<PXC_STATUS_NO_ERROR) break;
sp->Synchronize();

PXCImage::ImageData dcolor;
PXCImage::ImageData ddepth;
images[0]->AcquireAccess(PXCImage::ACCESS_READ_WRITE,PXCImage::COLOR_FORMAT_RGB32,&dcolor);
//images[1]->AcquireAccess(PXCImage::ACCESS_READ,&ddepth); 아래로 바꿔봤음
images[1]->AcquireAccess(PXCImage::ACCESS_READ,PXCImage::COLOR_FORMAT_DEPTH,&ddepth);

rgb_data=(unsigned int *)dcolor.planes[0];
IplImage* rgb_img=cvCreateImage(size_rgb,8,3);
unsigned char temp_r;
unsigned char temp_g;
unsigned char temp_b;

for(int y=0; y<480; y++)
{
for(int x=0; x<640; x++)
{
//for(int k=0; k<3 ; k++)
//{
temp_r=rgb_data[y*640+x];
temp_g=((rgb_data[y*640+x])>>8);
temp_b=((rgb_data[y*640+x])>>16);

//rgb_img->imageData[y*640*3+x*3+k]=rgb_data[y*640*3+x*3+k];
rgb_img->imageData[y*640*3+x*3]=temp_r;
rgb_img->imageData[y*640*3+x*3+1]=temp_g;
rgb_img->imageData[y*640*3+x*3+2]=temp_b; //왜 이거랑 순서가 다르지? ((pxcU32 *)dcolor.planes[0])[yy*pcolor.imageInfo.width+xx]|=0x000000FF; // (..)(R)(G)(B) 순서임
//}
}
}

depth_data=(unsigned short*)ddepth.planes[0];
IplImage* depth_img=cvCreateImage(size_depth,8,1);
unsigned char temp_d=0;

cv::Mat depthImage(240/*DepthSize.height*/, 320/*DepthSize.width*/,CV_16UC1, ddepth.planes[0], ddepth.pitches[0]);
double m, M;
cv::minMaxIdx(depthImage, &m, &M, 0, 0, depthImage < 32000);
cv::Mat dstImage(depthImage.size(), CV_8UC1);
depthImage.convertTo(dstImage, CV_8UC1, 255/(M-m), 1.0*(-m)/(M-m));
dstImage = 255 - dstImage;

depth_img=&IplImage(dstImage);

cvShowImage("test_depth",depth_img);
cvWaitKey(1);

附件: 

附件尺寸
下载 good.png59.38 KB
下载 bad.png88.53 KB

I have the same behavior on my side. To be honest, I didn't compare the image I build with the one from the sample. I think that the difference comes from the min and max values of the depth image: maybe they accept to saturate a little amout of pixel, whereas I saturate only the pixels which have max and min values.

Did you try to access the depth image as RGB32, as I've explained in my previous post ?

I tried to access tried depth image as RGB32. However, it doesn't work well with another part.So, I implemented ordinary source.

What I'd like to ask you is this.  

I think that minMaxldx of following code causes trouble like flickering because each frame have different min value and max value of depth. 

Can I get fixed min value and max value of depth? Is it correct method?  

Thank you for your time.

Sincerely,

Gabyong P.

cv::minMaxIdx(depthImage, &m, &M, 0, 0, depthImage < 32000);

cv::Mat dstImage(depthImage.size(), CV_8UC1);

Sure, if you want to have a fixed value of gray level associated to a depth value, you should fix min and max value to, for example, m=30.0 and max=2500.0. With these values, the points that are close to the camera (d < 3 cm) will be white and the far points (d > 2.5m) will be black. You'll not have flickering. Feel free to adjust these values to your needs.

By the way, what is the problem with RGB32 ?

I fixed min and max value of depth data like 'double m=30.0; double M=700.0  ' ,but It does still flicker . So, I decided to try to using what you recommended with RGB32.

However, on below code lines, what should I change ?

I tried to change one code line from images[1]->AcquireAccess(PXCImage::ACCESS_READ,&ddepth);  to  ' images[1]->AcquireAccess(PXCImage::ACCESS_READ,PXCImage::COLOR_FORMAT_RGB32,&ddepth); '.

And, it meet 'break' command in  ' if (!uvmap) break;  '  because uvmap doesn't fill.

What should I do ???

Thank you for your time.

--original code line --

for (int f=0;f<(int)cmdl.m_nframes;f++) {
PXCSmartArray<PXCImage> images(2);
PXCSmartSP sp;

sts=capture.ReadStreamAsync(images, &sp);
if (sts<PXC_STATUS_NO_ERROR) break;
sp->Synchronize();

PXCImage::ImageData dcolor;
PXCImage::ImageData ddepth;
images[0]->AcquireAccess(PXCImage::ACCESS_READ_WRITE,PXCImage::COLOR_FORMAT_RGB32,&dcolor);
images[1]->AcquireAccess(PXCImage::ACCESS_READ,&ddepth); // 아래로 바꿔봤음

float *uvmap=(float*)ddepth.planes[2];
if (!uvmap) break;

发表评论

登录添加评论。还不是成员?立即加入