OpenCV 카메라 이미지를 Publish 하는 예제
04 Jan 2018 | ROS OpenCV카메라 이미지 Publisher
여기 소스 코드를 참고했습니다.
main.cpp
#include "rclcpp/rclcpp.hpp" #include "sensor_msgs/msg/image.hpp" #include "opencv2/opencv.hpp" #include "opencv2/highgui/highgui.hpp" #include <cstdio> #include <memory> #include <string> using namespace std; using namespace cv; #define ROS_NODE_NAME "usb_camera_publisher" #define ROS_CAMERA_TOPIC_NAME "snowdeer_camera_topic" void (*breakCapture)(int); void signalingHandler(int signo) { printf("'Ctrl + C'(%d) processing...\n", signo); exit(1); } string mat_type2encoding(int mat_type) { switch (mat_type) { case CV_8UC1: return "mono8"; case CV_8UC3: return "bgr8"; case CV_16SC1: return "mono16"; case CV_8UC4: return "rgba8"; default: throw std::runtime_error("Unsupported encoding type"); } } void convert_frame_to_message(const cv::Mat & frame, size_t frame_id, sensor_msgs::msg::Image::SharedPtr msg) { msg->height = frame.rows; msg->width = frame.cols; msg->encoding = mat_type2encoding(frame.type()); msg->step = static_cast<sensor_msgs::msg::Image::_step_type>(frame.step); size_t size = frame.step * frame.rows; msg->data.resize(size); memcpy(&msg->data[0], frame.data, size); msg->header.frame_id = std::to_string(frame_id); } int main(int argc, char** argv) { breakCapture = signal(SIGINT, signalingHandler); rclcpp::init(argc, argv); rmw_qos_reliability_policy_t reliability_policy = RMW_QOS_POLICY_RELIABILITY_RELIABLE; rmw_qos_history_policy_t history_policy = RMW_QOS_POLICY_HISTORY_KEEP_ALL; size_t depth = 10; double freq = 30.0; size_t width = 320; size_t height = 240; setvbuf(stdout, NULL, _IONBF, BUFSIZ); auto node = rclcpp::Node::make_shared(ROS_NODE_NAME); rmw_qos_profile_t custom_camera_qos_profile = rmw_qos_profile_default; custom_camera_qos_profile.depth = depth; custom_camera_qos_profile.reliability = reliability_policy; custom_camera_qos_profile.history = history_policy; auto publisher1 = node->create_publisher<sensor_msgs::msg::Image>( ROS_CAMERA_TOPIC_NAME, custom_camera_qos_profile); rclcpp::WallRate loop_rate(freq); VideoCapture cap; if(!cap.open(0)) return 0; cap.set(CV_CAP_PROP_FRAME_WIDTH, static_cast<double>(width)); cap.set(CV_CAP_PROP_FRAME_HEIGHT, static_cast<double>(height)); if (!cap.isOpened()) { printf("Could not open video stream!!\n"); return 1; } Mat frame; auto msg = std::make_shared<sensor_msgs::msg::Image>(); msg->is_bigendian = false; size_t i = 1; while (rclcpp::ok()) { cap >> frame; if (!frame.empty()) { convert_frame_to_message(frame, i, msg); } if (!frame.empty()) { CvMat cvframe = frame; cvShowImage("Camera", &cvframe); if( waitKey(10) == 27 ) break; printf("Publishing image #%zd\n", i); publisher->publish(msg); ++i; if(i > 10000000) i = 0; } rclcpp::spin_some(node); loop_rate.sleep(); } rclcpp::shutdown(); return 0; }