본 글은 제가 직접 쓴 글이 아니라, 저희 PinkLAB의 유투브 채널의 공개 강의 영상들을 읽고, 따라한 한 수강생의 글을 제 블로그에 공유한 내용입니다.
https://youtu.be/qYjwygWig5I?feature=shared
안녕하세요, Rush To ROS 강의 잘 따라오고 계신가요 !
이번시간에는 [ R2R 실전편, cv_bridge로 OpenCV 영상 토픽 발행 해보기 ] 강의를 듣고 내용 정리 해 봤어요!
지난 시간에는 usb cam 패키지에서 usb로 연결된 카메라를 켜 보는 걸 배웠어요. ( 어떻게 저떻게 ㅋ_ㅋ )
카메라, 영상 정보는 네트워크 부하가 많이 걸릴 수 있기 때문에 조심해서 써야한다는 것도 배웠어요.
img_width 나 img_height를 바꿔서 혹은 framerate까지 바꾸어서 네트워크 부하를 줄이는 방법도 알려주셨어요.
하지만 usb cam 자체가 지원하는 사양이 정해져있기 때문에 내 마음대로 바꿀 수는 없었다는 이야기도 했어요.
이번에는 OpenCV로 직접 카메라를 다루었어요. 그리고 그 결과를 ROS2와 연결하는 방법을 배웠답니다!
그래서 이번 강의 키워드는 "ROS2와 영상" 이에요. ( 두구두구 😚 )
하나씩 가 봐요. 먼저
python3 -m pip config set global.break-system-packages true
를 설치해요.
pip 명령을 venv나 conda 같은 가상환경을 설정하지 않고 루트에서 바로 실행하는 경우에 에러가 난단말이죠.
그래서 그걸 해제하는 설정이에요.
pip3 install --upgrade pip
pip 를 최신 버전으로 유지를 해 주시구요,
그러고 난 다음에
sudo apt install python3-pip
혹시 설치 되어있지 않으면 설치를 해요.
pip install opency-python
opencv-python도 설치하구요.
sudo apt install ros-<distro>-cv-bridge
그리고 cv-bridge를 설치 할 거에요.
강사님이 이 영상을 찍으시던 시점 기준으로, 우리는 ROS2 humble 에서 jazzy로 넘어가는 중이에요.
Ubuntu 버전으로 이야기를 하면
Ubuntu 22.04가 ROS2 humble,
Ubuntu 24.04가 ROS2 jazzy
가 깔려요.
사실 어떤 걸 사용해도 상관은 없지만!
하드웨어 의존성이 강한 ROS 세상에서는 버전이 그렇게 중요한 문제는 아니래요. ( 강사님이 알고계신 한 회사는 여전히 6년 전에 나온 Ubuntu 18.04를 쓰고있지만, OS도 상관없고 문제가 없다고 해요. )
하지만 중요한건!
sudo apt install ros-<distro>-cv-bridge
이런 표현이 나왔을 때, <distro> 안에, 사용하는 버전에 따라 넣어야 하는 내용이 달라진다는 거에요.
내가 Ubuntu 22.04의 humble을 쓰고 있다면, 여기에 ros2-humble-cv-bridge 하시면 되는거구요,
내가 Ubuntu 24.04의 jazzy를 쓰고 있다면, 여기에 ros2-jazzy-cv-bridge라고 하시면 되는거에요.
cv-bridge는 뭘까요 ?
이 그림은 ROS2 cv-bridge 공식 홈페이지에서 가지고 온 거라 해요. (출처 밝힘!)
opencv가 생각하는 data type 과 ros가 생각하는 data type 이 달라요.
( cf. 영상이 이미지잖아요, 이미지가 초당 몇 번 나오냐 이게 영상이에요 )
그 사이를 이어주는 친구가 cv-bridge 랍니다!
일단 지난시간부터 하고 있던 my_opencv_tutorials 폴더 안에 img_pub.py라는 파일을 넣어뒀어요.
내용을 시작 해보자면,
rclpy 알고있구요,
Node 알고있어요.
Image 영상 다룰거니까.. 이미지 data type 을 import 했어요.
cv-bridge랑 opencv도 사용 할 거라서 두 개를 다 import 했어요.
이제 순서대로에요.
ImagePublisher class 하나 node 상속하도록 하구요,
그 다음에 __init__과 time_callback으로 나눠져있구요,
그 다음에 __init__ 안에는 img_publisher라는 이름으로 노드를 선언했어요.
그 다음에는 image_raw라는 이름으로..
( 이름을 맞추면 좋은 것 같아요. 지난 시간에 썼던 usb cam package가 발행하는 토픽 이름이 image_raw 였으니까요! )
그리고 이 아이는 Image라는 datatype을 쓰고 있는 거에요.
그리고 10ml/sec 마다 한 번씩 타이머가 발생하도록 해서,
time_period , 10ml/sec 마다 한 번씩 time_callback을 실행하라고 한 거에요.
그리고 cap이라는 아이는 opencv에서 VideoCapture(0)를 한 거에요.
VideoCapture(0)는 usb에 연결되어있는 첫 번째 카메라를 의미해요.
그리고 cv_bridge를 불렀구요,
이제 time_callback에서는 여기에서 읽어온 한 frame 식을 가지고
ret, frame = self.cap.read()
프레임 식이 여기까지는 opencv가 작동 한 거라고 해요.
frame이 여기까지는 opencv..!
img = self.cv_bridge.cv2_to_imgmsg(frame, "bgr8")
"opencv data를 ros data 로 바꿔라" 에요.
( cv_bridge ) 가 제공하는 ( cv2_to_imgmsg ) 기능을 써서 img로 바꿨어요.
그러니까 위 동그라미 속의 frame 은 opencv 구요, 아래 동그라미 속의 img는 ros2에요.
그리고 img를 publish해라 한 거에요. 단순하죠! ( ......녜.........🙄 )
그리고 main 과 __name__ 도 들어갔구요,
setup.py에서 entry_points를 잡아줘야해요.
alias도 하나 잡아줘요.
강사님이 실전 편 거의 첫 번째에서 이 함수를 소개 해 주셨어요.
그런데 이 함수를 쓰실 때 한 가지 주의하셔야 할 게 있어요.
tmp2 이건 하지 않으셔도 된다고 해요.
강사님의 주 pc는 mac이구요,
mac을 사용하는 경우, Ubuntu 가 되었던, 산딸기 rasberrypi 보드가 되었던 간에
대부분 ssh를 써요.
그런데, 주 pc가 Mac이 아니라 다른 노트북이나 데스크탑을 쓸 때가 있는데, 그 아이는 os가 Linux Mint 에요.
리눅스 민트는 Ubuntu 의 1TS 버전에 맞추어 나와서 Ubuntu랑 똑같다고 생각을 하시면 돼요.
몇 개만 빼구요. 그 몇 개중에 하나가 얘에요. --> tmp2 !
alias 여기 윗단에 뭐가 있냐면..
Mint 에서 ROS2 자동완성이 잘 안되는데요,
자동완성을 강제로 해 주는 코드를 집어넣고,
그걸 tmp2 여기에서 다시 호출하고 있는거에요.
그래서 이걸 그대로 따라하시는 분들은 tmp2를 살짝 지우고 쓰시면 된답니다!
이제 다시 터미널에서 source 명령으로 my_opencv_tutorials 환경을 다시 불렀어요.
빌드 했으니 다시 부르는거에요.
강사님은 여기 ROS_DOMAINID가 세팅되어있는데, 여러분들은 ROS_LOCALHOST_ONLY를 1로 세팅을 해야해요.
그러고
ros2 run my_opencv_tutorials img_pub
을 실행 해 보면 ...?!
아무 일도 없어요. 아무 로그도 안 보냈기 때문에!
그리고 다른 터미널에서 ros2 topic list를 해서 보시면 이렇게 떠요.
여기 내가 보낸 image_raw가 보여요.
강사님이 (ㅋㅋㅋㅋㅋ) 강의 보는 분들 눈 보호를 해 주시겠다고.... 블러처리를 하셨다 해요. ㅋㅋㅋ 🙈
지금 우리는 opencv에서 영상 카메라를 읽어들여서 ros2 topic으로 쏠려고 준비 중이에요.
현재 화면은 Ubuntu pc에요.
강사님은 Ubuntu pc가 따로 있다 하셨고, mac 에서 ssh로 접근을 해서 코드를 짜려고 한다고 말씀하셨어요.
이제 src폴더에 my_opencv_tutorials, 즉 튜토리얼즈에게 가서 ( 여기 재밌는 에피소드가 있는데... 10:51 부분에 있어요, 😂 )
img_pub.py 이걸 해 뒀어요.
그리고 setup.py에 가서
img_pub = my_opencv_tutorials.img_pub:main
미리미리 이미지 팝, 이미지 팝은 my_opencv_tutorials의 img_pub에 메인으로 진입을 해라 해두고 저장을 해 둘게요,
그 다음에 여기 와서 import rclpy, 그 다음에 from rclpy.node import Node 하구요,
from sensor_msgs.msg에서 image 가지고 오구요,
그 다음에 cv_bridge에서 cv_bridge 가지고 오구요,
그리고 opencv 불러왔어요. (cv2)
이제 class 선언하구요, ImgPublisher 상속받도록 했구요,
def __init__ 추가하구요,
그 다음에 슈퍼로, 상속받은 노드 클래스에 있는 __init__들을 다 가지고 와라 라고 시키고
이 노드 이름을 'ImgPublisher'라고 하겠다고 한거에요.
그러고 난 다음에 self.publisher한테 topic 이름을 image_raw라고 할게요.
그러고 난 다음에 time_period는 0.1 말고 0.01 정도로 잡고,
그리고 self.timer 하나 만들어서 self.create_timer로 (time_period) 받아오고,
해당 시간이 될 때마다 실행 할 콜백 함수를 timer_callback 이라고 지정 해 뒀어요.
그리고
self.cap = cv2.VideoCapture(0)
self.cap , VideoCapture , 0번에서 영상을 받아오는거고,
self.bridge = CvBridge()
self.bridge도 선언을 해 두었어요.
이제 timer_callback에서 할 일은 뭐냐면,
ret, frame = self.cap.read()
frame을 self.cap에서 읽어오게 하구요,
img = self.cv_bridge.cv2_to_imgmsg(frame, encoding='bgr8'
그러고 난 다음에 img는 cv_bridge에서, opencv --> ros 로 바꾸는 걸, frame에서 해와 하고 시켰어요.
self.publisher.publish(img)
그러고 나서 publisher 에게 publish 하라고 시켰어요.
cv2.waitKey(1)
화면 깜빡임을 살짝 막아주려고 1ms 정도 기다리게 한 코드에요.
그리고 난 다음에 이제 메인을 작성해야해요.
def main():
rclpy.init()
main은 들여쓰기 조심해야해요. main 다음에 rclpy.init() 하구요,
node = ImgPublisher()
그러고 난 다음에 node 선언을 하고
rclpy.spin(node)
rclpy - spin 돌게 시키구요,
node.destroy_node()
그러고 난 다음에 빠져나왔다면 destroy_node() 시키구요,
rclpy.shutdown()
다음에 셧다운을 시켜요.
if __name__ == '__main__':
main()
그러고 __name__ 안에 살짝 '__main__' 넣어주고 저장을 해요.
alias 는 터미널에서 추가하도록 해요.
(ssh 접근)
( Ubuntu 바로 작업하셔도 괜찮아요, 강사님은 영상 녹화를 하실 때 편해서 주 pc로 mac을 사용하신다 해요. )
nano editor 로
nano ~/alias_settings.sh
alias_settings.sh라는 파일을 만들어 두었으니 거기에 가서 ..
이렇게 만들어 져 있네요.
my_opencv_tutorials라는 걸로 만들었어요.
이 nano editor에서 빠져나가는 방법은
변경 사항이 없으면 < ctrl + x > ,
변경 사항이 있으면 < ctrl + x + y + enter >
하시면 돼요.
cd 로 my_opencv_tutorials에 가서 my_opencv_tutorials 환경을 부르고, colcon build 를 했어요.
오류가 났답니다!
'console_scripts' : [
'img_pub = my_opencv_tutorials.img_pub:main',
]
이 부분에서 ' 따옴표' 를 닫기만 하고 열어주질 않았어요.
수정 후에
이제 다시 colcon build 성공!
build 를 했으면 my_opencv_tutorials 를 부르셔야하구요,
그 다음에
ros2 run my_opencv_tutorials img_pub
환경을 불러요.
에러!
rclpy 오타가 있었구요,
( 저는 오타 되게 자주 나는데.. 에러 대응 해 가는 과정을 실시간으로 볼 수 있어 좋았어요 ㅋ_ㅋ )
다시 코드 바꿨으니
colcon build 하고
my_opencv_tutorials로 환경을 부르고
ros2 run my_opencv_tutorials img_pub 실행을 해요.
에러 메시지 읽어보시면.. cv_bridge 언급이 되어있어요.
강의자료에 cv_bridge 라고 되어있으니 통일을 해 줘야해요.
bridge --> cv_bridge 로 바꾸어 줬답니다!
다시 colcon build, 환경 부르고, 실행 하면!
새 터미널 열고 ssh 접근 후 , ( Ubuntu 에서 하시는 분들은 그냥 새 창... ) my_opencv_tutorials 부르구요,
ros2 topic list 다시 보면 image_raw가 있죠,
우분투 화면에서
my_opencv_tutorials를 부르구요, rqt를 할건데요, ( 강사님이 또 면도를 안하셨대요 😂 그래서 손으로 가리셨어요 ㅋㅋㅋ )
rqt 실행 ^-^
참고 ) 강사님의 강의 중에 rasberry pi 강의가 있어요. [ 산기정 ] 이라고, 산딸기 기초 정복 인데요,
그 강의에 이런 상태에서 , 새 창을 어떻게 다룰 것인가에 대한 이야기도 있어요.
이번시간에는 cv_bridge 라는 걸 이용해서 --> opencv로 얻은 카메라의 데이터를 --> ros2 topic으로 발행하는 이야기를 해 봤어요.
오늘도 고생하셨습니다아아 🙈 😊
'Robot > Robot Program - ROS' 카테고리의 다른 글
[R2R] 1-2 usb_cam pkg로 USB 카메라 활성화하기 2 (0) | 2025.07.07 |
---|---|
[R2R] 1-1 usb_cam pkg로 USB 카메라 활성화하기 1 (1) | 2025.07.03 |
[R2R] 1-0 또. 다시. 강조하는 bashrc (1) | 2025.06.30 |
ROS2 교육 유데미 유료 교육을 오픈했습니다. (8) | 2024.11.21 |
ROS2 무료 강의 R2R 응용편이 끝났습니다. (8) | 2024.11.11 |
Mac에서 ROS2 humble 설치 및 원격 설정 (5) | 2024.10.24 |
ROS2에서 rqt의 플러그인에서 TF tree가 시각화 되지 않을때 (2) | 2024.10.17 |