본문 바로가기
Programming/Capstone Design

[Capstone Design]3. 차선 인식(Lane Detection) - 1

by NoiB 2021. 11. 2.
반응형

이제 본격적으로 차선 인식을 진행해봅시다.

이 사진을 우리가 운전석에 앉아서 보는 전방 모습이라고 해볼까요. 여기서 우리가 사고를 내지 않기 위해서 생각해야 하는 것들은 뭘까요? 앞 차량과의 거리, 현재 내 차량의 속도, 내 차량의 차선이탈 여부 등등이 있겠지만 일단 이 포스팅은 차선 인식이니까 차선만 한 번 신경 써봅시다.

저렇게 파란색으로 칠해놓은 부분이 우리가 하려고 하는 차선인식의 핵심이 되겠죠? 저게 바로 현재 우리 차량이 위치하는 차선이니까요(사진은 임의로 차량의 블랙박스 영상이라고 하겠습니다). 그럼 이제 어떻게 하면 되는지에 대해 알아봅시다.

 

Grayscale(그레이스케일)

먼저 차선 인식을 사용하고자 하는 이미지를 그레이스케일, 즉 흑백 이미지로 바꿔야 합니다. 그 이유는 뭘까요? 차선은 흰색, 노란색만 있으니까 흰색 개체와 노란색 개체만을 추출하면 훨씬 간단하게 할 수 있지 않느냐는 질문이 나올 수도 있습니다(그런 전처리를 가끔 이용하기도 합니다만 그 내용은 또 나중에 포스팅에서 한 번 다뤄보겠습니다).

여러분에게 이 사진을 보고 차선이 무슨 색이냐고 묻는다면 바로 차선 전부를 흰색이라고 답할 것입니다. 하지만 컴퓨터의 시각에서 즉, 색상을 픽셀 단위의 데이터로 뜯어보았을 때는 어떨까요? 흰색은 hex코드 기준 #FFFFFF입니다. 하지만 차선 위에서 실제로 색상을 찍어보면 전부 다 같은 값이 나오지가 않습니다. 특히 양 끝의 흐려지는 부분은 검은색에 가깝게 나오겠죠. 또 왼쪽 차선에 차량의 헤드라이트 빛이 비치는 곳은 또 다른 값(붉은색이 높은 값)이 나올 겁니다. 그래서 사실 색상을 이용해서 잡아내는 것은 약간 문제가 있습니다(물론 못한다는 것은 아닙니다. 값의 범위를 넉넉하게 정해주면 근사하게 추출이 가능하죠). 따라서 색상에 따른 추출은 일단 사용하지 않는 것으로 하고 저희는 캐니 외곽선 검출(Canny Edge Detection)의 전처리로 이미지를 그레이스케일로 변환하는 것입니다.

 

실행결과 : 

이렇게 되면 더 이상 색상에 대한 데이터는 의미가 없어지죠.

Gaussian Blur(가우시안 블러)

가우시안 블러 또한 외곽선 검출의 전처리 과정입니다. 블러라는 말을 들으면 뭐가 생각나시나요? 저는 화장품이나 포토샵같은게 제일 먼저 떠오르는데요. '블러'는 흐릿하게 하다, 모호하게 하다 등의 뜻을 가지고 있는 영어 단어로 뭔가를 흐려보이도록 만드는 대부분의 작업을 말합니다. 화장품의 블러도 피부에 발라서 트러블이나 잡티등을 잘 안보이게 해주고, 포토샵에서도 굳이 보여주고 싶지 않은 부분을 조금 흐릿하게 하거나, 좀 더 포커싱을 하기 위해 테두리를 흐리게 하기도 하죠.

 

여기서 진행하는 가우시안 블러 작업은 전체 이미지를 약간 흐리게 합니다. 외곽선 검출 작업을 진행할 때 미리 블러 처리를 해줌으로써 외곽선 검출을 했을 때 좀 더 좋은 결과를 내게 하기 위함입니다. 

 

실행결과 :

흐릿하게 만드는 정도는 커널 사이즈 조절로 할 수 있기 때문에 본인이 작업 수행에 필요한 만큼 건드리시면 됩니다.

 

Canny Edge Detection(캐니 외곽 검출법)

차선 인식의 핵심 중 하나입니다. 이 방법으로 차선의 외곽선을 검출해서 저희 입맛대로 가공해보도록 하겠습니다.

 

실행결과 :

threshold1,2를 조절해서 더 많은 외곽선을 검출하거나 더 적은 외곽선을 검출하도록 할 수 있습니다. 저는 이번에 좀 대충 주긴 했습니다만, 차선은 선명하게 잘 나오고 있으니 이걸 이용해서 계속 진행해보죠. 외곽선은 구분이 뚜렷할수록 잘 검출이 되기 때문에 가우시안 블러 처리를 통해 원본 사진을 흐릿하게 해서 별로 중요하지 않은데 구분감이 뚜렷한 객체들이 검출이 되지 않도록 할 수 있습니다. 흐릿하게 할수록 검출되는 외곽선이 더 적어지기 때문에 그것도 잘 사용해서 원하는 객체만 깔끔하게 잡히도록 하나씩 건드려보시기 바랍니다. 외곽선 검출은 분명히 핵심이지만, 아직 다른 중요한 단계도 많이 남았기 때문에 갈 길이 멉니다. 하지만 여기서 더 썼다간 글이 너무 길어지는 관계로 여기서 마치겠습니다.

 

오늘 사용한 전체 코드 :

import cv2

def grayscale(img):
    return cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)#이미지 그레이스케일로 변환

def gaussian_blur(img, kernel_size):
    return cv2.GaussianBlur(img, (kernel_size, kernel_size), 0)#이미지 블러 처리

def canny(img, low_threshold, high_threshold):
    return cv2.Canny(img, low_threshold, high_threshold)#이미지 외곽선 검출

origin_img = cv2.imread('./lane_detection_sample.jpg')#이미지 불러오기
gray_img = grayscale(origin_img)#그레이스케일 함수 실행
blur_img = gaussian_blur(gray_img, 5)#블러 함수 실행
canny_img = canny(blur_img, 50, 200)#외곽 검출 함수 실행

cv2.imwrite('./canny_img.jpg',canny_img)#이미지 저장
cv2.imshow('canny',canny_img)#이미지 출력
cv2.waitKey(0)#키 입력 전까지 창 띄워놓기
cv2.destroyAllWindows()#모든 cv2 윈도우 끄기

 

반응형