-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextrapolate.py
73 lines (57 loc) · 2.42 KB
/
extrapolate.py
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import numpy as np
import cv2
import math
def average_slope_intercept(lines):
left_lines = [] # (slope, intercept)
left_weights = [] # (length,)
right_lines = [] # (slope, intercept)
right_weights = [] # (length,)
for line in lines:
for x1, y1, x2, y2 in line:
if x2==x1:
continue # ignore a vertical line
slope = (y2-y1)/(x2-x1)
intercept = y1 - slope*x1
length = np.sqrt((y2-y1)**2+(x2-x1)**2)
if slope < 0: # y is reversed in image
left_lines.append((slope, intercept))
left_weights.append((length))
else:
right_lines.append((slope, intercept))
right_weights.append((length))
# add more weight to longer lines
left_lane = np.dot(left_weights, left_lines) /np.sum(left_weights) if len(left_weights) >0 else None
right_lane = np.dot(right_weights, right_lines)/np.sum(right_weights) if len(right_weights)>0 else None
return left_lane, right_lane # (slope, intercept), (slope, intercept)
def make_line_points(y1, y2, line):
"""
Convert a line represented in slope and intercept into pixel points
"""
if line is None:
return None
slope, intercept = line
# make sure everything is integer as cv2.line requires it
x1 = int((y1 - intercept)/slope)
x2 = int((y2 - intercept)/slope)
y1 = int(y1)
y2 = int(y2)
return ((x1, y1), (x2, y2))
def lane_lines(image, lines):
left_lane, right_lane = average_slope_intercept(lines)
y1 = image.shape[0] # bottom of the image
y2 = y1*0.6 # slightly lower than the middle
left_line = make_line_points(y1, y2, left_lane)
right_line = make_line_points(y1, y2, right_lane)
return left_line, right_line
def draw_lane_lines(image, lines, color=[255, 0, 0], thickness=20):
# make a separate image to draw lines and combine with the orignal later
line_image = np.zeros_like(image)
for line in lines:
if line is not None:
cv2.line(line_image, *line, color, thickness)
# image1 * a + image2 * b + y
# image1 and image2 must be the same shape.
return cv2.addWeighted(image, 1.0, line_image, 0.95, 0.0)
# lane_images = []
# for image, lines in zip(test_images, list_of_lines):
# lane_images.append(draw_lane_lines(image, lane_lines(image, lines)))