Read image in main loop instead of imageCallback ?

asked 2019-02-28 15:23:44 -0500

pepethegiant gravatar image

updated 2019-03-01 03:38:37 -0500

Hello newbie here,

I am writing an application where I subscribe to an image topic. I followed this tutorial: http://wiki.ros.org/image_transport/T... . It's a great tutorial but it uses a callback function for processing the image. Because I need the image in my main loop, Is it possible to read the image in main? Because when I run my program I only get in the callback function and not the main code below the subscribe function.

   6 void imageCallback(const sensor_msgs::ImageConstPtr& msg)
   7 {
   8   try
   9   {
  10     cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
  11     cv::waitKey(30);
  12   }
  13   catch (cv_bridge::Exception& e)
  14   {
  15     ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
  16   }
  17 }
  18 
  19 int main(int argc, char **argv)
  20 {
  21   ros::init(argc, argv, "image_listener");
  22   ros::NodeHandle nh;
  23   cv::namedWindow("view");
  24   cv::startWindowThread();
  25   image_transport::ImageTransport it(nh);
  26   image_transport::Subscriber sub = it.subscribe("camera/image", 1, imageCallback);
  27   ros::spin();
  28   cv::destroyWindow("view");

         HERE'S SOME CODE THAT USES THE IMAGE DATA FOR PROCESSING (FOR EXAMPLE OPENCV FUNCTIONS)


  29 }

edit retag flag offensive close merge delete

Comments

Can you please update your question with a copy and paste of what you've done so far (the code)? This will help people to answer question, I believe.

jayess gravatar image jayess  ( 2019-02-28 18:45:11 -0500 )edit

Hello jayess, I've put in the example code of the tutorial and the place where I want to put my code. Thank you for the fast response

pepethegiant gravatar image pepethegiant  ( 2019-03-01 03:39:39 -0500 )edit

Hi, probably you need to define cv image as a global variable then inside the callback function: convert the coming message to cv image using the cv_bridge and then assign it to the global image variable, inside your main you can use the global variable.

mali gravatar image mali  ( 2019-03-01 04:19:56 -0500 )edit

Yes I am trying to, but it seems like the application stays in the imagecallback and never returns to main. For now I just have an imshow and waitkey in the callback and print to console in the main.

pepethegiant gravatar image pepethegiant  ( 2019-03-01 04:45:39 -0500 )edit
1

it seems like the application stays in the imagecallback and never returns to main.

Well the waitkey() would certainly do that.

gvdhoorn gravatar image gvdhoorn  ( 2019-03-01 04:54:13 -0500 )edit

I've removed the waitkey, but it still stays in the callback function. Maybe is there something with the ros::spin() that I am doing wrong? I've also tried with a ros::topic::waitForMessage<sensor_msgs::image>, but the video isn't smooth then.

pepethegiant gravatar image pepethegiant  ( 2019-03-01 05:17:02 -0500 )edit
1

It shouldn't stay in the callback function. But the ros::spin(); will block until you close your node, so any code after that line will only be executed as your node is shutting down. You will need a loop containing ros::spinOnce(); in main instead.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2019-03-01 06:08:44 -0500 )edit

The ros::spinOnce(); works! thank you very much!

pepethegiant gravatar image pepethegiant  ( 2019-03-01 06:18:12 -0500 )edit