skip to Main Content

I’m currently using Ubuntu 20.04, ROS2-foxy
what I’m trying to do is publish webcam image with using cv2, cv_bridge and subscribe it.
I successfully publish and subscribe the webcam but not in real-time.
publish node is publishing webcam every two seconds. which means publishing image like delayed image.
I tried to search and fix the problem but and can’t make it so I need some help.
I will post my publisher and subscriber code down here.

This is publisher code.

#include <chrono>
#include <memory>
#include "cv_bridge/cv_bridge.h"
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
#include "std_msgs/msg/header.hpp"
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <opencv2/core/types.hpp>
#include <opencv2/core/hal/interface.h>
#include <image_transport/image_transport.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std::chrono_literals;
using namespace cv;

class MinimalPublisher : public rclcpp::Node {

public:

MinimalPublisher() : Node("minimal_publisher"), count_(0) {

    auto qos_profile = rclcpp::QoS(rclcpp::KeepLast(10));
    publisher_ = this->create_publisher<sensor_msgs::msg::Image>("topic", qos_profile);
    timer_ = this->create_wall_timer(10ms, std::bind(&MinimalPublisher::timer_callback, this));

}

private:

void timer_callback() {

    cv_bridge::CvImagePtr cv_ptr;
    cv::VideoCapture cap(0);
    cv::Mat img(cv::Size(1280, 720), CV_8UC3);
    cap >> img;
    sensor_msgs::msg::Image::SharedPtr msg = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", img).toImageMsg();      
    publisher_->publish(*msg);
    RCLCPP_INFO(this->get_logger(), "publishing");
}
  rclcpp::TimerBase::SharedPtr timer_;
  rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr publisher_;
  size_t count_; 
};

int main(int argc, char *argv[]) {

  printf("Starting...");
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalPublisher>());
  rclcpp::shutdown();
  return 0; 
}

Subscriber code:

#include <chrono>
#include <memory>

#include "cv_bridge/cv_bridge.h"
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
#include "std_msgs/msg/header.hpp"
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <stdio.h>

#include <opencv2/core/types.hpp>
#include <opencv2/core/hal/interface.h>
#include <image_transport/image_transport.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using std::placeholders::_1;

class MinimalSubscriber : public rclcpp::Node {
  public:
    MinimalSubscriber()
    : Node("minimal_subscriber")
    {
      auto qos_profile = rclcpp::QoS(rclcpp::KeepLast(10));
      subscription_ = this->create_subscription<sensor_msgs::msg::Image>(
      "topic", qos_profile, std::bind(&MinimalSubscriber::topic_callback, this, _1));
    }

  private :
    void topic_callback(sensor_msgs::msg::Image::SharedPtr msg) const
    {
      RCLCPP_INFO(this->get_logger(), "In callback");
      cv_bridge::CvImagePtr cv_ptr;
      cv_ptr = cv_bridge::toCvCopy(msg,"bgr8");
      cv::imshow("minimal_subscriber", cv_ptr->image);
      cv::waitKey(1);
    }
    rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr subscription_;
};

int main(int argc, char *argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalSubscriber>());
  rclcpp::shutdown();
  return 0;
}

I want to see my webcam streaming working normally. I want this simple job happen in C++, cv_bridge, cv2.

2

Answers


  1. Every time the timer_callback function is called, you’re opening a new video capture stream with cv::VideoCapture cap(0);. The opening and closing of the video stream is be causing the delay you’re experiencing.

    Fixed it !

    here is a detailed code : https://github.com/Robotisim/solving_ros_problems/commit/b099e5d787d91205225416953516813ba2dce7c3

    Login or Signup to reply.
  2. Hello I could not fix the same problem,
    I run your code @Muhammad Luqman but shows the following errors

    Starting…[ WARN:0] global ./modules/videoio/src/cap_gstreamer.cpp (2075) handleMessage OpenCV | GStreamer warning: Embedded video playback halted; module v4l2src0 reported: Cannot identify device ‘/dev/video0’.
    [ WARN:0] global ./modules/videoio/src/cap_gstreamer.cpp (1053) open OpenCV | GStreamer warning: unable to start pipeline
    [ WARN:0] global ./modules/videoio/src/cap_gstreamer.cpp (616) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
    [ WARN:0] global ./modules/videoio/src/cap_v4l.cpp (890) open VIDEOIO(V4L2:/dev/video0): can’t open camera by index

    //Please Help. I am using ubuntu 22.04 on windows

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search