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{
@@ -177,6 +145,9 @@ ImageViewNode::ImageViewNode(const rclcpp::NodeOptions & options)
177145
178146ImageViewNode::~ImageViewNode ()
179147{
148+ image_mutex_.unlock ();
149+ new_data_mutex_.unlock ();
150+
180151 if (window_thread_.joinable ()) {
181152 window_thread_.join ();
182153 }
@@ -231,9 +202,10 @@ void ImageViewNode::imageCb(const sensor_msgs::msg::Image::ConstSharedPtr & msg)
231202 encoding = " bgr8" ;
232203 }
233204
234- queued_image_.set (
235- cv_bridge::cvtColorForDisplay (
236- cv_bridge::toCvShare (msg), encoding, options));
205+ image_mutex_.lock ();
206+ queued_image_ = cv_bridge::cvtColorForDisplay (cv_bridge::toCvShare (msg), encoding, options);
207+ image_mutex_.unlock ();
208+ new_data_mutex_.unlock ();
237209 } catch (cv_bridge::Exception & e) {
238210 RCLCPP_ERROR_EXPRESSION (
239211 this ->get_logger (), (static_cast <int >(this ->now ().seconds ()) % 30 == 0 ),
@@ -261,16 +233,23 @@ void ImageViewNode::mouseCb(int event, int /* x */, int /* y */, int /* flags */
261233 return ;
262234 }
263235
264- cv_bridge::CvImageConstPtr image (this_->shown_image_ . get () );
236+ const std::string filename = string_format (this_->filename_format_ , this_-> count_ );
265237
266- if (!image) {
238+ this_->image_mutex_ .lock ();
239+
240+ if (!this_->shown_image_ ) {
241+ this_->image_mutex_ .unlock ();
267242 RCLCPP_WARN (this_->get_logger (), " Couldn't save image, no data!" );
268243 return ;
269244 }
270245
271- std::string filename = string_format (this_->filename_format_ , this_->count_ );
246+ const cv::Mat image = this_->shown_image_ ->image ;
247+
248+ this_->image_mutex_ .unlock ();
249+
250+ const bool suc = cv::imwrite (filename, image);
272251
273- if (cv::imwrite (filename, image-> image ) ) {
252+ if (suc ) {
274253 RCLCPP_INFO (this_->get_logger (), " Saved image %s" , filename.c_str ());
275254 this_->count_ ++;
276255 } else {
@@ -291,19 +270,20 @@ void ImageViewNode::windowThread()
291270 }
292271
293272 while (rclcpp::ok ()) {
294- cv_bridge::CvImageConstPtr image (queued_image_.pop ());
295-
296273 if (cv::getWindowProperty (window_name_, 1 ) < 0 ) {
297274 break ;
298275 }
299276
300- if (image) {
301- cv::imshow (window_name_, image->image );
302- shown_image_.set (image);
303- cv::waitKey (1 );
304- } else {
305- rclcpp::sleep_for (std::chrono::milliseconds (20 ));
277+ // wait for new image data
278+ new_data_mutex_.lock ();
279+
280+ image_mutex_.lock ();
281+ if (queued_image_) {
282+ cv::imshow (window_name_, queued_image_->image );
283+ shown_image_ = queued_image_;
306284 }
285+ image_mutex_.unlock ();
286+ cv::waitKey (1 );
307287 }
308288
309289 cv::destroyAllWindows ();
0 commit comments