https://m.blog.naver.com/windowsub0406/220894645729
Python3.5 그리고 Opencv 3.1 기준 코드 작성
셋팅만 제대로 됐다면 복붙만해도 문제없이 돌아갈 것이다.
이번 글에서는 왼쪽 차선과 오른쪽 차선의 대표 직선을 찾아서 출력해보고, 차선 검출에 도움이 되는 몇몇 방법들을 소개하겠다.
이번 글은 그냥 무작정 따라하기 보다는 내가 묻는 문제에 대해서 먼저 스스로 고민해보고 생각해보면 좋을 것 같다. 이제 어느정도 기본은 다 알기 때문에 앞으로는 마냥 따라해서 얻을 건 별로 없고 그냥 내 생각을 따라하는 것 뿐일 것이다. 정답은 없기 때문에 내가 한것은 그냥 아무것도 아닌 방법일 수도 있다. 이 사람은 이렇게 했네 정도로만 생각했으면 좋겠다.
이전 단계들을 잘 소화했다면 차선의 Edge를 통해 차선 부근의 직선을 잘 추출할 수 있었을 것이다. 대표 직선을 추출하기 전에 다른 걸 먼저 해보자.
조금 어려운 사진들로 이전 알고리즘의 문제점을 테스트를 해보자.
Challenge 1
여기서 차선 추출이 잘 되는지 테스트해보고 해결을 해보길 바란다.
이전 글과 같은 코드로 실행해보겠다. 그 코드로 위 사진을 출력해 보면
결과 :
결과는 처참하다. 역시 차선인식이 이렇게 쉬웠을리가 없다.
이 말도 안되는 직선을들 좀 필터링해보자. 무엇을 기준으로 차선이 아닌 직선들을 골라낼 수 있을까?
우선 직선의 기울기를 이용해볼 수 있다. 내 차가 차선을 잘 맞춰서 가고 있다면 내 앞의 차선이 내 앞에 수평으로 놓일 상황이 있을까??(계속해서 말하지만 직선차선 기준이다.)
이전에 HoughLinesP() 함수를 통해서 모든 직선들의 시작점 끝점에 대한 좌표 값을 알고 있으므로 각 직선들의 기울기 또한 어렵지 않게 구할 수 있다. 그럼 우선 수평에 가깝고 완전 수직이지도 않은 기울기로 직선들을 추출해 보자.
결과 :
다행히 잘 걸러졌다.
이제 왼쪽 오른쪽 차선의 대표 선을 추출해 보자.
주저리주저리 설명하지 않고 코드를 첨부할테니 도움이 될 것 같으면 코드를 분석해보면 될 것 같다.
대표 선을 추출하는 방법만 한 두 방법이 아닐테고 내 코드가 답도 아니니까...
결과 :
나는 fitline() 함수를 썼고, 대표선도 잘 출력된다.
이제 추가될 수 있는 몇몇 방법들을 생각해보면
1. 소실점이라고 있다. Vanishing point 라고 하고 사진 찍는거 좋아하는 분들을 많이 들어봤을 것이다. 위에 내가 출력한 두개의 파란 선을 기준으로 설명하자면 두 파란선이 선분이 아니고 긴 직선이 된다고 하면 위쪽에서 교차점이 생길 것이다. 그 부분을 소실점이라고 한다. 그래서 소실점의 움직임을 Tracking 하면서 차량의 방향을 정하고, 칼만필터라든지 하는 것들을 통해 차선이 보이지 않는 경우에도 예측할 수 있다.
2. 대표 직선을 추출한 후에 동영상에 돌려보면 선들이 꽤나 짜잘짜잘하게 움직인다. 이러한 움직임을 좀 부드럽게 하고 싶다면 이전 프레임들의 선 정보를 저장 한 후에 평균치를 출력함으로써 부드러운 움직임을 볼 수 있다. 나 같은 경우에는 10프레임 정도 저장한다.
3. 차선 인식을 한다면서 직선만 고려하는 것은 말도 안 된다. 사실 웃기는게 인터넷에 올라와 있는 차선인식 대부분을 찾아보면 되게 잘되는 것 처럼 올렸지만 정작 곡선을 고려하지 않은 경우가 되게 많다. 그런데 그럴만도 한게 직선인식은 지금껏 해온 것처럼 크게 어렵지는 않지만, 곡선은 그리 쉽지 않기 때문이다. 올해 프로젝트에서 굉장히 급격하게 꺾이는 곡선까지 검출해야하는 경우가 있었는데, 꽤 힘들었었다. 다만 이 곡선에 대해서 글을 쓰지 않는 이유는 Udacity에서도 곧 배울 것이므로 좀 더 보완하고 스스로도 어느정도 지식을 더 쌓은 후에 글을 작성하려 한다.
4. 모든 차선을 검출하면 좋겠지만 어디에나 항상 변수가 있다. 차선 위에 장애물이 있어 검출이 안 될 경우도 있을 것이고, 차선이 지워져서 잘 안보일 수도 있다. 그러한 경우에 차선의 위치를 어느정도 예측을 할 수 있어야 한다. 위에 소실점에서 말했지만 칼만필터 실제 시중에 있는 차선 인식 시스템에는 아마 거의 대부분 있을 것이다. 예제 같은 것들이야 쉽게 구할 수 있지만 그것을 실제로 내가 하고 있는 것에 적용을 하려고 하면 아마 생각보다 어려울 것이다. 다만 최근에 딥러닝이 많이 연구되면서 RNN(Recurrent Neural Network) 의 성능이 매우 좋아 기존의 칼만필터를 대체하고 있다는 말을 들은 적이 있다.
5. Bird's eye view 라고 있다. Top View 라고 하면 되려나.. 하늘에서 본 것과 같이 이미지를 재구성한 후에 하는 방법이 있는데 일반 대학생이 아니라 석사 이상 분들 중에는 이 방법으로 하시는 분들을 꽤 많이 봤다. 이 방법은 조만간 나도 써볼 예정이다.
6. 이건 내 개인적인 경험이다. 이번 프로젝트에서 차선 외에 쓸모없는 직선들을 제외하기 위해서 RANSAC 알고리즘을 추가해봤다. Random Sample Consensus 의 줄임말이고 말그대로 랜덤으로 점 2개를 뽑아서 직선을 만들어 얼마나 많은 점들이 그 직선에 포함되는지를 여러번 반복하여 최적의 직선을 찾는 것이다. 계산량이 많아진다는 단점이 있지만 결과가 궁금해서 추가해봤고, 꽤 괜찮은 결과가 나왔다.
Challenge 2
동영상 크기가 커서 올릴 수가 없으니 위에 들어가서 challenge.mp4 동영상을 받고 오류없이 차선인식을 성공시켜보면 좋을 것 같다. 개인적으로 생각보다는 쉽지 않았다.
지금은 좀 더 보완을 했지만 아래는 제출당시 내 결과 동영상이고, 코드나 pipeline 설명 역시 위에 링크 걸어놓은 github에 있다.