├── .gitignore
├── A-BASIC-LANE-DETECTION
├── BASIC_LANE_DETECTION.ipynb
├── NOTES.txt
├── README.md
├── WRITEUP.pdf
├── examples
│ ├── P1_example.mp4
│ ├── grayscale.jpg
│ ├── laneLines_thirdPass.jpg
│ ├── line-segments-example.jpg
│ └── raw-lines-example.mp4
├── test_images
│ ├── A1-raw.png
│ ├── A10-overlap.png
│ ├── A2-grey.png
│ ├── A3-blur.png
│ ├── A4-edges.png
│ ├── A5-roi.png
│ ├── A6-mask.png
│ ├── A7-lines.png
│ ├── A8-lines.png
│ ├── A9-overlap.png
│ ├── B1-raw.png
│ ├── B10-overlap.png
│ ├── B2-grey.png
│ ├── B3-blur.png
│ ├── B4-edges.png
│ ├── B5-roi.png
│ ├── B6-mask.png
│ ├── B7-lines.png
│ ├── B8-lines.png
│ ├── B9-overlap.png
│ ├── C1-raw.png
│ ├── C10-overlap.png
│ ├── C2-grey.png
│ ├── C3-blur.png
│ ├── C4-edges.png
│ ├── C5-roi.png
│ ├── C6-mask.png
│ ├── C7-lines.png
│ ├── C8-lines.png
│ ├── C9-overlap.png
│ ├── D1-raw.png
│ ├── D10-overlap.png
│ ├── D2-grey.png
│ ├── D3-blur.png
│ ├── D4-edges.png
│ ├── D5-roi.png
│ ├── D6-mask.png
│ ├── D7-lines.png
│ ├── D8-lines.png
│ ├── D9-overlap.png
│ ├── E1-raw.png
│ ├── E10-overlap.png
│ ├── E2-grey.png
│ ├── E3-blur.png
│ ├── E4-edges.png
│ ├── E5-roi.png
│ ├── E6-mask.png
│ ├── E7-lines.png
│ ├── E8-lines.png
│ ├── E9-overlap.png
│ ├── F1-raw.png
│ ├── F10-overlap.png
│ ├── F2-grey.png
│ ├── F3-blur.png
│ ├── F4-edges.png
│ ├── F5-roi.png
│ ├── F6-mask.png
│ ├── F7-lines.png
│ ├── F8-lines.png
│ ├── F9-overlap.png
│ ├── solidWhiteCurve.jpg
│ ├── solidWhiteRight.jpg
│ ├── solidYellowCurve.jpg
│ ├── solidYellowCurve2.jpg
│ ├── solidYellowLeft.jpg
│ └── whiteCarLaneSwitch.jpg
└── videos
│ ├── 1-edge_extra.mp4
│ ├── 2-roi_extra.mp4
│ ├── 3-small-lines-extra.mp4
│ ├── challenge.mp4
│ ├── extra.mp4
│ ├── solidWhiteRight.mp4
│ ├── solidYellowLeft.mp4
│ ├── white.mp4
│ └── yellow.mp4
├── LICENSE
├── README.md
├── WRITEUP.pdf
├── birdseye.py
├── calibration_data.p
├── camera_cal
├── calibration1.jpg
├── calibration10.jpg
├── calibration11.jpg
├── calibration12.jpg
├── calibration13.jpg
├── calibration14.jpg
├── calibration15.jpg
├── calibration16.jpg
├── calibration17.jpg
├── calibration18.jpg
├── calibration19.jpg
├── calibration2.jpg
├── calibration20.jpg
├── calibration3.jpg
├── calibration4.jpg
├── calibration5.jpg
├── calibration6.jpg
├── calibration7.jpg
├── calibration8.jpg
└── calibration9.jpg
├── chessboard.py
├── curves.py
├── docs
└── Notes_FROM_REVIEWER.MD
├── helpers.py
├── lanefilter.py
├── notebooks
├── camera_calibration.ipynb
├── fitting_curves.ipynb
├── gradient_and_color_thresholding.ipynb
├── perspective_transform.ipynb
├── pipeline.ipynb
├── pipeline_debug.ipynb
├── pipeline_verbose.ipynb
└── projecting_lanes.ipynb
├── test_images
├── special_test1.jpg
├── straight_lines1.jpg
├── straight_lines2.jpg
├── test1.jpg
├── test2.jpg
├── test3.jpg
├── test4.jpg
├── test5.jpg
└── test6.jpg
└── videos
├── project_video.mp4
├── project_video_output.mp4
└── project_video_verbose_output.mp4
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | \.DS_Store
3 |
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/BASIC_LANE_DETECTION.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 118,
6 | "metadata": {
7 | "collapsed": false,
8 | "deletable": true,
9 | "editable": true
10 | },
11 | "outputs": [],
12 | "source": [
13 | "import matplotlib.pyplot as plt\n",
14 | "import matplotlib.image as mpimg\n",
15 | "import numpy as np\n",
16 | "import cv2\n",
17 | "%matplotlib inline\n",
18 | "\n",
19 | "import math"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": 119,
25 | "metadata": {
26 | "collapsed": false,
27 | "deletable": true,
28 | "editable": true
29 | },
30 | "outputs": [],
31 | "source": [
32 | "def read(path):\n",
33 | " return mpimg.imread(path)\n",
34 | "\n",
35 | "def show(image):\n",
36 | " print('This image is:', type(image), 'with dimensions:', image.shape)\n",
37 | " plt.imshow(image)\n",
38 | "\n",
39 | "def save(image, path = 'test.png'):\n",
40 | " plt.imsave(path, image)\n",
41 | "\n",
42 | "def convert_to_color(image):\n",
43 | " return np.dstack((image, image, image))"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": 120,
49 | "metadata": {
50 | "collapsed": true,
51 | "deletable": true,
52 | "editable": true
53 | },
54 | "outputs": [],
55 | "source": [
56 | "def gray(raw_image):\n",
57 | " '''convert the colored imaged to grayscale image'''\n",
58 | " return cv2.cvtColor(raw_image, cv2.COLOR_RGB2GRAY) \n",
59 | "\n",
60 | "def reduce_noise(gray_image, kernel_size):\n",
61 | " '''reduce noise of grayscale image using gausian blur'''\n",
62 | " return cv2.GaussianBlur(gray_image, (kernel_size, kernel_size), 0)"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": 121,
68 | "metadata": {
69 | "collapsed": true,
70 | "deletable": true,
71 | "editable": true
72 | },
73 | "outputs": [],
74 | "source": [
75 | "def get_edges(blur_image, low_threshold, high_threshold):\n",
76 | " '''find edges using canny transform algorithm'''\n",
77 | " return cv2.Canny(blur_image, low_threshold, high_threshold)"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": 122,
83 | "metadata": {
84 | "collapsed": true,
85 | "deletable": true,
86 | "editable": true
87 | },
88 | "outputs": [],
89 | "source": [
90 | "def get_vertices(x, y, axc, bxc, cyc, dyc, maxyc = 1.0, maxxc = 1.0, startxc = 0.0):\n",
91 | " ax = int(axc*x)\n",
92 | " bx = int(bxc*x)\n",
93 | " cy = int(cyc*y)\n",
94 | " dy = int(dyc*y)\n",
95 | " maxy = int(maxyc*y)\n",
96 | " maxx = int(maxxc*x)\n",
97 | " startx = int(startxc*x)\n",
98 | " bottom_left = (startx, maxy)\n",
99 | " top_left = (ax, cy)\n",
100 | " top_right = (bx, dy)\n",
101 | " bottom_right = (maxx, maxy)\n",
102 | " vertices = np.array([[bottom_left, top_left, top_right, bottom_right]], dtype=np.int32)\n",
103 | " return vertices "
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "execution_count": 123,
109 | "metadata": {
110 | "collapsed": false,
111 | "deletable": true,
112 | "editable": true
113 | },
114 | "outputs": [],
115 | "source": [
116 | "def get_roi(edge_image, vertices, ignore_value = 255):\n",
117 | " '''get the polygon to be used to block out everything in the image except the region of interest'''\n",
118 | " roi = np.zeros_like(edge_image)\n",
119 | " cv2.fillPoly(roi, vertices, ignore_value)\n",
120 | " return roi\n",
121 | "\n",
122 | "def mask(edge_image, roi):\n",
123 | " '''block out everything in the image except the edges in the region of interest'''\n",
124 | " return cv2.bitwise_and(edge_image, roi)"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": 124,
130 | "metadata": {
131 | "collapsed": true,
132 | "deletable": true,
133 | "editable": true
134 | },
135 | "outputs": [],
136 | "source": [
137 | "def get_lines(masked_edge_image, rho, theta_coef, min_votes, min_line_length, max_line_gap):\n",
138 | " '''convert edges into lines using hough transform algorithm '''\n",
139 | " theta = theta_coef*np.pi/180\n",
140 | " return cv2.HoughLinesP(masked_edge_image, rho, theta, min_votes, np.array([]), minLineLength = min_line_length, maxLineGap = max_line_gap)\n"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": 125,
146 | "metadata": {
147 | "collapsed": true,
148 | "deletable": true,
149 | "editable": true
150 | },
151 | "outputs": [],
152 | "source": [
153 | "def draw(lines, image, color=[255, 0, 0], thickness = 2, thresh = 0.5):\n",
154 | " ''' draw the lines on a blank image'''\n",
155 | " lined_image = np.copy(image)*0\n",
156 | " \n",
157 | " if lines is not None:\n",
158 | " for line in lines:\n",
159 | " for x1,y1,x2,y2 in line:\n",
160 | " slope, intercept = np.polyfit((x1,x2), (y1,y2), 1)\n",
161 | " if abs(slope) > thresh:\n",
162 | " cv2.line(lined_image, (x1, y1), (x2, y2), color, thickness)\n",
163 | " \n",
164 | " return lined_image"
165 | ]
166 | },
167 | {
168 | "cell_type": "code",
169 | "execution_count": 126,
170 | "metadata": {
171 | "collapsed": false,
172 | "deletable": true,
173 | "editable": true
174 | },
175 | "outputs": [],
176 | "source": [
177 | "# equation of a line: y = slope*x + intercept \n",
178 | "# left lane has a positive slope, right lane has a negative slope \n",
179 | "\n",
180 | "def extrapolate_lines(lines, image, color=[255, 0, 0], thickness = 10, \n",
181 | " positive_thresh = 0.5, negative_thresh = 0.5):\n",
182 | " \n",
183 | " imshape = image.shape\n",
184 | " image = np.copy(image)*0\n",
185 | " \n",
186 | " #initialize minimum and maximum y coordinate \n",
187 | " minimum_y = image.shape[0] \n",
188 | " maximum_y = image.shape[0]\n",
189 | " \n",
190 | " #initialize groups of values into empty lists\n",
191 | " left_slopes = []\n",
192 | " left_xs = []\n",
193 | " left_ys = [] \n",
194 | " right_slopes = []\n",
195 | " right_xs = []\n",
196 | " right_ys = []\n",
197 | " \n",
198 | " # segregate the small line segments into the left lane group or right lane group\n",
199 | " if lines is not None: \n",
200 | " for line in lines:\n",
201 | " for x1,y1,x2,y2 in line:\n",
202 | " \n",
203 | " # get the slope and intercept of the line (as defined by two points) using the polyfit function\n",
204 | " slope, intercept = np.polyfit((x1,x2), (y1,y2), 1)\n",
205 | " \n",
206 | " if (slope > positive_thresh): #if positive slope, put value to left lane group\n",
207 | " left_slopes += [slope]\n",
208 | " left_xs += [x1, x2]\n",
209 | " left_ys += [y1, y2]\n",
210 | " elif (slope < negative_thresh): #if negative slope, put value to right lane group\n",
211 | " right_slopes += [slope]\n",
212 | " right_xs += [x1, x2]\n",
213 | " right_ys += [y1, y2]\n",
214 | " \n",
215 | " # update the minimum y_coordinate based on values seen\n",
216 | " minimum_y = min(min(y1, y2), minimum_y)\n",
217 | " \n",
218 | " #average all the values in each group to get the slope, x, and y\n",
219 | " left_slope = np.mean(left_slopes)\n",
220 | " left_x = np.mean(left_xs)\n",
221 | " left_y = np.mean(left_ys)\n",
222 | " right_slope = np.mean(right_slopes)\n",
223 | " right_x = np.mean(right_xs)\n",
224 | " right_y = np.mean(right_ys)\n",
225 | " \n",
226 | " #derive the intercept using the equation of the line and average value\n",
227 | " left_intercept = left_y - (left_slope * left_x)\n",
228 | " right_intercept = right_y - (right_slope * right_x)\n",
229 | "\n",
230 | " if ((len(left_slopes) > 0) and (len(right_slopes) > 0)): #make sure we have points in each group\n",
231 | " #derive the x coordinate using the equation of the lines and derived values\n",
232 | " upper_left_x = int((minimum_y - left_intercept) / left_slope)\n",
233 | " lower_left_x = int((maximum_y - left_intercept) / left_slope)\n",
234 | " upper_right_x = int((minimum_y - right_intercept) / right_slope)\n",
235 | " lower_right_x = int((maximum_y - right_intercept) / right_slope)\n",
236 | " \n",
237 | " #draw the line based on two points \n",
238 | " cv2.line(image, (upper_left_x, minimum_y), (lower_left_x, maximum_y), color, thickness)\n",
239 | " cv2.line(image, (upper_right_x, minimum_y), (lower_right_x, maximum_y), color, thickness)\n",
240 | " \n",
241 | " return image"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": 127,
247 | "metadata": {
248 | "collapsed": true,
249 | "deletable": true,
250 | "editable": true
251 | },
252 | "outputs": [],
253 | "source": [
254 | "def overlap(first_image, second_image, α = 0.8, β = 0.5, λ = 0.0):\n",
255 | " '''first_image * α + second_image * β + λ (colored)'''\n",
256 | " return cv2.addWeighted(first_image, α, second_image, β, λ)"
257 | ]
258 | },
259 | {
260 | "cell_type": "code",
261 | "execution_count": 128,
262 | "metadata": {
263 | "collapsed": true,
264 | "deletable": true,
265 | "editable": true
266 | },
267 | "outputs": [],
268 | "source": [
269 | "param = {\n",
270 | " #blur parameters\n",
271 | " 'kernel_size': 5, \n",
272 | " \n",
273 | " #canny transform parameters\n",
274 | " 'canny_lo': 100, \n",
275 | " 'canny_hi': 200, \n",
276 | "\n",
277 | " #region of interest parameters\n",
278 | " 'ax_coef': 10.0/25,\n",
279 | " 'bx_coef': 14.0/25,\n",
280 | " 'cy_coef': 0.6,\n",
281 | " 'dy_coef': 0.6,\n",
282 | " 'maxy_coef': 1.0,\n",
283 | " 'maxx_coef': 1.0,\n",
284 | " 'startx_coef': 0.0,\n",
285 | "\n",
286 | " #hough parameters\n",
287 | " 'rho': 1, \n",
288 | " 'theta_coef': 1, \n",
289 | " 'min_votes': 30, \n",
290 | " 'min_line_length': 20, \n",
291 | " 'max_line_gap': 20\n",
292 | "}"
293 | ]
294 | },
295 | {
296 | "cell_type": "code",
297 | "execution_count": 129,
298 | "metadata": {
299 | "collapsed": false,
300 | "deletable": true,
301 | "editable": true
302 | },
303 | "outputs": [],
304 | "source": [
305 | "def pipeline(path, file, name, param = param):\n",
306 | " \n",
307 | " name = path + name\n",
308 | "\n",
309 | " raw_image = read(path + file)\n",
310 | " image = read(path + file)\n",
311 | " save(image, path = name + '1-raw.png')\n",
312 | " \n",
313 | " gray_image = gray(image)\n",
314 | " save(gray_image, path = name + '2-grey.png')\n",
315 | " \n",
316 | " blur_image = reduce_noise(gray_image, param['kernel_size'])\n",
317 | " save(blur_image, path = name + '3-blur.png')\n",
318 | " \n",
319 | " edge_image = get_edges(blur_image, param['canny_lo'], param['canny_hi'])\n",
320 | " save(edge_image, path = name + '4-edges.png')\n",
321 | " \n",
322 | " x = image.shape[1]\n",
323 | " y = image.shape[0]\n",
324 | " vertices = get_vertices(x, y, param['ax_coef'], param['bx_coef'],\n",
325 | " param['cy_coef'], param['dy_coef'],\n",
326 | " param['maxy_coef'], param['maxx_coef'], param['startx_coef'])\n",
327 | " \n",
328 | " roi = get_roi(edge_image, vertices)\n",
329 | " save(roi, path = name + '5-roi.png')\n",
330 | " \n",
331 | " mask_image = mask(edge_image, roi)\n",
332 | " save(mask_image, path = name + '6-mask.png')\n",
333 | " \n",
334 | " lines = get_lines(mask_image, param['rho'], param['theta_coef'],\n",
335 | " param['min_votes'], param['min_line_length'],\n",
336 | " param['max_line_gap'])\n",
337 | " \n",
338 | " line_image = draw(lines, raw_image)\n",
339 | " save(line_image, path = name + '7-lines.png')\n",
340 | " \n",
341 | " \n",
342 | " line_image2 = extrapolate_lines(lines, raw_image)\n",
343 | " save(line_image2, path = name + '8-lines.png')\n",
344 | "\n",
345 | " image = overlap(line_image, raw_image)\n",
346 | " save(image, path = name + '9-overlap.png')\n",
347 | "\n",
348 | " image = overlap(line_image2, raw_image)\n",
349 | " save(image, path = name + '10-overlap.png')\n",
350 | " \n",
351 | "\n",
352 | "pipeline(path = 'test_images/', file = 'solidWhiteCurve.jpg', name = 'A')\n",
353 | "pipeline(path = 'test_images/', file = 'solidWhiteRight.jpg', name = 'B')\n",
354 | "pipeline(path = 'test_images/', file = 'solidYellowCurve.jpg', name = 'C')\n",
355 | "pipeline(path = 'test_images/', file = 'solidYellowCurve2.jpg', name = 'D')\n",
356 | "pipeline(path = 'test_images/', file = 'solidYellowLeft.jpg', name = 'E')\n",
357 | "pipeline(path = 'test_images/', file = 'whiteCarLaneSwitch.jpg', name = 'F')\n",
358 | "\n"
359 | ]
360 | },
361 | {
362 | "cell_type": "code",
363 | "execution_count": 130,
364 | "metadata": {
365 | "collapsed": true,
366 | "deletable": true,
367 | "editable": true
368 | },
369 | "outputs": [],
370 | "source": [
371 | "# Import everything needed to edit/save/watch video clips\n",
372 | "from moviepy.editor import VideoFileClip\n",
373 | "from IPython.display import HTML"
374 | ]
375 | },
376 | {
377 | "cell_type": "code",
378 | "execution_count": 131,
379 | "metadata": {
380 | "collapsed": true,
381 | "deletable": true,
382 | "editable": true
383 | },
384 | "outputs": [],
385 | "source": [
386 | "def process_image(image):\n",
387 | "\n",
388 | " raw_image = np.copy(image)\n",
389 | " gray_image = gray(image) \n",
390 | " blur_image = reduce_noise(gray_image, param['kernel_size'])\n",
391 | " \n",
392 | " edge_image = get_edges(blur_image, param['canny_lo'], param['canny_hi'])\n",
393 | " \n",
394 | " x, y = image.shape[1], image.shape[0]\n",
395 | " vertices = get_vertices(x, y, param['ax_coef'], param['bx_coef'],\n",
396 | " param['cy_coef'], param['dy_coef'],\n",
397 | " param['maxx_coef'], param['maxy_coef'],\n",
398 | " param['startx_coef'])\n",
399 | " roi = get_roi(edge_image, vertices) \n",
400 | " mask_image = mask(edge_image, roi)\n",
401 | " \n",
402 | " lines = get_lines(mask_image, param['rho'], param['theta_coef'],\n",
403 | " param['min_votes'], param['min_line_length'],\n",
404 | " param['max_line_gap'])\n",
405 | " \n",
406 | " #line_image = draw(lines, raw_image) \n",
407 | " #result = overlap(line_image, raw_image)\n",
408 | " \n",
409 | " line_image2 = extrapolate_lines(lines, raw_image) \n",
410 | " result = overlap(line_image2, raw_image)\n",
411 | " return result"
412 | ]
413 | },
414 | {
415 | "cell_type": "code",
416 | "execution_count": 132,
417 | "metadata": {
418 | "collapsed": false,
419 | "deletable": true,
420 | "editable": true
421 | },
422 | "outputs": [
423 | {
424 | "name": "stdout",
425 | "output_type": "stream",
426 | "text": [
427 | "[MoviePy] >>>> Building video white.mp4\n",
428 | "[MoviePy] Writing video white.mp4\n"
429 | ]
430 | },
431 | {
432 | "name": "stderr",
433 | "output_type": "stream",
434 | "text": [
435 | "100%|█████████▉| 221/222 [00:06<00:00, 31.64it/s]\n"
436 | ]
437 | },
438 | {
439 | "name": "stdout",
440 | "output_type": "stream",
441 | "text": [
442 | "[MoviePy] Done.\n",
443 | "[MoviePy] >>>> Video ready: white.mp4 \n",
444 | "\n",
445 | "CPU times: user 3.32 s, sys: 917 ms, total: 4.23 s\n",
446 | "Wall time: 7.92 s\n"
447 | ]
448 | }
449 | ],
450 | "source": [
451 | "white_output = 'white.mp4'\n",
452 | "clip1 = VideoFileClip(\"solidWhiteRight.mp4\")\n",
453 | "white_clip = clip1.fl_image(process_image) #NOTE: this function expects color images!!\n",
454 | "%time white_clip.write_videofile(white_output, audio=False)"
455 | ]
456 | },
457 | {
458 | "cell_type": "code",
459 | "execution_count": 133,
460 | "metadata": {
461 | "collapsed": false,
462 | "deletable": true,
463 | "editable": true
464 | },
465 | "outputs": [
466 | {
467 | "data": {
468 | "text/html": [
469 | "\n",
470 | "\n"
473 | ],
474 | "text/plain": [
475 | ""
476 | ]
477 | },
478 | "execution_count": 133,
479 | "metadata": {},
480 | "output_type": "execute_result"
481 | }
482 | ],
483 | "source": [
484 | "HTML(\"\"\"\n",
485 | "\n",
488 | "\"\"\".format(white_output))"
489 | ]
490 | },
491 | {
492 | "cell_type": "code",
493 | "execution_count": 134,
494 | "metadata": {
495 | "collapsed": false,
496 | "deletable": true,
497 | "editable": true
498 | },
499 | "outputs": [
500 | {
501 | "name": "stdout",
502 | "output_type": "stream",
503 | "text": [
504 | "[MoviePy] >>>> Building video yellow.mp4\n",
505 | "[MoviePy] Writing video yellow.mp4\n"
506 | ]
507 | },
508 | {
509 | "name": "stderr",
510 | "output_type": "stream",
511 | "text": [
512 | "100%|█████████▉| 681/682 [00:28<00:00, 24.11it/s]\n"
513 | ]
514 | },
515 | {
516 | "name": "stdout",
517 | "output_type": "stream",
518 | "text": [
519 | "[MoviePy] Done.\n",
520 | "[MoviePy] >>>> Video ready: yellow.mp4 \n",
521 | "\n",
522 | "CPU times: user 11.1 s, sys: 3.01 s, total: 14.1 s\n",
523 | "Wall time: 29.6 s\n"
524 | ]
525 | }
526 | ],
527 | "source": [
528 | "yellow_output = 'yellow.mp4'\n",
529 | "clip2 = VideoFileClip('solidYellowLeft.mp4')\n",
530 | "yellow_clip = clip2.fl_image(process_image)\n",
531 | "%time yellow_clip.write_videofile(yellow_output, audio=False)"
532 | ]
533 | },
534 | {
535 | "cell_type": "code",
536 | "execution_count": 135,
537 | "metadata": {
538 | "collapsed": false,
539 | "deletable": true,
540 | "editable": true
541 | },
542 | "outputs": [
543 | {
544 | "data": {
545 | "text/html": [
546 | "\n",
547 | "\n"
550 | ],
551 | "text/plain": [
552 | ""
553 | ]
554 | },
555 | "execution_count": 135,
556 | "metadata": {},
557 | "output_type": "execute_result"
558 | }
559 | ],
560 | "source": [
561 | "HTML(\"\"\"\n",
562 | "\n",
565 | "\"\"\".format(yellow_output))"
566 | ]
567 | },
568 | {
569 | "cell_type": "code",
570 | "execution_count": 136,
571 | "metadata": {
572 | "collapsed": false,
573 | "deletable": true,
574 | "editable": true
575 | },
576 | "outputs": [],
577 | "source": [
578 | "p = {\n",
579 | " #blur parameters\n",
580 | " 'kernel_size': 3, \n",
581 | " \n",
582 | " #canny transform parameters\n",
583 | " 'canny_lo': 50, \n",
584 | " 'canny_hi': 150, \n",
585 | "\n",
586 | " #region of interest parameters\n",
587 | " 'ax_coef': 0.41,\n",
588 | " 'bx_coef': 0.60,\n",
589 | " 'cy_coef': 0.65,\n",
590 | " 'dy_coef': 0.65,\n",
591 | " 'maxy_coef': 0.9,\n",
592 | " 'maxx_coef': 0.85,\n",
593 | " 'startx_coef': 0.15,\n",
594 | "\n",
595 | " #hough parameters\n",
596 | " 'rho': 1, \n",
597 | " 'theta_coef': 1, \n",
598 | " 'min_votes': 20, \n",
599 | " 'min_line_length': 50, \n",
600 | " 'max_line_gap': 20\n",
601 | "}\n",
602 | "\n",
603 | "def process(image):\n",
604 | "\n",
605 | " raw_image = np.copy(image)\n",
606 | "\n",
607 | " gray_image = gray(image) \n",
608 | " blur_image = reduce_noise(gray_image, p['kernel_size'])\n",
609 | " \n",
610 | " edge_image = get_edges(blur_image, p['canny_lo'], p['canny_hi'])\n",
611 | " \n",
612 | " #return convert_to_color(edge_image) #check if canny parameters detect edges of lanes\n",
613 | "\n",
614 | " x = image.shape[1]\n",
615 | " y = image.shape[0]\n",
616 | " vertices = get_vertices(x, y, p['ax_coef'], p['bx_coef'],\n",
617 | " p['cy_coef'], p['dy_coef'],\n",
618 | " p['maxy_coef'], p['maxx_coef'], p['startx_coef'])\n",
619 | " \n",
620 | " roi = get_roi(edge_image, vertices)\n",
621 | " mask_image = mask(edge_image, roi)\n",
622 | " \n",
623 | " #return overlap(convert_to_color(roi), raw_image) #check if roi is good\n",
624 | " \n",
625 | " lines = get_lines(mask_image, p['rho'], p['theta_coef'],\n",
626 | " p['min_votes'], p['min_line_length'],\n",
627 | " p['max_line_gap'], )\n",
628 | " \n",
629 | " #line_image = draw(lines, raw_image, thresh = 0.5) \n",
630 | " #result = overlap(line_image, raw_image)\n",
631 | " \n",
632 | " line_image2 = extrapolate_lines(lines, raw_image, \n",
633 | " positive_thresh = 0.5, negative_thresh = -0.5) \n",
634 | " result = overlap(line_image2, raw_image)\n",
635 | " \n",
636 | " return result"
637 | ]
638 | },
639 | {
640 | "cell_type": "code",
641 | "execution_count": 137,
642 | "metadata": {
643 | "collapsed": false,
644 | "deletable": true,
645 | "editable": true
646 | },
647 | "outputs": [
648 | {
649 | "name": "stdout",
650 | "output_type": "stream",
651 | "text": [
652 | "[MoviePy] >>>> Building video extra.mp4\n",
653 | "[MoviePy] Writing video extra.mp4\n"
654 | ]
655 | },
656 | {
657 | "name": "stderr",
658 | "output_type": "stream",
659 | "text": [
660 | "100%|██████████| 251/251 [00:16<00:00, 15.36it/s]\n"
661 | ]
662 | },
663 | {
664 | "name": "stdout",
665 | "output_type": "stream",
666 | "text": [
667 | "[MoviePy] Done.\n",
668 | "[MoviePy] >>>> Video ready: extra.mp4 \n",
669 | "\n",
670 | "CPU times: user 6.35 s, sys: 1.68 s, total: 8.03 s\n",
671 | "Wall time: 18 s\n"
672 | ]
673 | }
674 | ],
675 | "source": [
676 | "challenge_output = 'extra.mp4'\n",
677 | "clip2 = VideoFileClip('challenge.mp4')\n",
678 | "challenge_clip = clip2.fl_image(process)\n",
679 | "%time challenge_clip.write_videofile(challenge_output, audio=False)"
680 | ]
681 | },
682 | {
683 | "cell_type": "code",
684 | "execution_count": 138,
685 | "metadata": {
686 | "collapsed": false,
687 | "deletable": true,
688 | "editable": true
689 | },
690 | "outputs": [
691 | {
692 | "data": {
693 | "text/html": [
694 | "\n",
695 | "\n"
698 | ],
699 | "text/plain": [
700 | ""
701 | ]
702 | },
703 | "execution_count": 138,
704 | "metadata": {},
705 | "output_type": "execute_result"
706 | }
707 | ],
708 | "source": [
709 | "HTML(\"\"\"\n",
710 | "\n",
713 | "\"\"\".format(challenge_output))"
714 | ]
715 | }
716 | ],
717 | "metadata": {
718 | "anaconda-cloud": {},
719 | "kernelspec": {
720 | "display_name": "Python 3",
721 | "language": "python",
722 | "name": "python3"
723 | },
724 | "language_info": {
725 | "codemirror_mode": {
726 | "name": "ipython",
727 | "version": 3
728 | },
729 | "file_extension": ".py",
730 | "mimetype": "text/x-python",
731 | "name": "python",
732 | "nbconvert_exporter": "python",
733 | "pygments_lexer": "ipython3",
734 | "version": "3.5.2"
735 | },
736 | "widgets": {
737 | "state": {},
738 | "version": "1.1.2"
739 | }
740 | },
741 | "nbformat": 4,
742 | "nbformat_minor": 0
743 | }
744 |
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/NOTES.txt:
--------------------------------------------------------------------------------
1 | Notes on parameter tweaking (from the reviewer)
2 |
3 | max_line_gap
4 | - maximum distance(in pixels) between segments that will be allowed to connect into a single line.
5 |
6 | min_line_len
7 | - minimum length of a line (in pixels) that we will accept in the output
8 |
9 | 1. Increasing min_line_len and max_line_gap(~100 and above) for Hough Transform will make your lines longer and will have less number of breaks.(this will make the solid annotated line longer in the output)
10 |
11 | 2. Increasing max_line_gap will allow points that are farther away from each other to be connected with a single line. threshold increasing(~ 50-60) will rule out the spurious lines.(defines the minimum number of intersections in a given grid cell that are required to choose a line.)
12 |
13 | 3. kernel-size in the Gaussian Filter will remove the noise making the image less blurry. Must be an odd number (3, 5, 7...)
14 |
15 | 4. Use rho value of 2 or 1 which gives distance resolution in pixels of the Hough grid
16 |
17 | 5. Can a different colour space be used to make the pipeline more robust. (HSL, YUV etc)
18 |
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/README.md:
--------------------------------------------------------------------------------
1 | # Detected highway lane lines on a video stream. Used OpencV image analysis techniques to identify lines, including Hough Transforms and Canny edge detection.
2 | ---
3 |
4 | ### Requirements:
5 | - Jupyter notebook: BASIC_LANE_DETECTION.ipynb
6 | - Writeup: WRITEUP.pdf
7 |
8 | ### Possible improvements on my pipeline
9 | - Parameters can be tweaked for even better performance
10 | - If there was abrupt changes between two frames, we can reject the result of the second frame because it does not make sense.
11 | - Considering the following two consecutive frames, this does not make sense because of the abrupt change so we should disregard the second frame and consider it as an error/anomaly/miscalculation.
12 |
13 | ### References
14 | - http://docs.opencv.org/trunk/da/d22/tutorial_py_canny.html
15 | - https://alyssaq.github.io/2014/understanding-hough-transform/
16 | - https://medium.com/@vijay120/detecting-car-lane-lines-using-computer-vision-d23b2dafdf4c#.x8h9qq21q
17 | - http://airccj.org/CSCP/vol5/csit53211.pdf
18 | - http://stackoverflow.com/questions/36598897/python-and-opencv-improving-my-lane-detection-algorithm
19 |
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/WRITEUP.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/WRITEUP.pdf
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/examples/P1_example.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/examples/P1_example.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/examples/grayscale.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/examples/grayscale.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/examples/laneLines_thirdPass.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/examples/laneLines_thirdPass.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/examples/line-segments-example.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/examples/line-segments-example.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/examples/raw-lines-example.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/examples/raw-lines-example.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A1-raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A1-raw.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A10-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A10-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A2-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A2-grey.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A3-blur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A3-blur.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A4-edges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A4-edges.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A5-roi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A5-roi.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A6-mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A6-mask.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A7-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A7-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A8-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A8-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/A9-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/A9-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B1-raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B1-raw.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B10-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B10-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B2-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B2-grey.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B3-blur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B3-blur.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B4-edges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B4-edges.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B5-roi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B5-roi.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B6-mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B6-mask.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B7-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B7-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B8-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B8-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/B9-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/B9-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C1-raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C1-raw.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C10-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C10-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C2-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C2-grey.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C3-blur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C3-blur.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C4-edges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C4-edges.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C5-roi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C5-roi.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C6-mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C6-mask.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C7-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C7-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C8-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C8-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/C9-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/C9-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D1-raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D1-raw.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D10-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D10-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D2-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D2-grey.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D3-blur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D3-blur.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D4-edges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D4-edges.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D5-roi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D5-roi.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D6-mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D6-mask.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D7-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D7-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D8-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D8-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/D9-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/D9-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E1-raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E1-raw.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E10-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E10-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E2-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E2-grey.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E3-blur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E3-blur.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E4-edges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E4-edges.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E5-roi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E5-roi.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E6-mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E6-mask.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E7-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E7-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E8-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E8-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/E9-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/E9-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F1-raw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F1-raw.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F10-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F10-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F2-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F2-grey.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F3-blur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F3-blur.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F4-edges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F4-edges.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F5-roi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F5-roi.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F6-mask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F6-mask.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F7-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F7-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F8-lines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F8-lines.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/F9-overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/F9-overlap.png
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/solidWhiteCurve.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/solidWhiteCurve.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/solidWhiteRight.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/solidWhiteRight.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/solidYellowCurve.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/solidYellowCurve.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/solidYellowCurve2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/solidYellowCurve2.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/solidYellowLeft.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/solidYellowLeft.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/test_images/whiteCarLaneSwitch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/test_images/whiteCarLaneSwitch.jpg
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/1-edge_extra.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/1-edge_extra.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/2-roi_extra.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/2-roi_extra.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/3-small-lines-extra.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/3-small-lines-extra.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/challenge.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/challenge.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/extra.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/extra.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/solidWhiteRight.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/solidWhiteRight.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/solidYellowLeft.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/solidYellowLeft.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/white.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/white.mp4
--------------------------------------------------------------------------------
/A-BASIC-LANE-DETECTION/videos/yellow.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/A-BASIC-LANE-DETECTION/videos/yellow.mp4
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Mithi Sevilla
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## [Basic Lane Detection](./A-BASIC-LANE-DETECTION/)
2 |
3 | # INTRODUCTION
4 |
5 | Built an advanced lane-finding algorithm using distortion correction, image rectification, color transforms, and gradient thresholding. Identified lane curvature and vehicle displacement. Overcame environmental challenges such as shadows and pavement changes
6 |
7 | # [MEDIUM ARTICLE](https://medium.com/@mithi/advanced-lane-finding-using-computer-vision-techniques-7f3230b6c6f2)
8 |
9 | In this project, I have used computer vision techniques to identify lane boundaries and compute the estimate the radius of curvature given a frame of video of the road.
10 |
11 | To achieve this, the following steps are taken:
12 | - Computed the camera calibration matrix and distortion coefficients of the camera lens used given a set of chessboard images taken by the same camera
13 | - Used the aforementioned matrix and coefficient to correct the distortions given by the raw output from the camera
14 | - Use color transforms, and sobel algorithm to create a thresholded binary image that has been filtered out of unnecessary information on the image
15 | - Apply perspective transform to see a “birds-eye view” of the image as if looking from the sky
16 | - Apply masking to get the region of interest, detect lane pixels,
17 | - Determine the best fit curve for each lane the curvature of the lanes
18 | - Project the lane boundaries back onto the undistorted image of the original view
19 | - Output a visual display of the lane boundaries and other related information
20 |
21 | # HOW TO USE
22 | - You need to setup dependencies to run a Jupyter Notebook on your computer and setup a handful of packages such as `opencv`
23 | ```
24 | import matplotlib.pyplot as plt
25 | %matplotlib inline
26 | import cv2
27 | import numpy as np
28 | import pickle
29 | from scipy.misc import imread
30 |
31 | from moviepy.editor import VideoFileClip
32 | from IPython.display import HTML
33 | ```
34 | - To run any notebook properly, copy the jupyter notebooks from the `/notebook` folder to the `root` directory
35 | - This is so that each notebook sees to see relevant files, the most relevant files being the python classes.
36 |
37 | # Relevant Links
38 |
39 | - My Medium article
40 | - - https://medium.com/@mithi/advanced-lane-finding-using-computer-vision-techniques-7f3230b6c6f2
41 | - My submitted detailed technical writeup
42 | - - https://github.com/mithi/advanced-lane-detection/blob/master/WRITEUP.pdf
43 | - Udacity's project page
44 | - - https://github.com/udacity/CarND-Advanced-Lane-Lines
45 |
46 | # RELEVANT FILES
47 |
48 | ### Video Output
49 | - project_video_output.mp4
50 | - project_video_verbose_output.mp4
51 |
52 | ### Pipeline
53 | - pipeline.ipynb
54 | - pipeline_verbose.ipynb
55 |
56 | ### Classes
57 | - ChessBoard - chessboard.py
58 | - BirdsEye - birdseye.py
59 | - LaneFilter - lanefilter.py
60 | - Curves - curves.py
61 |
--------------------------------------------------------------------------------
/WRITEUP.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/WRITEUP.pdf
--------------------------------------------------------------------------------
/birdseye.py:
--------------------------------------------------------------------------------
1 | from helpers import show_dotted_image
2 | import cv2
3 | import numpy as np
4 |
5 | class BirdsEye:
6 |
7 | def __init__(self, source_points, dest_points, cam_matrix, distortion_coef):
8 | self.spoints = source_points
9 | self.dpoints = dest_points
10 | self.src_points = np.array(source_points, np.float32)
11 | self.dest_points = np.array(dest_points, np.float32)
12 | self.cam_matrix = cam_matrix
13 | self.dist_coef = distortion_coef
14 |
15 | self.warp_matrix = cv2.getPerspectiveTransform(self.src_points, self.dest_points)
16 | self.inv_warp_matrix = cv2.getPerspectiveTransform(self.dest_points, self.src_points)
17 |
18 | def undistort(self, raw_image, show_dotted = False):
19 |
20 | image = cv2.undistort(raw_image, self.cam_matrix, self.dist_coef, None, self.cam_matrix)
21 |
22 | if show_dotted:
23 | show_dotted_image(image, self.spoints)
24 |
25 | return image
26 |
27 | def sky_view(self, ground_image, show_dotted = False):
28 |
29 | temp_image = self.undistort(ground_image, show_dotted = False)
30 | shape = (temp_image.shape[1], temp_image.shape[0])
31 | warp_image = cv2.warpPerspective(temp_image, self.warp_matrix, shape, flags = cv2.INTER_LINEAR)
32 |
33 | if show_dotted:
34 | show_dotted_image(warp_image, self.dpoints)
35 |
36 | return warp_image
37 |
38 | def project(self, ground_image, sky_lane, left_fit, right_fit, color = (0, 255, 0)):
39 |
40 | z = np.zeros_like(sky_lane)
41 | sky_lane = np.dstack((z, z, z))
42 |
43 | kl, kr = left_fit, right_fit
44 | h = sky_lane.shape[0]
45 | ys = np.linspace(0, h - 1, h)
46 | lxs = kl[0] * (ys**2) + kl[1]* ys + kl[2]
47 | rxs = kr[0] * (ys**2) + kr[1]* ys + kr[2]
48 |
49 | pts_left = np.array([np.transpose(np.vstack([lxs, ys]))])
50 | pts_right = np.array([np.flipud(np.transpose(np.vstack([rxs, ys])))])
51 | pts = np.hstack((pts_left, pts_right))
52 |
53 | cv2.fillPoly(sky_lane, np.int_(pts), color)
54 |
55 | shape = (sky_lane.shape[1], sky_lane.shape[0])
56 | ground_lane = cv2.warpPerspective(sky_lane, self.inv_warp_matrix, shape)
57 |
58 | result = cv2.addWeighted(ground_image, 1, ground_lane, 0.3, 0)
59 | return result
--------------------------------------------------------------------------------
/calibration_data.p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/calibration_data.p
--------------------------------------------------------------------------------
/camera_cal/calibration1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration1.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration10.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration11.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration12.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration13.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration14.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration15.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration16.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration17.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration17.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration18.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration18.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration19.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration19.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration2.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration20.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration20.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration3.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration4.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration5.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration6.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration7.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration8.jpg
--------------------------------------------------------------------------------
/camera_cal/calibration9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/camera_cal/calibration9.jpg
--------------------------------------------------------------------------------
/chessboard.py:
--------------------------------------------------------------------------------
1 |
2 | import cv2
3 | import numpy as np
4 | from scipy.misc import imread
5 |
6 | class ChessBoard:
7 |
8 | def __init__(self, i, path, nx = 9, ny = 6):
9 |
10 | self.i = i
11 | self.path = path
12 | self.nx, self.ny = nx, ny
13 | self.n = (self.nx, self.ny)
14 |
15 | temp_image = imread(self.path)
16 | temp_gray = cv2.cvtColor(temp_image, cv2.COLOR_RGB2GRAY)
17 |
18 | self.rows, self.cols, self.channels = temp_image.shape
19 | self.dimensions = (self.rows, self.cols)
20 |
21 | self.has_corners, self.corners = cv2.findChessboardCorners(temp_gray, self.n, None)
22 | self.object_points = self.get_object_points()
23 | self.matrix, self.distortion, self.can_undistort = None, None, False
24 |
25 | def get_object_points(self):
26 | # (0, 0 ,0), (0, 1, 0)... (8, 5, 0)
27 | number_of_points = self.nx * self.ny
28 | points = np.zeros((number_of_points, 3), np.float32)
29 | points[:, :2] = np.mgrid[0:self.nx, 0:self.ny].T.reshape(-1, 2)
30 | return points
31 |
32 | def image(self):
33 | temp_image = imread(self.path)
34 | return temp_image
35 |
36 | def image_with_corners(self):
37 | ''' if this image doesn't have calculated corners, return raw image '''
38 | temp_image = imread(self.path)
39 | if self.has_corners:
40 | cv2.drawChessboardCorners(temp_image, self.n, self.corners, self.has_corners)
41 | return temp_image
42 |
43 | def undistorted_image(self):
44 | '''if camera parameters is not initialized, return None '''
45 | temp_image = None
46 | if self.can_undistort:
47 | temp_image = imread(self.path)
48 | temp_image = cv2.undistort(temp_image, self.matrix, self.distortion, None, self.matrix)
49 | return temp_image
50 |
51 | def load_undistort_params(self, camera_matrix, distortion):
52 | self.distortion = distortion
53 | self.matrix = camera_matrix
54 | self.can_undistort = True
--------------------------------------------------------------------------------
/curves.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 |
4 | class Curves:
5 | def __init__(self, number_of_windows, margin, minimum_pixels, ym_per_pix, xm_per_pix):
6 |
7 | self.min_pix = minimum_pixels
8 | self.margin = margin
9 | self.n = number_of_windows
10 | self.ky, self.kx = ym_per_pix, xm_per_pix
11 |
12 | self.binary, self.h, self.w, self.window_height = None, None, None, None
13 | self.all_pixels_x, self.all_pixels_y = None, None
14 | self.left_pixels_indices, self.right_pixels_indices = [], []
15 | self.left_pixels_x, self.left_pixels_y = None, None
16 | self.right_pixels_x, self.right_pixels_y = None, None
17 | self.out_img = None
18 | self.left_fit_curve_pix, self.right_fit_curve_pix = None, None
19 | self.left_fit_curve_f, self.right_fit_curve_f = None, None
20 | self.left_radius, self.right_radius = None, None
21 | self.vehicle_position, self.vehicle_position_words = None, None
22 | self.result = {}
23 |
24 | def store_details(self, binary):
25 | self.out_img = np.dstack((binary, binary, binary)) * 255
26 | self.binary = binary
27 | self.h, self.w = binary.shape[0], binary.shape[1]
28 | self.mid = self.h / 2
29 | self.window_height = np.int(self.h / self.n)
30 | self.all_pixels_x = np.array(binary.nonzero()[1])
31 | self.all_pixels_y = np.array(binary.nonzero()[0])
32 |
33 | def start(self, binary):
34 | hist = np.sum(binary[np.int(self.h / 2):, :], axis = 0)
35 | mid = np.int(hist.shape[0] / 2)
36 | current_leftx = np.argmax(hist[:mid])
37 | current_rightx = np.argmax(hist[mid:]) + mid
38 | return current_leftx, current_rightx
39 |
40 | def next_y(self, w):
41 | y_lo = self.h - (w + 1) * self.window_height
42 | y_hi = self.h - w * self.window_height
43 | return y_lo, y_hi
44 |
45 | def next_x(self, current):
46 | x_left = current - self.margin
47 | x_right = current + self.margin
48 | return x_left, x_right
49 |
50 | def next_midx(self, current, pixel_indices):
51 | if len(pixel_indices) > self.min_pix:
52 | current = np.int(np.mean(self.all_pixels_x[pixel_indices]))
53 | return current
54 |
55 | def draw_boundaries(self, p1, p2, color, thickness = 5):
56 | cv2.rectangle(self.out_img, p1, p2, color, thickness)
57 |
58 | def indices_within_boundary(self, y_lo, y_hi, x_left, x_right):
59 | cond1 = (self.all_pixels_y >= y_lo)
60 | cond2 = (self.all_pixels_y < y_hi)
61 | cond3 = (self.all_pixels_x >= x_left)
62 | cond4 = (self.all_pixels_x < x_right)
63 | return (cond1 & cond2 & cond3 & cond4 ).nonzero()[0]
64 |
65 | def pixel_locations(self, indices):
66 | return self.all_pixels_x[indices], self.all_pixels_y[indices]
67 |
68 | def plot(self, t = 4):
69 |
70 | self.out_img[self.left_pixels_y, self.left_pixels_x] = [255, 0, 255]
71 | self.out_img[self.right_pixels_y, self.right_pixels_x] = [0, 255, 255]
72 |
73 | self.left_fit_curve_pix = np.polyfit(self.left_pixels_y, self.left_pixels_x, 2)
74 | self.right_fit_curve_pix = np.polyfit(self.right_pixels_y, self.right_pixels_x, 2)
75 |
76 | kl, kr = self.left_fit_curve_pix, self.right_fit_curve_pix
77 | ys = np.linspace(0, self.h - 1, self.h)
78 |
79 | left_xs = kl[0] * (ys**2) + kl[1] * ys + kl[2]
80 | right_xs = kr[0] * (ys**2) + kr[1] * ys + kr[2]
81 |
82 | xls, xrs, ys = left_xs.astype(np.uint32), right_xs.astype(np.uint32), ys.astype(np.uint32)
83 |
84 | for xl, xr, y in zip(xls, xrs, ys):
85 | cv2.line(self.out_img, (xl - t, y), (xl + t, y), (255, 255, 0), int(t / 2))
86 | cv2.line(self.out_img, (xr - t, y), (xr + t, y), (0, 0, 255), int(t / 2))
87 |
88 | def get_real_curvature(self, xs, ys):
89 | return np.polyfit(ys * self.ky, xs * self.kx, 2)
90 |
91 | def radius_of_curvature(self, y, f):
92 | return ((1 + (2 * f[0] * y + f[1])**2)**(1.5)) / np.absolute(2 * f[0])
93 |
94 | def update_vehicle_position(self):
95 | y = self.h
96 | mid = self.w / 2
97 | kl, kr = self.left_fit_curve_pix, self.right_fit_curve_pix
98 | xl = kl[0] * (y**2) + kl[1]* y + kl[2]
99 | xr = kr[0] * (y**2) + kr[1]* y + kr[2]
100 | pix_pos = xl + (xr - xl) / 2
101 | self.vehicle_position = (pix_pos - mid) * self.kx
102 |
103 | if self.vehicle_position < 0:
104 | self.vehicle_position_words = str(np.absolute(np.round(self.vehicle_position, 2))) + " m left of center"
105 | elif self.vehicle_position > 0:
106 | self.vehicle_position_words = str(np.absolute(np.round(self.vehicle_position, 2))) + " m right of center"
107 | else:
108 | self.vehicle_position_words = "at the center"
109 |
110 | def fit(self, binary):
111 |
112 | self.store_details(binary)
113 | mid_leftx, mid_rightx = self.start(binary)
114 |
115 | left_pixels_indices, right_pixels_indices = [], []
116 | x, y = [None, None, None, None], [None, None]
117 |
118 | for w in range(self.n):
119 |
120 | y[0], y[1] = self.next_y(w)
121 | x[0], x[1] = self.next_x(mid_leftx)
122 | x[2], x[3] = self.next_x(mid_rightx)
123 |
124 | self.draw_boundaries((x[0], y[0]), (x[1], y[1]), (255, 0, 0))
125 | self.draw_boundaries((x[2], y[0]), (x[3], y[1]), (0, 255, 0))
126 |
127 | curr_left_pixels_indices = self.indices_within_boundary(y[0], y[1], x[0], x[1])
128 | curr_right_pixels_indices = self.indices_within_boundary(y[0], y[1], x[2], x[3])
129 |
130 | left_pixels_indices.append(curr_left_pixels_indices)
131 | right_pixels_indices.append(curr_right_pixels_indices)
132 |
133 | mid_leftx = self.next_midx(mid_leftx, curr_left_pixels_indices)
134 | mid_rightx = self.next_midx(mid_rightx, curr_right_pixels_indices)
135 |
136 | self.left_pixels_indices = np.concatenate(left_pixels_indices)
137 | self.right_pixels_indices = np.concatenate(right_pixels_indices)
138 |
139 | self.left_pixels_x, self.left_pixels_y = self.pixel_locations(self.left_pixels_indices)
140 | self.right_pixels_x, self.right_pixels_y = self.pixel_locations(self.right_pixels_indices)
141 |
142 | self.left_fit_curve_f = self.get_real_curvature(self.left_pixels_x, self.left_pixels_y)
143 | self.right_fit_curve_f = self.get_real_curvature(self.right_pixels_x, self.right_pixels_y)
144 |
145 | self.left_radius = self.radius_of_curvature(self.h * self.ky, self.left_fit_curve_f)
146 | self.right_radius = self.radius_of_curvature(self.h * self.ky, self.right_fit_curve_f)
147 |
148 | self.plot()
149 | self.update_vehicle_position()
150 |
151 | self.result = {
152 | 'image': self.out_img,
153 | 'left_radius': self.left_radius,
154 | 'right_radius': self.right_radius,
155 | 'real_left_best_fit_curve': self.left_fit_curve_f,
156 | 'real_right_best_fit_curve': self.right_fit_curve_f,
157 | 'pixel_left_best_fit_curve': self.left_fit_curve_pix,
158 | 'pixel_right_best_fit_curve': self.right_fit_curve_pix,
159 | 'vehicle_position': self.vehicle_position,
160 | 'vehicle_position_words': self.vehicle_position_words
161 | }
162 |
163 | return self.result
--------------------------------------------------------------------------------
/docs/Notes_FROM_REVIEWER.MD:
--------------------------------------------------------------------------------
1 | Notes From The reviewer
2 |
3 | To see some ideas on using deep learning instead, you can read
4 | - https://chatbotslife.com/small-u-net-for-vehicle-detection-9eec216f9fd6#.3dr04zwkm
5 | - https://github.com/JamesLuoau/Self-Driving-Car-Vehicle-Detection
6 | - http://www.learnopencv.com/histogram-of-oriented-gradients/
7 |
8 | - You might be able to speed up the pipeline's speed a bit while maintaining good accuracy by using more pixels per cell. For example, I've seen these settings perform well...
9 |
10 | ` colorspace = 'YUV' `
11 | ` orient = 11 `
12 | ` pix_per_cell = 16 `
13 | ` cell_per_block = 2 `
14 | ` hog_channel = "ALL" `
15 |
16 | - To optimize the model's accuracy, you could also try a grid search to tune the SVC's C parameter.
17 | - http://stats.stackexchange.com/questions/31066/what-is-the-influence-of-c-in-svms-with-linear-kernel
18 | - http://scikit-learn.org/stable/modules/grid_search.html
19 |
20 | - It will probably help the output video results to use a different colorspace for the HOG extraction. Most students have success with YCrCb or YUV, and the best solutions seem to use one of those colorspaces with all color channels.
21 |
22 | - http://www.pyimagesearch.com/2015/03/23/sliding-windows-for-object-detection-with-python-and-opencv/
23 | - Tip: You might be able to use fewer window scales — many students do well using just 1-3 scales, with overlap in the 0.65 - 0.85 range.
24 |
25 | ### Tip: To help with reducing false positives, other ideas you could have tried include:
26 | - Using the SVM's built-in decision_function method, which returns a confidence score based on how far a data point is from the decision boundary — higher values equate to higher confidence predictions that can be thresholded.
27 | - Augment the training with hard negative mining.
28 | - http://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html#sklearn.svm.LinearSVC.decision_function
29 | - https://www.reddit.com/r/computervision/comments/2ggc5l/what_is_hard_negative_mining_and_how_is_it/
30 |
31 | ### Tip: pipeline speed
32 | Considering that a pipeline on a real car needs to be processed in real-time, it would be great to also address the pipeline's speed performance more explicitly (e.g., in frames per second).
33 |
34 | For improved speed performance in extracting HOG features, you could try using cv2.HOGDescriptor (read more here)
35 | And for additional ideas on speeding up vehicle detection, you can read about Haar Cascades.
36 | - http://stackoverflow.com/questions/28390614/opencv-hogdescripter-python
37 | - https://github.com/andrewssobral/vehicle_detection_haarcascades
38 |
--------------------------------------------------------------------------------
/helpers.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import cv2
3 | import numpy as np
4 | from matplotlib.patches import Circle
5 | from scipy.misc import imsave
6 |
7 | def scale_abs(x, m = 255):
8 | x = np.absolute(x)
9 | x = np.uint8(m * x / np.max(x))
10 | return x
11 |
12 | def roi(gray, mn = 125, mx = 1200):
13 | m = np.copy(gray) + 1
14 | m[:, :mn] = 0
15 | m[:, mx:] = 0
16 | return m
17 |
18 | def save_image(img, name, i):
19 | path = "output_images/" + name + str(i) + ".jpg"
20 | imsave(path, img)
21 |
22 |
23 | def show_images(imgs, per_row = 3, per_col = 2, W = 10, H = 5, tdpi = 80):
24 |
25 | fig, ax = plt.subplots(per_col, per_row, figsize = (W, H), dpi = tdpi)
26 | ax = ax.ravel()
27 |
28 | for i in range(len(imgs)):
29 | img = imgs[i]
30 | ax[i].imshow(img)
31 |
32 | for i in range(per_row * per_col):
33 | ax[i].axis('off')
34 |
35 |
36 | def show_dotted_image(this_image, points, thickness = 5, color = [255, 0, 255 ], d = 15):
37 |
38 | image = this_image.copy()
39 |
40 | cv2.line(image, points[0], points[1], color, thickness)
41 | cv2.line(image, points[2], points[3], color, thickness)
42 |
43 | fig, ax = plt.subplots(1)
44 | ax.set_aspect('equal')
45 | ax.imshow(image)
46 |
47 | for (x, y) in points:
48 | dot = Circle((x, y), d)
49 | ax.add_patch(dot)
50 |
51 | plt.show()
52 |
53 |
--------------------------------------------------------------------------------
/lanefilter.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import numpy as np
3 | from helpers import roi, scale_abs
4 |
5 | class LaneFilter:
6 | def __init__(self, p):
7 | self.sat_thresh = p['sat_thresh']
8 | self.light_thresh = p['light_thresh']
9 | self.light_thresh_agr = p['light_thresh_agr']
10 | self.grad_min, self.grad_max = p['grad_thresh']
11 | self.mag_thresh, self.x_thresh = p['mag_thresh'], p['x_thresh']
12 | self.hls, self.l, self.s, self.z = None, None, None, None
13 | self.color_cond1, self.color_cond2 = None, None
14 | self.sobel_cond1, self.sobel_cond2, self.sobel_cond3 = None, None, None
15 |
16 | def sobel_breakdown(self, img):
17 | self.apply(img)
18 | b1, b2, b3 = self.z.copy(), self.z.copy(), self.z.copy()
19 | b1[(self.sobel_cond1)] = 255
20 | b2[(self.sobel_cond2)] = 255
21 | b3[(self.sobel_cond3)] = 255
22 | return np.dstack((b1, b2,b3))
23 |
24 | def color_breakdown(self, img):
25 | self.apply(img)
26 | b1, b2 = self.z.copy(), self.z.copy()
27 | b1[(self.color_cond1)] = 255
28 | b2[(self.color_cond2)] = 255
29 | return np.dstack((b1, b2, self.z))
30 |
31 | def apply(self, rgb_image):
32 | self.hls = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2HLS)
33 | self.l = self.hls[:, :, 1]
34 | self.s = self.hls[:, :, 2]
35 | self.z = np.zeros_like(self.s)
36 | color_img = self.apply_color_mask()
37 | sobel_img = self.apply_sobel_mask()
38 | filtered_img = cv2.bitwise_or(sobel_img, color_img)
39 | return filtered_img
40 |
41 | def apply_color_mask(self):
42 | self.color_cond1 = (self.s > self.sat_thresh) & (self.l > self.light_thresh)
43 | self.color_cond2 = self.l > self.light_thresh_agr
44 | b = self.z.copy()
45 | b[(self.color_cond1 | self.color_cond2)] = 1
46 | return b
47 |
48 | def apply_sobel_mask(self):
49 | lx = cv2.Sobel(self.l, cv2.CV_64F, 1, 0, ksize = 5)
50 | ly = cv2.Sobel(self.l, cv2.CV_64F, 0, 1, ksize = 5)
51 | gradl = np.arctan2(np.absolute(ly), np.absolute(lx))
52 | l_mag = np.sqrt(lx**2 + ly**2)
53 | slm, slx, sly = scale_abs(l_mag), scale_abs(lx), scale_abs(ly)
54 | b = self.z.copy()
55 | self.sobel_cond1 = slm > self.mag_thresh
56 | self.sobel_cond2 = slx > self.x_thresh
57 | self.sobel_cond3 = (gradl > self.grad_min) & (gradl < self.grad_max)
58 | b[(self.sobel_cond1 & self.sobel_cond2 & self.sobel_cond3)] = 1
59 | return b
--------------------------------------------------------------------------------
/notebooks/fitting_curves.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "collapsed": true,
8 | "deletable": true,
9 | "editable": true
10 | },
11 | "outputs": [],
12 | "source": [
13 | "import matplotlib.pyplot as plt\n",
14 | "%matplotlib inline\n",
15 | "import cv2 \n",
16 | "import numpy as np\n",
17 | "import pickle\n",
18 | "from scipy.misc import imread\n",
19 | "\n",
20 | "from birdseye import BirdsEye\n",
21 | "from lanefilter import LaneFilter\n",
22 | "from curves import Curves\n",
23 | "from helpers import show_images, save_image, roi"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": 2,
29 | "metadata": {
30 | "collapsed": false,
31 | "deletable": true,
32 | "editable": true
33 | },
34 | "outputs": [],
35 | "source": [
36 | "calibration_data = pickle.load(open(\"calibration_data.p\", \"rb\" ))\n",
37 | "\n",
38 | "matrix = calibration_data['camera_matrix']\n",
39 | "dist_coef = calibration_data['distortion_coefficient']\n",
40 | "\n",
41 | "source_points = [(580, 460), (205, 720), (1110, 720), (703, 460)]\n",
42 | "dest_points = [(320, 0), (320, 720), (960, 720), (960, 0)]\n",
43 | "\n",
44 | "p = { 'sat_thresh': 120, 'light_thresh': 40, 'light_thresh_agr': 205,\n",
45 | " 'grad_thresh': (0.7, 1.4), 'mag_thresh': 40, 'x_thresh': 20 }\n",
46 | "\n",
47 | "birdsEye = BirdsEye(source_points, dest_points, matrix, dist_coef)\n",
48 | "laneFilter = LaneFilter(p)\n",
49 | "curves = Curves(number_of_windows = 9, margin = 100, minimum_pixels = 50, \n",
50 | " ym_per_pix = 30 / 720 , xm_per_pix = 3.7 / 700)"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": 3,
56 | "metadata": {
57 | "collapsed": false,
58 | "deletable": true,
59 | "editable": true
60 | },
61 | "outputs": [],
62 | "source": [
63 | "def curve_test(path):\n",
64 | " img = imread(path)\n",
65 | " binary = laneFilter.apply(img)\n",
66 | " wb = np.logical_and(birdsEye.sky_view(binary), roi(binary)).astype(np.uint8)\n",
67 | " result = curves.fit(wb)\n",
68 | " print(\"[real world] left best-fit curve parameters:\", result['real_left_best_fit_curve'])\n",
69 | " print(\"[real world] right best-fit curve parameters:\", result['real_right_best_fit_curve'])\n",
70 | " print(\"[pixel] left best-fit curve parameters:\", result['pixel_left_best_fit_curve'])\n",
71 | " print(\"[pixel] left best-fit curve parameters:\", result['pixel_right_best_fit_curve'])\n",
72 | " print(\"[left] current radius of curvature:\", result['left_radius'], \"m\")\n",
73 | " print(\"[right] current radius of curvature:\", result['right_radius'], \"m\")\n",
74 | " print(\"vehicle position:\", result['vehicle_position_words'])\n",
75 | " plt.imshow(result['image'])"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": 4,
81 | "metadata": {
82 | "collapsed": false,
83 | "deletable": true,
84 | "editable": true
85 | },
86 | "outputs": [
87 | {
88 | "name": "stdout",
89 | "output_type": "stream",
90 | "text": [
91 | "[real world] left best-fit curve parameters: [ 4.68567498e-04 -2.61879574e-02 2.19431869e+00]\n",
92 | "[real world] right best-fit curve parameters: [ 2.37038169e-04 -2.50823064e-02 5.73248022e+00]\n",
93 | "[pixel] left best-fit curve parameters: [ 1.53902613e-04 -2.06436601e-01 4.15141373e+02]\n",
94 | "[pixel] left best-fit curve parameters: [ 7.78560054e-05 -1.97720884e-01 1.08452328e+03]\n",
95 | "[left] current radius of curvature: 1067.08805899 m\n",
96 | "[right] current radius of curvature: 2109.73810098 m\n",
97 | "vehicle position: 0.13 m right of center\n"
98 | ]
99 | },
100 | {
101 | "data": {
102 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAADfCAYAAAD4Bhh5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFypJREFUeJzt3X+sJWV9x/H3p+CC4o9dUMh2dy0QN1b+EZaNXaoxFhSB\nGpYmkGBM2FKaTforWpvoUv9oTPpHaRuxxAbdiHZpUKEoZUOslCw07T8g9woiP92LP9jbXVkNsFZJ\nqtRv/zjP2Z2999x75tw7c2bmmc/r5ubMPOe5d54585zvec4zzzyjiMDMzPL1a00XwMzM6uVAb2aW\nOQd6M7PMOdCbmWXOgd7MLHMO9GZmmasl0Eu6RNIzkuYk7apjG2ZmVo6qHkcv6QTgu8D7gHngYeCD\nEfFkpRsyM7NS6mjRvwOYi4jvRcQvgK8A22vYjpmZlXBiDf9zA3CgsD4P/NZyfyCp8ctzzz//fGZn\nZ5suRinnN7ml8wuv0eyokqz8NezGq2+rMr3Ku3jDs8evDlRU65qrvD+JiDeNy1RHoNeItEWBXNJO\nYGcN21+RmZkZAKRRxW+XGUa/yFULZkZsvLBlLX5eKyjZsHK0/5W3VRtWmWke7GH3dHGbR8uxyoI0\nX3l/WCZTHYF+HthUWN8IHFyYKSJ2A7uhHS16M+uZDjTqqlJHH/3DwGZJZ0laA1wN7K1hO5WS1InW\n/LTE4i9hx1vw2az0Y9Y60oKgvnA9f5W36CPiFUl/CtwLnAB8ISKeqHo71oDo15vDLBeVD69cUSHc\ndTORoP4uwZEt+mKgH9GiX/m2hv/DstfYwS7W1wo33nzlnY2IreMy+crYpA0feGZmdXCgNzPLXB2j\nbjrJJ2LHnIBdptvGzNrNLXoz65F+Nugc6O0oD4+0PPkbqAO9mVnmHOitEmMvsDKzxjjQ23HcfWOW\nHwd6G88jbiwL/W3EONCbmWXOgd7MMuZvoOALpixZ6clU9+mbtZ9b9GZmmXOgt+X5RKxZ57nrpkNi\nieUmtaUc1iJlKsU0Kk6xYdLzeym4Rd8R9b8v+v1GMMuZW/QdU2c4XsmHyWrKM40bqFiD2nRwV1tR\nV/s/Gja2RS/pC5IOS3q8kHaqpPsk7U+P61K6JN0kaU7SY5K21Fl4q9ayI2jcP2/WWWW6bv4JuGRB\n2i5gX0RsBvaldYBLgc3pdydwczXFNDOzlRob6CPiP4EXFiRvB/ak5T3AFYX0W2PgQWCtpPVVFdam\nrOcnsMxysdKTsWdExCGA9Hh6St8AHCjkm09p1mJR+DHLQxy/2PN7Qld9MnZUE3DkKyxpJ4PuHTMz\nq9FKW/TPD7tk0uPhlD4PbCrk2wgcHPUPImJ3RGyNiK0rLIOZ2WKjWu89vyf0SgP9XmBHWt4B3F1I\nvyaNvtkGHBl28ViHecSNdVnPgzyU6LqR9GXgPcAbJc0DfwX8DXCHpOuA54CrUvavA5cBc8DLwLU1\nlNka5onMrLV63he/FEULXhjJTcZx6rxmY+RJ2GXmuKkq0PuCqUw1dYHRMJYdt90KCtHuC6Zmy3R/\newoEM8uHu2lGcqA3s+6LcJBfhgN9z006dt7989ZKDvLLcqA3M8ucA33PjWyh+2YjlgW38occ6M3M\nMudAb2YZ8TfQURzozcwy50BvZpY530qwpZb6AlrtF9PJ/5u/GFtpTVSW4vlXV9aj3KLvNY+4sUz5\npjnHcYu+5equrpOG8pWWp93ThVgtmjzYVW47g/aOW/RmlokMInJNHOh7btIpDXy7QbPucaA3M8uc\nA72ZWeYc6HvOXTGWh2I99in/hRzo7RgPrTTL0thAL2mTpAckPSXpCUkfTumnSrpP0v70uC6lS9JN\nkuYkPSZpS907YSvn+eXN8lemRf8K8BcR8TZgG/Anks4BdgH7ImIzsC+tA1wKbE6/O4GbKy+1VSLS\nj5nlbWygj4hDEfGttPw/wFPABmA7sCdl2wNckZa3A7fGwIPAWknrKy+5mZmVMlEfvaQzgfOAh4Az\nIuIQDD4MgNNTtg3AgcKfzae0hf9rp6QZSTOTF9vMzMoqPQWCpNcCXwU+EhE/1dL3aBz1xKL+gYjY\nDexO/9v9Bx3hPn1rH4+4GadUi17SqxgE+dsi4msp+flhl0x6PJzS54FNhT/fCBysprhWpSWDtj93\nzbJSZtSNgFuApyLiU4Wn9gI70vIO4O5C+jVp9M024Miwi8dazLP9mWVLEcu33iS9C/gv4DvAr1Ly\nXzLop78DeDPwHHBVRLyQPhg+A1wCvAxcGxHL9sO762axumd7XDTapsQY+tV023j2yh6Z+sGuueum\n3ZV3NiK2jss0NtBPgwP9Yg701lkO9NNUKtD7ylgzs8z5xiM94wukzPrHLXoz6zAPrSzDLfoWiiWW\nq6Hl/+syp0v8XcCWtbCCTKPC+GbgpTjQ985K3w1uLVnbLazbrrNDDvQtVk811fIjbmooS7sHLVil\n2nKQl75yv7yMKq776M3MMucWfc9MMurG89pYq0Uca227f35ZbtGbWfcUg/xCVXTbZMaB3szy0oKr\n/dvGgd7MumVcIHeLfhEHejtmwRh6X0VrrePW+oo40NuSfDLWLA8O9H3neeit69zIH8vDK3vC3TBm\n/eUWvZl1Q7F/3kMrJ+JAb2b58MnakcrcM/ZkSd+U9G1JT0j6ZEo/S9JDkvZLul3SmpR+UlqfS8+f\nWe8umJklbtGPVKZF/7/AhRHxduBc4JJ00+8bgBsjYjPwInBdyn8d8GJEvAW4MeWzhnkEjXWaW+qr\nMjbQx8DP0uqr0m8AFwJ3pvQ9wBVpeXtaJz1/UbphuHWIPxjM8lGqj17SCZIeBQ4D9wHPAi9FxCsp\nyzywIS1vAA4ApOePAKeN+J87Jc1ImlndLtiKlbghuFmrHXeDKTdOllIq0EfE/0XEucBG4B3A20Zl\nS4+jXu1FUSQidkfE1jJ3MLfpcmveLC8TjbqJiJeA/wC2AWslDcfhbwQOpuV5YBNAev4NwAtVFNbM\nbGQ7xK35ZZUZdfMmSWvT8quB9wJPAQ8AV6ZsO4C70/LetE56/v4In0npEl9cZZ3jELOsMlfGrgf2\nSDqBwQfDHRFxj6Qnga9I+mvgEeCWlP8W4J8lzTFoyV9dQ7mz1MS9lZfit42V0ppKK1faZagNjW3J\nZwJhGvV0mXvFLjoE1X8V9pfrDE31nZs2psVJi5+oSPsr7WyZ85ye66aF6qpbk70nY9UnZTO6t7KN\nU/dBnuYc9EF2ldZTIPSE+90tC0u25m05DvRmZplzoDez9hvXNdOCc41t5kDfE4v6231VrHWJ7xO7\nKg70PeE+esuWg/xYDvS2JH84WCu4W2bVPLzSRvJ8N9YJbs2X4ha9mXWTg3xpDvQ94Ra6dZ7H0K+Y\nu256wv3t1llHW+4xIs3KcIvezCxzDvQ9MGlr3t08ZnlxoO8BB26zfnOgNzPLnAN9H3n6A7NecaA3\nsw4oNkjcFTmp0oFe0gmSHpF0T1o/S9JDkvZLul3SmpR+UlqfS8+fWU/RrQ7uzzfLzyQt+g8zuCn4\n0A3AjRGxGXgRuC6lXwe8GBFvAW5M+axBZUfdOMib5alUoJe0Efhd4PNpXcCFwJ0pyx7girS8Pa2T\nnr8o5bclBMd/MY2Kfyctx7S3axmouvIsV5mmua1MlG3Rfxr4GPCrtH4a8FJEvJLW54ENaXkDcAAg\nPX8k5T+OpJ2SZiTNrLDsVrlMa7lZz42dAkHSB4DDETEr6T3D5BFZl7sX9KIIEhG7gd1pG44wtOOm\n4FWUwTcF76FpHuzab0Re8/9vQJm5bt4JXC7pMuBk4PUMWvhrJZ2YWu0bgYMp/zywCZiXdCLwBuCF\nyktupQmV7qcPwn311mKumysxtusmIq6PiI0RcSZwNXB/RHwIeAC4MmXbAdydlvemddLz90f4zgFN\n8oRmZv22mnH0Hwc+KmmOQR/8LSn9FuC0lP5RYNfqimi1cY+ZdYLr6WqpDY3tvvfR192nvahFP7wy\ndsTLXkW3jfvoe2QqB3vKF0vFdDZTkdmI2Douk6+M7QH3uZv1mwN9DxzXog8HfbO+caDP3CQnYt3y\nN8uTA70BDvJmOXOgN7OOcGNkpRzoM+eWupk50GfOF0tZt7n+VsGB3gB/IJjlzIHezCxzDvQGuC/f\nLGcO9Blzd4yZgQN91txKNzNwoM9emWDvDwRrP9fR1XCgz9yS3Tf9njDUrFfK3GHKarTwpuDNlKFb\n87LaFJWtlHVU3mJjxO2SVXGL3swsc27Rt0TTNwavavu+6Uimmj6grqCrUqpFL+kHkr4j6VFJMynt\nVEn3SdqfHteldEm6SdKcpMckbalzB2wCnoverJcm6br5nYg4t3Dbql3AvojYDOzj2L1hLwU2p9+d\nwM1VFdbMzCa3mj767cCetLwHuKKQfmsMPAislbR+Fduxmnl4pVneygb6AP5d0qyknSntjIg4BJAe\nT0/pG4ADhb+dT2nHkbRT0sywK8jMzOpR9mTsOyPioKTTgfskPb1M3lHNw0XnBCNiN7AbQPKg7jp4\nCgTrrmLd9TfO1SrVoo+Ig+nxMHAX8A7g+WGXTHo8nLLPA5sKf74ROFhVgc3MbDJjA72kUyS9brgM\nXAw8DuwFdqRsO4C70/Je4Jo0+mYbcGTYxWNmZtNXpuvmDOAuScP8X4qIb0h6GLhD0nXAc8BVKf/X\ngcuAOeBl4NrKS22lCI3tvvGJWOuEGFGP5bpblmLUCzjtQvS4j77u6zeOC/TFcfSFl7zKYN/T61Hy\n1dgBHTP9wUqDfH4VdLYw5H1JvjLWzNrNLfdV81w3GfOoGzMDB3ozs+w50GfMJ1rNDBzozax1fLFU\n1Rzoe86tfrP8OdCbmWXOgd7MLHMO9BmJ9FNcNzPzBVMtUU1IVrn/pYUfBtX30/t245mZZpuhWHHc\nVqmEW/S9JuoMx36PmrWDW/QNE/VNvzEu0NbZ4naQz0xTX8+m/abIlFv0GfPQSTMDB/qs+WSsdY8v\nlqqDA32P+YPArB8c6HvMXTtm/eBAb2aWuVKBXtJaSXdKelrSU5IukHSqpPsk7U+P61JeSbpJ0pyk\nxyRtqXcXrJRw692sr8q26P8B+EZE/CbwduApYBewLyI2A/vSOsClwOb0uxO4udISm5nZRMYGekmv\nB94N3AIQEb+IiJeA7cCelG0PcEVa3g7cGgMPAmslra+85LYq7p83648yLfqzgR8DX5T0iKTPSzoF\nOCMiDgGkx9NT/g3AgcLfz6c0axGPuLF2c0OkSmUC/YnAFuDmiDgP+DnHumlGGXWEFkUVSTslzUia\nKVVSMzNbkTKBfh6Yj4iH0vqdDAL/88MumfR4uJB/U+HvNwIHF/7TiNgdEVsjYutKC29mZuONDfQR\n8SPggKS3pqSLgCeBvcCOlLYDuDst7wWuSaNvtgFHhl08Nl3uh7ducXdiXcpOavZnwG2S1gDfA65l\n8CFxh6TrgOeAq1LerwOXAXPAyymvmZk1RBHNf4pKar4QDapv9srCy1ocR59e7jpb/HXtk03ZVA/k\nFOa5ya9izpbp/vaVsRnretdNGxohNoKPS+c40FtrSd3+oMqWj0vnONCbmWXOgd7MLHO+lWCLTLvn\n0z2tVto0Kss0bwres7vXu0XfsPrfP83V5h69j6xKnmm1cm7Rt0RdVXv5OW2ilpE5/qaQkeHd66cZ\ne+veVg8rqFv0Pdb14ZeWkx5G3ylyoO8xz2Bp1g8O9D3mFr2tSl0XTvmCrMo50JvZykj1BGVfkFU5\nB/rMudVuZg70ZrZybn13ggN9j/lkrFk/ONCbdVijM3z6pGlnONBbJ3jK4tGKM3yWeY068Tp2oYwj\nDF/bNr7GvjK2x7p0otZTFo9X5jWq9HWs7H8tuOFIRw/18LVtY10d26KX9FZJjxZ+fyrpI5JOlXSf\npP3pcV3KL0k3SZqT9JikLfXvhq2E++i7a6lWYxtbkxMZln/ho61KmZuDPxMR50bEucD5DO4Dexew\nC9gXEZuBfWkd4FJgc/rdCdxcR8HN+m5UUG9ja3JiDvKVm7SP/iLg2Yj4IbAd2JPS9wBXpOXtwK0x\n8CCwVtL6SkprK9KlLhorR9LRoN75VrzVbtJAfzXw5bR8RkQcAkiPp6f0DcCBwt/MpzQzW6WqW/Ft\nPoEIeJx+RUoHeklrgMuBfxmXdUTaolokaaekGUkzZctg1XM/fbdU3TUz6gRiq4L+wrK0qWwdMkmL\n/lLgWxHxfFp/ftglkx4Pp/R5YFPh7zYCBxf+s4jYHRFbI2Lr5MU2s7o03s8/3L60uEXfdNk6apJA\n/0GOddsA7AV2pOUdwN2F9GvS6JttwJFhF4+Z2bKKQd4qozJf0yS9hkG/+9kRcSSlnQbcAbwZeA64\nKiJe0KA58BngEgYjdK6NiGW7ZyT19vvYcMdrv6lO4RWu+z00rX2yKan9DlMLxtHXLa8KOlumV6RU\noK+bA/2UNzSlCp7H+8hqr6TFt/807xebRwUtFejbcmXsz4Bnmi5Exd4I/GRcpqnVtdVvqNT+dIj3\np6zaK6lGLuJjVMZvlMnUlkD/TG4nZSXN5LRP3p92y21/IL99anJ/PKmZmVnmHOjNzDLXlkC/u+kC\n1CC3ffL+tFtu+wP57VNj+9OKUTdmZlaftrTozcysJo0HekmXSHomzV+/a/xfNE/SJkkPSHpK0hOS\nPpzSOz1Hv6QTJD0i6Z60fpakh9L+3J7mO0LSSWl9Lj1/ZpPlHkXSWkl3Sno6HacLMjg+f57q2+OS\nvizp5C4dI0lfkHRY0uOFtImPiaQdKf9+STtGbWtaltinv0v17jFJd0laW3ju+rRPz0h6fyG93jgY\nEY39AicAzwJnA2uAbwPnNFmmkuVeD2xJy68DvgucA/wtsCul7wJuSMuXAf/GYJTwNuChpvdhif36\nKPAl4J60fgdwdVr+LPBHafmPgc+m5auB25su+4h92QP8YVpeA6zt8vFhMAPs94FXF47N73fpGAHv\nBrYAjxfSJjomwKnA99LjurS8rmX7dDFwYlq+obBP56QYdxJwVop9J0wjDjZ94C8A7i2sXw9c33SF\nXMF+3A28j8FFX+tT2noG1wcAfA74YCH/0Xxt+WUw+dw+4ELgnvQG+0mhwh49VsC9wAVp+cSUT03v\nQ2FfXp+Cohakd/n4DKf/PjW95vcA7+/aMQLOXBAUJzomDObc+lwh/bh8bdinBc/9HnBbWj4uvg2P\n0TTiYNNdN52fuz59JT4PeIhuz9H/aeBjwK/S+mnASxHxSlovlvno/qTnj6T8bXE28GPgi6kr6vOS\nTqHDxyci/hv4ewbzSh1i8JrP0t1jNDTpMWn9sVrgDxh8M4EG96npQF9q7vq2kvRa4KvARyLip8tl\nHZHWmv2U9AHgcETMFpNHZF1uOqjW7A+DFuwW4OaIOA/4OcdudTlK2/eH1He9ncFX/l8HTmEwdfhC\nXTlG4yxV/s7sl6RPAK8Atw2TRmSbyj41HehLzV3fRpJexSDI3xYRX0vJq5qjv0HvBC6X9APgKwy6\nbz7N4DaQw2kyimU+uj/p+TcAL0yzwGPMA/MR8VBav5NB4O/q8QF4L/D9iPhxRPwS+Brw23T3GA1N\neky6cKxIJ4k/AHwoUn8MDe5T04H+YWBzGjmwhsFJo70Nl2ksSQJuAZ6KiE8VnurkHP0RcX1EbIyI\nMxkcg/sj4kPAA8CVKdvC/Rnu55Upf2taVRHxI+CApLempIuAJ+no8UmeA7ZJek2qf8N96uQxKpj0\nmNwLXCxpXfqWc3FKaw1JlwAfBy6PiJcLT+0Frk4jos4CNgPfZBpxsMmTGKneXcZg1MqzwCeaLk/J\nMr+LwVerx4BH0+9lDPpA9wH70+OpKb+Af0z7+B1ga9P7sMy+vYdjo27OThVxjsEtJE9K6Sen9bn0\n/NlNl3vEfpwLzKRj9K8MRmh0+vgAnwSeBh4H/pnB6I3OHCMGNy46BPySQSv2upUcEwb93nPp99oW\n7tMcgz73YWz4bCH/J9I+PQNcWkivNQ76ylgzs8w13XVjZmY1c6A3M8ucA72ZWeYc6M3MMudAb2aW\nOQd6M7PMOdCbmWXOgd7MLHP/DzfHLJ+aY39oAAAAAElFTkSuQmCC\n",
103 | "text/plain": [
104 | ""
105 | ]
106 | },
107 | "metadata": {},
108 | "output_type": "display_data"
109 | }
110 | ],
111 | "source": [
112 | "curve_test(\"test_images/test1.jpg\")"
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": 5,
118 | "metadata": {
119 | "collapsed": false,
120 | "deletable": true,
121 | "editable": true
122 | },
123 | "outputs": [
124 | {
125 | "name": "stdout",
126 | "output_type": "stream",
127 | "text": [
128 | "[real world] left best-fit curve parameters: [ -7.02114020e-04 3.97765732e-02 1.44017797e+00]\n",
129 | "[real world] right best-fit curve parameters: [ -1.51996477e-04 2.62856822e-02 4.81262927e+00]\n",
130 | "[pixel] left best-fit curve parameters: [ -2.30611775e-04 3.13554068e-01 2.72466102e+02]\n",
131 | "[pixel] left best-fit curve parameters: [ -4.99237677e-05 2.07206954e-01 9.10497430e+02]\n",
132 | "[left] current radius of curvature: 712.140946864 m\n",
133 | "[right] current radius of curvature: 3291.00402479 m\n",
134 | "vehicle position: 0.35 m right of center\n"
135 | ]
136 | },
137 | {
138 | "data": {
139 | "image/png": "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\n",
140 | "text/plain": [
141 | ""
142 | ]
143 | },
144 | "metadata": {},
145 | "output_type": "display_data"
146 | }
147 | ],
148 | "source": [
149 | "curve_test(\"test_images/test2.jpg\")"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": 6,
155 | "metadata": {
156 | "collapsed": false,
157 | "deletable": true,
158 | "editable": true
159 | },
160 | "outputs": [
161 | {
162 | "name": "stdout",
163 | "output_type": "stream",
164 | "text": [
165 | "[real world] left best-fit curve parameters: [ 3.88347451e-04 -3.78982629e-02 2.58001454e+00]\n",
166 | "[real world] right best-fit curve parameters: [ 4.53502052e-04 -3.42454112e-02 5.81137293e+00]\n",
167 | "[pixel] left best-fit curve parameters: [ 1.27554061e-04 -2.98747568e-01 4.88110859e+02]\n",
168 | "[pixel] left best-fit curve parameters: [ 1.48954315e-04 -2.69952566e-01 1.09944893e+03]\n",
169 | "[left] current radius of curvature: 1287.91838502 m\n",
170 | "[right] current radius of curvature: 1102.61269943 m\n",
171 | "vehicle position: 0.11 m right of center\n"
172 | ]
173 | },
174 | {
175 | "data": {
176 | "image/png": "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\nHOjNzFru/wGbG3cxZHXT9wAAAABJRU5ErkJggg==\n",
177 | "text/plain": [
178 | ""
179 | ]
180 | },
181 | "metadata": {},
182 | "output_type": "display_data"
183 | }
184 | ],
185 | "source": [
186 | "curve_test(\"test_images/test3.jpg\")"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": 7,
192 | "metadata": {
193 | "collapsed": false,
194 | "deletable": true,
195 | "editable": true
196 | },
197 | "outputs": [
198 | {
199 | "name": "stdout",
200 | "output_type": "stream",
201 | "text": [
202 | "[real world] left best-fit curve parameters: [ 3.33022440e-04 -1.82659201e-02 2.17934762e+00]\n",
203 | "[real world] right best-fit curve parameters: [ 8.58865755e-04 -3.90634079e-02 5.81322996e+00]\n",
204 | "[pixel] left best-fit curve parameters: [ 1.09382371e-04 -1.43988109e-01 4.12309010e+02]\n",
205 | "[pixel] left best-fit curve parameters: [ 2.82097423e-04 -3.07932270e-01 1.09980026e+03]\n",
206 | "[left] current radius of curvature: 1501.4069511 m\n",
207 | "[right] current radius of curvature: 582.298921827 m\n",
208 | "vehicle position: 0.29 m right of center\n"
209 | ]
210 | },
211 | {
212 | "data": {
213 | "image/png": "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\ngg==\n",
214 | "text/plain": [
215 | ""
216 | ]
217 | },
218 | "metadata": {},
219 | "output_type": "display_data"
220 | }
221 | ],
222 | "source": [
223 | "curve_test(\"test_images/test4.jpg\")"
224 | ]
225 | },
226 | {
227 | "cell_type": "code",
228 | "execution_count": 8,
229 | "metadata": {
230 | "collapsed": false,
231 | "deletable": true,
232 | "editable": true
233 | },
234 | "outputs": [
235 | {
236 | "name": "stdout",
237 | "output_type": "stream",
238 | "text": [
239 | "[real world] left best-fit curve parameters: [ 7.31552375e-04 -4.14797348e-02 2.15356924e+00]\n",
240 | "[real world] right best-fit curve parameters: [ 3.81290902e-04 -2.92450110e-02 5.71812881e+00]\n",
241 | "[pixel] left best-fit curve parameters: [ 2.40280904e-04 -3.26979891e-01 4.07432018e+02]\n",
242 | "[pixel] left best-fit curve parameters: [ 1.25236314e-04 -2.30534997e-01 1.08180815e+03]\n",
243 | "[left] current radius of curvature: 683.48403414 m\n",
244 | "[right] current radius of curvature: 1311.41447804 m\n",
245 | "vehicle position: 0.01 m left of center\n"
246 | ]
247 | },
248 | {
249 | "data": {
250 | "image/png": "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\nbUKFFQAAAABJRU5ErkJggg==\n",
251 | "text/plain": [
252 | ""
253 | ]
254 | },
255 | "metadata": {},
256 | "output_type": "display_data"
257 | }
258 | ],
259 | "source": [
260 | "curve_test(\"test_images/test5.jpg\")"
261 | ]
262 | },
263 | {
264 | "cell_type": "code",
265 | "execution_count": 9,
266 | "metadata": {
267 | "collapsed": false,
268 | "deletable": true,
269 | "editable": true
270 | },
271 | "outputs": [
272 | {
273 | "name": "stdout",
274 | "output_type": "stream",
275 | "text": [
276 | "[real world] left best-fit curve parameters: [ 4.07619638e-04 -3.94705586e-02 2.69252793e+00]\n",
277 | "[real world] right best-fit curve parameters: [ 9.99777706e-04 -4.85624756e-02 6.02875317e+00]\n",
278 | "[pixel] left best-fit curve parameters: [ 1.33884078e-04 -3.11141791e-01 5.09397177e+02]\n",
279 | "[pixel] left best-fit curve parameters: [ 3.28380440e-04 -3.82812308e-01 1.14057492e+03]\n",
280 | "[left] current radius of curvature: 1227.04848957 m\n",
281 | "[right] current radius of curvature: 500.209080721 m\n",
282 | "vehicle position: 0.29 m right of center\n"
283 | ]
284 | },
285 | {
286 | "data": {
287 | "image/png": "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\n",
288 | "text/plain": [
289 | ""
290 | ]
291 | },
292 | "metadata": {},
293 | "output_type": "display_data"
294 | }
295 | ],
296 | "source": [
297 | "curve_test(\"test_images/test6.jpg\")"
298 | ]
299 | },
300 | {
301 | "cell_type": "code",
302 | "execution_count": 10,
303 | "metadata": {
304 | "collapsed": false,
305 | "deletable": true,
306 | "editable": true
307 | },
308 | "outputs": [
309 | {
310 | "name": "stdout",
311 | "output_type": "stream",
312 | "text": [
313 | "[real world] left best-fit curve parameters: [ -1.62054436e-04 4.31245011e-03 1.71104116e+00]\n",
314 | "[real world] right best-fit curve parameters: [ 1.45790386e-04 -3.29495738e-03 5.03763237e+00]\n",
315 | "[pixel] left best-fit curve parameters: [ -5.32273392e-05 3.39945391e-02 3.23710490e+02]\n",
316 | "[pixel] left best-fit curve parameters: [ 4.78853559e-05 -2.59737632e-02 9.53065583e+02]\n",
317 | "[left] current radius of curvature: 3085.51848009 m\n",
318 | "[right] current radius of curvature: 3429.73435532 m\n",
319 | "vehicle position: 0.0 m left of center\n"
320 | ]
321 | },
322 | {
323 | "data": {
324 | "image/png": "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\nrkJggg==\n",
325 | "text/plain": [
326 | ""
327 | ]
328 | },
329 | "metadata": {},
330 | "output_type": "display_data"
331 | }
332 | ],
333 | "source": [
334 | "curve_test(\"test_images/straight_lines1.jpg\")"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": 11,
340 | "metadata": {
341 | "collapsed": false,
342 | "deletable": true,
343 | "editable": true
344 | },
345 | "outputs": [
346 | {
347 | "name": "stdout",
348 | "output_type": "stream",
349 | "text": [
350 | "[real world] left best-fit curve parameters: [ 1.64554188e-04 -4.59339191e-03 1.73918011e+00]\n",
351 | "[real world] right best-fit curve parameters: [ -2.26645751e-05 -1.96955590e-03 5.13256373e+00]\n",
352 | "[pixel] left best-fit curve parameters: [ 5.40483913e-05 -3.62091705e-02 3.29034074e+02]\n",
353 | "[pixel] left best-fit curve parameters: [ -7.44425795e-06 -1.55257785e-02 9.71025571e+02]\n",
354 | "[left] current radius of curvature: 3038.63982034 m\n",
355 | "[right] current radius of curvature: 22061.2260569 m\n",
356 | "vehicle position: 0.02 m right of center\n"
357 | ]
358 | },
359 | {
360 | "data": {
361 | "image/png": "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\n",
362 | "text/plain": [
363 | ""
364 | ]
365 | },
366 | "metadata": {},
367 | "output_type": "display_data"
368 | }
369 | ],
370 | "source": [
371 | "curve_test(\"test_images/straight_lines2.jpg\")"
372 | ]
373 | },
374 | {
375 | "cell_type": "code",
376 | "execution_count": null,
377 | "metadata": {
378 | "collapsed": true,
379 | "deletable": true,
380 | "editable": true
381 | },
382 | "outputs": [],
383 | "source": []
384 | }
385 | ],
386 | "metadata": {
387 | "kernelspec": {
388 | "display_name": "Python 3",
389 | "language": "python",
390 | "name": "python3"
391 | },
392 | "language_info": {
393 | "codemirror_mode": {
394 | "name": "ipython",
395 | "version": 3
396 | },
397 | "file_extension": ".py",
398 | "mimetype": "text/x-python",
399 | "name": "python",
400 | "nbconvert_exporter": "python",
401 | "pygments_lexer": "ipython3",
402 | "version": "3.5.2"
403 | },
404 | "widgets": {
405 | "state": {},
406 | "version": "1.1.2"
407 | }
408 | },
409 | "nbformat": 4,
410 | "nbformat_minor": 2
411 | }
412 |
--------------------------------------------------------------------------------
/notebooks/pipeline.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": 1,
6 | "metadata": {
7 | "collapsed": true,
8 | "deletable": true,
9 | "editable": true
10 | },
11 | "outputs": [],
12 | "source": [
13 | "import matplotlib.pyplot as plt\n",
14 | "%matplotlib inline\n",
15 | "import cv2 \n",
16 | "import numpy as np\n",
17 | "import pickle\n",
18 | "from scipy.misc import imread\n",
19 | "\n",
20 | "from birdseye import BirdsEye\n",
21 | "from lanefilter import LaneFilter\n",
22 | "from curves import Curves\n",
23 | "from helpers import show_images, save_image, roi\n",
24 | "\n",
25 | "from moviepy.editor import VideoFileClip\n",
26 | "from IPython.display import HTML"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 2,
32 | "metadata": {
33 | "collapsed": false,
34 | "deletable": true,
35 | "editable": true
36 | },
37 | "outputs": [],
38 | "source": [
39 | "calibration_data = pickle.load(open(\"calibration_data.p\", \"rb\" ))\n",
40 | "\n",
41 | "matrix = calibration_data['camera_matrix']\n",
42 | "distortion_coef = calibration_data['distortion_coefficient']\n",
43 | "\n",
44 | "source_points = [(580, 460), (205, 720), (1110, 720), (703, 460)]\n",
45 | "destination_points = [(320, 0), (320, 720), (960, 720), (960, 0)]\n",
46 | "\n",
47 | "p = { 'sat_thresh': 120, 'light_thresh': 40, 'light_thresh_agr': 205,\n",
48 | " 'grad_thresh': (0.7, 1.4), 'mag_thresh': 40, 'x_thresh': 20 }\n",
49 | "\n",
50 | "birdsEye = BirdsEye(source_points, destination_points, matrix, distortion_coef)\n",
51 | "laneFilter = LaneFilter(p)\n",
52 | "curves = Curves(number_of_windows = 9, margin = 100, minimum_pixels = 50, \n",
53 | " ym_per_pix = 30 / 720 , xm_per_pix = 3.7 / 700)"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": 3,
59 | "metadata": {
60 | "collapsed": true,
61 | "deletable": true,
62 | "editable": true
63 | },
64 | "outputs": [],
65 | "source": [
66 | "def pipeline(img):\n",
67 | " \n",
68 | " ground_img = birdsEye.undistort(img)\n",
69 | " binary = laneFilter.apply(ground_img)\n",
70 | " wb = np.logical_and(birdsEye.sky_view(binary), roi(binary)).astype(np.uint8)\n",
71 | " result = curves.fit(wb)\n",
72 | " ground_img_with_projection = birdsEye.project(ground_img, binary, \n",
73 | " result['pixel_left_best_fit_curve'], result['pixel_right_best_fit_curve'])\n",
74 | "\n",
75 | " text_pos = \"vehicle position: \" + result['vehicle_position_words']\n",
76 | " text_l = \"left radius: \" + str(np.round(result['left_radius'], 2)) \n",
77 | " text_r = \" right radius: \" + str(np.round(result['right_radius'], 2)) \n",
78 | " cv2.putText(ground_img_with_projection, text_l, (20, 40), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 0), 2)\n",
79 | " cv2.putText(ground_img_with_projection, text_r, (400, 40), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 0), 2)\n",
80 | " cv2.putText(ground_img_with_projection, text_pos, (20, 80), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 0), 2)\n",
81 | "\n",
82 | " return ground_img_with_projection"
83 | ]
84 | },
85 | {
86 | "cell_type": "code",
87 | "execution_count": 4,
88 | "metadata": {
89 | "collapsed": false,
90 | "deletable": true,
91 | "editable": true
92 | },
93 | "outputs": [
94 | {
95 | "name": "stdout",
96 | "output_type": "stream",
97 | "text": [
98 | "[MoviePy] >>>> Building video project_video_output.mp4\n",
99 | "[MoviePy] Writing video project_video_output.mp4\n"
100 | ]
101 | },
102 | {
103 | "name": "stderr",
104 | "output_type": "stream",
105 | "text": [
106 | "100%|█████████▉| 1260/1261 [06:30<00:00, 3.41it/s]\n"
107 | ]
108 | },
109 | {
110 | "name": "stdout",
111 | "output_type": "stream",
112 | "text": [
113 | "[MoviePy] Done.\n",
114 | "[MoviePy] >>>> Video ready: project_video_output.mp4 \n",
115 | "\n",
116 | "CPU times: user 5min 57s, sys: 1min 12s, total: 7min 9s\n",
117 | "Wall time: 6min 31s\n"
118 | ]
119 | }
120 | ],
121 | "source": [
122 | "project_output = 'project_video_output.mp4'\n",
123 | "clip1 = VideoFileClip(\"project_video.mp4\");\n",
124 | "white_clip = clip1.fl_image(pipeline) \n",
125 | "%time white_clip.write_videofile(project_output, audio = False);"
126 | ]
127 | },
128 | {
129 | "cell_type": "code",
130 | "execution_count": 5,
131 | "metadata": {
132 | "collapsed": false,
133 | "deletable": true,
134 | "editable": true
135 | },
136 | "outputs": [
137 | {
138 | "data": {
139 | "text/html": [
140 | "\n",
141 | "\n"
144 | ],
145 | "text/plain": [
146 | ""
147 | ]
148 | },
149 | "execution_count": 5,
150 | "metadata": {},
151 | "output_type": "execute_result"
152 | }
153 | ],
154 | "source": [
155 | "HTML(\"\"\"\n",
156 | "\n",
159 | "\"\"\".format(project_output))"
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": null,
165 | "metadata": {
166 | "collapsed": true,
167 | "deletable": true,
168 | "editable": true
169 | },
170 | "outputs": [],
171 | "source": []
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": null,
176 | "metadata": {
177 | "collapsed": true,
178 | "deletable": true,
179 | "editable": true
180 | },
181 | "outputs": [],
182 | "source": []
183 | }
184 | ],
185 | "metadata": {
186 | "kernelspec": {
187 | "display_name": "Python 3",
188 | "language": "python",
189 | "name": "python3"
190 | },
191 | "language_info": {
192 | "codemirror_mode": {
193 | "name": "ipython",
194 | "version": 3
195 | },
196 | "file_extension": ".py",
197 | "mimetype": "text/x-python",
198 | "name": "python",
199 | "nbconvert_exporter": "python",
200 | "pygments_lexer": "ipython3",
201 | "version": "3.5.2"
202 | },
203 | "widgets": {
204 | "state": {},
205 | "version": "1.1.2"
206 | }
207 | },
208 | "nbformat": 4,
209 | "nbformat_minor": 2
210 | }
211 |
--------------------------------------------------------------------------------
/test_images/special_test1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/special_test1.jpg
--------------------------------------------------------------------------------
/test_images/straight_lines1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/straight_lines1.jpg
--------------------------------------------------------------------------------
/test_images/straight_lines2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/straight_lines2.jpg
--------------------------------------------------------------------------------
/test_images/test1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/test1.jpg
--------------------------------------------------------------------------------
/test_images/test2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/test2.jpg
--------------------------------------------------------------------------------
/test_images/test3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/test3.jpg
--------------------------------------------------------------------------------
/test_images/test4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/test4.jpg
--------------------------------------------------------------------------------
/test_images/test5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/test5.jpg
--------------------------------------------------------------------------------
/test_images/test6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/test_images/test6.jpg
--------------------------------------------------------------------------------
/videos/project_video.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/videos/project_video.mp4
--------------------------------------------------------------------------------
/videos/project_video_output.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/videos/project_video_output.mp4
--------------------------------------------------------------------------------
/videos/project_video_verbose_output.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mithi/advanced-lane-detection/f9215b9fb837f27e59e14c05186241514b16544d/videos/project_video_verbose_output.mp4
--------------------------------------------------------------------------------