Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

:)

명도차 기반 차선 인식 본문

ROS

명도차 기반 차선 인식

mihee 2022. 3. 30. 17:29

차선 추종 주행

  • 좌우 차선을 찾아내어 차선을 벗어나지 않게끔 주행한다.

차선을찾기 위한 작업

  1. Image Read - 카메라 영상신호를 이미지로 읽기
  2. GrayScale - 흑백 이미지로 변환
  3. Gaussian Blur - 노이즈 제거
  4. HSV - Binary - HSV 기반으로 이진화 처리
  5. 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()

line.py 실행결과

  • 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()

canny,py 실행결과

  • 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()

nonzero.py 실행결과

카메라 영상에서 차선 검출하기

  • 트랙 영상에서 특정 영역을 ROI로 설정하여 차선위치를 검출
    • BGR -> HSV -> 이진화
  • 검출된 차선을 녹색 사각형으로 표시하기
    • 이진화된 이미지를 BGR로 변환하여 색상을 가지는 사각형이 표시될 수 있도록
  • 관심영역 ROI 설정 (동영상 파일 프레임 크기 : 640X480)
    • 세로 좌표 430 ~ 450 영역(차량 바로 앞의 차선), 가로 0200, 440640 (왼쪽과 오른쪽 차선을 발견하기 위한 구간)

  • 영역내 흰색 픽셀 개수를 기준으로 차선 인식
    • 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()

line_find.py  싫행결과

 

'ROS' 카테고리의 다른 글

와핑기법과 원근 변환  (0) 2022.04.10
허프변환 기반 차선인식  (0) 2022.04.10
OpenCV 자이카 카메라 활용  (0) 2022.03.28
자이카 센서  (0) 2022.03.11
RVIZ 오도메트리 활용  (0) 2022.03.10
Comments