catkin_make에서 opencv2 오류가 발생해서 cvbridge 예제를 못하고 있는 중입니다...
opencv2의 path를 찾지 못해서 나는 오류라고 하는데 버전은 있으면서 package는 왜 없는지 모르겠네요..
먼저 제가 가지고 있는 opencv버전이 무엇인지 확인해보았습니다.
예제에서 패키지를 만들 때 의존성으로 opencv2를 사용하라고 했는데 제가 가지고 있는 것은 그냥 opencv였습니다.
제 노트북에 있던 opencv폴더의 이름이 OpenCV였기 때문에 CMakeLists.txt 파일에 의존성 이름을 아래와 같이 바꾸니까 catkin_make오류는 이제 뜨지 않네요. opencv2 오류가 완벽하게 해결된 건지는 모르겠습니다.
**또 다른 오류 해결법**
알고 보니 wiki사이트 맨 아래에 kinetic 버전 이후로는 의존성 패키지에 opencv를 빼도 된다고 적혀있더라고요.
안 적어도 실행이 됩니다! 저는 나중에 발견했네요ㅠㅠ
코드를 작성할 때는 publisher로 rospy를 import 하여 이미지를 받아오고 subscriber의 callback 함수에서 원래 있던 코드의 while 문을 실행시키면 됩니다.
cv_example.py 코드를 실행시켰을 때 이렇게 나왔는데 제대로 나온 건지 잘 모르겠네요.
위 rqt_graph는 카메라 노드를 실행시키지 않았을 때입니다.
실행시키니까 위처럼 print 하라고 한 거만 뜨고 실행이 되지 않길래 뭔가 싶었는데 topic을 잘못 적었더라고요.
바꾸고 나니까 node가 하나로 나오는데 이걸 publisher랑 subscriber각각 다른 이름으로 나오게 하고 싶은데 그리고 converter는 중간에 있어야 하는 게 아닌가 싶은데 어떻게 하는 걸까요
코드에서 rospy.init_node()는 노드의 이름을 한 번만 지정할 수 있게 해 주더라고요. 만약 여러 노드를 쓰려면 코드를 나눠서 실행을 해야 할 거 같아요. 그럼 주는 거 이름을 publisher로 하고 받는 거 이름을 subscriber로 하면 converter는 어디에 들어가야 하는 걸까요..
제가 아예 publisher와 subscriber 개념을 이해를 잘못하고 있었던 것 같아요.
굳이 코드를 나눌필요도 없고 한 코드에서 실행하면 되는데 주는 노드가 usb cam이니까 publisher는 이름이 usb cam으로 정해져 있고 받는 노드의 이름만 지정해주면 되는데 그것이 image_converter였습니다.
cv_example 코드를 실행시켜보려고 하는데 왜 카메라 창이 뜨지 않는 걸까요.
cv2.imshow 에서 잘못 불러온 건가
위 오류는 callback 함수 자체를 못 들어가는 거였습니다. 실수로 camera node를 안 키고 실행시켰더라고요ㅋㅋㅋㅋ
그런데 callback함수에 들어가고 나서 또 오류가 발생했는데 이는 CompressedImage에서 Image로 import를 바꿔주니까 해결이 됐습니다.
잘못된 영상
ros 이미지를 opencv이미지로 전환하여 영상을 내보내도록 하였는데 왜 이렇게 영상이 끊기는 걸까요
토픽을 받아오는데 시간이 걸려서 그런가
아래 그림은 위 영상처럼 나타날 때의 rqt_graph입니다.
해결 완료!
오류 해결한 영상
publisher 랑 subscriber에 토픽 이름이 같아서 그런 거였습니다.
받아오는 이미지가 같으니까 보여주는 이미지가 시간차로 계속 끊겨서 보이는 거죠
publisher 이름은 그냥 내 마음대로 지으면 되는 거였습니다. 받아오는 subscriber 이름만 카메라 토픽으로 써주면 되는 거였어요
이거였습니다! 이미지 변환 성공!!
그럼 이제 실시간 영상에서 마커 인식을 해보겠습니다.
마커 인식하는 코드와 이미지 변환해주는 코드를 합쳐서 ros 환경에서 마커 인식을 하였습니다.
그런데 로봇이 정면을 보고 있을 때 화살표를 표시하고 싶은데 위 영상을 보면 정면을 보지 않아도 화살표 방향을 표시하는 것을 볼 수 있습니다. 정면을 보도록 하고 싶으면 어떻게 해야 할까요... 축을 평행하게 만드는 방법이 뭘까요
방법은 마커의 xy평면과 카메라의 xy평면을 평행하도록 하는 것입니다.
블로그 맨 아래 질문란에 자세히 적혀있습니다.
rvec 행렬에 값 순서대로 x, y, z 축으로 얼마만큼 회전했는지 라디안 각도를 의미합니다.
마커의 x축이 180도 돌면 마커의 xy평면과 카메라의 xy평면이 평행하게 됩니다. 이를 조건으로 사용하여 rvec의 0번 값은 3~3.2 사이로 오고 1번 값은 0~0.02 사이로 오도록 하고 tvec에 x, y 값이 0에 가까우면 정면을 보는 것으로 인식하고 'front'라고 출력하도록 하였습니다.
카메라가 로봇에 부착될 것이기 때문에고 rvec에 z는 0도와 가까울 것으로 생각하여 조건을 넣지 않았습니다.
다음으로 할 것은 마커의 위치로부터 카메라의 위치를 구해야 합니다.
-회전구하기
1. 구한 rvec(회전벡터)를 cv2.Rodrigues 함수를 이용하여 회전행렬로 만들기
주로 공장에서 로봇을 사용할 때 마커 인식을 통해 로봇의 위치를 인식하도록 하는데요. 그럼 공장 내부 곳곳에 마커가 부착되어있어야 하는데 마커의 크기가 크면 보기 싫지 않을까요? 저는 여 러크기의 마커를 부착한 후 카메라와의 거리에 따라 변화하는 인식 정도를 알아보았습니다.
마커의 크기를 줄이거나 카메라와의 거리를 멀게 하여 언제 마커가 가장 잘 인식이 되는가를 보았습니다.
이때까지 위에서 사용한 마커의 크기는 100mm였습니다.
아래 측정에 사용된 마커 정보입니다.
마커 번호 : 100
마커 크기(mm) : 10, 30, 50
마커 크기가 100일 때는 상당히 먼 거리에서도 인식이 가능한 것을 확인하였습니다.
10일 때는 25cm 정도까지, 30일 때는 60cm 정도까지, 50일 때는 100cm 정도까지 인식은 가능한데 좌표축이 엄청 작게 나왔습니다.
측정 결과 거의 마커 크기에 두배 정도 거리까지 인식이 가능한 것 같습니다.
크기 10mm 거리 25cm 크기 30mm 거리 60cm 크기 50mm 거리 100cm
거리가 멀어졌을 때 인식률을 확인해 봤으니까 다음으로 거리가 어느 정도 이상 가까워지면 인식이 되지 않는지 확인해 보겠습니다.
10일 때는 4cm 30일 때는 4cm로 거의 동일하게 나왔는데요.
가까운 정도는 창안에 마커가 다 들어오면 되는 거라서 로봇이 마커에 아예 밀착하지 않는 이상 웬만하면 마커를 인식할 수 있을 것 같습니다.
마커의 크기는 카메라를 로봇에 부착해본 후 마커를 발견하고 로봇이 마커를 정면으로 바라보기까지 움직일 수 있는 반경을 고려해서 정해야 할 것 같습니다.
마커에 대해 더 찾아보고 현재 사용되는 마커는 어떤 것 이 있는지 왜 그 마커가 사용되는지 등등 여러 장단점을 비교해 본 후 어떤 마커를 쓰는 것이 가장 좋을지 조사해보겠습니다.
또한 카메라의 위치도 고민을 해봐야 합니다.
로봇의 전면부가 어떤 축인 지 확인한 후 그 축에 카메라를 설치할 경우 오랫동안 마커를 볼 수 있습니다.
그 위치가 가장 좋은 위치 아닌가 생각합니다.
마커를 인식한 후 로봇이 움직이도록 해보겠습니다.
먼저 웹캠에서 마커의 위치를 뽑아내서 토픽으로 내보내보겠습니다.
orientation : 방향
아래 영상은 뽑아낸 위치를 이용해 마커와 카메라사이 거리와 축의 각도를 토픽으로 알려주는 것 입니다.
마커를 인식했으니 그 위치를 이용해 속도를 publish해서 로봇을 움직여 보겠습니다.
로봇은 실행시키지 않고 realsense로 마커를 인식하라고 했을 때 입니다.
로봇을 실행시켜본 결과 아래 두 영상과 같이 나왔는데 각도값을 변경하거나 축이 맞는지 다시 봐야할 것 같습니다.
카메라가 마커를 인식했을 때 반대로 움직이는 것을 확인한 후 로봇의 z축값에 마커로부터 구한 angle그대로의 값을 넣은 것이 아니라 -angle로 넣어봤습니다.
또한 저는 로봇과 마커사이를 본 것이 아니라 카메라에서 본 마커의 위치를 이용해 거리와 각도를 계산했습니다.
그랬더니 위 오류를 해결할 수 있었습니다. 이와 관련된 영상은 아래에 있습니다.
마커를 문에 붙이지 않고 마커가 움직이면 로봇이 따라가도록 해보았습니다.
마커가 멀리있을때, 각이 클때 로봇이 조금더 빨리 움직이도록 하였고 마커와 카메라사이 거리가 10cm정도 떨어지게되면 더이상 가까이 오지않도록 하였습니다.
줄자로 재봤을때 실제로 10cm 떨어져있는지 확인한 후 다시 글을 쓰도록 하겠습니다....
영상이 어두워지면 마커를 인식하지못해서 이를 HE(histogram equalization)을 통해 이미지대조비를 높혀서 인식률을 높여보았습니다.
제가 사용한 것은 CLAHE (Contrast Limited Adaptive Histogram Equalization)입니다.
HE를 사용하면 이미지전체가 밝아져서 영상이 잘 안보이는 부분이 발생할수있기때문에 CLAHE를 사용하여 clip limit(histogram의 높이를 제한하는 값)값이상이 되는 부분만 밝게 하는 방법을 사용했습니다.
이는 계산시간이 길다는 단점이 있는데 얼마나 느린지, 인식속도에 문제가 없는지 확인해보겠습니다.
질문
Q1. import image 랑 compressedimage 랑 차이점?
A1. compressed 가 압축한다는 뜻인데 받아오는 이미지를 압축해서 쓸 것인지 그대로 쓸 것인지 묻는 것입니다. 카메라가 여러 대여서 받아와야 하는 이미지가 많고 용량이 크다면 압축을 해서 풀어서 사용하는 경우가 있는데 저는 카메라가 한대라 image를 셔요 하였습니다. compressed 이미지를 토픽으로 받아왔는데 엔코딩이 잘못됐다는 오류가 떴었는데 해결하는 방법은 더 찾아봐야 할 것 같습니다.
Q2. CmakeList에 의존성으로 opencv2를 사용하라고 했는데 가지고 있는 것이 opencv라서 그냥 opencv를 사용하였는데 같은 건가요?
A2. 예전 버전이 아마 opencv2일 텐데 그냥 opencv를 써도 상관없습니다.
Q3. 지금은 x축 원점에 가까워졌을 때만 방향을 표시하였는데 정면을 보지는 않습니다. 카메라를 정면으로 보게 만들고 싶으면 어떤 조건이 들어가야 할까요?
A3. 정면을 보려면 마커의 xy평면과 카메라의 xy평면이 평행하다는 조건을 넣어줘야 하는데 이는 rvec 값을 조정하면 됩니다. 정면을 보고 싶을 때 마커가 카메라의 중앙에 왔으면 할 때 rvec를 (3.14 , 0, 0)로 만들어 주고 tvec를 (0,0, z)로 만들어 주면 됩니다. rvec는 라디안 값입니다. (좌표의 부호는 상관없습니다.)
위 코드를 이용하여 cmake설정을 해줘도 되고 $ ccmake .. 을 쳐서 직접 입력을 해도됩니다. 저는 설정이 제대로 되지않아 ccmake ..을 이용하여 직접 바꿨습니다. 다 입력을 하고 키보드 c 와 g 를 눌러줍니다. c 는 configure 을 의미하고 g 는 generate 를 의미합니다. ccmake .. 이 뭐였지...
터미널에서 버전을 확인하려고 했을때 안뜰수도있습니다. sudo apt-get 명령어를 통해서 설치한 것이 아니면 안뜰가능성이 있다고 합니다.
파이썬에서 아래와 같이 나오면 opencv가 깔려있는것입니다.
yehjin@yehjin-900X3L:~$ python2
Python 2.7.17 (default, Feb 27 2021, 15:10:58)
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'4.2.0'
ctrl+D를 하면 파이썬을 빠져나올수있습니다.
g++에러
yehjin@yehjin-900X3L:~$ g++ -o facedetect /usr/local/share/opencv4/samples/cpp/facedetect.cpp $(pkg-config opencv4 --libs --cflags)
Package opencv4 was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv4.pc'
to the PKG_CONFIG_PATH environment variable
No package 'opencv4' found
g++: error: /usr/local/share/opencv4/samples/cpp/facedetect.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
ros 환경에서 파이썬을 실행해도되지만 opencv를 설치하는 과정이 까다롭기때문에 설치가 완료됐어도 없다고 오류가 뜰수있습니다. 그럴때는 ros환경에서 실행시키는 것이 아니라 코드가 있는 폴더로 이동하여 python으로 실행시키면 됩니다.
코드를 입력하여 실행해보았을때 오류가 떠서 실행되지않습니다. 먼저 노트북의 웹캠이 작동하는지 보았는데 /dev/video0자체가 없더라구요
realsense를 꽂고 실행시킨후 ls /dev/video*를 해도 없다고 뜹니다
lsusb로 연결은 된것을 확인했는데 왜 dev에는 없는건지 모르겠습니다.
$ sudo apt-get install cheese
$ cheese
하면 된다고 하는데 사진이 없다고 뜹니다.
marker라는 패키지를 만들어서 python코드를 실행시키려고 했봤습니다.
위 코드처럼 터미널에서 오류가 떠서 실행되지않습니다.
cvtColor오류는 이미지를 불러들이는 path가 잘못돼서 그렇다고 하는데 코드에서 path가
cap = cv2.VideoCapture() 이부분이라고 생각하는데 아닌것같아서 잘못된곳을 못찾겠습니다.
원래 사이트에서 코드를 조금 고쳤는데 함수를 track(matrix_coefficients, distortion_coefficients)이렇게 쓰는게 아닌가요...? 왜 실행이 안되는 걸까요. 저거는 그냥 함수부분 자체문제가 있다는 뜻이었습니다... 저 함수를 사용하는데는 문제가 없는거 같아요
계속 path가 문제라고 하길래 video를 받아오지 못하면 empty frame이라고 출력하도록 했는데 역시 path문제가 맞았습니다....
제가 저장한 calibration파일에서 행렬을 못불러오는거같아서 직접 입력을 했는데 행렬이 여전히 들어가지는 못해요.
이 문제는 print를 통해 해결을 했습니다.
카메라를 불러오는데 문제가 있었기 때문에 연결이 문제인가했는데
usb에 연결됐다고는 떠도 실시간 영상을 불러오지는 못하더라구요. 코드자체도 애초에 webcam을 받아오라는 코드였는데 webcam만 따로 켜보려고해도 켜지지않았습니다. 이걸로 일주일 넘게 고민했는데 알고보니 하드웨어 오류...
다른 노트북에서 하니까 webcam이 잘 켜지더라구요 코드문제인줄알았는데 아니였네요..
진작 하드웨어인지 의심해볼걸 그랬어요
ros에서 python을 실행시키는게 python [파일이름] 이었는데 저는 그걸모르고 python에 들어가서 하는거랑 ros에서 하는거랑 다른건줄 알았네요. 근데 왜 쟤는 파일이 없다고 할까요ㅎㅎㅎ
다른 컴퓨터에서 해봤는데 카메라는 되는데 이제 함수부분이 문제네요....
* 포트 보는방법
코드에 포트번호를 입력할때 Bus 옆에 번호를 넣으면 됩니다.
왜 함수에 대한 잘못된 인수라고 뜰까요? 어떤 형식으로 값을 넣어야되는지 모르겠습니다.
변수이름만 넣어도 안되고 배열로 지정하고 넣어도 안되고 어떤 형식으로 적어야 할까요...
저거는 들어가는 변수의 개수가 더 많아서 그런거였습니다. 뒤에 cameraMatrix, distCoeff부분을 지우니까 됐습니다. 카메라는 작동하는데 이제는 마크 자체를 인식을 못하네요.
realsense로 해보려고 했는데 videocapture가 웹캠에 사용되는 거라서 realsense로는 되지않기때문에 카메라를 웹캠으로 바꿨습니다. 예전에 차선인식할때 realsense로 해봤던거 같은데 그때 어떻게 했지...
id: dictionary 에 속한 마커들 중 사용할 마커의 id 입니다. DICT_6X6_250의 경우 0부터 249까지의 id를 지정할수있습니다.
마크를 인식하기는 하는데 하자마자 카메라가 꺼졌습니다. 왜그런가 했더니 웹캠으로 다시 camera calibration을 해야한다고 합니다. 사진크기가 이전에 realsense와 달라서 불러온 matrix가 문제가 있는거 아닌가 하는 것입니다.
웹캠으로는 어떻게 하지.......
제 노트북에서 realsense로 영상을 받아오는게 안됐다고 위에서 말씀드렸는데요.
카메라 usb port색에 따라서 버전이 다른데요 포트 부분이 파란색은 3.0 흰색은 2.0이라고 합니다.
노트북에 포트가 2.0이라서 realsense의 3.0포트가 맞지않아서 코드를 통해 실시간 영상을 불러오는게 안될수도 있다고 합니다.
realsense camera로 마커인식하는 것은 다음에 다시 도전하겠습니다...일단 webcam으로 먼저 해볼게요..