OpenCV 원근변환과 슬라이딩 윈도우를 이용한 차선 찾기

조환영·2023년 4월 28일

OpenCV

목록 보기
3/3
post-thumbnail

[15일차]

TIL

차선 검출 (원근변환, 슬라이딩 윈도우 사용)

  • 카메라 보정

  • 버드 아이 뷰

  • 이미지 임계값 및 이진 이미지

  • 슬라이딩 윈도우로 차선 위치 파악

  • 파악된 차선 위치 원본 이미지에 표시


학습내용

[1] Camera Calibration

1. 카메라 보정을 하는 이유

  • 카메라 이미지의 목적은 2D 이미지로부터 실제 3D 공간 좌표를 복원하고, 3D로 부터 영상 이미지에 투영된 위치를 파악하기 위함이다.

  • 이 작업에 카메라 내부 기구적 요인(렌즈의 종류, 렌즈와 이미지 센서간의 거리 및 각도 등)이 방해가 될 수 있다.

  • 이를 제거하기 위해 카메라 내부 요인의 파라미터 값을 구하는 과정이 camera calibration이다.

  • 결국 이 파라미터를 이용해 왜곡된 지점을 왜곡되지 않은 지점으로 사상시키는 것 (mapping)

  • Pin-hole 카메라의 2D perspective projection model로 카메라 내부, 외부 파라미터를 다루는 방법을 설명한 글이 있으니 나중에 관심이 있으면 참고하자. (지금은 활용법을 터득하는게 우선인 듯)

출처: https://darkpgmr.tistory.com/32

2. 보정 방법

(1) 패턴 설치: 대비와 패턴이 강하고 규칙적인 "체스판 이미지"를 사용한다.

(2) 패턴 촬영: 체스판을 다양한 각도와 거리에서 찍는다.

(3) 이미지 전처리: 찍은 이미지 보정, 노이즈 제거 및 코너 검출 등

(4) 내부 파라미터 추정: Calibration에 사용될 intrinsic parameter를 계산한다. (수학적 모델은 찾아보길...)

(5) 외부 파라미터 추정: extrinsic parameter는 카메라 설치 높이, 방향 등 외부적 요인을 말한다.

(6) 파라미터 최적화: 추정된 내, 외부 파라미터를 최적화 한다.

(7) 왜곡 보정: 파라미터로 왜곡을 보정하고 (mapping)

(8) 평가: 결과를 평가한다.

<참고> 큰 개념을 이해하기 위해 얄팍한 지식으로 끄적인 겁니다..ㅎㅎ

3. 함수 [Python]

  • 체스판의 코너를 찾는 함수

    findChessboardCorners()
  • 체스판의 코너를 그리는 함수

    drawChessboardCorners()
  • camera matrix, skew_c, 회전/변환벡터 반환

    cv2.calibrateCamera()

  • 왜곡 된 이미지를 펴주는 함수 (교정)

    cv2.undistort()

[2] Bird-eye View

1. 개념 및 필요성

  • 새가 하늘에서 내려다보듯이 위에서 아래를 내려다 보는 방식

  • 선의 곡률을 측정하기 위해 도로 이미지를 하향식 보기로 변환할 필요가 있다.

2. 원근 변환 방법

(1) 원근변환(perspective tf) 행렬 M을 계산한다.

cv2.getPerspectiveTransform(src, dst)

(2) 역 원근변환을 계산한다.

cv2.getPerspectiveTransofrm(dst, src)
  • 단순히 src와 dst 의 위치를 바꾸면 된다.

(3) 원근변환을 사용해서 이미지를 뒤튼다. (원하는 구도로 변환하기 위해)

cv.warpPerspective(img, M, img_size, flags=cv2.INTER_LINEAR)
  • 원근 변환을 위한 4개의 점 식별법
    • bird-eye view에서의 직사가형을 나타내는 원본이미지의 사다리꼴 모양 4개의 점을 선택한다.
    • 가장자리 또는 모서리 감지를 통해 이미지에서 4개의 점을 감지하고 색상 및 속성을 분석해 선택한다.
    • 선택한 4개의 점을 적절하게 정렬한다.

[3] 이미지 임계값, 이진 이미지

1. 배경지식

  • HSV
    • H (색조) / S (채도) / V (명도)
    • 명도가 낮을 수록 검은색, 명도가 낮고 채도가 낮을 수록 흰색
  • LAB
    • L (명도) / A (red, green 값) / B (yellow, blue 값)
    • 노란색 차선을 인식할 때 B를 사용하면 좋은 성능을 낸다.
  • HLS
    • H (색조) / L (밝기) / S (채도)
    • 색상 균형, HSV의 V(명도)를 L(밝기)로 바꿈
    • 밝기가 낮은 수록 검은색, 밝기가 높을 수록 흰색
    • 흰색 차선을 인식할 때 L을 사용하면 좋은 성능을 낸다.

2. 히스토그램 방법

  • 도로 이미지에 보정, 임계값 및 원근 변환을 적용

  • 차선이 두드러지는 이진 이미지를 얻음

  • 이미지를 기반으로 라인의 일부, 왼쪽/오른쪽 라인 등을 결정해야 함 => 히스토그램 사용

  • 이미지의 각 열(column)의 픽셀 개수를 더하면, 히스토그램에서 차선이라고 의심되는 곳에 peak 가 생성된다.
    (흰색이 몰려있으니까 당연히 peak가 생김)

  • peak가 생긴 곳의 x 좌표를 읽으면, 차선일 가능성이 높은 곳의 위치를 알 수 있음.

[4] 슬라이딩 윈도우

1. 개념

  • python 알고리즘의 일종으로,
    고정 사이즈의 윈도우(특정 범위)가 이동하면서 윈도우 내에 있는 데이터를 이용해 문제를 풀이하는 알고리즘이다.

  • 고정적인 범위를 탐색할 때 유리하고, 중복으로 연산을 제거하면서 효율을 높일 수 있다는 장점이 있다.

    2. 방법

  • 히스토그램으로 찾아낸 차선 위치 x를 이용한다.

  • 선 중심 주변에 배치된 슬라이딩 윈도우를 사용해 프레임 상단까지 선을 찾아 따라간다.

  • 한 윈도우 안에서 감지되는 선의 중심을 기준으로 계속 윈도우가 쌓인다. (현재 블럭의 중심을 기준으로 새로운 블럭을 쌓아가는 것)

  • 윈도우가 여러 개(사용자 지정 수) 쌓이게 되면, 그 중심을 연결해서 선을 그린다.

  • Polyfit을 사용하여 2차원으로 표현한다.
    (쌍곡선 방정식이 도출된다. ay^2+by+c=x)

  • 2차식의 a, b, c 값을 구해서 polygon을 그린다.

[5] 변환 과정 정리

1. Original 이미지 -> 카메라 Calibration

2. Yellow, White 마스킹

3. Bird's-eye View 및 이진화

4. 히스토그램 및 슬라이딩 윈도우, Polyfit

5. 결과 이미지


출처: Programmers K-Digital-Training: 자율주행 데브코스 Planning & Control - 차선인식기법 강의

profile
자율주행 TIL(Today I Learned) 기록

0개의 댓글