:)
명도차 기반 차선 인식 본문
차선 추종 주행
- 좌우 차선을 찾아내어 차선을 벗어나지 않게끔 주행한다.
차선을찾기 위한 작업
- Image Read - 카메라 영상신호를 이미지로 읽기
- GrayScale - 흑백 이미지로 변환
- Gaussian Blur - 노이즈 제거
- HSV - Binary - HSV 기반으로 이진화 처리
- ROI - 관심영역 잘라내기
차선 검출을 위한 영상 처리
- gray.py - 컬러(bgr8) 이미지를 흑백(grayscale) 이미지로 변환
import cv2
img = cv2.imread('sample.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', gray)
cv2.waitKey(1000)
- blur.py - 차선 인식에 방해가 되는 노이즈 제거
import cv2
img = cv2.imread('sample.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
cv2.imshow('blur', blur)
cv2.waitKey(1000)
노이즈 제거 - Gaussian Blur
- 각 픽셀에 5X5 윈도우를 올려 놓고 그 영역 안에 포함되는 값을 모두 더한 뒤 이것을 25로 나누어 인접한 점들의 밝기 산술평균을 구하는 방식으로 노이즈를 제거
- 윈도우의 크기를 크게 할수록 더 부드러운 blur를 얻게 됨.
- line.py - HSV 기반 이진화 방법으로 차선을 추출
import cv2
import numpy as np
img = cv2.imread('sample.jpg')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower_white = np.array([0,0,70])
upper_white = np.array([131,255,255])
mask = cv2.inRange(hsv, lower_white,upper_white)e
cv2.imshow('line' mask)
cv2.waitKey()
- canny.py - 외곽선을 추출해서 차선을 찾을 수도 있음(Canny Edge Detector)
import cv2
img = cv2.imread('sample.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
edge = cv2.Canny(blur, 20, 190) # lower/upper threshld
cv2.imshow('edge', edge)
cv2.waitKey()
- nonzero.py - 사각형 안에 있는 흰색 점의 개수를 세서 일정 개수 이상이면 녹색으로 표시
import cv2
import numpy as np
image = cv2.imread('sample.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower_white = np.array([0,0,70])
upper_white = np.array([131,255,255])
mask = cv2.inRange(hsv, lower_white,upper_white)
xx = 20
while True:
area = mask[430:450, xx:xx+15]
if cv2.countNonZero(area) > 200:
image = cv2.rectangle(image,(xx,430), (xx+15,450),(0,255,0),3)
else:
image = cv2.rectangle(image,(xx,430),(xx+15,450),(255,0,0),3)
xx = xx + 20
if xx > 640:
break
cv2.imshow('countNonZero', image)
cv2.waitKey()
카메라 영상에서 차선 검출하기
- 트랙 영상에서 특정 영역을 ROI로 설정하여 차선위치를 검출
- BGR -> HSV -> 이진화
- 검출된 차선을 녹색 사각형으로 표시하기
- 이진화된 이미지를 BGR로 변환하여 색상을 가지는 사각형이 표시될 수 있도록
- 관심영역 ROI 설정 (동영상 파일 프레임 크기 : 640X480)
- 세로 좌표 430 ~ 450 영역(차량 바로 앞의 차선), 가로 0
200, 440640 (왼쪽과 오른쪽 차선을 발견하기 위한 구간)
- 세로 좌표 430 ~ 450 영역(차량 바로 앞의 차선), 가로 0
- 영역내 흰색 픽셀 개수를 기준으로 차선 인식
- 20X10 중 80%(160개) 이상이 흰색이면 차선으로 간주
#!/usr/bin/env python3
import cv2, time
import numpy as np
cap = cv2.VideoCapture('xycar_track1.mp4')
threshold_60 = 60 # 이진화에 이용할 명도 하한
width_640 = 640
scan_width_200, scan_height_20 = 200, 20 # 영역의 가로와 세로 크기
lmid_200, rmid_440 = scan_width_200, width_640 - scan_width_200 # 왼쪽, 오른쪽 검사가 끝날 가로 좌표
area_width_20, area_height_10 = 20, 10
vertical_430 = 430 # ROI 설정을 위한 세로 좌표(위쪽 끝)
row_begin_5 = (scan_height_20 - area_height_10) // 2
row_end_15 = row_begin_5 + area_height_10
pixel_threshold_160 = 0.8 * area_width_20 * area_height_10
while True:
ret, frame = cap.read()
if not ret:
break
if cv2.waitKey(1) & 0XFF == 27:
break
roi = frame[vertical_430:vertical_430 + scan_height_20, :]
frame = cv2.rectangle(frame, (0, vertical_430), (width_640 - 1, vertical_430 + scan_height_20), (255, 0, 0), 3) # 설정된 ROI 둘레에 파란색 사각형을 그림
hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # 이진화작업
lbound = np.array([0,0,threshold_60], dtype=np.uint8)
ubound = np.array([131, 255, 255], dtype=np.uint8)
bin = cv2.inRange(hsv, lbound, ubound)
view = cv2.cvtColor(bin, cv2.COLOR_GRAY2BGR) # 초록색 사각형을 그리기위해 BGR 변환
left, right = -1, -1
for l in range(area_width_20, lmid_200):
area = bin[row_begin_5:row_end_15, l - area_width_20:l]
if cv2.countNonZero(area) > pixel_threshold_160:
left = l
break
for r in range(width_640 - area_width_20, rmid_440, -1):
area = bin[row_begin_5:row_end_15, r:r + area_width_20]
if cv2.countNonZero(area) > pixel_threshold_160:
right = r
break
if left != -1:
lsquare = cv2.rectangle(view,
(left - area_width_20, row_begin_5),
(left, row_end_15),
(0, 255, 0), 3)
else:
print("Lost left line") # 왼쪽 차선이 검출되었으면 잘라낸 ROI 이미지에 녹색 사각형을 그림
if right != -1:
rsquare = cv2.rectangle(view,
(right, row_begin_5),
(right + area_width_20, row_end_15),
(0, 255, 0), 3)
else:
print("Lost right line") # 오른쪽 차선이 검출되었으면 잘라낸 ROI 이미지에 녹색 사각형을 그림
cv2.imshow("origin", frame) # 파란사각형
cv2.imshow("view", view) # ROI 잘라내어 이진화한 영상
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lbound = np.array([0,0,threshold_60], dtype=np.uint8)
ubound = np.array([131, 255,255], dtype=np.uint8)
hsv = cv2.inRange(hsv, lbound, ubound)
cv2.imshow("hsv", hsv) # 카메라 영상을 이진화한 영상
time.sleep(0.1)
cap.release()
cv2.destroyAllWindows()
'ROS' 카테고리의 다른 글
와핑기법과 원근 변환 (0) | 2022.04.10 |
---|---|
허프변환 기반 차선인식 (0) | 2022.04.10 |
OpenCV 자이카 카메라 활용 (0) | 2022.03.28 |
자이카 센서 (0) | 2022.03.11 |
RVIZ 오도메트리 활용 (0) | 2022.03.10 |
Comments