有ROS2中的网络摄像头发布存在小问题。

huangapple go评论59阅读模式
英文:

have little problem with webcam publish in ROS2

问题

I am currently your Chinese translator, I will only return the translated parts and avoid including any additional content. Here is the translation of your provided 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;
}

订阅者的代码:

#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'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 &lt;chrono&gt;
#include &lt;memory&gt;
#include &quot;cv_bridge/cv_bridge.h&quot;
#include &quot;rclcpp/rclcpp.hpp&quot;
#include &quot;sensor_msgs/msg/image.hpp&quot;
#include &quot;std_msgs/msg/header.hpp&quot;
#include &lt;opencv2/opencv.hpp&gt;
#include &lt;stdio.h&gt;
#include &lt;opencv2/core/types.hpp&gt;
#include &lt;opencv2/core/hal/interface.h&gt;
#include &lt;image_transport/image_transport.hpp&gt;
#include &lt;opencv2/imgproc/imgproc.hpp&gt;

using namespace std::chrono_literals;
using namespace cv;

class MinimalPublisher : public rclcpp::Node {

public:

MinimalPublisher() : Node(&quot;minimal_publisher&quot;), count_(0) {

    auto qos_profile = rclcpp::QoS(rclcpp::KeepLast(10));
    publisher_ = this-&gt;create_publisher&lt;sensor_msgs::msg::Image&gt;(&quot;topic&quot;, qos_profile);
    timer_ = this-&gt;create_wall_timer(10ms, std::bind(&amp;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 &gt;&gt; img;
    sensor_msgs::msg::Image::SharedPtr msg = cv_bridge::CvImage(std_msgs::msg::Header(), &quot;bgr8&quot;, img).toImageMsg();      
    publisher_-&gt;publish(*msg);
    RCLCPP_INFO(this-&gt;get_logger(), &quot;publishing&quot;);
}
  rclcpp::TimerBase::SharedPtr timer_;
  rclcpp::Publisher&lt;sensor_msgs::msg::Image&gt;::SharedPtr publisher_;
  size_t count_; 
};

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

  printf(&quot;Starting...&quot;);
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared&lt;MinimalPublisher&gt;());
  rclcpp::shutdown();
  return 0; 
}

Subscriber code:

#include &lt;chrono&gt;
#include &lt;memory&gt;

#include &quot;cv_bridge/cv_bridge.h&quot;
#include &quot;rclcpp/rclcpp.hpp&quot;
#include &quot;sensor_msgs/msg/image.hpp&quot;
#include &quot;std_msgs/msg/header.hpp&quot;
#include &lt;opencv2/opencv.hpp&gt;
#include &lt;opencv2/highgui.hpp&gt;
#include &lt;stdio.h&gt;

#include &lt;opencv2/core/types.hpp&gt;
#include &lt;opencv2/core/hal/interface.h&gt;
#include &lt;image_transport/image_transport.hpp&gt;
#include &lt;opencv2/imgproc/imgproc.hpp&gt;

using std::placeholders::_1;

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

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

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

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

答案1

得分: 1

每次调用timer_callback函数时,都会使用cv::VideoCapture cap(0);打开一个新的视频捕获流。视频流的打开和关闭导致了您正在经历的延迟问题。

已解决!

这是详细的代码:https://github.com/Robotisim/solving_ros_problems/commit/b099e5d787d91205225416953516813ba2dce7c3

英文:

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

huangapple
  • 本文由 发表于 2023年5月18日 12:37:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76277775.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定