├── .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": "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\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": "iVBORw0KGgoAAAANSUhEUgAAAXoAAADfCAYAAAD4Bhh5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAF/dJREFUeJzt3V+MHeV5x/HvryaGhPyxTQJybaeAskrDTcBYqWmiKIWE\nAI0wlUAiioRLXVnqPyVNpcQ0F1WkXpS2CilKRWKFpKYiCZSE2kJpKDJU7Q0Ou4EQwBAv+YO3dnAi\nwGmC1ITm6cV5z3r27PkzZ3fmzJmZ38danZn3zO7MeN59zrPPvDOjiMDMzJrr16reADMzK5cDvZlZ\nwznQm5k1nAO9mVnDOdCbmTWcA72ZWcOVEuglXSHpGUnzkvaUsQ4zM8tHRY+jl7QG+C7wPmABeAT4\nYEQ8VeiKzMwslzIy+ncA8xHxvYj4BfAVYEcJ6zEzsxxOK+FnbgKOZuYXgN8a9g2SfHnuABdPy9ov\nnjs1PXcxMLds6XGs7rutdqrtyB1zaSMuLrD3Vd+RfxIRbxq1UBmBXn3algVySbuB3SWsv1Fm02u/\n/9SyxeLagdnMFmgWrXCLuh2hiv2xClXZkYElIWiugI2Yno78wzwLlRHoF4AtmfnNwLHehSJiL7AX\nnNFPvcgGeR8qs7opo0b/CDAj6TxJa4HrgQMlrMdKFMv/CFu00mzezKpReEYfEa9I+lPgfmAN8IWI\neLLo9ZiZja+dSUrhwytXtBEu3QxUVSlwMaPvU7ZZTUY/PaVNm6jKD3zBG1D5/iyai4htoxbylbFm\n1nDOIx3ozcwaroxRN9ZECp+ENaspZ/Q2WDiwW5O0tz870Ftuw4Zcmk0n91lwoLc8PCjKrNYc6K0/\nl23MGsMnYy0Xn4g1qy9n9GbWUNmSY7sTFQd6W2bJxdKuz5vVngO9mVnDOdDbSK7Pm9WbA70t4bKN\nWfM40NtAzuStvnwiNsvDKydspTlyFbl19LyajaVfx5lUZ8rGdndgZ/Q2irMhs7pzRl+RaQyf2fq8\ncm7g9Dx/wabWxJ+a05PCF7X+Gnf2kRm9pC9IOiHpiUzbBkkPSDqSXtendkm6VdK8pMclbS1z483M\nbLQ8pZt/Aq7oadsDHIyIGeBgmge4EphJX7uB24rZTDOzHCJ6Mu4apt8lGBnoI+I/gRd6mncA+9L0\nPuCaTPsd0fEwsE7SxqI21sqzkrKN2dRx5+1rpSdjz4mI4wDp9ezUvgk4mlluIbXZFIief3mWM7P6\nK/pkbL+P077RQtJuOuUdm2KBHyFoVncrzeif75Zk0uuJ1L4AbMkstxk41u8HRMTeiNgWEdtWuA22\nSn0zdl8Na43hBKVrpYH+ALAzTe8E9mfab0ijb7YDJ7slHptevaPRzOrLnbmfkaUbSV8G3gO8UdIC\n8FfA3wB3S9oFPAdclxb/OnAVMA+8DNxYwjZbQVySMWsHxRSkc1J76gVVXnPRW6rpBvp+NzITWlx+\n2AdCja8hsbJV0jlKvMfNdHb2uTzlb98CoUVGZvDt+bw1axUH+pYb9gedSztWX+67Wb7XTcvkDd7d\nYZUO9lYf/ot0EGf0ZmYN50DfYr7tgVk7ONCbmTWcA70tcj3e6suPDhzGgd6WcLA3ax4H+pZyfd6s\nPTy8siLTNBBs+bZoQLvZEIM6zCQ6kh8GPpQzejNbPQfXqeaMviJVV0uKOnXl329bouqODcU+DHwa\n9qcAzujNrOY84mYUB/oW8olYs3ZxoDczazgHejOzhnOgbzGXbczawYG+ZabggWJmBfKJ2DxGBnpJ\nWyQ9JOmwpCclfTi1b5D0gKQj6XV9apekWyXNS3pc0tayd8LMzAbLk9G/AvxFRLwN2A78iaQLgD3A\nwYiYAQ6meYArgZn0tRu4rfCtNjOz3EYG+og4HhHfStP/AxwGNgE7gH1psX3ANWl6B3BHdDwMrJO0\nsfAtt1Vxfd6sPcaq0Us6F7gIOAScExHHofNhAJydFtsEHM1820Jq6/1ZuyXNSpodf7NtJVyft1Zw\nR18md6CX9Frgq8BHIuKnwxbt07bsfz4i9kbEtojYlncbzMwWRZ8TsQ7yfeUK9JJeRSfI3xkRX0vN\nz3dLMun1RGpfALZkvn0zcKyYzTUzS5bcsTIc5IfIM+pGwO3A4Yj4VOatA8DONL0T2J9pvyGNvtkO\nnOyWeMzMCjEsqPsE1DKKEZ+Ckt4F/BfwHeBXqfkv6dTp7wbeDDwHXBcRL6QPhs8AVwAvAzdGxNA6\nvKTWfBR3d7SKrtg91EX+HlS5PzZFKukI0Xeysx0FbEg97l45l6f8PTLQT4ID/QTWW9KNzBzoDXCg\nr06uQO8rY82sfly6GYsDvZnVTzaYt6YesHIO9GZWQwOiu7P5vvwowQnp7ZYTTUJ6hhs7AbJC9OtI\nk+pcg+K5O3dfDvRmNr6JB1RH8NVwoJ+wSoZVlrB+j7YxYDIdIO/IwNWWbRrcqV2jN7Pp1S/Iuw4/\nNgf6Boief2aNMSqoZ7v7FFwTNK0c6BtAPX9rZoP90vs++RfBak7CI27G5xq9mTVDWZd/N4Az+oYa\nVMJxacdqZSXB20F+GQd6M5t+Dt6r4tJNg0XPXZl6a/lmU683wEc0cvhj2ZzRN0TfIB6ZIO9fDqu7\n3iDfrwrpjt6XM/qGElo68izNOau32vGwyVVzRt9QPhlrjTBOkHc2P5ADfQv5wiqrBWfyhcnzzNgz\nJH1T0rclPSnpk6n9PEmHJB2RdJektan99DQ/n94/t9xdsH6WlGh8oZTVzbhB3tn8UHky+v8FLo2I\ntwMXAlekh37fDNwSETPAi8CutPwu4MWIeAtwS1rOJmzJ8OMBdXln9WbtMDLQR8fP0uyr0lcAlwL3\npPZ9wDVpekeaJ71/WXpguJVonKCtzD+zRohwqWeIXDV6SWskPQacAB4AngVeiohX0iILwKY0vQk4\nCpDePwmc1edn7pY0K2l2dbtgZq3goZUrlivQR8T/RcSFwGbgHcDb+i2WXvv9by87LBGxNyK25XmC\nua2OSzRWOw7ahRpr1E1EvAT8B7AdWCepOw5/M3AsTS8AWwDS+28AXihiY20wl2GsUXwytlB5Rt28\nSdK6NP1q4L3AYeAh4Nq02E5gf5o+kOZJ7z8Y4eJZmYYOl+wZceMPBKuFcQK3g/xIea6M3Qjsk7SG\nzgfD3RFxn6SngK9I+mvgUeD2tPztwD9LmqeTyV9fwnbXRiUPBY/BHd+fuFaoyjuUn3afh6Yh2Zaa\nO9C7/B3rs4YYNoa+2OzHuVSLldq5+z1CsPftknpfvTr1XJ7znL7XzYSU1XfG/12LVZVvGvz8ZFup\nMjrDqI5dRrmmsemmb4FQe665WyP1BvJRQyttKAf6FvJwS5t6w54s5ZOvY3PppiG6mX3v70ff60r8\nV4DVhYN6IZzRN0Dn3vPO0q1hHOQL44y+wXqDvzN5qw0H+UI5o2+Ifll9b2B31m/15w+AlXCgbwgH\ncTMbxIG+4VyusfpzErNartE3SeaK2GyJ08HerN0c6GvOJRszG8WlGzOzhnNGX0PO4s1sHM7ozawm\nfK5ppRzoa8gnV81sHC7dNFS2vOMPBrN2c0ZfU+MEb9f0rb7cd4uQO9BLWiPpUUn3pfnzJB2SdETS\nXZLWpvbT0/x8ev/ccjbdluh5qpSzeDPrGiej/zCdh4J33QzcEhEzwIvArtS+C3gxIt4C3JKWsxIM\nCua+m6WZZeUK9JI2A78LfD7NC7gUuCctsg+4Jk3vSPOk9y9Ly7dGZL76tRX51X/9y98pc33WcKM6\nQ1mdu7fDlbmehnfuvBn9p4GPAb9K82cBL0XEK2l+AdiUpjcBRwHS+yfT8ktI2i1pVtLsCrfdcmvV\n56yZ9Rg56kbSB4ATETEn6T3d5j6LDntu9LLPy4jYC+xN62jk5+kkwmue/7jVbocfCG5AxR1Axa2/\nhR06z/DKdwJXS7oKOAN4PZ0Mf52k01LWvhk4lpZfALYAC5JOA94AvFD4llt/zfzMNLNVGFm6iYib\nImJzRJwLXA88GBEfAh4Crk2L7QT2p+kDaZ70/oMR4ehTAp9wtWZz/y7KasbRfxz4qKR5OjX421P7\n7cBZqf2jwJ7VbaINsjjqJlr0N6iZjU3TkGw3rUY/6RJg9hBKxT8rtoUlTcuqrANk+3GBK29Wh56L\niG2jFvKVsQ3ki6XMLMuBvoGCpVfGupZv1m6+qVkDda+M7c3s+7WZWfM50NdY9Ck2DsrendWbtZdL\nNzU2LDvvfU/pn1k9lHQitqUc6GsuG7wln4g1s+Uc6BvIwd7Mslyjr6nFmrsvlrK26F4w0q6b4RbC\ngb5GsqNmuq/R834vZ/dWOxFLy/K9VwSu6Oe1+/fApZsa8dh4azUH+RVzRl8T/R8mEgwakeBM3mpp\nMTCvMosv4nsbxBl9TfQL3A7m1jgOzKVwRl8D49be/QFgZlnO6GtAPf9geI3e9XurN18sVTRn9AXr\nfWZymWsY/PPlUG/Fm1SnWjLiZkLrbDhn9LUypNdr2YSZGeCMvjTlhNvld6XM5veD7lq5Gs16RoOt\nShWdoIx1tvCvhFwZvaQfSPqOpMckzaa2DZIekHQkva5P7ZJ0q6R5SY9L2lrmDrRRtwbf+3CwxfY2\n9mQzG2ic0s3vRMSFmcdW7QEORsQMcJBTz4a9EphJX7uB24raWOvwqBozG8dqavQ7gH1peh9wTab9\njuh4GFgnaeMq1mMZeYO8s3oz68ob6AP4d0lzknantnMi4jhAej07tW8Cjma+dyG1LSFpt6TZbinI\nhnPgNrOVynsy9p0RcUzS2cADkp4esmy/lHNZlIqIvcBeAEmOYjl0g71LN2Y2jlwZfUQcS68ngHuB\ndwDPd0sy6fVEWnwB2JL59s3AsaI22PJl9/4wMLOukYFe0pmSXtedBi4HngAOADvTYjuB/Wn6AHBD\nGn2zHTjZLfHYyvV70Hfv+71Xz5rVj6+KLUOe0s05wL3q3GzoNOBLEfENSY8Ad0vaBTwHXJeW/zpw\nFTAPvAzcWPhWt8wk6/MuD5k1j6J3MHYVG9GgGn1ZFxj1DfbZp0up6AuluhdgpR9f2E+22ploJ5hA\nRt+sTj2XGfI+kG+BUBOjgnjRGbgz+ukwDYmY1Z8DfV31ZPMeftlM8v3ZrQAO9BUbJ0A7y17OGa/Z\naA70FSu6rt42znjNRnOgb5g2BntrIn+AF8mBvmFc3jGzXg70NeJs3cxWwoG+RpytW7M5kSmLA32N\nOKM3s5XwowRLUk1I9kPBrUC9nanszrXsoeCBT8oWwxl9rbjTW1s4ZSmSM/oSlBmOh3V/P0fZSlF2\nfjHsorci192se9yMxRm9mVnDOdA3hEfkWOP4qufCONA3hEfkmNkgDvQ14mBuZivhQN8QLt1YYzif\nKVyuQC9pnaR7JD0t6bCkSyRtkPSApCPpdX1aVpJulTQv6XFJW8vdhfZwMDezlcib0f8D8I2I+E3g\n7cBhYA9wMCJmgINpHuBKYCZ97QZuK3SLW2xY6Sbww0fMrL+RgV7S64F3A7cDRMQvIuIlYAewLy22\nD7gmTe8A7oiOh4F1kjYWvuVt1vN0qSVvOeBbnXTH0Fc5Vr8F8mT05wM/Br4o6VFJn5d0JnBORBwH\nSK9np+U3AUcz37+Q2myV8pRulP6ZWUbLh2rmCfSnAVuB2yLiIuDnnCrT9NPvf3TZx6mk3ZJmJc3m\n2lIbmak7wJtZP3kC/QKwEBGH0vw9dAL/892STHo9kVl+S+b7NwPHen9oROyNiG0RsW2lG2+nOMib\n2SAjA31E/Ag4Kumtqeky4CngALAzte0E9qfpA8ANafTNduBkt8Rjq+Ngbq3R8lJL0fLe1OzPgDsl\nrQW+B9xI50Pibkm7gOeA69KyXweuAuaBl9OyVoBRo278QWCNEeFgXyDFFJyNllT9RhSk7DtoBzFw\n1E0Zgb7FN/yzSRz8fqNugnKCfDM781ye8rdvU9wAzuTNbBjfAqEBPG7ezIZxoK8RB3QzWwkHejOr\n1rJnxVrRXKMvQTl9dfhPLfv3w49pbrEqgm+Z68z+7JZ0amf0tdGSHmktMiiau68XzRl9wUSZo7g0\npE5f3jh6/zXdUsuGPJawgn7DuycR51vWqZ3RN4SHWFrtTME1PG3hQF8jHnVjZivhQG9m08WZfuEc\n6BvC2b7Vju9lMzE+GdsQ3Rp9v4Dv+r1NpUGZuz8ACudA3wDZQO6gbrWxGNCjT5sVyaUbM7OGc6A3\nM2s4B/oG8IlYMxvGgb4BXJc3s2FGBnpJb5X0WObrp5I+ImmDpAckHUmv69PyknSrpHlJj0vaWv5u\nmJnZIHkeDv5MRFwYERcCF9N5Duy9wB7gYETMAAfTPMCVwEz62g3cVsaGm5lZPuOWbi4Dno2IHwI7\ngH2pfR9wTZreAdwRHQ8D6yRtLGRrbRmXbcxslHED/fXAl9P0ORFxHCC9np3aNwFHM9+zkNqsBD4R\na/XWwpvDVyB3oJe0Frga+JdRi/ZpWxaNJO2WNCtpNu82mJnZ+MbJ6K8EvhURz6f557slmfR6IrUv\nAFsy37cZONb7wyJib0Rsi4ht42+2mZnlNU6g/yCnyjYAB4CdaXonsD/TfkMafbMdONkt8ZiZ2eQp\nctwSVNJr6NTdz4+Ik6ntLOBu4M3Ac8B1EfGCJAGfAa6gM0LnxogYWp6R1KhCc3lPmEo1+cj8ZJX3\nZKlT60yrKnUtNtVKe2hwRTX65nTquTxVkVyBvmxNDfQTWcEEO2r9fydsxcrq1Nlf/aigh9W/U+cK\n9NNy98qfAc9UvRFFSX3njcBPylzBhJW3P9Xw/oyjtD6nvpOJj9Fov5FnoWkJ9M807aSspNkm7ZP3\nZ7o1bX+geftU5f74XjdmZg3nQG9m1nDTEuj3Vr0BJWjaPnl/plvT9geat0+V7c9UjLoxM7PyTEtG\nb2ZmJak80Eu6QtIz6f71e0Z/R/UkbZH0kKTDkp6U9OHUXut79EtaI+lRSfel+fMkHUr7c1e63xGS\nTk/z8+n9c6vc7n4krZN0j6Sn03G6pAHH589Tf3tC0pclnVGnYyTpC5JOSHoi0zb2MZG0My1/RNLO\nfuualAH79Hep3z0u6V5J6zLv3ZT26RlJ78+0lxsHI6KyL2AN8CxwPrAW+DZwQZXblHO7NwJb0/Tr\ngO8CFwB/C+xJ7XuAm9P0VcC/0RkpvB04VPU+DNivjwJfAu5L83cD16fpzwJ/lKb/GPhsmr4euKvq\nbe+zL/uAP0zTa4F1dT4+dO4A+33g1Zlj8/t1OkbAu4GtwBOZtrGOCbAB+F56XZ+m10/ZPl0OnJam\nb87s0wUpxp0OnJdi35pJxMGqD/wlwP2Z+ZuAm6rukCvYj/3A++hc9LUxtW2kc30AwOeAD2aWX1xu\nWr7o3HzuIHApcF/6BftJpsMuHivgfuCSNH1aWk5V70NmX16fgqJ62ut8fLq3/96Q/s/vA95ft2ME\nnNsTFMc6JnTuufW5TPuS5aZhn3re+z3gzjS9JL51j9Ek4mDVpZva37s+/Ul8EXCIet+j/9PAx4Bf\npfmzgJci4pU0n93mxf1J759My0+L84EfA19MpajPSzqTGh+fiPhv4O/p3FfqOJ3/8znqe4y6xj0m\nU3+sevwBnb9MoMJ9qjrQ57p3/bSS9Frgq8BHIuKnwxbt0zY1+ynpA8CJiJjLNvdZdNitoKZmf+hk\nsFuB2yLiIuDnnHrUZT/Tvj+k2vUOOn/y/zpwJp1bh/eqyzEaZdD212a/JH0CeAW4s9vUZ7GJ7FPV\ngT7XveunkaRX0Qnyd0bE11Lzqu7RX6F3AldL+gHwFTrlm0/TeQxk9zYZ2W1e3J/0/huAFya5wSMs\nAAsRcSjN30Mn8Nf1+AC8F/h+RPw4In4JfA34bep7jLrGPSZ1OFakk8QfAD4UqR5DhftUdaB/BJhJ\nIwfW0jlpdKDibRpJkoDbgcMR8anMW7W8R39E3BQRmyPiXDrH4MGI+BDwEHBtWqx3f7r7eW1afmqy\nqoj4EXBU0ltT02XAU9T0+CTPAdslvSb1v+4+1fIYZYx7TO4HLpe0Pv2Vc3lqmxqSrgA+DlwdES9n\n3joAXJ9GRJ0HzADfZBJxsMqTGKnfXUVn1MqzwCeq3p6c2/wuOn9aPQ48lr6uolMDPQgcSa8b0vIC\n/jHt43eAbVXvw5B9ew+nRt2cnzriPJ1HSJ6e2s9I8/Pp/fOr3u4++3EhMJuO0b/SGaFR6+MDfBJ4\nGngC+Gc6ozdqc4zoPLjoOPBLOlnsrpUcEzp17/n0deMU7tM8nZp7NzZ8NrP8J9I+PQNcmWkvNQ76\nylgzs4arunRjZmYlc6A3M2s4B3ozs4ZzoDczazgHejOzhnOgNzNrOAd6M7OGc6A3M2u4/wdPs5QN\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": "iVBORw0KGgoAAAANSUhEUgAAAXoAAADfCAYAAAD4Bhh5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFpVJREFUeJzt3W+MHPV9x/H3pyaGhPyxTQJybaeAckrDk4CxUtNEUQoJ\nwSTCVAKJKBIudXVS/ylpKiWmeVBF6oPSViFFqUiskNREJIGSUFsoDUWGqn2Cw10gBDDER/7gqx0c\nBDhNkJrQfPtgf2uP73ZvZ+/m3858XtZpZ347uzNzM/u5n78zO6OIwMzM2us36l4AMzMrl4PezKzl\nHPRmZi3noDczazkHvZlZyznozcxarpSgl3SFpKclzUnaVcY8zMwsHxV9Hr2kVcD3gfcB88DDwIci\n4slCZ2RmZrmU0aN/BzAXET+IiF8CXwO2lzAfMzPL4bQS3nMDcDgzPg/8zlIvkNSJr+deXMU7Xjx7\ncnh20BxnB7StXDnvaoUrficcLbsfXjw7YCEK2Hu6uwM+HxFvGjVRGUGvAW2LglzSNDBdwvwbayY9\nDvoFLUeceMfsTDLvrgHPAypsCU5u2OLe0UpV9E441kxPHTxBK1yYoMs74I/zTFRG0M8DmzLjG4Ej\nCyeKiN3AbuhOj97MrA5l1OgfBqYknSdpNXAdsK+E+ZhZG/jCiqUrvEcfEa9I+jPgPmAV8MWIeKLo\n+ZiZWT6Fn165rIXoSOmmjHp2LDz8Edka/eBfq2v0HVb1Bos4dV7DPukrqdN3u0Y/GxFbRk3kb8aa\nWb1WejDWRnLQm5m1nIPezMqRtywc4QOyJXPQm1n9XL4plYPezIrnHnqjOOgn3KIzaLJn2oR7SWbm\noDezog3rzZdxaqXlUsYlEKwii86hN6uTyzWN5R79BCvyi09mK+KQbzQHfQf5fwJm3eKgNzNrOQd9\nxyj9M2sMl31K56A3M2s5B33HuD5v1j0+vbIGxUatxn5HR70VuxOs9M208rcY9HpXKE9wj75C3u+s\ndo3bCRu3QK3kHn0Nirs5+PK6QcXe+MQmzsIdYMU3I0kvHPegalnfiPVOucjIHr2kL0o6JunxTNs6\nSfdLOpQe16Z2SbpF0pykxyRtLnPhu85nz1hj+MyZRstTuvln4IoFbbuA/RExBexP4wDbgKn0Mw3c\nWsximlmr+Po2lRoZ9BHxn8ALC5q3A3vS8B7g6kz77dHzELBG0vqiFtbMJsygPHfIV265B2PPiYij\nAOnx7NS+ATicmW4+tZmZWU2KPhg76E/1wOKdpGl65R0z6wr35mux3B79c/2STHo8ltrngU2Z6TYC\nRwa9QUTsjogtEbFlmctgZpPEIV+b5Qb9PmBHGt4B7M20X5/OvtkKHO+XeKwcyznzxt+ONeuWkaUb\nSV8F3gO8UdI88NfA3wJ3SdoJPAtcmyb/JnAlMAe8DNxQwjJbxnJC26dlWuEkn2LZYIoGbBxJ9S9E\nRYKiv7A04FeXvVfskF9tUWG/4u/aWP2K2oiDskRDR8rTrZ1yNk/525dAMLNyuCbfGA56M1u5hb15\nh3yjOOg7yDV6K5zkcG8wB72ZFaMBx/tsMAf9hHPv3BrHPfvGcdCbWXEc8o3koJ9w/vKTNYZDvrEc\n9GZmLeegNzNrOd9KsAZ1F1vqnr/VbNgOUMaOka3meMerjXv0Zl3isO0k9+hrUOwhKy3jgGwUfq0b\nmzB1HDcta55FX0CqhdyjNzNrOQd9B/lLVmbd4qBvo+5c9dnMcnDQm5m1nIN+wvmbsWY2ioPezKzl\nRga9pE2SHpR0UNITkj6S2tdJul/SofS4NrVL0i2S5iQ9Jmlz2SvRZT6wamaj5OnRvwL8ZUS8DdgK\n/KmkC4BdwP6ImAL2p3GAbcBU+pkGbi18qc1s8kQMvma9r2NfupFBHxFHI+I7afh/gIPABmA7sCdN\ntge4Og1vB26PnoeANZLWF77kZjb5HPKVGKtGL+lc4CLgAHBORByF3h8D4Ow02QbgcOZl86lt4XtN\nS5qRNDP+YttK+ACu1SZ7KeN+yPvyxqXLfQkESa8Fvg58NCJ+puEbZ9ATi5IlInYDu9N7O3mWaTmh\n7bq+Wbfk6tFLehW9kL8jIr6Rmp/rl2TS47HUPg9syrx8I3CkmMU1s4nl3nxt8px1I+A24GBEfDrz\n1D5gRxreAezNtF+fzr7ZChzvl3iseO6d28RyyFdGMeJgiKR3Af8FfA/4dWr+K3p1+ruANwPPAtdG\nxAvpD8NngSuAl4EbImLJOnyXSjdlXGhvYPkm0lwG/GqL/OPQf3d/ZCdE5Rssu/+VNNNuX71yNiK2\njJpoZNBXwUG/0vd00FtODvq2yRX0/masmVnLOegn3Lhn3bimb5Xxl6Maw0E/4Rzc1kgO+UbxrQRr\nUOfuHiUVNLtdJp1Ape6ES725ypn3wvf0zngK9+g7x5+ATqt083tfawr36Csmij/xYbwOUnE3Bl/e\n/K122c1fxlk4weBz5Ks4b94740Du0ZtZcSL8RagGctB3jA/eWqkc8o3koG8Bh7eZLcVB3wK+7LCZ\nLcVBb2bWcg56M7OWc9C3Xbh+b9Z1DvoWGOdgrOv5Zt3joG8Bh7eZLcVBb2bWcg56M7OWy3PP2DMk\nfVvSdyU9IelTqf08SQckHZJ0p6TVqf30ND6Xnj+33FWwcWr0/nKVWffk6dH/L3BpRLwduBC4It30\n+ybg5oiYAl4EdqbpdwIvRsRbgJvTdGZmVpORQR89P0+jr0o/AVwK3J3a9wBXp+HtaZz0/GXphuFm\nZlaDXDV6SaskPQocA+4HngFeiohX0iTzwIY0vAE4DJCePw6cNeA9pyXNSJpZ2SrYOHyGjln35Ar6\niPi/iLgQ2Ai8A3jboMnS46De+6J0iYjdEbElzx3MbWkObzNbylhn3UTES8B/AFuBNZL6Ny7ZCBxJ\nw/PAJoD0/BuAF4pYWBvMB1jNbCl5zrp5k6Q1afjVwHuBg8CDwDVpsh3A3jS8L42Tnn8gwncFbgr/\nUTDrnjy3ElwP7JG0it4fhrsi4l5JTwJfk/Q3wCPAbWn624AvS5qj15O/roTlnlgxZLiO+VvHVbEz\nDrptoVVOTehsS6p/ISpS3ooueOfsxcxO+fWW16P3/xUmTBWfuuy+V+UF9rqzM87mOc7pm4PXpOj9\nMP9nttibg5dxb2mrWFUbr+z5eGccypdAaAnX3s1sGAe9mVnLOehbwufSm9kwDnozq0cDTgTpCgd9\nS+St0buWb43QD3mHfSUc9GZWrWy4+3qHlXDQt0TeGr1r+VabCPfga+KgbwmXZMxsGAe9mZXDvffG\ncNC3hEsy1ih5Q95/DCrhoDezYo0T3j4YWwkHfUsMrdEvuF6ca/lm3eOg7xiXeMy6x0HfEnkCXOnf\nOK8xK43LNpVx0HdIpH8L28xq4QOxlXHQt8Q4tfd+uPdf47A3a7fcQS9plaRHJN2bxs+TdEDSIUl3\nSlqd2k9P43Pp+XPLWXTLGjess2Ev5LC3YriX3kjj9Og/Qu+m4H03ATdHxBTwIrAzte8EXoyItwA3\np+lsTGUFrzL/FrabrZjr7o2UK+glbQQ+AHwhjQu4FLg7TbIHuDoNb0/jpOcvS9NbRoz4AY2cZuH0\nRcx33B9rgdp2CnlnrEjeHv1ngI8Dv07jZwEvRcQraXwe2JCGNwCHAdLzx9P0p5A0LWlG0swyl33i\nlLsvek+3SeN9tiojbw4u6YPAsYiYlfSefvOASZe6Ne+iLRoRu4HdaR6d2uJl/Pcm7y+wvpuSW2PV\nuVMUOW/vjEONDHrgncBVkq4EzgBeT6+Hv0bSaanXvhE4kqafBzYB85JOA94AvFD4ktspfEDVJo4r\nupUZWbqJiBsjYmNEnAtcBzwQER8GHgSuSZPtAPam4X1pnPT8AxE+FG9mVpeVnEf/CeBjkubo1eBv\nS+23AWel9o8Bu1a2iFYUn1ljpXOfrpHUhM52V2r0Sx3EKOb9M7/GSHMp+aJmZa+TlaisjXfKrQIH\nzO/EcwXPuJs742xEbBk1kb8Za2bWcg56MytOAyoEtpiD3syK4zNpGslB3xI+tdImjnv/lXHQt4TP\nqLGJ495/ZRz0ZlY9h3yl8nwz1sxseYJTT3d0wNfCPXozK47r7o3koO8Q1/GtdNkeu7R43GrhoO8Q\nn5ljlXGoN4qDviUc4tYYDvnGcdC3xCllmfAHzcxOctC3RJ4evWv0Zt3koG+JPCHu8o5ZN/k8+hqU\nE7d53lWOelus7J2i3wfxzlcb9+htxVwQMms29+hrUNfNwX1jcBuoqr/UZc/HO+RQuXr0kn4k6XuS\nHpU0k9rWSbpf0qH0uDa1S9ItkuYkPSZpc5krYD0+0Gpmw4xTuvm9iLgwc9uqXcD+iJgC9nPy3rDb\ngKn0Mw3cWtTCmpnZ+FZSo98O7EnDe4CrM+23R89DwBpJ61cwHzMzW4G8QR/Av0ualTSd2s6JiKMA\n6fHs1L4BOJx57XxqO4WkaUkz/VKQmbWdi+h1yXsw9p0RcUTS2cD9kp5aYtpBxeJFWzgidgO7ASR5\nD1ghnyNvZsPk6tFHxJH0eAy4B3gH8Fy/JJMej6XJ54FNmZdvBI4UtcA2mA/GmtkwI4Ne0pmSXtcf\nBi4HHgf2ATvSZDuAvWl4H3B9OvtmK3C8X+Kx8rhHb2bD5CndnAPco94V6U4DvhIR35L0MHCXpJ3A\ns8C1afpvAlcCc8DLwA2FL7UtIuSwN7OBFA24I0xXavT9lSyryHIi6LNXr8z8aosu75S9PlayyjZg\n9uNd4sy6uUPOZk55H8qXQDAzazkHvZlZyznozcxazkFvZtZyDnozs5Zz0LeET600s2Ec9GZmLeeg\nNzNrOQe9mVnL+VaCNainmu4bg9sQVd0cvIp59efRrW/HjuQefUXqD9n6l8DM6uEefcXKu87NqPkW\nP2d3nCacqP76MP35RIBKmKn7MwM56M2sPBELSjcpicsIeRvKQW9mxRp1RVyHfOUc9GZWrEVBHks8\nZ1XwwdgO8G0GzbrNQd8BvjyCWbflCnpJayTdLekpSQclXSJpnaT7JR1Kj2vTtJJ0i6Q5SY9J2lzu\nKpiZ2VLy9uj/EfhWRPw28HbgILAL2B8RU8D+NA6wDZhKP9PArYUusZmZjWVk0Et6PfBu4DaAiPhl\nRLwEbAf2pMn2AFen4e3A7dHzELBG0vrCl9xyc43erNvy9OjPB34KfEnSI5K+IOlM4JyIOAqQHs9O\n028ADmdeP5/arAoDbgzuGr1Zt+UJ+tOAzcCtEXER8AtOlmkGGdR9XJQ0kqYlzUiaybWkZma2LHmC\nfh6Yj4gDafxuesH/XL8kkx6PZabflHn9RuDIwjeNiN0RsSUitix34S0fl27Mum1k0EfET4DDkt6a\nmi4DngT2ATtS2w5gbxreB1yfzr7ZChzvl3isPEuFuUs3Vq+qL19pC+X9ZuyfA3dIWg38ALiB3h+J\nuyTtBJ4Frk3TfhO4EpgDXk7TmplZTRSjrktRxUJI9S9Eycq+SOCJXvuAg7G9+frqlTZAZVevzH7E\nS5xZ1VfjrN9snvK3vxnbAa7Rm3Wbg74DXKM36zYHfQe4R2/WbQ56M7OW8/XoS7awaFJHEcWFGxso\nhgyXwWdY1so9+k7wJ8usy9yjr0j5VXINPehadI3ep1W2TNUbs8z5eeccyD16M7OWc9CbmbWcg97M\nrOUc9C3hL0WZ2TAOejOzlnPQm5m1nIPezKzlHPRmZi3noDczazkHvZlZy40MeklvlfRo5udnkj4q\naZ2k+yUdSo9r0/SSdIukOUmPSdpc/mqYmdkweW4O/nREXBgRFwIX07sP7D3ALmB/REwB+9M4wDZg\nKv1MA7eWseBmNqEacPvSrhm3dHMZ8ExE/BjYDuxJ7XuAq9PwduD26HkIWCNpfSFLa2aTJWJwsDvs\nKzVu0F8HfDUNnxMRRwHS49mpfQNwOPOa+dRmNfDdpaw2DvPGyB30klYDVwH/MmrSAW2LtrikaUkz\nkmbyLoOZTRC5k9EU4/TotwHfiYjn0vhz/ZJMejyW2ueBTZnXbQSOLHyziNgdEVsiYsv4i21mE81/\nBCo1TtB/iJNlG4B9wI40vAPYm2m/Pp19sxU43i/xmFnHSItD3SFfOUWOOpqk19Cru58fEcdT21nA\nXcCbgWeBayPiBUkCPgtcQe8MnRsiYsnyjKTWFvP6K1bFrn3Kpky/0jJq9Mu5iU9EIH/Am6XKnfOU\n6m2JM+zeHaZm81RFcgV92boQ9JXPrOSdvVufpZaq+lOX/ZhHiXtQt3bOXEHflHvG/hx4uu6FKNgb\ngecr3efKndkbgedLnUO1vD6VB6IGDi7B22i038ozUVOC/um2HZSVNNOmdfL6NFvb1gfat051ro+v\ndWNm1nIOejOzlmtK0O+uewFK0LZ18vo0W9vWB9q3TrWtTyPOujEzs/I0pUdvZmYlqT3oJV0h6el0\n/fpdo19RP0mbJD0o6aCkJyR9JLVP9DX6Ja2S9Iike9P4eZIOpPW5M13vCEmnp/G59Py5dS73IJLW\nSLpb0lNpO13Sgu3zF2l/e1zSVyWdMUnbSNIXJR2T9HimbextImlHmv6QpB2D5lWVIev092m/e0zS\nPZLWZJ67Ma3T05Len2kvNwcjorYfYBXwDHA+sBr4LnBBncuUc7nXA5vT8OuA7wMXAH8H7Ertu4Cb\n0vCVwL/RO3t4K3Cg7nUYsl4fA74C3JvG7wKuS8OfA/44Df8J8Lk0fB1wZ93LPmBd9gB/lIZXA2sm\nefvQuwLsD4FXZ7bNH0zSNgLeDWwGHs+0jbVNgHXAD9Lj2jS8tmHrdDlwWhq+KbNOF6SMOx04L2Xf\nqipysO4NfwlwX2b8RuDGunfIZazHXuB99L70tT61raf3/QCAzwMfykx/Yrqm/NC7+Nx+4FLg3vQB\nez6zw57YVsB9wCVp+LQ0nepeh8y6vD6Foha0T/L26V/+e136nd8LvH/SthFw7oJQHGub0Lvm1ucz\n7adM14R1WvDc7wN3pOFT8q2/jarIwbpLNxN/7fr0X+KLgANM9jX6PwN8HPh1Gj8LeCkiXknj2WU+\nsT7p+eNp+qY4H/gp8KVUivqCpDOZ4O0TEf8N/AO960odpfc7n2Vyt1HfuNuk8dtqgT+k9z8TqHGd\n6g76XNeubypJrwW+Dnw0In621KQD2hqznpI+CByLiNls84BJl7oMVmPWh14PdjNwa0RcBPyCk7e6\nHKTp60OqXW+n91/+3wTOpHfp8IUmZRuNMmz5J2a9JH0SeAW4o980YLJK1qnuoM917fomkvQqeiF/\nR0R8IzWv6Br9NXoncJWkHwFfo1e++Qy920D2L5ORXeYT65OefwPwQpULPMI8MB8RB9L43fSCf1K3\nD8B7gR9GxE8j4lfAN4DfZXK3Ud+422QSthXpIPEHgQ9HqsdQ4zrVHfQPA1PpzIHV9A4a7at5mUaS\nJOA24GBEfDrz1EReoz8iboyIjRFxLr1t8EBEfBh4ELgmTbZwffrreU2avjG9qoj4CXBY0ltT02XA\nk0zo9kmeBbZKek3a//rrNJHbKGPcbXIfcLmktel/OZentsaQdAXwCeCqiHg589Q+4Lp0RtR5wBTw\nbarIwToPYqT97kp6Z608A3yy7uXJuczvovdfq8eAR9PPlfRqoPuBQ+lxXZpewD+ldfwesKXudVhi\n3d7DybNuzk874hy9W0ientrPSONz6fnz617uAetxITCTttG/0jtDY6K3D/Ap4CngceDL9M7emJht\nRO/GRUeBX9Hrxe5czjahV/eeSz83NHCd5ujV3PvZ8LnM9J9M6/Q0sC3TXmoO+puxZmYtV3fpxszM\nSuagNzNrOQe9mVnLOejNzFrOQW9m1nIOejOzlnPQm5m1nIPezKzl/h/Tr+zv+T92AwAAAABJRU5E\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 --------------------------------------------------------------------------------