0
$\begingroup$

Rosanswers logo

Hi

I am Using opencv 2.2 and cv::bridge out of the ros diamondback deb packages. I changed the Makefile of opencv to get a newer version of opencv (Revision 5427)

I convert the const sensor_msgs::ImageConstPt to cv_bridge::CvImagePtr with

cv_ptr_depth_ = cv_bridge::toCvCopy(depth_image_msgs, sensor_msgs::image_encodings::TYPE_32FC1);

With cv::VideoWriter I want to store the depth image as an avi file. That works fine for the rgb image that is converted to sensor_msgs::image_encodings::BGR8 but not for the depth image. The cv::VideoWriter needs images with depth = IPL_DEPTH_8U and nChannels = 1.

But I cannot convert the 32FC1 type in 8UC1

How can I handle this problem?

Thanks Stefan


Originally posted by Stefan on ROS Answers with karma: 90 on 2011-06-10

Post score: 0

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

Hi Stefan,

There might be a more direct answer to your question, but Mike Ferguson has a depth_viewer ROS package that does the conversion I think you need. Check it out at http://www.ros.org/wiki/depth_viewer.

--patrick


Originally posted by Pi Robot with karma: 4046 on 2011-06-10

This answer was ACCEPTED on the original site

Post score: 0

$\endgroup$
0
$\begingroup$

Rosanswers logo

First up is understanding the format of the message. It is indeed a 32FC1 -- meaning it is a 32-bit float. This float corresponds to depth in meters (which concurs with ROS standards).

If you then need to convert to an 8UC1 image, you can scale the 32-bit float into the min->max range (something like 0.0 or 0.5m to 5.5m):

    cv::Mat img(cv_ptr_depth_->image.rows, cv_ptr_depth_->image.cols, CV_8UC1);
    for(int i = 0; i < cv_ptr_depth_->image.rows; i++)
    {
        float* Di = cv_ptr_depth_->image.ptr<float>(i);
        char* Ii = img.ptr<char>(i);
        for(int j = 0; j < cv_ptr_depth_->image.cols; j++)
        {   
            Ii[j] = (char) (255*((Di[j]-min_range_)/(max_range_-min_range_)));
        }   
    }

Where min_range_ and max_range_ would be floats, set to your min and max range. This also means you'll be able to actually view data with the human eye (the float32 representation generally just looks black, since the numbers are all fairly small).

This same block of code does show up in the depth_viewer I wrote, as Patrick mentioned.


Originally posted by fergs with karma: 13902 on 2011-06-10

This answer was NOT ACCEPTED on the original site

Post score: 9


Original comments

Comment by domikilo on 2014-02-28:
I think we can use this code , it is more efficient than the above code double minVal, maxVal; minMaxLoc(cv_ptr->image, &minVal, &maxVal); //find minimum and maximum intensities //Mat draw; cv_ptr->image.convertTo(blur_img, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal));

Comment by dash95 on 2016-06-17:
I want disparity in pixels .... Can you suggest how can I modify your code accordingly :) Thanks in advance :)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.