#차선인식 #OpenCV #영상처리 #차선곡률 #자율주행
[0] 개요: 자율주행 프로젝트에서 카메라를 이용한 차선 인식을 학부생 기간 동안 연구했다. 이 부분에 대해 공유하고자 이 글을 쓰게 되었다. 코드 부분은 추후 GetHub를 통해 업로드 한다. 다음 글은 이론적인 부분을 쓴다고 생각하면 된다.
실제 최근 진행되고 있는 차선 인식 연구는 딥러닝 기반으로 이뤄지고 있다. Feature 기반 차선 인식 process는 old한 방식에 한계점도 많이 존재한다. 대표적으로 다음과 같다.
1. 조도에 따른 차선색 검출값을 매번 변경해야 한다는 점 #2. 도로폭에 따라 ROI 영역을 달리해야 한다는 점 #3. 정확한 곡률 추종에 한계가 있어 급격한 커브 구간에서 탈선하는 경우가 발생한다.
그럼에도 해당 프로세서를 우리 플랫폼에 적용하고자 하는 이유는 다음과 같다.플랫폼에서 이미 object detection 문제를 해결하기 위해 욜로브4를 돌리고 있는데, 함께 돌리면 자원이 한정적이어서 시스템 다운이 될 것 같다는 점, 훈련이 번거롭다는 점이다.
[1] 파이프라인 : 필자의 차선 인식 프로세스는 다음과 같은 순서로 이루어진다.Katri에서 제공하는 강의 차선인식 pipeline에 학교 수업이었던 영상처리에서 배운 전공 지식을 더했다.
스텝 1. Camera Calibration을 가지고 있는 카메라에서 영상처리를 적용하기 위해서는 카메라 내/외부 파라미터를 구해야 한다. 이 파라미터를 구하기 위해서는 Python에서 제공하는 몇 개의 함수를 사용하여 사용하는 카메라에서 Checkerboardimage를 취득한 후에 적용하면 된다. 이 중 외부 파라미터를 가지고 있으면 왜곡을 보정할 수 있다.(왜곡 보정과 Calibration는 별개의 것이다.)
아래 사진을 보면 검정색과 bending되어 있는 영역은 왜곡되었음을 확인할 수 있는데, 이는 광각 카메라를 사용할 경우 쉽게 확인할 수 있다. 이를 보정하면 왜곡에 대한 부분이 사라지게 될 것이다.적용할 경우 원본 이미지에서 끝 영역이 잘려 보이는 현상을 확인할 수 있는데, 이는 위의 설명이 그 이유라고 보면 된다.
주의: resize 하기 전 원본 이미지를 Calibration 해야 한다.
스텝 2. ROI 지정 후 Personation 왜곡이 보정된 이미지는 다음으로 사용자 임의로 4개의 ROI점을 지정한 후 Personation을 적용하여 Bird-eye-viewimage로 전환한다. 이 과정을 다른 논문에서는 bird-eye-viewconversion이라고도 부르는 꽤 많은 연산량을 차지하고 있다.
여기서 나중에 말씀드리겠지만 우리가 잡는 ROI 4점의 실제 거리를 측정하면 이를 perspectivetransformation을 적용하면 픽셀당 몇 m인지 확인할 수 있다. 이것은 나중에 Localmap 기반의 Purepursuits 가로제어, 곡률 기반의 PID종 제어에 적용하기 위해 필요한 task이다.
예를 들어 우리가 잡으려는 ROI 4점이 가로 4m, 세로 3m이고 우리가 resize로 하는 이미지가 600×400이라면 가로는 1pixel에 4m/600으로 환산할 수 있다.
Perspevtivetransformation은 간단히 말해 4가지 점을 각각 자신들이 원하는 점으로 이동시키는 것이라고 생각하면 된다. 4개의 ROI점을 각각 우리가 재정의하는 화면의 정점으로 이동시키면 그 안의 점은 perspectivetransformation 변환 행렬을 통해 적절한 위치로 이동하게 된다. 이렇게 새가 바닥을 보는 듯한 bird-eye-viewimage가 만들어진다.
영상처리 수업에서는 해당 변환을 하기 전에 선행하는 단계의 변환이 있는데 이는 다음과 같다. 참고하기 바란다.
Step 3. Filtering 다음은 real world 이미지를 우리가 원하는 차선만을 고르기 위한 filtering 작업에 대해 설명한다. 사실 filtering에 대한 부분은 정답이 없다. Python에서 제공하는 filter를 이것저것 바꿔가며 적용하면서 본인의 사양에 맞는 만큼 분산값을 설정하고 추가적인 filter를 적용하거나 빼야 한다. 따라서 concept만 catch해 나가면 될 것이다.
검은 아스팔트 도로 위에서 우리가 원하는 차선의 흰색과 노란색 선을 빼려면 어떤 방법이 있을까?전공 지식을 알고 있다면 선이라는 것은 색깔이 급격히 변하는 것이라고도 생각할 수 있고, 혹은 자체인 특정 색에 대한 정보를 담고 있기 때문에 이에 착안해 필터링하면 될 것이다.
이를 위해, gradient를 추출한 필터링 결과와 황색 백선을 추출한 필터링 결과를 정합하는 것으로 시작된다.
(1) Gradient 추출 번역하면 경사도를 의미한다. (edge와 달리) 급격하게 변하는 부분을 찾음으로써 영상 처리에서는 general하게 Sobelfiltering으로 많이 찾곤 하는데 우리가 테스트한 환경에서는 노이즈가 되는 부분이 많아 보다 정교한 경사도 검출 필터링이 필요했다. 그것이 바로 Scharrfilter다.(샤를 필터라고 읽는다.) 아래 블로그에 설명이 더 자세히 적혀 있다.
이를 이용하여 수평 수직 방향의 gradient 성분을 찾고 이를 summation하면 모든 방향의 gradient를 검출할 수 있다. 이렇게 되면 차선 부분이 검출되고 주변의 noise에 대한 부분도 함께 검출될 것이다.
https://talkingaboutme.tistory.com/entry/OpenCV-Scharr-filterLearningOpenCV에 보면 sobel 미분에 상세하게 scharr 필터에 대한 내용이 들어 있습니다. 앞의 포스트에서 말하기를, 소벨 미분은 각 축에 대한 미분을 실시해 다항식을 근사화시킨 결과라고 말했습니다.talkingaboutme.tistory.com (2) 황색 백선 검출 차선의 색상을 구분하기 위해 적용하는 process이다. 흰색 영역은 RGB 영역에서 upperlower thresholding 값을 실험적으로 찾아 검출하고 노란색 영역은 HSV로 변환한 후 upperlower thresholding 값을 실험적으로 찾아 검출한다.
그다음에 지문인식에 사용하는 영상처리 기법 중에서 Thickened 기법이 있는데, 이를 적용하면 검출된 결과가 좀 더 증폭된다.
(1)(2)를 통해 필터링된 화상은 bitwiseand 연산자로 정합한다.
(3) Medianfiltering 정합된 이미지에도 테스트 환경에서는 점과 같은 Noise가 다수 존재했던 이 부분은 saltandpeppernoise로서 Medianfiltering으로 제거할 수 있다. Medianfiltering은 픽셀값을 상승순으로 정렬하고 가운데 중간값을 선택하여 픽셀값을 결정하는 필터링이다.
이렇게 하면 최종적으로 검출된 차선을 확인할 수 있게 된다.
다음 포스트에 이어서