-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththreshold.py
176 lines (150 loc) · 6.59 KB
/
threshold.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import numpy as np
import cv2
import math as m
import utils
"""
Take an absolute value of passed Sobel and apply a threshold.
"""
def abs_sobel_threshold(sobel, thresh=(0, 255)):
# Take the absolute value of the derivative or gradient
abs_sobel = np.absolute(sobel)
# Scale to 8-bit (0 - 255) then convert to type = np.uint8
scaled_sobel = np.uint8(255 * abs_sobel / np.max(abs_sobel))
# Create a mask of 1's where the scaled gradient magnitude is > thresh_min and < thresh_max
binary_output = np.zeros_like(scaled_sobel)
binary_output[(scaled_sobel >= thresh[0]) & (scaled_sobel <= thresh[1])] = 1
# Return this mask as binary_output image
return binary_output
"""
Compute the magnitude of the gradient and apply a threshold
"""
def mag_threshold(sobelx, sobely, thresh=(0, 255)):
# Calculate the magnitude
abs_sobelxy = np.sqrt(sobelx * sobelx + sobely * sobely)
# Scale to 8-bit (0 - 255) and convert to type = np.uint8
scaled_sobel = np.uint8(255 * abs_sobelxy / np.max(abs_sobelxy))
# Create a binary mask where mag thresholds are met
binary_output = np.zeros_like(scaled_sobel)
binary_output[(scaled_sobel >= thresh[0]) & (scaled_sobel <= thresh[1])] = 1
# Return this mask as binary_output image
return binary_output
"""
Compute the direction of the gradient and apply a threshold.
"""
def dir_threshold(sobelx, sobely, thresh=(0, np.pi / 2)):
# Take the absolute value of the x and y gradients, so that's why thresh in range [0, pi/2], not [-pi, pi]x
abs_sobelx = np.absolute(sobelx)
abs_sobely = np.absolute(sobely)
# Use np.arctan2(abs_sobely, abs_sobelx) to calculate the direction of the gradient
grad_direction = np.arctan2(abs_sobely, abs_sobelx)
# Create a binary mask where direction thresholds are met
binary_output = np.zeros_like(grad_direction)
binary_output[(grad_direction >= thresh[0]) & (grad_direction <= thresh[1])] = 1
# Return this mask as binary_output image
return binary_output
"""
Threshold image using gradient x and y absolute values, gradient magnitude and gradient direction.
"""
def gradient_threshold(img, working_ch='gray',
ksize=3, x_abs_thresh=(0, 255), y_abs_thresh=(0, 255),
mag_thresh=(0, 255), dir_thresh=(0, np.pi / 2)):
if working_ch == 'L':
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HLS).astype(np.float)
one_ch_img = hsv[:, :, 1]
elif working_ch == 'S':
hsv = cv2.cvtColor(img.astype(np.uint8), cv2.COLOR_RGB2HLS)
hsv = hsv.astype(np.float)
one_ch_img = hsv[:, :, 2]
else:
# by default grayscale is used
one_ch_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# Take the gradient in x and y separately
sobelx = cv2.Sobel(one_ch_img, cv2.CV_64F, 1, 0, ksize=ksize)
sobely = cv2.Sobel(one_ch_img, cv2.CV_64F, 0, 1, ksize=ksize)
# Apply each of the thresholding functions
gradx = abs_sobel_threshold(sobelx, thresh=x_abs_thresh)
grady = abs_sobel_threshold(sobely, thresh=y_abs_thresh)
mag_binary = mag_threshold(sobelx, sobely, thresh=mag_thresh)
dir_binary = dir_threshold(sobelx, sobely, thresh=dir_thresh)
combined = np.zeros_like(dir_binary)
combined[(((gradx == 1) | (grady == 1))) & (mag_binary == 1) & (dir_binary == 1)] = 1
return combined
"""
The method thresholds image using gradient thresholding by Grayscale and S channel.
This method is used for flow:
origin_image -> undistort -> top-down-perspective (aka bird-eye-view) -> threshold
"""
def threshold_image(img):
img = np.copy(img)
img = utils.gaussian_blur(img, kernel_size=5)
ksize = 11
x_abs_thresh = (20, 100)
y_abs_thresh = (20, 100)
mag_thresh = (20, 100)
#dir_thresh = (m.radians(0), m.radians(10))
dir_thresh = (m.radians(0), m.radians(45))
# use Grayscale
grad_g_binary = gradient_threshold(img, 'G', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
# use S channel of HSL
grad_s_binary = gradient_threshold(img, 'S', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
# use L channel of HSL
# grad_l_binary = gradient_threshold(img, 'L', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
# Combine
combined = np.zeros_like(grad_g_binary)
combined[(grad_g_binary == 1) | (grad_s_binary == 1)] = 1
# Stack each channel
color_binary = np.dstack((combined, grad_g_binary, grad_s_binary))
return color_binary
"""
origin_image -> undistort -> threshold -> top-down-perspective (aka bird-eye-view)
"""
def threshold_origin_image(img):
img = np.copy(img)
ksize = 11
x_abs_thresh = (20, 100)
y_abs_thresh = (20, 100)
mag_thresh = (30, 100)
dir_thresh = (m.radians(35), m.radians(55))
# use Grayscale
grad_g_binary = gradient_threshold(img, 'G', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
# use S channel of HSL
grad_s_binary = gradient_threshold(img, 'S', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
# use L channel of HSL
# grad_l_binary = gradient_threshold(img, 'L', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
# Combine
combined = np.zeros_like(grad_g_binary)
combined[(grad_g_binary == 1) | (grad_s_binary == 1)] = 1
# Stack each channel
color_binary = np.dstack((combined, grad_g_binary, grad_s_binary))
return color_binary
# def threshold_origin_image(img, s_thresh=(170, 255)):
# img = np.copy(img)
#
# ksize = 11
# x_abs_thresh = (20, 100)
# y_abs_thresh = (20, 100)
# mag_thresh = (30, 100)
# dir_thresh = (m.radians(35), m.radians(55))
#
# # use Grayscale
# grad_g_binary = gradient_threshold(img, 'G', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
# grad_s_binary = gradient_threshold(img, 'S', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
# #sxbinary = gradient_threshold(img, 'L', ksize, x_abs_thresh, y_abs_thresh, mag_thresh, dir_thresh)
#
# # Convert to HSV color space and separate the V channel
# hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HLS).astype(np.float)
# s_channel = hsv[:, :, 2]
#
# # Threshold color channel
# s_binary = np.zeros_like(s_channel)
# s_binary[(s_channel >= s_thresh[0]) & (s_channel <= s_thresh[1])] = 1
#
# # Combine
# combined = np.zeros_like(grad_g_binary)
# #combined[(sxbinary == 1) | (s_binary == 1)] = 1
# combined[(grad_g_binary == 1) | (grad_s_binary == 1)] = 1
#
# # Stack each channel
# # color_binary = np.dstack((np.zeros_like(sxbinary), sxbinary, s_binary))
# color_binary = np.dstack((combined, grad_g_binary, grad_s_binary))
# return color_binary