본 글은 제가 직접 쓴 글이 아니라, 저희 PinkLAB의 유투브 채널의 공개 강의 영상들을 읽고, 따라한 한 수강생의 글을 제 블로그에 공유한 내용입니다.
https://youtu.be/8CXw0KcL_Ho?feature=shared
안녕하세요, 😊
잘 지내고 계신가요 ~ ? ( 대답은 못 듣지만! 그래도... 그렇다고 믿어요 ❄️ )
이번시간에는 [ Optical Flow node 만들기 ] 수업을 듣고 포스팅 해 봤어요.
지금 우리는 R2R 실전편 중이구요, 현재 OpenCV 관련된 일종의 튜토리얼 패키지를 만들어 가고 있는 중이에요.
그 중에서 오늘은 Optical Flow 이야기를 해 보려고 해요.
좀 바뀐 것이 있는데!! 뭘까요 ㅋ_ㅋ 히히히히히
강사님께서 오른쪽 하단에 Edge Detection 적용 하셔서 이제 화면에도 나오시잖아요,
그런데 이번에는 간판도 다셨답니다 !! 🩷😉 핑크윙크 간판이에요 ~ ㅋㅋ 귀여워요 ㅋㅋ
깜빡깜빡거려요 ! 만드는 방법도 알려주셨는데요, ( 말 길어져서 미아내요.. 하지만 재밌는걸요😚 )
OpenCV로 구현을 하셨는데요,
OpenCV Edge Detection 적용 하고
깜빡거리는 효과는 Fade Out 설정을 걸고
주기는 3초로 설정을 하면 저렇게 깜빡거리게 된다 하셔요.
폰트도 되게 예쁜걸 쓰고싶으셨는데, OpenCV에서는 기본으로 제공하는 폰트 외의 것을 쓰기가 어려워서
그건 다음에 시간 날 때 하기로 하셨답니다. ㅋㅋ ( 폰트 중요하죠.ㅋㅋ )
아무도 신경쓰지 않지만 혼자 몇시간 보내셨다고,, --> 일단 여기한명 있어요 👋🏻 저도 제가 아는게 제일 중요하다 생각하는 사람~
이제 진짜 수업내용으로 들어가볼게요!
Optical Flow 가 뭘까요 !
여러가지 수학적인 기술들이 들어가 있긴 하구요, 깊이 파고들면 개념이 조금 어려울 수 있다 하셨어요.
하지만 간단하게 설명을 해 보자면,
Optical Flow는 아주 쉽게 이야기 하면 'Pixel의 변화를 체크하는 것' 이라고 생각하면 된다하셔요.
그러니까.. 왼쪽 그림처럼, 어떤 Pixel의 값들이 있었는데, 오른쪽 그림처럼 이렇게 바뀐 거란 말이에요.
(왼쪽)000/100/000 이렇게 있었다고 쳐요, (오른쪽) 000/010/000이렇게 있었다면,
1->0 인 경우, pixel은 변화율이 내려갔고 0->1인 경우, pixel은 변화율이 올라갔어요.
왼쪽에 있던 1이 오른쪽으로 이동했을 거란 말이에요.
그러니까 '1이 어느 쪽으로 이동했고, 어느 방향으로 갔을 것이다' 하고 체크를 해 보고 싶은거예요.
이거 되게 어려워요.
실제로 공식 문서들을 보시면 논문도 있구요, 되게 복잡한 수식들로 표현되어 있는데
누군가가 고맙게도 명령어 하나로 만들어줬어요. 그래서 우리는 쉽게 쓸 수 있어요.
Optical Flow 개념 이야기를 잠시 했구요,
지난번에도 강사님께서 이 방식을 설명 해 주셨는데요,
강사님께서는 저희 상황을 모르시기에 조금 더 깔끔하게,
이 영상에서 나오는 코드를 연습 할 수 있게 가이드를 해 주셨어요.
git을 잘 알고 계시고, build 같은 것들을 잘 알고 계신 분들은 넘어가셔도 된다 하셔요.
지금 우리는 my_opencv_tutorials라는 워크스페이스를 쓰고있구요,
그래서 cd 명령으로 거기로 먼저 가요.
그리고 기존에 만들어 둔 빌드를 하면 만들어지는 build install log 폴더를 지우시고
그 다음에 src 폴더도요.
물론, 버전 관리를 잘 하시는 분들은 그냥 쓰시면 되는데요, 그렇지 않으신 분들은 src 폴더도 지워요.
그러고 난 다음에 mkdir 명령으로 src 폴더를 만드시구요,
그 폴더로 이동하시고
그리고 난 다음에 opencv_tutorials_for_ROS2 선택하시구요,
( 기억나시나요! 강사님 git의 repositories 가 있어요.
여기로 찾아가는 방법은, google 검색창 -> github pinkwink 검색 -> repositories -> opencv_tutorials_for_ROS2 )
여기에서 코드 복사하시면 돼요.
그래서 clone을 받으시구요,
그러고 난 다음에 다시 워크스페이스로 돌아가는 거예요.
git clone을 src 폴더에서 했어요. 그럼 현재 내가 src 폴더에 있겠죠! 그러니까 이제 workspace로 돌아가야해요.
그러고 난 다음에 빌드를 하는 거예요.
우리 영상에서 항상 말씀 하시는데요,
혹시 아직도 익숙하지 않으신 분들을 위해...
" 빌드는 워크스페이스에서 " 이거 꼭 기억 해 주세요!
( 강사님께서 오프라인 수업 하실 때에도 구호처럼 외치고 다니시던 멘트랍니다 .... ㅋ.ㅋ
"빌드는 워크스페이스에서 합니다아" "빌드는 워크스페이스!" "빌드,워크스페이스에서 하셨나요?" 등등... )
강사님께서는 원래 alias를 만드는 걸 좋아하셨어요.
그래서 alias로 ROS를 만드신 다음에 my_opencv_tutorials 이렇게 불렀어요.
이렇게 하지 않으신 분들이 있다면 source 명령으로
source ./install/local_setup.bash
하시면 된답니다.
이제 optical flow라는 노드를 하나 만들어 두었어요.
노드에 전체 코드 구조는 github 에서 받으시면 되지만, 구조만 이야기를 하자면,
구조는 import 우르르 로 받구요,
그 다음에 Optical Flow Publisher라는 이름의 class를 만들거예요.
그리고 그 안에는 __init__과 image_callback과 draw_flow_vectors 가 있어요.
그리고 main함수 하나 만들어 두고 __name__ 적용하도록 해 둔 상태예요.
main함수는 원래 우리가 항상 하던 일이에요.
rclpy에서 __init__ 부르구요,
그 다음에 위에서 만들어 둘 OpticalFlowPublisher 선언하구요,
그 다음에 spin(node)로 열심히 일해라~ 한 다음에
멈출 때에는 destroy_node 하고 shutdown 시키면 그만이에요.
이제 __init__ 부분 보아요.
OpticalFlowPublisher 라는 클래스 안에
__init__ 하나 만들어 두고
optical_flow_publisher라는 이름으로 node를 선언했어요.
그리고 image_raw를 구독하도록 했어요.
image_raw는 OpenCV에요.
OpenCV 카메라를 엑세스 해서 topic으로 발행을 해도 돼요.
그 다음에 usb cam package의 usb_cam node를 이용해서 발행해도 된답니다.
카메라 데이터 그 자체, 그걸 image_raw라고 이름을 잡아 둔 거에요. 내가 구독 할 거니까요.
그러고 난 다음에 image_raw 토픽이 들어 올 때 마다
image_callback 함수를 실행하라고 해 두었어요.
image가 위 그림처럼 있으면, optical flower의 흐름을 vector로 표현하고 싶어요.
시각적인 효과를 눈😶으로 보고싶은거죠. optical flow가 무엇인지!
그걸 발행하는 토픽의 이름도 정해 두었어요.
프레임이 FPS 30이다, 하면 초당 30장의 프레임이 들어오는 거잖아요.
그러면 현재 프레임과 이전 프레임 사이에 어떠한 작업을 해야해요.
이전 프레임을 저장하기 위해서 optical flow는 그레이를 쓰거든요,
그래서 previous grey라는 의미로 빈 변수 하나를 만들어 두었어요.
image_callback에서는 굉장히 간단해요.
image_callback에서는 camera topic으로 들어온 image를
OpenCV로 바꾸고,
( cv_bridge를 이용해서 )
bgr을 grey로 살짝 바꾸어주었어요.
previous grey가 none이라는건, 어떤의미일까요?
previous grey가 none이라는건, __init__ 한 번 통과했다는 뜻이에요.
나중에 callback에서 다시 이걸 이전값으로 저장을 하거든요.
그러니까, 현재 None이 들어왔다는 건, image_callback 함수가 처음으로 실행되었다는 뜻이에요.
그래서 처음 실행되었을 때에만 현재 값을 그냥 prev_grey에 넣어두어라 라는 뜻이랍니다.
image_callback 함수의 중간부분이예요.
여기 지금 행 번호에 유의하셔요 ! image_callback 함수의 중간 부분에서는
calcOpticalFlowFarneback ( 저 발음..... 이 어렵다구, 영어가 싫으시다 하셨어요.ㅋㅋㅋㅋㅋ ("난 영어가 싫어요!"8:03) )
는 OpenCV가 제공하는 함수이구요,
Grey로 되어있는 이전 프레임과,
Grey로 되어있는 현재 프레임을 던져주는 것이 가장 중요하다 하셨어요.
나머지는 default 값들을 그대로 썼다고 생각을 해 주시면 된답니다.
그리고 image_callback의 마지막 부분에서는 이게 중요해요.
이건 다음페이지에서 소개를 할 건데요,
화면에 화살표를 그리는 아이예요.
화면에 그려둔 화살표를 계산하기 위해서
위에서 플로우를 받아 온 거예요.
이걸 받아온거예요.
받아온 것 에다가 지금 이미지 값을 넣어서 겹쳐서 그려라 해 주고,
다 되었으면 다시 ROS data type 으로 바꾸고 끝나요.
이제 발행하면 돼요.
여기는.. 현재 grey 값을 prev_grey 값으로 저장 해 두는 거예요.
그리고 draw_flow_vectors는 별거 없어요.
화살표의 크기를, 변화율이니까 변화가 심하면 화살표를 길게 표현하면 되거든요.
길게 표현 할 화살표 때문에 이 값을 계산 한 거예요.
받아와서 계산을 하고, 몇 콤마 몇 부터 몇 콤마 몇 까지 하고 난 다음에
color 값을 살짝 주고 끝난 거예요.
launch파일도 하나 만들어 둬야해요. 그래서 launch 파일은 여기 img_pub node 실행 하고
optical_flow 실행하라고 시켰어요.
여러분들이 직접 타이핑 하시는 경우에는 setup.py entry point도 작업을 해 주셔야해요.
그러고 난 다음에 build 하시구요.
git clone 하신 분들은 이미 build를 했으니 상관이 없겠지만,
그리고 my_opencv_tutorials 이건 우리 수업에는 계속 alias로 잡아두었던 거예요.
그러고난 다음에 ros2 launch로 my_opencv_tutorials에서 optical_flow.launch.xml 실행을 하면 된답니다.
그러면 ...
짠! 이렇게 나와요. 어때요!??
픽셀의 변화에 따라 화살표로 픽셀의 변화가 보여요.
아니! 근데! 여기는 왜 커지는거죠!?
여기는 왜 그러냐면요,
픽셀의 변화가 굉장히 정확하잖아요, 이게 경계선이거든요.
흰색 바탕에 까만색 선이 하나 탁 지나가잖아요,
그런데 강사님께서 이 폰을 흔들면서 의자가 조금씩 움직인다구요.
카메라 자체가 실제로 움직여요. 아주 조금.
근데 픽셀의 변화가 워낙 정확하게 심하게 변화하는 곳이다 보니까?
크게 변화율이 체크가 된 거예요.
변화율이에요, 변화율!
이제 아까 했던 실습, optical flow 이야기를 조금 해 보도록 할게요 !
강사님께서는 my_opencv_tutorials라는 폴더를 홈에 만들어 두었거든요,
그리고 이전 수업을 진행하면서 쭉 build를 했기 때문에 흔적들이 남아있단 말이에요.
이걸 sudo rm -r build/ install/ log/ src/
해서 지울게요.
계속 언급을 해 주셨지만, 이걸 왜 지우는지 이미 잘 이해하신 분들은 굳이 이대로 하지 않으셔도 괜찮아요.
"저는 지난번 코드에서 잘 업데이트 할 수 있어요" "저는 이미 알아서 하고있어요" 하면 괜찮아요,
그런데 강사님께서 굳이 이렇게 하시는 이유는 이 영상만 깔끔하게 실행되는 걸 보여드리기 위해서에요.
mkdir 명령으로 src 폴더를 만들구요, 그 src 폴더로 넘어갈게요.
그리고 web browser 하나를 켜시구요,
그리고 git hub pinkwink로 가서,
repositories 들어가셔서
opencv_tutorials_for_ROS2 선택하시구요,
코드에서 카피 하시구요,
그 다음에 여기에서 git clone + < ctrl + shift + v > 하면 다 들어와요.
그쵸. 그리고 다시 work space로 가요. 이 워크스페이스여야해요!
그러고 난 다음에 강사님께서는 ubuntu 버전이 jazzy 에요.
그런데 여러분들이 humble을 쓰신다면,
그리고 강사님 영상 초창기부터 들어오셨다면, alias를, humble이라는걸 만들어 두셨을 거예요.
강사님께서는 현재 jazzy 버전이니 jazzy를 만들어 두신 거예요.
하나 더 이야기 할까요!
만약에.. 난 이 영상 처음 봐서 모르겠어요! 어떻게 하죠! 하신다면,
source 명령으로 ros2가 깔려있다면 opt 경로에 ros 경로에 탭을 탁! 탁! 해 보시면 jazzy에요.
humble 이신 분들은 여기가 humble이구요,
강사님께서는 jazzy라서 jazzy에요.
이제 여기서 setup.bash를 부르시면 돼요.
강사님께서는 이걸 alias로 만들어 두신 거예요. 물론 ROS_DOMAINID도 다 세팅을 해 둔 상태였구요.
그러고 난 다음에 buid를 해야해요.
build가 다 끝났네요. biuld가 끝나고 나면
source 명령으로 install 폴더에 local_setup.bash를 부르셔야한답니다.
강사님께서는 이것도 더 편하게 하기 위해서
my_opencv_tutorials (alias)를 만들어 두신거예요.
여기까지 혹시 bashrc와 alias souce 이 명령 잘 모르겠다, 그러면 입문편을 다시 한 번 가 보시기를 바라요. 한번 가 볼까요!
핑크랩 유튜브 여기 가셔서 보시면 playlist 재생목록이 있을거예요.
여기에서 제일 먼저 입문과정은 여기구요,
여기서 bashrc 설정, alias 설정, ROS_DOMAINID 설정 이런 것들을 하고있어요.
그러고 난 다음에 또 뭘 하고있냐면요,
이번에는 응용편으로 가셔서 보시면,
여기에서 내가 만든 패키지 이야기가 나오거든요,
이 때 또 alias 잡는 부분을 강사님께서 이야기 해 주셔요.
그리고 또 하나, 지금 우리가 실전편 있잖아요,
실전편에 가서 보시면 여기에서 또 bashrc 이야기를 해요.
여기서 이제 jazzy 버전으로 이야기를 하고 있어요. 그래서 이 부분들을 꼭 확인하셨으면 해요!
다시 돌아와서,
build를 했구요, 빌드 환경을 부르는 my_opencv_tutorials alias도 했어요.
그러고 난 다음에 ros2 launch my_opencv_tutorials에서 optical flow launch 파일을 만들었단말이죠.
실행해요!
이제 또 환경을 부르고 난 다음에 rqt를 실행하면 또 나올텐데,
손바닥 보이죠. 어떤가요!
optical flow가 보이나요!
안보이시는 분들은 새로고침 한번 누르시고 topic을 찾으시면 된답니다. optical flow 에 짠짠 이렇게 쓱쓱 흐름이 보이죠,
이걸로 할 수 있는 게 많아요. 카메라 내에서 움직이고 있는 영역 움직임이 발생한 영역을 찾는다던지... 이런 것들이 가능해져요.
오늘은 무더운 날이에요... 여러분은 어떤 계절에 보고계실까요 !
고생하셨습니다 😊
'Robot > Robot Program - ROS' 카테고리의 다른 글
[ROS2] 1-9 Cartoon 스타일 만들기 (3) | 2025.07.31 |
---|---|
[R2R] 1-8 ROS2에서 Canny Edge Detector 구현하기 (3) | 2025.07.28 |
[R2R] 1-7 HSV 색 체계를 이용한 채도, 명도 조절 패키지 사용해보기 - 실습 (4) | 2025.07.24 |
[R2R] 1-6 HSV 색 체계를 이용한 채도, 명도 조절 패키지 만들어보기. (1) | 2025.07.21 |
[R2R] 1-5 OpenCV에서 직접 받은 영상을 ROS2에서 FPS, size 조절하기 (2) | 2025.07.17 |
[R2R] 1-4 OpenCV로 읽은 영상에 parameter 적용하기 (3) | 2025.07.14 |
[R2R] 1-3 cv_bridge로 OpenCV 영상 토픽 발행 해보기 (1) | 2025.07.10 |