자율주행은 정말 정말 많은 기술들이 합쳐져서 돌아간다...카메라 인식, 센서 인식(LiDAR, Encoder, GPS, IMU), 딥러닝 등ㅜㅅㅜ
그 모든 작업들에 참여하지는 못했지만 내가 참여한 작업들은 기록을 남겨놓으려고 한당
팀에 들어온 이후, 처음으로 이뤄낸 성과같다ㅋㅋ
처음에 카메라 캘리브레이션 미션을 맡았을 때는 "이게 뭐지ㅣ...이런것까지 해야하는건가!!" 싶었는데, 카메라 캘리브레이션에 대해 공부하면서 정확히 장애물을 인식하고, 차선을 인식하기 위해서는 꼭 필요한 기술이라는 것을 알았다.
캘리브레이션 이론은 증말루 복잡해서 내가 설명을 하지는 못할 것 같다.. 구글에 치면 많이 나온다!!
다행히 Python Opencv를 사용하면 코드 몇줄로도 카메라 캘리브레이션을 할 수 있다.
현대 과학, 컴퓨터 공학 너무 사랑해😍
wayp0int/workspace/src/wayp0int/scripts/lib/cam_util.py 에 추가한 코드의 완성본은 이렇다!
이제 어떻게 해서 이 코드가 된건지 같이 알아보자.
코드는 블로그에서 참고했다! http://www.gisdeveloper.co.kr/?p=6868
증말루 증말루 감사드린다ㅜㅅㅜ
이론을 설명하자면 정말 길고 이미 많은 전문 블로그에 잘 설명이 되어있기 때문에 나는 야매로 빨리 설명해보겠다!!
코드를 두 부분으로 나눠서 설명하겠다!
5~37번째 줄은 ./data/*안의 모든 사진들을 for문으로 분석하면서 카메라 메트릭스를 알아낸다.
카메라 메트릭스 계수는 현재 내가 사용하는 카메라의 휘어짐(?쉽게말해서) 특성이다. 그래서 카메라 메트릭스(=카메라 내부 파라미터)만 알면 나중에 어떤 이미지가 들어와도 이전에 알아낸 카메라 메트릭스 계수만 대입해서 왜곡을 보정하는 과정만 거치면 된다.
(너무 야매여서 이론적으로 틀릴수도 있습니다ㅜㅅㅜ일단 처음하는 사람들은 대충 맥락만 이해하세요ㅎㅎ...)
37번째 줄을 보면
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
라고 cv2.calibrateCamera() 함수가 ret, mtx, dist, rvecs, tvecs 를 반환하는 것을 볼 수 있다.
cv2.calibrateCamera() 는 카메라 메트릭스, 왜곡계수, 회전/이동 벡터들을 반환한다. 나중에 이 값들에 어떤 수가 들어있는지 한번 살펴보자!!
40~58번째 줄은 내가 보정하고 싶은 사진을 불러와서 아까 찾았던 계수들로 보정을 해서 calibresult.png로 저장한다. 이미지를 저장하고 나서 calib.npz로도 보정 계수를 저장해준다.
그 아래 mean_error가 나오는 이유는 왜곡 제거 시 수행된 작업에 발생된 오차가 얼마인지 알기위한 기능이다. 결과값이 0에 가까울수록 정확하다.
위의 코드에서 ret, mtx, dist, Total error 값만 뽑아낸 것이다.
처음엔 print하고 나서 이게 뭐지..? 하면서 보다가 두번째 mtx의 배열 모양이
camera matrix의 배열 모양과 같은걸 발견했다.
바로 이게 이거였구나!! 이해가 되고 찾아낸 저값을 코드에 박아줘서 계속 재활용할 수 있게 만들어줬다ㅋㅋㅋㅋ
다시 코드 완성본을 보자! (지금보니 ret 값은 필요 없는 것 같다..)
mtx, dist에 np.array를 사용해서 똑같은 배열을 만들어준 후 파라미터로 받은 image를 캘리브레이션 하는 코드다! 당연히 return 도 dst(=image)다.
최종적인 ret, mtx, dist 계수는 직접 저렇게 사진을 100장 이상 찍어서 한번에 돌려서 나온 숫자다ㅋㅋㅋ큐ㅠㅠㅠ
정말 노가다였지만 결과물을 보니 흡족하다. (사진을 보면 색깔 점이 찍힌 것을 볼 수 있다!)
오른쪽이 보정 전, 왼쪽이 보정 후
솔직히 그렇게 많은 차이가 있지는 않다...그래도 보정후 오른쪽 코너를 보면 조금 펴진걸 볼수는 있다ㅋㅋㅋ