
이진화된 이미지의 특정 부분을 수평으로 잘라 도로를 의미하는 0(검은색)과 차선을 의미하는 0이 아닌 다른 값을 갖는 영역을 찾는 방법으로 차선을 인식할 수 있다.

차선 인식을 위한 데이터 전처리 방법은 다음과 같다.
원본 이미지 -> Gray scale(흑백 이미지) -> Gaussian blur(노이즈 제거) -> HSV binary(색표현) -> ROI(관심영역)
import cv2
img = cv2.imread('img.png')
# 원본 이미지
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 흑백 이미지 변환
blur = cv2.GaussianBlur(gray, (5,5), 0)
# 노이즈 제거
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
lower_white = np.array([0,0,70])
uppper_white = np.array([131,255,255])
mask = cv2.inRange(hsv, lower_white, upper_white)
cv2.imshow('ori', img)
cv2.imshow('gray', gray)
cv2.imshow('blur', blur)
cv2.imshow('gray', mask)
cv2.waitKey(10000)
import cv2
import numpy as np
img = cv2.imread('img.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_white = np.array([0,0,70])
uppper_white = np.array([131,255,255])
mask = cv2.inRange(hsv, lower_white, upper_white)
xx = 20
while True:
area = img[430:450, xx:xx+15]
if cv2.countNonZero(area) > 200:
img = cv2.rectagle(img, (xx,430), (xx+15, 450), (0,255,0), 3)
else:
img = cv2.rectagle(img, (xx,430), (xx+15, 450), (255,0,0), 3)
xx+=20
if xx > 640:
break
cv2.imshow('countNonZero', img)
cv2.waitKey(10000)
import cv2
img = cv2.imread('img.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5),0)
edge = cv2.Canny(blur, 20, 190)
# 20~190을 기준으로 선을 찾는다.
cv2.imshow('edge', edge)
cv2.waitKey(10000)
catkin_create_pkg line_drive rospy tf geometry_msgs rviz xacro
#!/usr/bin/env python
import cv2, time
import numpy as np
cap = cv2.VideoCapture('track1.avi')
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
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)
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)
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")
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")
cv2.imshow("origin", frame)
cv2.imshow("view", view)
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()