Ask Your Question
1

Mat structure for depth map?

asked 2015-06-09 07:17:22 -0500

stillNovice gravatar image

I am reading an image in to a cv::Mat.

cv::Mat depth_map = cv::imread("patio_depth.jpg", -1);

The Mat is then passed to this function: (that gets xyz coordinates from a depth map).

 inline cv::Point3d getPoint3D(int x, int y) const
 {

    cv::Point3d point;
    point.x = depth_map.at<cv::Vec3f>(y, x)[0];
    point.y = depth_map.at<cv::Vec3f>(y, x)[1];
    point.z = depth_map.at<cv::Vec3f>(y, x)[2];

    return point; }

Which causes an assertion error.

Assertion failed <dims &lt;="2" &amp;&amp;="" data="" &amp;&amp;="" <unsigned="">i0 <unsigned>size.p[0] && <unsigned><i1*datatype<_tp>::channels> in \core\mat.hpp

I assume that this means the Mat I am using is incompatible with the function, but what Mat structure WILL work? Or do I need to convert it somehow before I pass it through?

edit retag flag offensive close merge delete

Comments

try cv::Mat depth_map = cv::imread("patio_depth.jpg", 1);

sturkmen gravatar imagesturkmen ( 2015-06-09 07:20:29 -0500 )edit

thanks for answering. That gives me the same error...

stillNovice gravatar imagestillNovice ( 2015-06-09 07:30:11 -0500 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2015-06-09 07:29:42 -0500

updated 2015-06-09 09:23:00 -0500

You are reading a JPG image, therefore you get a BGR image in depth_map, not a float. You should use cv::Vec3b instead of cv::Vec3f to access pixels.

You could check the type of your image with depth_map.type() but it returns a number (check with CV_32FC3 if you want to use cv::Vec3f or CV_8UC3 to check with cv::Vec3b).

--EDIT code according to @stillNovice remark--

By the way, to avoid multiple access to the pixel, prefer doing:

cv::Vec3b pixel = depth_map.at< cv::Vec3b >( y, x );
point.x = pixel[ 0 ]; point.y = pixel[ 1 ]; point.z = pixel[ 2 ];
// OR should work but untested: 
point = cv::Point3f( pixel );
edit flag offensive delete link more

Comments

Thanks you! Works great. Much appreciated.

stillNovice gravatar imagestillNovice ( 2015-06-09 07:34:05 -0500 )edit

Sorry, I have now moved on from testing with jpgs to streaming images in from a kinect, and I am getting the same error. depth_map.type() gives me '0' . How can I tell which Vec it is that I need? Thanks again.

also, minor edit to your code... point.x = pixel[0]; point.y = pixel[1]; point.z = pixel[2];

stillNovice gravatar imagestillNovice ( 2015-06-09 08:25:12 -0500 )edit

Thanks, I've updated the code.

0 is for CV_8U, so depth_map.at< uchar >( y, x );

Mathieu Barnachon gravatar imageMathieu Barnachon ( 2015-06-09 09:25:13 -0500 )edit

thanks again. So I have this:

cv::Point3d point; cv::Vec3b pixel = depth_map.at< uchar >(y, x); point.x = pixel[0]; point.y = pixel[1]; point.z = pixel[2];

but it is giving unexpected results. The point data results are 157, 0, 0. Which are surely wrong...

stillNovice gravatar imagestillNovice ( 2015-06-09 09:38:29 -0500 )edit

The template parameter is the type you get so, it becomes:

uchar pixel = depth_map.at< uchar >( y, x );

This is normal as your image is CV_8U, not CV_32FC3 as you seem expected.

Mathieu Barnachon gravatar imageMathieu Barnachon ( 2015-06-09 09:45:10 -0500 )edit

Ok thanks I understand. BUT, I need 3 values for the point, how can i get them from a uchar?

stillNovice gravatar imagestillNovice ( 2015-06-09 10:08:14 -0500 )edit

if you have a depth map, you have only one value: the depth. If you need 3, use x and y if you are in the image plane.

Mathieu Barnachon gravatar imageMathieu Barnachon ( 2015-06-09 10:09:20 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2015-06-09 07:17:22 -0500

Seen: 524 times

Last updated: Jun 09 '15