7070namespace image_view
7171{
7272
73- void ThreadSafeImage::set (cv_bridge::CvImageConstPtr image)
74- {
75- std::lock_guard<std::mutex> lock (mutex_);
76- image_ = image;
77- condition_.notify_one ();
78- }
79-
80- cv_bridge::CvImageConstPtr ThreadSafeImage::get ()
81- {
82- std::lock_guard<std::mutex> lock (mutex_);
83- return image_;
84- }
85-
86- cv_bridge::CvImageConstPtr ThreadSafeImage::pop ()
87- {
88- cv_bridge::CvImageConstPtr image;
89-
90- {
91- std::unique_lock<std::mutex> lock (mutex_);
92-
93- condition_.wait_for (
94- lock, std::chrono::milliseconds (100 ),
95- [this ] {
96- return !image_;
97- });
98-
99- image = std::move (image_);
100- }
101-
102- return image;
103- }
104-
10573ImageViewNode::ImageViewNode (const rclcpp::NodeOptions & options)
10674: rclcpp::Node(" image_view_node" , options)
10775{
@@ -180,6 +148,9 @@ ImageViewNode::ImageViewNode(const rclcpp::NodeOptions & options)
180148
181149ImageViewNode::~ImageViewNode ()
182150{
151+ image_mutex_.unlock ();
152+ new_data_available_.release ();
153+
183154 if (window_thread_.joinable ()) {
184155 window_thread_.join ();
185156 }
@@ -234,9 +205,10 @@ void ImageViewNode::imageCb(const sensor_msgs::msg::Image::ConstSharedPtr & msg)
234205 encoding = " bgr8" ;
235206 }
236207
237- queued_image_.set (
238- cv_bridge::cvtColorForDisplay (
239- cv_bridge::toCvShare (msg), encoding, options));
208+ image_mutex_.lock ();
209+ queued_image_ = cv_bridge::cvtColorForDisplay (cv_bridge::toCvShare (msg), encoding, options);
210+ image_mutex_.unlock ();
211+ new_data_available_.release ();
240212 } catch (cv_bridge::Exception & e) {
241213 RCLCPP_ERROR_EXPRESSION (
242214 this ->get_logger (), (static_cast <int >(this ->now ().seconds ()) % 30 == 0 ),
@@ -264,16 +236,23 @@ void ImageViewNode::mouseCb(int event, int /* x */, int /* y */, int /* flags */
264236 return ;
265237 }
266238
267- cv_bridge::CvImageConstPtr image (this_->shown_image_ . get () );
239+ const std::string filename = string_format (this_->filename_format_ , this_-> count_ );
268240
269- if (!image) {
241+ this_->image_mutex_ .lock ();
242+
243+ if (!this_->shown_image_ ) {
244+ this_->image_mutex_ .unlock ();
270245 RCLCPP_WARN (this_->get_logger (), " Couldn't save image, no data!" );
271246 return ;
272247 }
273248
274- std::string filename = string_format (this_->filename_format_ , this_->count_ );
249+ const cv::Mat image = this_->shown_image_ ->image ;
250+
251+ this_->image_mutex_ .unlock ();
252+
253+ const bool suc = cv::imwrite (filename, image);
275254
276- if (cv::imwrite (filename, image-> image ) ) {
255+ if (suc ) {
277256 RCLCPP_INFO (this_->get_logger (), " Saved image %s" , filename.c_str ());
278257 this_->count_ ++;
279258 } else {
@@ -294,19 +273,20 @@ void ImageViewNode::windowThread()
294273 }
295274
296275 while (rclcpp::ok ()) {
297- cv_bridge::CvImageConstPtr image (queued_image_.pop ());
298-
299276 if (cv::getWindowProperty (window_name_, 1 ) < 0 ) {
300277 break ;
301278 }
302279
303- if (image) {
304- cv::imshow (window_name_, image->image );
305- shown_image_.set (image);
306- cv::waitKey (1 );
307- } else {
308- rclcpp::sleep_for (std::chrono::milliseconds (20 ));
280+ // wait for new image data;
281+ new_data_available_.acquire ();
282+
283+ image_mutex_.lock ();
284+ if (queued_image_) {
285+ cv::imshow (window_name_, queued_image_->image );
286+ shown_image_ = queued_image_;
309287 }
288+ image_mutex_.unlock ();
289+ cv::waitKey (1 );
310290 }
311291
312292 cv::destroyAllWindows ();
0 commit comments