[2023-04-10] 2. OpenCV 카메라 활용
OpenCV 카메라 활용
-
카메라로 차선 등을 찾아 자율주행 구현
- 차선 찾아서 차선을 벗어나지 않고 주행하도록 하기
- 사람을 찾아서 사람을 쫓아 주행하도록 만들기
- 앞 차의 뒤꽁무니를 찾아서 앞 차를 따라가도록 만들기(군집 주행)
-
카메라를 이용한 주변상황 인지
- 전방 이동물체 인식 : 차량, 사람, 자전거 등
- 전방 고정물체 인식 : 교통 표지판, 신호등, 정지선, 횡단보도
-
카메라 영상으로 자기위치 파악 (Localization)
- 앞에 펼쳐진 전경 및 지형지물을 확인하고 지도 데이터와 비교하여 현재 차량의 위치 유추
자이카 카메라 활용
카메라 관련 ROS 패키지
- 카메라로부터 영상 데이터를 획득할 수 있음
카메라 관련 노드와 토픽
- /usb_cam 노드에서 발행하는 /usb_cam/image_raw 토픽과 /usb_cam/image_raw/compressed 토픽을 이용
- /usb_cam/image_raw 토픽
-
카메라 기능을 사용하려면 Launch 파일에서 “usb_cam” 노드를 실행
- Pkg = usb_cam
- Type = usb_cam_node.cpp
-
해상도 Resolution
-
가로 x 세로 = 640 x 480
- <param name = “image_height” value = “480” / >
-
-
노출도 Exposure
- 조명 상황에 맞춰 조정
- 주변 광원의 밝기에 따라 알맞은 노출을 설정함으로써 오브젝트 인식의 정확도를 높을 수 있음
<launch>
<node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen">
<param name="video_device" value="/dev/v41/by-id/..."/>
<param name="autoexposure" value="false" />
<param name="exposure" value="150"/>
<param name="image_width" value="640" />
<param name="image_height" value="480" />
<param name="pixel_format" value="yuyv" />
<param name="camera_frame_id" value="usb_cam" />
<param name="io_method" value="mmap"/>
</node>
</launch>
카메라 활용 ROS 프로그래밍
패키지 생성
$ catkin_create_pkg my_cam std_msgs rospy
$ mkdir launch
파이썬 코드 및 launch 파일 작성
- edge_cam.launch
<launch>
<node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen">
<param name="video_device" value="/dev/video0" />
<param name="autoexposure" value="false" />
<param name="exposure" value="48"/>
<param name="image_width" value="640" />
<param name="image_height" value="480" />
<param name="pixel_format" value="yuyv" />
<param name="camera_frame_id" value="usb_cam" />
<param name="io_method" value="mmap"/>
</node>
<node name="my_cam" pkg="my_cam" type="edge_cam.py" output="screen" />
</launch>
- edge_cam.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cv2 # OpenCV 사용 준비
import rospy
import numpy as np # numpy 사용 준비
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
bridge = CvBridge() # ROS 에서 OpenCV를 편하게 사용하기 위한 CvBridge 사용 준비
cv_image = np.empty(shape = [0])
def img_callback(data) : # image 토픽을 처리하는 콜백함수 정의
global cv_image
cv_image = bridge.imgmsg_to_cv2(data, "bgr8") # ROS에서 영상정보가 메시지로 날라오는 것을 OpenCV용 이미지로 바꿈
rospy.init_node("cam_tune", anonymous = True)
rospy.Subscriber("/usb_cam/image_raw/", Image, img_callback)
while not rospy.is_shutdownt() : # Image 토픽이 오면 콜백함수가 호출되도록 세팅
if cv_image.size != (640*480*3) : # 640 x 480 이미지 한 장이 모일 때 까지 잠시 기다림
continue
gray = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY) # 원본 이미지를 그레이칼라로 변경
blue_gray = cv2.GaussianBlur(gray, (5,5), 0) # 부드럽게 변경
edge_img = cv2.Canny(np.unit8(blur_gray), 60, 70) # 이미지의 외곽선만 표시하게 변경
cv2.imshow("original", cv_image)
cv2.imshow("gray", gray)
cv2.imshow("gaussian blur", blur_gray)
cv2.imshow("edge", edge_img) # 원본을 포함한 4개의 이미지 표시
cv2.waitKey(1)
실행
- roslaunch my_cam edge_cam.launch
실행 결과
- 총 4개의 영상이 실행되는 것을 확인할 수 있음
- rqt_graph
카메라 ROS 토픽을 이용한 동영상 파일 제작
ROS 토픽 저장
- 카메라의 ROS 토픽을 저장했다가 나중에 사용할 수 있음
$ rosbag record -a
: 날아다니는 모든 토픽을 저장$ rosbag record rosout xycar_imu
: rosout, xycar_imu 2개의 토픽을 저장$ rosbag record -O subset xycar_ultrasonic
: 토픽을 subset.bag 파일로 저장$ rosbag info subset.bag
: 저장된 파일의 각종 정보를 보여줌
ROS 토픽 재생
- 저장한 ROS 토픽을 재생할 수 있음
$ rosbag play subset.bag
: 저장했던 토픽을 재생함$ rosbag play -r 2 subset.bag
: 2 배속으로 재생함
저장된 ROS bag 파일에서 카메라 토픽만 꺼내기
- full_topic.bag 파일 안에 모든 토픽이 담겨 있음
$ rosbag play full_topic.bag
: 저장된 ROS bag 파일을 재생함$ rosbag record -O cam_topic /usb_cam/image_raw/
: 카메라 토픽만 골라서 저장하며 cam_topic.bag으로 파일을 저장함$ rosbag info cam_topic.bag
-
$ rosbag play cam_topic.bag
: cam_topic.bag 재생 -
토픽 확인
-
$ rostopic list
-
$ python edge_cam.py
-
카메라 토픽을 모아서 동영상 파일 만들기
$ rosrun image view video_recorder image:= "/usb_cam/image_raw" _filename:="track2.avi" _fps:= 30
$ rosbag plat cam_topic.bag