Ask Your Question
2

Trying to publish 16 bit images as ROS msg

asked 2016-06-22 12:01:15 -0500

SpacemanSPIFF gravatar image

Hi all,

I am trying to publish sensor msg from lepton camera connected over SPI. The images that I get from the sensor is 14 bit, I have zero padded it and have it as 16 bit value. I am trying to publish the 16 bit image as sensor::msgs Image, but the the image message type can hold only 8 bit of data as the data type is uint8[] data (I used the encoding mono16). Then I tried with opencv Mat and cv_bridge, the relevant code is

cv::Mat image_holder(IR_img.height,IR_img.width, CV_16UC1);
for(int i=(NO_BITS_SKIP+1); i<FRAME_SIZE_UINT16;i++)
        {
            if(i % PACKET_SIZE_UINT16 < 2)
                continue;
            image_holder.at<uchar>(ii,jj)=(unsigned char)init_buf[i];
            jj++;
            if(jj==80)
            {
                jj=0;
                ii++;
            }
            if(ii==60)
            {
                ii=0;
            }
        }

where init_buf is a 16bit pointer to the data. When i assign the values into the matrix, its ignoring the 2nd byte and considers only 1st byte. and surprisingly the size of the image is half the size.

This is the 8bit image (successfully published)

image description

16bit image I am having problems with

image description

I am not sure where i am going wrong. Is there a tutorial I can refer to for publishing 16 bit grayscale images? Any help is greatly appreciated..

I am using ROS indigo and opencv 2.4.8

Thanks

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2016-06-23 14:34:59 -0500

uwleahcim gravatar image

Use cv_bridge and make sure to set the encoding to 16-bit

For example

cv_bridge::CvImage img16;
// copy raw image into img16.image
img16.encoding = sensor_msgs::image_encodings::MONO16;
// img16.header
image_pub.publish(img16);

Just remember to convert it into a 8-bit before displaying it.

image_callback(const snesor_msgs::ImageConstPtr& img)
{
    cv_bridge::CvImagePtr cv_ptr;
    cv_ptr = cv_bridge::toCvCopy(img, sensor_msgs::image_encodings::MONO16);  
    cv::Mat img8(HEIGHT, WIDTH, CV_8UC1);
    cv_ptr->image.convertTo(img8, CV_8UC1);
    cv::imshow("8-bit Mono", img8);  
    cv::waitKey(1);
}
edit flag offensive delete link more

Comments

Thanks. Tat was pretty much wat I was trying to do, jus realized tat , the prob was my type cast, as uchar ignored the 2nd byte. wen I used ushort it solved the issue. I was just curious why we cannot view it as a 16 bit image? wen i rostopic echo it displays 8bit values. -Thank You

SpacemanSPIFF gravatar image SpacemanSPIFF  ( 2016-06-27 15:22:06 -0500 )edit

Great answer. Please be aware of the type of 16 bit to 8 bit conversion you want to accomplish. The above convertTo() only takes into account the first 8 bit and everything above is set to 255. This OpenCV asnwer sums up pretty well the different type of conversions.

pemo gravatar image pemo  ( 2020-02-28 03:19:11 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2016-06-22 12:01:15 -0500

Seen: 1,793 times

Last updated: Jun 23 '16