3 #include <boost/iostreams/filtering_streambuf.hpp>
4 #include <boost/iostreams/copy.hpp>
5 #include <boost/iostreams/filter/gzip.hpp>
6 #include <boost/iostreams/filter/zstd.hpp>
8 #include <cv_bridge/cv_bridge.h>
13 #include <opencv2/core/core.hpp>
14 #include <opencv2/imgcodecs.hpp>
16 #include <ros/console.h>
18 #include <sensor_msgs/distortion_models.h>
32 bool convert(
const cv::Mat& image, sensor_msgs::Image& image_msg)
34 cv_bridge::CvImage image_cv_bridge;
36 if (image.type() == CV_32FC1)
37 image_cv_bridge.encoding =
"32FC1";
38 else if (image.type() == CV_8UC3)
39 image_cv_bridge.encoding =
"bgr8";
43 image_cv_bridge.image = image;
44 image_cv_bridge.toImageMsg(image_msg);
53 sensor_msgs::Image& image_msg,
54 sensor_msgs::CameraInfo& cam_model_msg)
57 int width =
static_cast<int>(cam_model_msg.width);
58 int height =
static_cast<int>(cam_model_msg.height);
60 cv_bridge::CvImage image_cv_bridge;
63 if (image.type() == CV_32FC1)
65 image_cv_bridge.encoding =
"32FC1";
66 img_rect = cv::Mat(height, width, CV_32FC1, cv::Scalar(0.));
68 else if (image.type() == CV_8UC3)
70 image_cv_bridge.encoding =
"bgr8";
71 img_rect = cv::Mat(height, width, CV_8UC3, cv::Scalar(0, 0, 0));
77 cv::Rect crop_rect(0, 0,
std::min(img_rect.cols, image.cols),
std::min(img_rect.rows, image.rows));
78 image(crop_rect).copyTo(img_rect.rowRange(0, crop_rect.height).colRange(0, crop_rect.width));
80 image_cv_bridge.image = img_rect;
81 image_cv_bridge.toImageMsg(image_msg);
93 if (msg->version == 1)
97 image->
rgb_image_ = cv::imdecode(cv::Mat(msg->rgb), cv::IMREAD_UNCHANGED);
101 float depthQuantA =
static_cast<float>(msg->params[0]);
102 float depthQuantB =
static_cast<float>(msg->params[1]);
104 cv::Mat decompressed = cv::imdecode(msg->depth, cv::IMREAD_UNCHANGED);
105 image->
depth_image_ = cv::Mat(decompressed.size(), CV_32FC1);
108 cv::MatIterator_<float> itDepthImg = image->
depth_image_.begin<
float>(),
110 cv::MatConstIterator_<unsigned short> itInvDepthImg = decompressed.begin<
unsigned short>(),
111 itInvDepthImg_end = decompressed.end<
unsigned short>();
113 for (; (itDepthImg != itDepthImg_end) && (itInvDepthImg != itInvDepthImg_end); ++itDepthImg, ++itInvDepthImg)
118 *itDepthImg = depthQuantA / (
static_cast<float>(*itInvDepthImg) - depthQuantB);
126 sensor_msgs::CameraInfo cam_info_msg;
128 cam_info_msg.D.resize(5, 0.0);
129 cam_info_msg.K.fill(0.0);
130 cam_info_msg.K[0] = msg->cam_info[0];
131 cam_info_msg.K[2] = msg->cam_info[2];
132 cam_info_msg.K[4] = msg->cam_info[1];
133 cam_info_msg.K[5] = msg->cam_info[3];
134 cam_info_msg.K[8] = 1.0;
136 cam_info_msg.R.fill(0.0);
137 cam_info_msg.R[0] = 1.0;
138 cam_info_msg.R[4] = 1.0;
139 cam_info_msg.R[8] = 1.0;
141 cam_info_msg.P.fill(0.0);
142 cam_info_msg.P[0] = msg->cam_info[0];
143 cam_info_msg.P[2] = msg->cam_info[2];
144 cam_info_msg.P[3] = msg->cam_info[4];
145 cam_info_msg.P[5] = msg->cam_info[1];
146 cam_info_msg.P[6] = msg->cam_info[3];
147 cam_info_msg.P[7] = msg->cam_info[5];
148 cam_info_msg.P[10] = 1.0;
150 cam_info_msg.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
151 cam_info_msg.width =
static_cast<unsigned int>(image->
rgb_image_.cols);
152 cam_info_msg.height =
static_cast<unsigned int>(image->
rgb_image_.rows);
153 image_geometry::PinholeCameraModel cam_model;
154 cam_model.fromCameraInfo(cam_info_msg);
157 image->
timestamp_ = msg->header.stamp.toSec();
161 else if (msg->version == 2)
168 else if (msg->version == 3)
172 boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
173 in.push(boost::iostreams::gzip_decompressor());
175 boost::iostreams::copy(in, decompressed);
179 else if (msg->version == 4)
183 boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
184 in.push(boost::iostreams::zstd_decompressor());
186 boost::iostreams::copy(in, decompressed);
192 ROS_ERROR_STREAM_NAMED(
"conversions",
"convert: version '" << msg->version <<
"' not supported");