서론
ROS2는 다양한 센서와 카메라에서 얻은 데이터를 주고받을 수 있는 시스템을 제공한다. 특히, 카메라 데이터는 sensor_msgs/Image 메시지 형식으로 전달된다. 이를 OpenCV 이미지 형식으로 변환하려면 cv_bridge 라이브러리를 사용할 수 있다.
1. cv_bridge 설치
ROS2를 설치하였다면 기본적으로 cv_bridge는 설치가 되어 있다. 혹시 설치가 되었는지 모르겠거나 설치를 하고 싶다면 아래 명령어를 통해서 설치를 진행하면 된다.
$ sudo apt update
$ sudo apt install ros-<distro>-cv-bridge
<distro> 부분에 현재 사용하는 ROS2 버전을 입력하면 된다(Foxy, Humble 등)
2. 패키지 생성 및 관련 설정
cv_bridge를 통해서 sensor_msgs/Image의 데이터를 사용할 패키지를 생성한다. 패키지 생성 방법은 아래 포스트를 참고하면 좋다.
2024.10.29 - [ROS/ROS2] - [ROS2] 005 : ROS2 C++ 패키지, 노드 작성 가이드
[ROS2] 005 : ROS2 C++ 패키지, 노드 작성 가이드
서론이전 글에서 노드(Node)에 대해 이해해 보았다.2024.10.29 - [ROS/ROS2] - [ROS2] 004 : ROS2 노드(Node)와 데이터 [ROS2] 004 : ROS2 노드(Node)와 데이터서론이전 글에서 demo_nodes_cpp, turtlesim을 실행해 보며 노드,
menggu1234.tistory.com
2024.10.31 - [ROS/ROS2] - [ROS2] 006 : ROS2 QT GUI C++ 패키지, 노드 작성
[ROS2] 006 : ROS2 QT GUI C++ 패키지, 노드 작성
서론이전 글에서 C++을 사용하여 ROS2 패키지를 간단하게 작성해 보았다.2024.10.29 - [ROS/ROS2] - [ROS2] 005 : ROS2 C++ 패키지, 노드 작성 가이드 [ROS2] 005 : ROS2 C++ 패키지, 노드 작성 가이드서론이전 글에서
menggu1234.tistory.com
이제 package.xml과 CMakeLists.txt에 cv_bridge와 sensor_msgs 종속성을 추가해 준다.
package.xml
<depend>rclpy</depend>
<depend>sensor_msgs</depend>
<depend>cv_bridge</depend>
CMakeLists.txt
find_package(cv_bridge REQUIRED)
find_package(sensor_msgs REQUIRED)
add_executable(${EXECUTABLE_NAME} src/image_subscriber.cpp)
ament_target_dependencies(${EXECUTABLE_NAME} rclcpp sensor_msgs cv_bridge)
install(TARGETS ${EXECUTABLE_NAME} DESTINATION lib/${PROJECT_NAME})
3. 노드 작성
이제 ROS2 노드 소스 코드에서 sensor_msgs/Image 메시지를 서브스크라이브 하고, cv_bridge를 사용하여 OpenCV 이미지로 변환하는 코드를 작성한다.
간단한 예제 코드이다.
// image_subscriber_cpp/src/image_subscriber.cpp
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"
#include <cv_bridge/cv_bridge.h>
#include <opencv2/opencv.hpp>
class ImageSubscriber : public rclcpp::Node
{
public:
ImageSubscriber()
: Node("image_subscriber")
{
subscription_ = this->create_subscription<sensor_msgs::msg::Image>(
"/camera/image_raw", // 구독할 토픽 이름
10,
std::bind(&ImageSubscriber::image_callback, this, std::placeholders::_1)
);
RCLCPP_INFO(this->get_logger(), "Image subscriber node has been started.");
}
private:
void image_callback(const sensor_msgs::msg::Image::SharedPtr msg)
{
try
{
// ROS 이미지 메시지를 OpenCV 이미지로 변환
cv::Mat cv_image = cv_bridge::toCvCopy(msg, "bgr8")->image;
// 변환된 이미지 출력 (또는 원하는 작업 수행)
cv::imshow("Received Image", cv_image);
cv::waitKey(1);
}
catch (cv_bridge::Exception& e)
{
RCLCPP_ERROR(this->get_logger(), "Error converting image: %s", e.what());
}
}
rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr subscription_;
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<ImageSubscriber>());
rclcpp::shutdown();
return 0;
}
코드 설명
- topic subscription : /camera/image_raw 토픽을 서브스크라이브하여 sensor_msgs::msg::Image 메시지 수신
- cv_bridge : cv_bridge를 사용하여 ROS 이미지 메시지를 OpenCV cv::Mat 형식으로 변환
- cv::imshow : 변환된 OpenCV 이미지를 화면에 출력
'ROS > ROS2' 카테고리의 다른 글
[ROS2] 007 : ROS2 launch 파일 작성 (0) | 2024.10.31 |
---|---|
[ROS2] 006 : ROS2 QT GUI C++ 패키지, 노드 작성 (2) | 2024.10.31 |
[ROS2] 005 : ROS2 C++ 패키지, 노드 작성 가이드 (1) | 2024.10.29 |
[ROS2] 004 : ROS2 노드(Node)와 데이터 (0) | 2024.10.29 |
[ROS2] 002 : ROS2 예제 (demo_nodes, turtlesim) (0) | 2024.10.29 |