0
$\begingroup$

Rosanswers logo

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


Originally posted by SpacemanSPIFF on ROS Answers with karma: 78 on 2016-06-22

Post score: 2

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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);
}

Originally posted by uwleahcim with karma: 101 on 2016-06-23

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by SpacemanSPIFF on 2016-06-27:
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

Comment by pemo on 2020-02-28:
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.

$\endgroup$

Your Answer

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