본문 바로가기

Robot/Robot Program - ROS

[R2R] 1-6 HSV 색 체계를 이용한 채도, 명도 조절 패키지 만들어보기.

본 글은 제가 직접 쓴 글이 아니라, 저희 PinkLAB의 유투브 채널의 공개 강의 영상들을 읽고, 따라한 한 수강생의 글을 제 블로그에 공유한 내용입니다.

https://youtu.be/Dwe6i6wONnA?feature=shared

 

안녕하세요, 잘 지내셨나요!

이번시간에는 [ HSV 색 체계를 이용한 채도, 명도 조절 패키지 만들어보기 ] 라는 주제의 강의를 듣고 글 올려봐요 . 

이번 강의는 평소보다 조금 더 길어요, 힘내야해요 ! 알록달록해서 재밌을 거예요 ❤️💚💙🩶💙💚❤️ 

R2R ! Rush to Ros , 현재 우리는 로스 관련된 수업 실전 편을 듣고있어요. 

이전시간에는 cv_bridge를 이용해서 opencv --> ros2 데이터로 바꾸는 작업을 소개했어요. 

 

그리고 카메라 토픽에 대해서, 네트워크 입장에서는 조금 부담이 된다는 이야기도 했어요.

그래서 usb_cam_package를 사용하는 것도 괜찮지만,

CPU 자원이 조금 남는다면 OpenCV를 이용, resize 함수 같은 걸 사용해서 

직접 핸들링 하는 것도 괜찮다 라는 이야기도 했어요. 

지난번에는 카메라를 직접 다루는 이야기만 했다면, 

이번에는  OpenCV pkg를 만들고,  ( 우리가 그 때 사용하던 이름이 my_opencv_tutorials 였어요! ) 

 

HSV converter 라는 것도 한 번 만들어 보도록 할게요. 

우선, 지난시간과 조금 바뀐 부분이 있어요.

우리가 직접 타이핑을 하지 않고, 강사님께서 코드를 설명 해 주시고,

그 코드로 패키지를 하나 만들고 사용하는 방법을 알아가 볼 거예요. 

 

여기 pinkwink 깃허브에 코드가 보관되어있답니다. 

https://github.com/PinkWink/opencv_tutorials_for_ROS2

 

GitHub - PinkWink/opencv_tutorials_for_ROS2: opencv_tutorials_for_ROS2

opencv_tutorials_for_ROS2. Contribute to PinkWink/opencv_tutorials_for_ROS2 development by creating an account on GitHub.

github.com

한 번 들어 가 볼게요. 

" PinkLAB이 진행하는 유튜브 강좌 중 R2R 실전편 중 OpenCV ROS2 패키지 수업의 소스코드입니다 " 

라고 적혀있어요. 

아래 " PinkLAB R2R ROS2 실전편 재생목록 " 누르시면 

실전편 재생 목록으로 넘어가요. 

 

이 중에서 우리가 지난번에 usb_cam_package 한 번 써봤고,

opencv로 직접 영상을 받아서 cv_bridge로 바꾸고, 토픽을 발행하는 부분을 이야기 했어요. 

 

repositories --> opencv_tutorials_for_ROS2 --> my_opencv_tutorials --> my_opencv_tutorials

 

지금 보이는 대로 이렇게 코드를 만들어 두셨어요.

지난번에 우리가 했던 게 img_pub node 였어요. 

 

그리고 오늘 할 이야기는 convert_hsv.py 에요.

HSV converter 이야기를 할 예정이에요. 

 

지난 시간과 바뀐 점이 있다면...

지난 시간에는 size.yaml 이었구요, 

이번에는 cv_params.yaml이에요. 이름만 바꾼거에요!

이제 HSV converter 이야기를 해 볼거예요. 

HSV란 뭘까요? 

원래 우리가 색을 이야기 할 때 

HSVRGB❤️💚💙로 이야기를 많이 하죠..! 

OpenCVBGR💙💚❤️이구요.

BGR, RGB 모두 3색이에요.

우리가 OpenCV로 색을 이야기 할 때 가장 이해하기 편한 게 RGB, BGR 3색이에요. 

 

상황을 하나 가정 해 주셨는데요,

RGB 값으로 100, 100, 100을 만들었어요,

이 색을 좀 더 밝게 하려면..? 어떻게 해야할까아 요? ( 질문 )💡

RGB 값을 다 조금씩 더해야하나..? 이런게 헷갈릴 수 있다 하셔요.

실제로 RGB에서 구현하기가 어려울 수 있어서요. 

 그런데이 색 체계를 쓰면 이해하는 게 조금 달라져요.

어차피 RGB 나 BGR이나 그것도 3채널이에요. 3차원이죠.

그런데 HSV 체계도 3차원이에요. 

 

 

첫 번째 H(hue) 가 의미하는건 < 각도 > 에요. 

각도 0도, 30도, 90도, 180도 이렇게 각도랍니다. 

각도마다 색상이 정해져있어요. 

H는 각도에 따른 색상을 의미해요.

채도를 의미하는 아이는 따로 있는데요, S( Saturation ) 이 친구에요. 위에 표시된 방향이에요.

명도 V ( Value! ) 아래로 내려가는 방향이에요.

명도는 내려 갈 수록 검정색이에요.

HSV는 보통 이렇게 원뿔형으로 많이 표현한대요. 

 

조금 더 밝게 하려면 V 값만 살짝 올려주면 되구요, 

색을 더 선명하게 하고싶으면 S를 조금 올려주면 된답니다!

 

RGB에서는 고민을 엄청 해야 할  것이, HSV 얘로 바꾸면 고민할 게 많이 없어진다 하셨어요.

이해 하기 쉽게 비유를 들어주셨는데요,

기하학에서 X, Y, Z 좌표계 말고 원통 좌표계를 쓰겠다 라고 하면

우리가 반지름이랑 높이, 이런 걸 알면 되는 거잖아요. 이렇게 공간을 바꾸는거에요.  

생각하는 공간을 바꿔서 구현하거나 사용하기 쉽게 만들어 주는 것, 이런게 체계를 바꾸는 것 이라고 하셨어요. 

 

HSV 색체계가 있어요.

HSV 색 체계에서 남색을 표현하고싶다면,

빨간색을 기준으로 H(hue) 는 240도 회전한 위치, S 채도는 100%, V 명도는 50%

-->  이렇게 해서 240, 100, 50 이렇게 표현을 해요. 

 

Saturation - 채도'진한 정도'에요. 100%가 가장 진한거구요.

'

명도라는 것은 '밝은 정도'를 말해요.

검정이 '0'이구요. 흰색이 완전 밝은 100%에요. 

이제 HSV 이야기는 실컷 했구... 코드로 넘어 가 봤어요. 

 

핵심이 되는 부분, 흐름이에요. 먼저 image_raw를 구독 할 거에요.

이 토픽은 누군가는 쏘아 줄 거에요.

누가 쏘는지 모르더라도, image_raw를 구독하겠다 하면 '토픽'을 구독 한 거잖아요 ,

구독 한 거니까 이건 ROS 데이터 체계란 말이죠! 

 

 

그런데 우리가 HSV나 색을 바꾸는 건 OpenCV 명령이니까,

OpenCVcv_bridge를 써서 바꿔요.

그리고 BGR 체계에서 HSV 색 체계로 변환을 할 거에요. 

그렇게 해 두고 ROS2 Parameter가 있었잖아요, 

ROS2 Parameter로 지정되어 있던 값을 이용해서 S나 V 채널을 보정하는 거에요. 

그리고 난 다음에 보정이 끝났으니까 다시 HSV를 BGR로 바꿔줘요.

그러고 난 다음에 (위 동그라미 부분은 OpenCV 거든요!) 

그래서 cv_bridge를 써서 지금까지의 OpenCV 내용을 다시 ROS 토픽으로 바꿔요. (이제 OpenCV 작업이 끝났으니까요!)

바뀐 토픽, 여기서는 image_hsv 토픽을 발행하도록 해 둔거에요. 

이게 전체 흐름이에요. 이제 코드 전체 구조를 한 번 보도록 할게요. 

가장 중요한 HsvConverter class 가 있구요,

__init__ 이 있구요, 

그 다음에 image_callback 이 있어요.

여기에 모든 내용이 다 들어가있어요. 

파라미터에 관련된 부분은  logger를 남겨주려고 사용을 하고 있어요. 

main이 들어가있고 __name__ 들어 가 있어요.

 

여기에서는 __init__ 부분만 먼저 이야기를 해 볼게요. 

__init__에는 우선 HsvConverter라고 노드 이름을 잡아주었구요, 

그 다음에 여기서 loggerconverter가 시작됐다 라고 로그를 남겨주었어요.

그 다음에 image_raw를 구독하도록 했어요. 

 

image_raw를 구독하도록 하고, image_callback 함수를 여기서 선언 한 거에요.

그래서 image_raw 토픽이  들어 올 때 마다, image_callback을 실행해! 라고 해 둔거에요. 

그리고 image_raw 토픽이 들어 올 때 마다, 실행되는 callback 함수에서 변환 작업이 다 끝나고 나면

image_hsv라는 토픽을 쏘아야했잖아요,

 

그래서 __init__ 부분에서 image_hsv 토픽을 발행 하는 것을 선언해 두었어요.

 

그리고 난 다음, 우리가 배운 적 있는 dynamic reconfigure에서 parameter를 슬라이드 바로 조정하고 싶었던 거에요.

그렇게 하려면 파란색으로 밑줄 친 내용이 들어가야해요. 

채도와 명도에 대해서는 곱하기로 할 건데요, 채도 값이 있으면, 여기다 0.0 부터 2.0 사이를 곱하기 할 거에요. 

" 두 배 정도 밝게 " 이런 식으로 !

그래서 이렇게 잡아주었어요. 

 

그리고 난 다음에 parameter를 declare_parametersaturation_scalevalue_scale을 정의 해 두었구요,

그리고 초기값은 둘 다 1, 원래 값을 그대로 쓰도록 곱하기 하도록 해 두었구요, 

 

( 그 다음, 파란색 괄호💙 속 내용을 보시면, )

get_parameter로 받아오도록 했어요.

그리구.. logger를 남기구요, Initial value를 남겨줘야해요.  남기고..

( 파란 밑줄 + 체크💙 보시면 ) 그 다음에 파라미터가 변경되었을 때 실행 할 callback 함수까지 선언을 해 두었어요.

우리가 이 parameter부분 있잖아요, parameter_callback 이랑 이거 언제 했냐면요!  무슨 이야기지 🙄 하는 생각이 드신다면..!

구글 입력 창에 pinklab youtube 검색 -->

 

여기 왼쪽에서 다섯번째  ෆ 응용과정이 있어요. 무작정 따라하는 ROS2 - 응용과정

여기에 쭉 내려보시면 parameter 이야기가 있어요.

터미널에서 parameter 다루는 부분, 

패키지 코드 내에서 파라미터 다루기 두 편, 

파라미터 reconfigure 이야기를 했어요. 

그리고 조금 더 뒤로 가면

reconfigure에서 슬라이드 바를 어떻게 만들 것인가? 에 대한 이야기도 하고있어요.

그러니까, 지금 우리가 배우고 있는 내용은 여기 R2R 과정의 응용편에서 넘어 온 거에요.

 

여기서 그래도 요약을 조금 하면,

여기 이 함수 이 부분에서 parameter_callback이라는 함수를 선언 해 둔 건 뭐냐면, 

parameter가 변경되었을 때, 이 callback 함수를 실행하도록 해 둔거에요.

그래서 내가 원하는 어떤 파라미터의 변경에 대해서 바로바로 반응하도록 하는거죠.

 

그게 여기에요. parameter_callback 이에요.

뭘 하나? 프린트를 하죠. 

logger 남겨라! 해 준거에요. 

callback 함수 이야기, 여기가 본 스토리에요. callback 함수에서 무엇을 하고있는지 이야기 할 거에요.

 

callback 함수 선언을 해 두었구요, 그 다음에 ( 윗부분 파란 괄호💙 ) 여기서도 parameter를 받아오도록 했어요.

parameter를 여기서 받으면 장점이 하나 있어요. 받는 코드를 callback 함수에다 넣어두면

아까 파라미터 변화에 대해서 즉각 즉각 반응하도록 하는 코드가 복잡하게, 많은 내용이 들어가지 않더라도

여기에서 바로 적용이 가능해요.  parameter_callback 함수에다가 아래 괄호 내용을 다 집어넣어버리면 

약간 복잡해지거든요.. ! 

 

근데 거기를 log만 남겨두고 image로 토픽이 들어왔을 때에만 실행하는, 여기에서만 이렇게파라미터를 받도록 하면 편하다는거에요!

 

 

그리고 cv_bridge를 통해서 ROS 이미지 데이터를 OpenCV 데이터로 변경하도록 해 뒀어요.

 

이제 그 다음줄에서는 convert color 명령을 이용해서 받아온 cv 이미지를 BGR to HSV 색 체계로 바꿔치기 한 거에요.

 

그렇게 해 두고 H, S, V라고 Split을 시켜서 한 채널 씩 받아온 거에요.

강사님은 H 채널을 건드리지 않을 거라 하셨지만, 우선 받아오셨어요.

 

S 채널은 원래 100%가 맥시멈인데요,

OpenCV 는 255 를 맥시멈으로 하고있어요. 

그래서 0 부터 255 사이를 Saturation 걸면서

원래 S 채널에서 Saturation scale을 곱해라 한 거에요. 

 

내가 1보다 작은 값을 주면 채도를 낮추는 것이구요,

1보다 큰 값을 곱하면 채도를 높이는 효과가 나는 거에요. 

 

그리고 이게 또 integer(정수)로만 되어야 하는데요, 그러다 보니 소수점이 들어가면 안돼요,

( saturation_scale을 어떻게 잘 만져보거나, 더하기 하고 바꿔치기 하고.... 🐒 그럼 또 괜찮을 수 있지만 )

S = np.unit8(S)

그것 보다는 이 한 줄 넣는 게 편해서 , 이렇게 부호 없는 정수형으로 바꾸어 주었답니다! 

 

V 채널도 마찬가지 역할을 하구요, 

그리고 H, S, V 로 분리시켜서 S, V에 보정을 했잖아요, saturation_scale과 value_scale을 가지고

 

 다시 merge를 시켜요.

이렇게 원래 채널로 합쳐지는 거에요.  

💙이 2개 값은 어디서 오는 걸까요!

파라미터에요.

launch 파일로 실행 할 때 만들어 두거나,

dynamic_reconfigure로 다시 수정을 하거나 해서 parameter로 만들어 뒀어요. 

 

 

그러고 난 다음에 다 변환 했으면 다시 HSV를 BGR로 바꿔치기 해야해요.

그렇게 해야 보기 편해진다고 하셔요!

 

여기까지가 OpenCV였잖아요, 그래서 OpenCV 데이터를 ROS 이미지 데이터로 바꾸는 과정이에요.

 

그리고 바꾸어진 데이터를 다시 publish 해라 라고 만들어 주는거에요.

지금 조심하셔야 하는게, image_callback 이 시작되고 나서부터 아래까지는 image_callback 함수에요.

"😂 코드 , 어떻게 하라고 이렇게 막 넘어가시는건가요!!! " ( 영상 14:43 ) 하시면서 자문자답 하신 강사님....

오늘도 웃음 한스푼이여 ㅋ.ㅋ

( 참고! 코드는 Github에 올려두셨답니다! )

https://github.com/PinkWink/opencv_tutorials_for_ROS2

 

GitHub - PinkWink/opencv_tutorials_for_ROS2: opencv_tutorials_for_ROS2

opencv_tutorials_for_ROS2. Contribute to PinkWink/opencv_tutorials_for_ROS2 development by creating an account on GitHub.

github.com

스크롤 하면 에너지가 소진되시는 분들을 위해 한번 더 링크를..

그 외의,

 launch 파일은 이렇게 구성을 해 두었구요,

첫번째 파란 밑줄💙 보시면 cv_params 받도록 했어요.

두번째 밑줄💙은 팝 이미지로, 지난 시간에 했던 카메라를 기동하는 거였어요. 

세 번째 밑줄💙은 convert_hsv를 실행하도록 해 두었어요. 

💙cv_params 에서 camera_device가 몇 번이고, width는 몇이고, height는 몇이고 frame_rate는 몇이다, 

한 것들은 지난 시간에 했던 내용들이구요, 

그 다음에 이번 시간에 새롭게 시작 한 게

💙 saturation_scale 과 value_scale을 수정할 수 있도록 해 둔거에요.

 

이제 코드를 사용 해 봐야해요. 

workspace를 하나 만들어요. my_opencv_tutorials의 src라는 폴더까지 만드시고,

src 폴더로 가셔서 아래 주소를 Git Clone 하시면 된답니다.  

https://github.com/PinkWink/opencv_tutorials_for_ROS2

 

GitHub - PinkWink/opencv_tutorials_for_ROS2: opencv_tutorials_for_ROS2

opencv_tutorials_for_ROS2. Contribute to PinkWink/opencv_tutorials_for_ROS2 development by creating an account on GitHub.

github.com

 

또는! 구글에서 pinkwink github 하면 나와요. 

 

아직 주목받을 만한 repositories 가 아니어서 숨겨져있다 하셨어요. 

 

repositories 클릭 하셔서, opencv_tutorials for ROS2 찾으셔서 들어가시면 돼요. 

 

Git Clone 까지 다 했으면 뭘 해야할까요! 

jazzy를 부르면 돼요. 

한번 더 언급 해 주셨던 부분이 있는데요, 

원래는 저희 수업에서 ROS2 환경을 터미널에서 활성화시키려면

source opt / ros / humble / setup.bash ( Ubuntu 22.04 )

source opt / ros / jazzy / setup.bash ( Ubuntu 24.04 )

이렇게 불러야하잖아요, 

그런데 강사님께서는 수업 때 해당 과정이 귀찮으니! 🦦 

.bashrc에 위 내용을 넣어서 alias를 잡기로 했어요.

humble 버전 쓰시는 분들은 humble 이라고 alias를 잡고, 

jazzy 버전 쓰시는 분들은 jazzy라고 alias를 잡으면 된다 라고 앞서 이야기를 많이 했어요. 

이렇게 해 두고, build를 해요. 

자주 쓰는 workspace면 이것조차도 alias를 거는데요, 편하신 대로 선택을 하면 된답니다! 

source 명령어로 현재 workspace의 install 폴더에 있는 local_setup.bash를 불러요.

그러고 난 다음에 ros2 명령어로

ros2 launch my_opencv_tutorials hsv_converter_cv.launch.xml

부르시면 돼요!

그러면

첫번째 파란 괄호💙 속에 우리가 logger 남겨놓은 것,

두번째 파란 괄호💙 속 img_publisher에 logger 남겨놓은 것, 

여기서 logger가 뜨면서 두 개의 노드가 동시에 기동되었음을 알 수 있어요. 

 

이제 또 다른 터미널에서 로스 활성화 시키시구요,

rqt를 실행해요. 

 

 

plugin에서 visualization 에서 image_raw,

plugin 에서 dynamic reconfigure 두 개를 불러서 배치를 한 거에요. 

중요한건 image_hsv라는 토픽을 보고있다는거죠. 그리고 혹시 목록에 뜨지 않으면 Refresh 버튼을 눌러주세요 !

 

여기서 클릭 하고, saturation_scale을 이렇게 dynamic_reconfigure을 이용해서 슬라이드 바로 만들 수 있게 된 거에요. 

 

이 상태에서 바꿔볼게요, 뭘!?

maximum으로! 

이게 사실 2.0을 곱하는게 maximum은 아니에요. 

 

만약에 해당 값이 20이었으면 2를 곱해봐야 40이 되는 거잖아요,

그러니까 2 정도 곱하는게 아니라 어쩌면 10을 곱하거나 더하기를 해서 255까지 더하기 형태로 갔어야 할 수도 있어요. 

그건 여러분들의 구현 취향에 맞추셔도 된다고 하셔요. 

 

255를 꽉 채워줘야지 하시면 아까 말씀 드린 대로 0부터 255를 더하는 형태로 가셔도 된다 하셔요. 

 

두 개를 다 2를 곱했더니, 아까보다 훨씬 진해지고, 밝아졌어요. 

 

확실히 다르죠! 

지금까지 해서 OpenCV tutorials라는 이름으로 두가지 작업을 했어요. 

카메라를 기동하는 부분, 그리고 HSV 색 체계를 살짝 바꿀 수 있는 부분, 이렇게 바꿔봤어요. 

 

이번시간도 고생 많으셨습니다 ^-^

포스트잇 감성 살리기... ❤️🧡💛💚🩵💙💜 히힛 🩶

다음 시간에 만나요 ! 

반응형