📄 v1개정 이력 보기
ROS2 OpenCV 비전 처리 실전 시리즈 — CV Bridge·HSV·Canny·Cartoon·Optical Flow
초록
본 자료는 ROS2 환경에서 USB 카메라 영상을 획득하고, CV Bridge를 통해 OpenCV와 연동하는 기초부터, HSV 색 변환·Canny 엣지 검출·Cartoon Styler·Optical Flow ROS2 노드 구현까지 5개 주제를 단계별로 정리한다. PinkLAB 강의자료 Docs 20~24 기반.
1. ROS2와 OpenCV — CV Bridge (Doc 20)
1.1 usb_cam 패키지 설치 및 실행
sudo apt install ros-jazzy-usb-cam
ros2 run usb_cam usb_cam_node_exe
실행 후 발행되는 주요 토픽:
| 토픽 | 타입 | 설명 |
|---|---|---|
/image_raw |
sensor_msgs/Image | 원본 이미지 (비압축) |
/image_raw/compressed |
CompressedImage | JPEG 압축 이미지 |
/camera_info |
CameraInfo | 캘리브레이션 정보 |
640×480 BGR 이미지 1프레임 ≈ 921KB, 30fps → 초당 약 27MB 전송.
1.2 네트워크 최적화
강의실처럼 여러 명이 같은 네트워크를 쓸 때 DDS 멀티캐스트로 네트워크가 포화될 수 있다.
export ROS_LOCALHOST_ONLY=1 # 가장 효과적인 해결책
1.3 CV Bridge 핵심
from cv_bridge import CvBridge
bridge = CvBridge()
# ROS Image → OpenCV
cv_image = bridge.imgmsg_to_cv2(ros_msg, "bgr8")
# OpenCV → ROS Image
ros_msg = bridge.cv2_to_imgmsg(cv_image, "bgr8")
1.4 파라미터화 패턴
cv_params.yaml에 설정을 외부화하면 코드 변경 없이 동작을 바꿀 수 있다.
img_publisher:
ros__parameters:
camera_device: 0
width: 320
height: 240
frame_rate: 10
2. HSV 컨버터 (Doc 21)
2.1 HSV 색 체계
| 채널 | 의미 | OpenCV 범위 |
|---|---|---|
| H (Hue, 색상) | 색의 종류 (빨강=0°, 초록=120°, 파랑=240°) | 0~179 |
| S (Saturation, 채도) | 색의 진한 정도 | 0~255 |
| V (Value, 명도) | 밝기 | 0~255 |
BGR보다 HSV가 색 기반 객체 검출에 적합한 이유: H 값만으로 색 종류를 쉽게 구분 가능.
2.2 HSV 변환 파이프라인
/image_raw 구독
→ imgmsg_to_cv2('bgr8')
→ cvtColor(BGR2HSV)
→ split(H, S, V)
→ S *= saturation_scale; V *= value_scale (np.clip 필수)
→ merge(H, S, V)
→ cvtColor(HSV2BGR)
→ cv2_to_imgmsg('bgr8')
→ /image_hsv 발행
np.clip(S * scale, 0, 255)으로 오버플로를 방지하는 것이 핵심.
2.3 Dynamic Reconfigure
ParameterDescriptor + FloatingPointRange를 사용하면 rqt에서 슬라이더 UI가 자동 생성된다.
3. Canny Edge Detection ROS2 Node (Doc 22)
3.1 Canny 알고리즘 개요
- 가우시안 블러로 노이즈 제거
- Sobel 필터로 기울기 크기·방향 계산
- Non-Maximum Suppression으로 엣지 얇게 만들기
- 이중 임계값(Double Threshold)으로 강한/약한 엣지 구분
- Hysteresis로 최종 엣지 결정
edges = cv2.Canny(gray_image, threshold1=100, threshold2=200)
# threshold1:threshold2 비율 = 1:2 또는 1:3 권장
3.2 ROS2 노드 구조
/image_raw 구독
→ imgmsg_to_cv2('bgr8')
→ cvtColor(BGR2GRAY)
→ cv2.Canny(gray, t1, t2)
→ cv2_to_imgmsg(edges, 'mono8')
→ /image_edge 발행
threshold1, threshold2는 ROS2 파라미터로 등록하여 실행 중 동적 변경 가능.
4. Cartoon Styler ROS2 (Doc 23)
Cartoon Effect = 엣지 강조 + Bilateral Filter(색 영역 매끄럽게)의 조합.
주요 구성 요소
Bilateral Filter: 엣지를 보존하면서 색 영역을 평탄화- Canny로 엣지 마스크 생성 후 원본에 합성
ParameterDescriptor로 Bilateral Filter 파라미터(d, sigmaColor, sigmaSpace)를 실시간 조절
/image_raw → Bilateral Filter + Canny Edge → Cartoon 합성 → /image_cartoon
5. Optical Flow ROS2 Node (Doc 24)
5.1 Optical Flow 개념
- Dense Optical Flow: 모든 픽셀의 움직임 벡터 계산 (Farneback 알고리즘)
- Sparse Optical Flow: 특징점(feature point)만 추적 (Lucas-Kanade)
5.2 Farneback 알고리즘
flow = cv2.calcOpticalFlowFarneback(
prev_gray, curr_gray,
None,
pyr_scale=0.5, levels=3, winsize=15,
iterations=3, poly_n=5, poly_sigma=1.2, flags=0
)
5.3 움직임 벡터 시각화
cv2.arrowedLine으로 각 픽셀의 움직임 방향과 크기를 화살표로 표시.
/image_raw 구독
→ 이전 프레임과 비교 → Farneback Dense Optical Flow
→ draw_flow_vectors (arrowedLine)
→ /image_flow 발행
공통 패턴 정리
| 패턴 | 설명 |
|---|---|
CvBridge |
ROS2 ↔ OpenCV 이미지 변환의 핵심 |
declare_parameter + add_on_set_parameters_callback |
동적 파라미터 변경 지원 |
ParameterDescriptor + FloatingPointRange/IntegerRange |
rqt 슬라이더 UI 자동 생성 |
| launch + YAML | 코드 변경 없이 설정 관리 |
출처: PinkLAB 강의자료 Docs 20~24. 정리: Moojoco (hb5u), 2026-06-22.
