Skip to content

Commit 17e70bc

Browse files
committed
Added rendered_image_is_static option.
1 parent 06e2920 commit 17e70bc

File tree

9 files changed

+55
-15
lines changed

9 files changed

+55
-15
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ viewpoint, useful for self-filtering, occlusion detection, and robot awareness a
7272
values to decrease the resolution of the rendered image.
7373
- `~upscaling_interpolation` (string, default: "INTER_LINEAR"): OpenCV interpolation method for upscaling when the
7474
rendered image is smaller than camera info size.
75+
- `~rendered_image_is_static` (bool, default: false): Enable caching of rendered images for identical camera geometry.
76+
When true, subsequent camera infos with identical camera geometry
77+
will reuse the last rendered image without triggering rendering or
78+
TF lookups, but output images will have correct timestamps. Use
79+
this when the visible parts of the robot do not move.
7580

7681
#### Lens Distortion
7782

include/robot_model_renderer/RobotModelRenderer.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct RobotModelRendererConfig
9494
cv::Mat staticMaskImage;
9595
std::string staticMaskImageEncoding; //!< Encoding from sensor_msgs/image_encodings.h . If empty, BGR(A) is assumed.
9696
bool staticMaskIsBackground {true}; //!< If false, the static mask image will be drawn over the rendered image.
97+
bool renderedImageIsStatic {false}; //!< If true, cache rendered images for identical camera geometry.
9798
};
9899

99100
struct RenderErrors
@@ -173,6 +174,8 @@ class RobotModelRenderer : public cras::HasLogger
173174
OgreStaticImage staticImagePass_;
174175

175176
int cvImageType;
177+
178+
cv::Mat cached_image_;
176179
};
177180

178181
}

include/robot_model_renderer/RosCameraRobotModelRenderer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct RosCameraRobotModelRendererConfig
7373

7474
sensor_msgs::Image staticMaskImage;
7575
bool staticMaskIsBackground {true}; //!< If false, the static mask image will be drawn over the rendered image.
76+
bool renderedImageIsStatic {false}; //!< If true, cache rendered images for identical camera geometry.
7677
};
7778

7879
/**

include/robot_model_renderer/c_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct robot_model_renderer_RobotModelRendererConfig
8383
int upscalingInterpolation;
8484
double renderImageScale;
8585
size_t maxRenderImageSize;
86+
bool renderedImageIsStatic;
8687

8788
size_t staticMaskImageWidth;
8889
size_t staticMaskImageHeight;

nodelets/robot_model_renderer_nodelet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ class RobotModelRendererNodelet : public cras::Nodelet
331331
config.upscalingInterpolation = params->getParam("upscaling_interpolation", config.upscalingInterpolation);
332332
config.renderImageScale = params->getParam("render_image_scale", config.renderImageScale);
333333
config.maxRenderImageSize = params->getParam("max_render_image_size", config.maxRenderImageSize, "px (0 = none)");
334+
config.renderedImageIsStatic = params->getParam("rendered_image_is_static", config.renderedImageIsStatic);
334335

335336
const auto staticMaskImageFile = params->getParam("static_mask_image_file", "");
336337
const auto staticMaskImageFileEncoding = params->getParam("static_mask_image_encoding", "");

src/RobotModelRenderer.cpp

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,13 @@ bool RobotModelRenderer::updateCameraInfo(const robot_model_renderer::PinholeCam
334334

335335
CRAS_DEBUG_NAMED("camera_info", "Updating new camera info");
336336

337+
// Invalidate cache if camera geometry changes and static rendering is enabled
338+
if (this->config.renderedImageIsStatic && this->cached_image_.total() > 0)
339+
{
340+
this->cached_image_ = cv::Mat();
341+
CRAS_DEBUG_NAMED("camera_info", "Invalidating cached image due to camera geometry change");
342+
}
343+
337344
const auto prevOrigCamMsg = this->origCameraModel.cameraInfo();
338345
this->origCameraModel = model;
339346

@@ -488,33 +495,47 @@ bool RobotModelRenderer::updateCameraInfo(const robot_model_renderer::PinholeCam
488495

489496
cras::expected<cv::Mat, std::string> RobotModelRenderer::render(const ros::Time& time, RenderErrors& errors)
490497
{
498+
// Check if we can use cached rendering for static images
499+
if (this->config.renderedImageIsStatic && this->cached_image_.total() > 0)
500+
return this->cached_image_.clone();
501+
491502
auto renderResult = this->renderInner(time, errors);
492503
if (!renderResult.has_value())
493504
return renderResult;
494505

495-
if (!this->hasOverlays())
496-
return *renderResult;
506+
cv::Mat finalImage;
497507

498-
cv::Mat overlaidImg(renderResult->rows, renderResult->cols, this->cvImageType);
508+
if (!this->hasOverlays())
509+
{
510+
finalImage = *renderResult;
511+
}
512+
else
499513
{
500-
auto renderedImg = renderResult->isContinuous() ? *renderResult : renderResult->clone();
514+
finalImage = cv::Mat(renderResult->rows, renderResult->cols, this->cvImageType);
515+
{
516+
auto renderedImg = renderResult->isContinuous() ? *renderResult : renderResult->clone();
501517

502-
auto renderLock {render_system_.lock()};
518+
auto renderLock {render_system_.lock()};
503519

504-
// Draw the previously rendered scene onto overlay_scene_tex_ .
505-
{
506-
const Ogre::PixelBox renderPb(renderedImg.cols, renderedImg.rows, 1, this->config.pixelFormat, renderedImg.data);
507-
overlay_scene_tex_->getBuffer()->blitFromMemory(renderPb);
508-
}
520+
// Draw the previously rendered scene onto overlay_scene_tex_ .
521+
{
522+
const Ogre::PixelBox renderPb(renderedImg.cols, renderedImg.rows, 1, this->config.pixelFormat,
523+
renderedImg.data);
524+
overlay_scene_tex_->getBuffer()->blitFromMemory(renderPb);
525+
}
509526

510-
overlay_rt_->update();
527+
overlay_rt_->update();
511528

512-
const Ogre::PixelBox pb(overlay_tex_->getWidth(), overlay_tex_->getHeight(), 1, this->config.pixelFormat,
513-
overlaidImg.data);
514-
overlay_rt_->copyContentsToMemory(pb);
529+
const Ogre::PixelBox pb(overlay_tex_->getWidth(), overlay_tex_->getHeight(), 1, this->config.pixelFormat,
530+
finalImage.data);
531+
overlay_rt_->copyContentsToMemory(pb);
532+
}
515533
}
516534

517-
return overlaidImg;
535+
if (this->config.renderedImageIsStatic)
536+
this->cached_image_ = finalImage.clone();
537+
538+
return finalImage;
518539
}
519540

520541
cras::expected<cv::Mat, std::string> RobotModelRenderer::renderInner(const ros::Time& time, RenderErrors& errors)
@@ -662,6 +683,8 @@ void RobotModelRenderer::reset()
662683
{
663684
Ogre::MaterialManager::getSingleton().remove(overlay_material_->getName());
664685
}
686+
687+
cached_image_ = cv::Mat();
665688
}
666689

667690
}

src/RosCameraRobotModelRenderer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <robot_model_renderer/pinhole_camera.hpp>
2020
#include <robot_model_renderer/RobotModelRenderer.hpp>
2121
#include <robot_model_renderer/RosCameraRobotModelRenderer.hpp>
22+
#include <robot_model_renderer/utils/sensor_msgs.hpp>
2223
#include <robot_model_renderer/utils/sensor_msgs_ogre.hpp>
2324
#include <robot_model_renderer/utils/validate_floats.hpp>
2425
#include <tf2_ros/buffer.h>
@@ -71,6 +72,7 @@ RosCameraRobotModelRenderer::RosCameraRobotModelRenderer(
7172
robotConfig.staticMaskImage = cv_bridge::toCvCopy(config.staticMaskImage)->image;
7273
robotConfig.staticMaskImageEncoding = config.staticMaskImage.encoding;
7374
robotConfig.staticMaskIsBackground = config.staticMaskIsBackground;
75+
robotConfig.renderedImageIsStatic = config.renderedImageIsStatic;
7476

7577
this->linkUpdater = std::make_unique<TFROSLinkUpdater>(this->log, tf, "", "", config.tfTimeout);
7678
this->renderer = std::make_unique<RobotModelRenderer>(this->log, model, this->linkUpdater.get(),

src/c_api.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ inline robot_model_renderer::RobotModelRendererConfig convertConfig(
8383
cpp.upscalingInterpolation = static_cast<cv::InterpolationFlags>(c.upscalingInterpolation);
8484
cpp.renderImageScale = c.renderImageScale;
8585
cpp.maxRenderImageSize = c.maxRenderImageSize;
86+
cpp.renderedImageIsStatic = c.renderedImageIsStatic;
8687

8788
if (c.staticMaskImageWidth > 0 && c.staticMaskImageHeight > 0 && c.staticMaskImage != nullptr)
8889
{
@@ -142,6 +143,7 @@ robot_model_renderer_RobotModelRendererConfig robot_model_renderer_createDefault
142143
c.upscalingInterpolation = cpp.upscalingInterpolation;
143144
c.renderImageScale = cpp.renderImageScale;
144145
c.maxRenderImageSize = cpp.maxRenderImageSize;
146+
c.renderedImageIsStatic = cpp.renderedImageIsStatic;
145147

146148
c.staticMaskImageWidth = 0u;
147149
c.staticMaskImageHeight = 0u;

src/robot_model_renderer/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class _RobotModelRendererConfig(Structure):
179179
("upscalingInterpolation", c_int),
180180
("renderImageScale", c_double),
181181
("maxRenderImageSize", c_size_t),
182+
("renderedImageIsStatic", c_bool),
182183
("staticMaskImageWidth", c_size_t),
183184
("staticMaskImageHeight", c_size_t),
184185
("staticMaskImageStep", c_size_t),
@@ -230,6 +231,7 @@ def __init__(self):
230231
self.upscalingInterpolation = conf.upscalingInterpolation
231232
self.renderImageScale = conf.renderImageScale
232233
self.maxRenderImageSize = conf.maxRenderImageSize
234+
self.renderedImageIsStatic = conf.renderedImageIsStatic
233235
self.staticMaskImage = None # An OpenCV-compatible Numpy array
234236
self.staticMaskImageEncoding = ""
235237
self.staticMaskIsBackground = conf.staticMaskIsBackground

0 commit comments

Comments
 (0)