|
14 | 14 | #include <thread> |
15 | 15 | #include <vector> |
16 | 16 |
|
| 17 | +#include <opencv2/imgcodecs.hpp> |
| 18 | + |
17 | 19 | #include <urdf/model.h> |
18 | 20 |
|
19 | 21 | #include <cras_cpp_common/nodelet_utils.hpp> |
20 | 22 | #include <cras_cpp_common/param_utils.hpp> |
| 23 | +#include <cras_cpp_common/string_utils.hpp> |
| 24 | +#include <cv_bridge/cv_bridge.h> |
21 | 25 | #include <image_transport/image_transport.h> |
22 | 26 | #include <pluginlib/class_list_macros.h> |
23 | 27 | #include <nodelet/nodelet.h> |
@@ -203,6 +207,41 @@ class RobotModelRendererNodelet : public cras::Nodelet |
203 | 207 | } |
204 | 208 | } |
205 | 209 |
|
| 210 | + std::string bestImageEncodingFromCvMat(const cv::Mat staticMaskImage) |
| 211 | + { |
| 212 | + const auto nchannels = staticMaskImage.channels(); |
| 213 | + const auto depth = staticMaskImage.depth(); |
| 214 | + if (depth == CV_8U && nchannels == 1) |
| 215 | + return sensor_msgs::image_encodings::MONO8; |
| 216 | + else if (depth == CV_8U && nchannels == 3) |
| 217 | + return sensor_msgs::image_encodings::BGR8; // OpenCV always loads in BGR order |
| 218 | + else if (depth == CV_8U && nchannels == 4) |
| 219 | + return sensor_msgs::image_encodings::BGRA8; // OpenCV always loads in BGR order |
| 220 | + else if (depth == CV_16U && nchannels == 1) |
| 221 | + return sensor_msgs::image_encodings::MONO16; |
| 222 | + else if (depth == CV_16U && nchannels == 3) |
| 223 | + return sensor_msgs::image_encodings::BGR16; // OpenCV always loads in BGR order |
| 224 | + else if (depth == CV_16U && nchannels == 4) |
| 225 | + return sensor_msgs::image_encodings::BGRA16; // OpenCV always loads in BGR order |
| 226 | + else if (depth == CV_32F && nchannels == 1) |
| 227 | + return sensor_msgs::image_encodings::TYPE_32FC1; |
| 228 | + else if (depth == CV_32F && nchannels == 2) |
| 229 | + return sensor_msgs::image_encodings::TYPE_32FC2; |
| 230 | + else if (depth == CV_32F && nchannels == 3) |
| 231 | + return sensor_msgs::image_encodings::TYPE_32FC3; |
| 232 | + else if (depth == CV_32F && nchannels == 4) |
| 233 | + return sensor_msgs::image_encodings::TYPE_32FC4; |
| 234 | + else if (depth == CV_64F && nchannels == 1) |
| 235 | + return sensor_msgs::image_encodings::TYPE_64FC1; |
| 236 | + else if (depth == CV_64F && nchannels == 2) |
| 237 | + return sensor_msgs::image_encodings::TYPE_64FC2; |
| 238 | + else if (depth == CV_64F && nchannels == 3) |
| 239 | + return sensor_msgs::image_encodings::TYPE_64FC3; |
| 240 | + else if (depth == CV_64F && nchannels == 4) |
| 241 | + return sensor_msgs::image_encodings::TYPE_64FC4; |
| 242 | + return ""; |
| 243 | + } |
| 244 | + |
206 | 245 | void onInitialize() |
207 | 246 | { |
208 | 247 | const auto& publicParams = this->publicParams(); |
@@ -258,6 +297,8 @@ class RobotModelRendererNodelet : public cras::Nodelet |
258 | 297 |
|
259 | 298 | RosCameraRobotModelRendererConfig config; |
260 | 299 |
|
| 300 | + cras::TempLocale l(LC_ALL, "en_US.UTF-8"); |
| 301 | + |
261 | 302 | config.renderingMode = params->getParam("rendering_mode", config.renderingMode); |
262 | 303 |
|
263 | 304 | if (config.renderingMode == RenderingMode::MASK) |
@@ -291,6 +332,20 @@ class RobotModelRendererNodelet : public cras::Nodelet |
291 | 332 | config.renderImageScale = params->getParam("render_image_scale", config.renderImageScale); |
292 | 333 | config.maxRenderImageSize = params->getParam("max_render_image_size", config.maxRenderImageSize, "px (0 = none)"); |
293 | 334 |
|
| 335 | + const auto staticMaskImageFile = params->getParam("static_mask_image_file", ""); |
| 336 | + const auto staticMaskImageFileEncoding = params->getParam("static_mask_image_encoding", ""); |
| 337 | + config.staticMaskIsBackground = params->getParam("static_mask_is_background", config.staticMaskIsBackground); |
| 338 | + |
| 339 | + const auto staticMaskImage = cv::imread(staticMaskImageFile, cv::IMREAD_UNCHANGED); |
| 340 | + if (staticMaskImage.total() > 0) |
| 341 | + { |
| 342 | + auto encoding = staticMaskImageFileEncoding; |
| 343 | + if (encoding.empty()) |
| 344 | + encoding = bestImageEncodingFromCvMat(staticMaskImage); |
| 345 | + cv_bridge::CvImage maskImage({}, encoding, staticMaskImage); |
| 346 | + config.staticMaskImage = *maskImage.toImageMsg(); |
| 347 | + } |
| 348 | + |
294 | 349 | const auto inflationPadding = params->getParamVerbose("body_model/inflation/padding", 0.0, "m"); |
295 | 350 | const auto inflationScale = params->getParamVerbose("body_model/inflation/scale", 1.0); |
296 | 351 | config.shapeInflationRegistry = std::make_shared<ShapeInflationRegistry>(inflationScale, inflationPadding); |
|
0 commit comments