Skip to content

Commit dc082be

Browse files
committed
Added support for adding static image underlay of overlay.
1 parent 349d561 commit dc082be

20 files changed

+1103
-20
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ add_library(${PROJECT_NAME}_distortion
148148
src/compositors/OgreCameraDistortion.cc
149149
src/compositors/OgreInvertColors.cc
150150
src/compositors/OgreOutline.cc
151+
src/compositors/OgreStaticImage.cc
151152
)
152153
target_link_libraries(${PROJECT_NAME}_distortion PUBLIC
153154
${catkin_LIBRARIES} OPENCV OGRE Eigen3::Eigen

include/robot_model_renderer/RobotModelRenderer.hpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
#include <robot_model_renderer/compositors/OgreCameraDistortion.hpp>
2727
#include <robot_model_renderer/compositors/OgreInvertColors.hpp>
2828
#include <robot_model_renderer/compositors/OgreOutline.hpp>
29+
#include <robot_model_renderer/compositors/OgreStaticImage.hpp>
2930
#include <robot_model_renderer/pinhole_camera.hpp>
3031
#include <robot_model_renderer/ogre_helpers/render_system.hpp>
3132
#include <robot_model_renderer/robot/link_updater.hpp>
3233
#include <robot_model_renderer/robot/robot.hpp>
3334
#include <robot_model_renderer/robot/shape_filter.hpp>
3435
#include <robot_model_renderer/robot/shape_inflation_registry.hpp>
36+
#include <robot_model_renderer/types.hpp>
3537
#include <urdf/model.h>
3638

3739
namespace Ogre
@@ -49,16 +51,6 @@ class Camera;
4951
namespace robot_model_renderer
5052
{
5153

52-
/**
53-
* \brief Mode of robot model rendering.
54-
*/
55-
enum class RenderingMode
56-
{
57-
NORMAL, //!< Normal mode, visual meshes use their textures, collision meshes use red or link color.
58-
COLOR, //!< All meshes are rendered with the specified color (with lighting effects).
59-
MASK, //!< All meshes are rendered as a binary mask (robot = white, background = black).
60-
};
61-
6254
/**
6355
* \brief Configuration of RobotModelRenderer.
6456
*/
@@ -95,6 +87,10 @@ struct RobotModelRendererConfig
9587
cv::InterpolationFlags upscalingInterpolation {cv::INTER_LINEAR};
9688
double renderImageScale {1.0};
9789
size_t maxRenderImageSize {0u};
90+
91+
cv::Mat staticMaskImage;
92+
std::string staticMaskImageEncoding; //!< Encoding from sensor_msgs/image_encodings.h . If empty, BGR(A) is assumed.
93+
bool staticMaskIsBackground {true}; //!< If false, the static mask image will be drawn over the rendered image.
9894
};
9995

10096
struct RenderErrors
@@ -130,6 +126,9 @@ class RobotModelRenderer : public cras::HasLogger
130126

131127
protected:
132128
virtual void updateOgreCamera();
129+
virtual cras::expected<cv::Mat, std::string> renderInner(const ros::Time& time, RenderErrors& errors);
130+
131+
virtual bool hasOverlays() const;
133132

134133
LinkUpdater* linkUpdater;
135134

@@ -148,13 +147,27 @@ class RobotModelRenderer : public cras::HasLogger
148147
Ogre::SceneManager* scene_manager_ {nullptr};
149148
Ogre::Light* default_light_ {nullptr};
150149
Ogre::SceneNode* scene_node_ {nullptr};
150+
151151
Ogre::TexturePtr tex_;
152152
Ogre::RenderTarget* rt_ {nullptr};
153153
Ogre::Camera* camera_ {nullptr};
154154
Ogre::Viewport* viewPort_ {nullptr};
155+
155156
OgreCameraDistortion distortionPass_;
156157
OgreInvertColors invertColorsPass_;
157158
OgreOutline outlinePass_;
159+
160+
Ogre::SceneManager* overlay_scene_manager_ {nullptr};
161+
Ogre::SceneNode* overlay_scene_node_ {nullptr};
162+
Ogre::SharedPtr<Ogre::Rectangle2D> overlay_;
163+
Ogre::TexturePtr overlay_tex_;
164+
Ogre::TexturePtr overlay_scene_tex_;
165+
Ogre::RenderTarget* overlay_rt_ {nullptr};
166+
Ogre::Camera* overlay_camera_ {nullptr};
167+
Ogre::Viewport* overlay_viewPort_ {nullptr};
168+
169+
OgreStaticImage staticImagePass_;
170+
158171
int cvImageType;
159172
};
160173

include/robot_model_renderer/RosCameraRobotModelRenderer.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ struct RosCameraRobotModelRendererConfig
7070
cv::InterpolationFlags upscalingInterpolation {cv::INTER_LINEAR};
7171
double renderImageScale {1.0};
7272
size_t maxRenderImageSize {0u};
73+
74+
sensor_msgs::Image staticMaskImage;
75+
bool staticMaskIsBackground {true}; //!< If false, the static mask image will be drawn over the rendered image.
7376
};
7477

7578
/**

include/robot_model_renderer/c_api.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ struct robot_model_renderer_RobotModelRendererConfig
8383
int upscalingInterpolation;
8484
double renderImageScale;
8585
size_t maxRenderImageSize;
86+
87+
size_t staticMaskImageWidth;
88+
size_t staticMaskImageHeight;
89+
size_t staticMaskImageStep;
90+
int staticMaskImageCVType;
91+
void* staticMaskImage;
92+
const char* staticMaskImageEncoding; //!< Encoding from sensor_msgs/image_encodings.h . If empty, BGR(A) is assumed.
93+
bool staticMaskIsBackground; //!< If false, the static mask image will be drawn over the rendered image.
8694
};
8795

8896
struct ros_Time
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// SPDX-FileCopyrightText: Czech Technical University in Prague
3+
4+
#pragma once
5+
6+
/**
7+
* \file
8+
* \brief OGRE compositor drawing a static image under or over the scene.
9+
* \author Martin Pecka
10+
*/
11+
12+
#include <memory>
13+
14+
#include <opencv2/core/mat.hpp>
15+
16+
#include <OgrePixelFormat.h>
17+
18+
#include <cras_cpp_common/log_utils.h>
19+
20+
#include <robot_model_renderer/types.hpp>
21+
22+
namespace Ogre
23+
{
24+
25+
class Camera;
26+
27+
}
28+
29+
namespace robot_model_renderer
30+
{
31+
32+
/**
33+
* \brief Ogre implementation static image compositor.
34+
*/
35+
class OgreStaticImage : public cras::HasLogger
36+
{
37+
public:
38+
OgreStaticImage(const cras::LogHelperPtr& log, const cv::Mat& staticImage, Ogre::PixelFormat staticImageFormat,
39+
Ogre::PixelFormat sceneFormat, bool staticImageIsBackground, RenderingMode renderingMode,
40+
const Ogre::ColourValue& colorModeColor);
41+
42+
virtual ~OgreStaticImage();
43+
44+
/**
45+
* \brief Destroy the pass and unregister it where needed.
46+
*/
47+
void Destroy();
48+
49+
/**
50+
* \brief Create the render pass.
51+
*/
52+
void CreateRenderPass();
53+
54+
/**
55+
* \brief Set the ogre camera that the render pass applies to
56+
*
57+
* \param[in] camera Pointer to the ogre camera.
58+
*/
59+
virtual void SetCamera(Ogre::Camera* camera);
60+
61+
protected:
62+
Ogre::Camera* ogreCamera = nullptr; //!< Pointer to the ogre camera
63+
64+
struct Implementation;
65+
std::unique_ptr<Implementation> dataPtr; //!< PIMPL data
66+
};
67+
68+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// SPDX-FileCopyrightText: Czech Technical University in Prague
3+
4+
#pragma once
5+
6+
/**
7+
* \file
8+
* \brief Common types.
9+
* \author Martin Pecka
10+
*/
11+
12+
13+
namespace robot_model_renderer
14+
{
15+
16+
/**
17+
* \brief Mode of robot model rendering.
18+
*/
19+
enum class RenderingMode
20+
{
21+
NORMAL, //!< Normal mode, visual meshes use their textures, collision meshes use red or link color.
22+
COLOR, //!< All meshes are rendered with the specified color (with lighting effects).
23+
MASK, //!< All meshes are rendered as a binary mask (robot = white, background = black).
24+
};
25+
26+
}

nodelets/robot_model_renderer_nodelet.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@
1414
#include <thread>
1515
#include <vector>
1616

17+
#include <opencv2/imgcodecs.hpp>
18+
1719
#include <urdf/model.h>
1820

1921
#include <cras_cpp_common/nodelet_utils.hpp>
2022
#include <cras_cpp_common/param_utils.hpp>
23+
#include <cras_cpp_common/string_utils.hpp>
24+
#include <cv_bridge/cv_bridge.h>
2125
#include <image_transport/image_transport.h>
2226
#include <pluginlib/class_list_macros.h>
2327
#include <nodelet/nodelet.h>
@@ -203,6 +207,41 @@ class RobotModelRendererNodelet : public cras::Nodelet
203207
}
204208
}
205209

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+
206245
void onInitialize()
207246
{
208247
const auto& publicParams = this->publicParams();
@@ -258,6 +297,8 @@ class RobotModelRendererNodelet : public cras::Nodelet
258297

259298
RosCameraRobotModelRendererConfig config;
260299

300+
cras::TempLocale l(LC_ALL, "en_US.UTF-8");
301+
261302
config.renderingMode = params->getParam("rendering_mode", config.renderingMode);
262303

263304
if (config.renderingMode == RenderingMode::MASK)
@@ -291,6 +332,20 @@ class RobotModelRendererNodelet : public cras::Nodelet
291332
config.renderImageScale = params->getParam("render_image_scale", config.renderImageScale);
292333
config.maxRenderImageSize = params->getParam("max_render_image_size", config.maxRenderImageSize, "px (0 = none)");
293334

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+
294349
const auto inflationPadding = params->getParamVerbose("body_model/inflation/padding", 0.0, "m");
295350
const auto inflationScale = params->getParamVerbose("body_model/inflation/scale", 1.0);
296351
config.shapeInflationRegistry = std::make_shared<ShapeInflationRegistry>(inflationScale, inflationPadding);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// SPDX-FileCopyrightText: Czech Technical University in Prague
3+
4+
uniform sampler2D rt_scene; // The RTT from the compositor
5+
uniform sampler2D static_image; // The RTT from the compositor
6+
uniform sampler2D orig_static_image; // The RTT from the compositor
7+
uniform int is_background;
8+
uniform vec4 background_color;
9+
uniform int rendering_mode;
10+
uniform vec4 color_mode_color;
11+
12+
const int RM_NORMAL = 0;
13+
const int RM_COLOR = 1;
14+
const int RM_MASK = 2;
15+
16+
float length(vec4 vec)
17+
{
18+
return sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z + vec.w * vec.w);
19+
}
20+
21+
void main()
22+
{
23+
vec2 uv = gl_TexCoord[0].xy;
24+
vec4 scene_color = texture2D(rt_scene, uv);
25+
vec4 static_color = texture2D(static_image, uv);
26+
vec4 orig_static_color = texture2D(orig_static_image, uv);
27+
28+
vec4 final_static_color;
29+
if (rendering_mode == RM_NORMAL)
30+
final_static_color = static_color;
31+
else if (rendering_mode == RM_COLOR)
32+
final_static_color = color_mode_color;
33+
else if (rendering_mode == RM_MASK)
34+
final_static_color = vec4(1.0, 1.0, 1.0, 1.0);
35+
36+
if (is_background == 0)
37+
{
38+
if (orig_static_color.a < 0.5 || orig_static_color == background_color)
39+
gl_FragColor = scene_color;
40+
else
41+
gl_FragColor = final_static_color;
42+
}
43+
else
44+
{
45+
if (scene_color.a < 0.5)
46+
gl_FragColor = final_static_color;
47+
else
48+
gl_FragColor = scene_color;
49+
}
50+
}

ogre_media/materials/scripts/outline.compositor

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ compositor Outline
55
{
66
technique
77
{
8-
texture rt0 target_width_scaled 0.25 target_height_scaled 0.25 PF_R8G8B8A8
9-
texture blurred target_width_scaled 0.25 target_height_scaled 0.25 PF_R8G8B8A8
10-
texture rt_scene target_width target_height PF_R8G8B8A8
8+
texture rt0 target_width_scaled 0.25 target_height_scaled 0.25 PF_A8R8G8B8
9+
texture blurred target_width_scaled 0.25 target_height_scaled 0.25 PF_A8R8G8B8
10+
texture rt_scene target_width target_height PF_A8R8G8B8
1111

1212
// Pass 1: Render the scene to our temporary texture.
1313
target rt_scene
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// SPDX-FileCopyrightText: Czech Technical University in Prague
3+
4+
compositor StaticImage
5+
{
6+
technique
7+
{
8+
texture rt_scene target_width target_height PF_A8R8G8B8
9+
10+
target rt_scene
11+
{
12+
input previous
13+
}
14+
15+
target_output
16+
{
17+
input none
18+
19+
pass render_quad
20+
{
21+
material StaticImageMat
22+
input 0 rt_scene
23+
}
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)