forked from udacity/CarND-Advanced-Lane-Lines
/
writeup_report.html
707 lines (704 loc) · 121 KB
/
writeup_report.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>writeup_report</title>
<style>.markdown-preview:not([data-use-github-style]) { padding: 2em; font-size: 1.2em; color: rgb(56, 58, 66); overflow: auto; background-color: rgb(250, 250, 250); }
.markdown-preview:not([data-use-github-style]) > :first-child { margin-top: 0px; }
.markdown-preview:not([data-use-github-style]) h1, .markdown-preview:not([data-use-github-style]) h2, .markdown-preview:not([data-use-github-style]) h3, .markdown-preview:not([data-use-github-style]) h4, .markdown-preview:not([data-use-github-style]) h5, .markdown-preview:not([data-use-github-style]) h6 { line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; color: rgb(0, 0, 0); }
.markdown-preview:not([data-use-github-style]) h1 { font-size: 2.4em; font-weight: 300; }
.markdown-preview:not([data-use-github-style]) h2 { font-size: 1.8em; font-weight: 400; }
.markdown-preview:not([data-use-github-style]) h3 { font-size: 1.5em; font-weight: 500; }
.markdown-preview:not([data-use-github-style]) h4 { font-size: 1.2em; font-weight: 600; }
.markdown-preview:not([data-use-github-style]) h5 { font-size: 1.1em; font-weight: 600; }
.markdown-preview:not([data-use-github-style]) h6 { font-size: 1em; font-weight: 600; }
.markdown-preview:not([data-use-github-style]) strong { color: rgb(0, 0, 0); }
.markdown-preview:not([data-use-github-style]) del { color: rgb(94, 97, 110); }
.markdown-preview:not([data-use-github-style]) a, .markdown-preview:not([data-use-github-style]) a code { color: rgb(82, 111, 255); }
.markdown-preview:not([data-use-github-style]) img { max-width: 100%; }
.markdown-preview:not([data-use-github-style]) > p { margin-top: 0px; margin-bottom: 1.5em; }
.markdown-preview:not([data-use-github-style]) > ul, .markdown-preview:not([data-use-github-style]) > ol { margin-bottom: 1.5em; }
.markdown-preview:not([data-use-github-style]) blockquote { margin: 1.5em 0px; font-size: inherit; color: rgb(94, 97, 110); border-color: rgb(209, 209, 210); border-width: 4px; }
.markdown-preview:not([data-use-github-style]) hr { margin: 3em 0px; border-top-width: 2px; border-top-style: dashed; border-top-color: rgb(209, 209, 210); background: none; }
.markdown-preview:not([data-use-github-style]) table { margin: 1.5em 0px; }
.markdown-preview:not([data-use-github-style]) th { color: rgb(0, 0, 0); }
.markdown-preview:not([data-use-github-style]) th, .markdown-preview:not([data-use-github-style]) td { padding: 0.66em 1em; border: 1px solid rgb(209, 209, 210); }
.markdown-preview:not([data-use-github-style]) pre, .markdown-preview:not([data-use-github-style]) code { color: rgb(0, 0, 0); background-color: rgb(234, 234, 235); }
.markdown-preview:not([data-use-github-style]) pre, .markdown-preview:not([data-use-github-style]) pre.editor-colors { margin: 1.5em 0px; padding: 1em; font-size: 0.92em; border-radius: 3px; background-color: rgb(240, 240, 240); }
.markdown-preview:not([data-use-github-style]) kbd { color: rgb(0, 0, 0); border-width: 1px 1px 2px; border-style: solid; border-color: rgb(209, 209, 210) rgb(209, 209, 210) rgb(193, 193, 194); background-color: rgb(234, 234, 235); }
.markdown-preview[data-use-github-style] { font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; line-height: 1.6; word-wrap: break-word; padding: 30px; font-size: 16px; color: rgb(51, 51, 51); overflow: scroll; background-color: rgb(255, 255, 255); }
.markdown-preview[data-use-github-style] > :first-child { margin-top: 0px !important; }
.markdown-preview[data-use-github-style] > :last-child { margin-bottom: 0px !important; }
.markdown-preview[data-use-github-style] a:not([href]) { color: inherit; text-decoration: none; }
.markdown-preview[data-use-github-style] .absent { color: rgb(204, 0, 0); }
.markdown-preview[data-use-github-style] .anchor { position: absolute; top: 0px; left: 0px; display: block; padding-right: 6px; padding-left: 30px; margin-left: -30px; }
.markdown-preview[data-use-github-style] .anchor:focus { outline: none; }
.markdown-preview[data-use-github-style] h1, .markdown-preview[data-use-github-style] h2, .markdown-preview[data-use-github-style] h3, .markdown-preview[data-use-github-style] h4, .markdown-preview[data-use-github-style] h5, .markdown-preview[data-use-github-style] h6 { position: relative; margin-top: 1em; margin-bottom: 16px; font-weight: bold; line-height: 1.4; }
.markdown-preview[data-use-github-style] h1 .octicon-link, .markdown-preview[data-use-github-style] h2 .octicon-link, .markdown-preview[data-use-github-style] h3 .octicon-link, .markdown-preview[data-use-github-style] h4 .octicon-link, .markdown-preview[data-use-github-style] h5 .octicon-link, .markdown-preview[data-use-github-style] h6 .octicon-link { display: none; color: rgb(0, 0, 0); vertical-align: middle; }
.markdown-preview[data-use-github-style] h1:hover .anchor, .markdown-preview[data-use-github-style] h2:hover .anchor, .markdown-preview[data-use-github-style] h3:hover .anchor, .markdown-preview[data-use-github-style] h4:hover .anchor, .markdown-preview[data-use-github-style] h5:hover .anchor, .markdown-preview[data-use-github-style] h6:hover .anchor { padding-left: 8px; margin-left: -30px; text-decoration: none; }
.markdown-preview[data-use-github-style] h1:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h2:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h3:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h4:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h5:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h6:hover .anchor .octicon-link { display: inline-block; }
.markdown-preview[data-use-github-style] h1 tt, .markdown-preview[data-use-github-style] h2 tt, .markdown-preview[data-use-github-style] h3 tt, .markdown-preview[data-use-github-style] h4 tt, .markdown-preview[data-use-github-style] h5 tt, .markdown-preview[data-use-github-style] h6 tt, .markdown-preview[data-use-github-style] h1 code, .markdown-preview[data-use-github-style] h2 code, .markdown-preview[data-use-github-style] h3 code, .markdown-preview[data-use-github-style] h4 code, .markdown-preview[data-use-github-style] h5 code, .markdown-preview[data-use-github-style] h6 code { font-size: inherit; }
.markdown-preview[data-use-github-style] h1 { padding-bottom: 0.3em; font-size: 2.25em; line-height: 1.2; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); }
.markdown-preview[data-use-github-style] h1 .anchor { line-height: 1; }
.markdown-preview[data-use-github-style] h2 { padding-bottom: 0.3em; font-size: 1.75em; line-height: 1.225; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); }
.markdown-preview[data-use-github-style] h2 .anchor { line-height: 1; }
.markdown-preview[data-use-github-style] h3 { font-size: 1.5em; line-height: 1.43; }
.markdown-preview[data-use-github-style] h3 .anchor { line-height: 1.2; }
.markdown-preview[data-use-github-style] h4 { font-size: 1.25em; }
.markdown-preview[data-use-github-style] h4 .anchor { line-height: 1.2; }
.markdown-preview[data-use-github-style] h5 { font-size: 1em; }
.markdown-preview[data-use-github-style] h5 .anchor { line-height: 1.1; }
.markdown-preview[data-use-github-style] h6 { font-size: 1em; color: rgb(119, 119, 119); }
.markdown-preview[data-use-github-style] h6 .anchor { line-height: 1.1; }
.markdown-preview[data-use-github-style] p, .markdown-preview[data-use-github-style] blockquote, .markdown-preview[data-use-github-style] ul, .markdown-preview[data-use-github-style] ol, .markdown-preview[data-use-github-style] dl, .markdown-preview[data-use-github-style] table, .markdown-preview[data-use-github-style] pre { margin-top: 0px; margin-bottom: 16px; }
.markdown-preview[data-use-github-style] hr { height: 4px; padding: 0px; margin: 16px 0px; border: 0px none; background-color: rgb(231, 231, 231); }
.markdown-preview[data-use-github-style] ul, .markdown-preview[data-use-github-style] ol { padding-left: 2em; }
.markdown-preview[data-use-github-style] ul.no-list, .markdown-preview[data-use-github-style] ol.no-list { padding: 0px; list-style-type: none; }
.markdown-preview[data-use-github-style] ul ul, .markdown-preview[data-use-github-style] ul ol, .markdown-preview[data-use-github-style] ol ol, .markdown-preview[data-use-github-style] ol ul { margin-top: 0px; margin-bottom: 0px; }
.markdown-preview[data-use-github-style] li > p { margin-top: 16px; }
.markdown-preview[data-use-github-style] dl { padding: 0px; }
.markdown-preview[data-use-github-style] dl dt { padding: 0px; margin-top: 16px; font-size: 1em; font-style: italic; font-weight: bold; }
.markdown-preview[data-use-github-style] dl dd { padding: 0px 16px; margin-bottom: 16px; }
.markdown-preview[data-use-github-style] blockquote { padding: 0px 15px; color: rgb(119, 119, 119); border-left-width: 4px; border-left-style: solid; border-left-color: rgb(221, 221, 221); }
.markdown-preview[data-use-github-style] blockquote > :first-child { margin-top: 0px; }
.markdown-preview[data-use-github-style] blockquote > :last-child { margin-bottom: 0px; }
.markdown-preview[data-use-github-style] table { display: block; width: 100%; overflow: auto; word-break: keep-all; }
.markdown-preview[data-use-github-style] table th { font-weight: bold; }
.markdown-preview[data-use-github-style] table th, .markdown-preview[data-use-github-style] table td { padding: 6px 13px; border: 1px solid rgb(221, 221, 221); }
.markdown-preview[data-use-github-style] table tr { border-top-width: 1px; border-top-style: solid; border-top-color: rgb(204, 204, 204); background-color: rgb(255, 255, 255); }
.markdown-preview[data-use-github-style] table tr:nth-child(2n) { background-color: rgb(248, 248, 248); }
.markdown-preview[data-use-github-style] img { max-width: 100%; box-sizing: border-box; }
.markdown-preview[data-use-github-style] .emoji { max-width: none; }
.markdown-preview[data-use-github-style] span.frame { display: block; overflow: hidden; }
.markdown-preview[data-use-github-style] span.frame > span { display: block; float: left; width: auto; padding: 7px; margin: 13px 0px 0px; overflow: hidden; border: 1px solid rgb(221, 221, 221); }
.markdown-preview[data-use-github-style] span.frame span img { display: block; float: left; }
.markdown-preview[data-use-github-style] span.frame span span { display: block; padding: 5px 0px 0px; clear: both; color: rgb(51, 51, 51); }
.markdown-preview[data-use-github-style] span.align-center { display: block; overflow: hidden; clear: both; }
.markdown-preview[data-use-github-style] span.align-center > span { display: block; margin: 13px auto 0px; overflow: hidden; text-align: center; }
.markdown-preview[data-use-github-style] span.align-center span img { margin: 0px auto; text-align: center; }
.markdown-preview[data-use-github-style] span.align-right { display: block; overflow: hidden; clear: both; }
.markdown-preview[data-use-github-style] span.align-right > span { display: block; margin: 13px 0px 0px; overflow: hidden; text-align: right; }
.markdown-preview[data-use-github-style] span.align-right span img { margin: 0px; text-align: right; }
.markdown-preview[data-use-github-style] span.float-left { display: block; float: left; margin-right: 13px; overflow: hidden; }
.markdown-preview[data-use-github-style] span.float-left span { margin: 13px 0px 0px; }
.markdown-preview[data-use-github-style] span.float-right { display: block; float: right; margin-left: 13px; overflow: hidden; }
.markdown-preview[data-use-github-style] span.float-right > span { display: block; margin: 13px auto 0px; overflow: hidden; text-align: right; }
.markdown-preview[data-use-github-style] code, .markdown-preview[data-use-github-style] tt { padding: 0.2em 0px; margin: 0px; font-size: 85%; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157); }
.markdown-preview[data-use-github-style] code::before, .markdown-preview[data-use-github-style] tt::before, .markdown-preview[data-use-github-style] code::after, .markdown-preview[data-use-github-style] tt::after { letter-spacing: -0.2em; content: " "; }
.markdown-preview[data-use-github-style] code br, .markdown-preview[data-use-github-style] tt br { display: none; }
.markdown-preview[data-use-github-style] del code { text-decoration: inherit; }
.markdown-preview[data-use-github-style] pre > code { padding: 0px; margin: 0px; font-size: 100%; word-break: normal; white-space: pre; border: 0px; background: transparent; }
.markdown-preview[data-use-github-style] .highlight { margin-bottom: 16px; }
.markdown-preview[data-use-github-style] .highlight pre, .markdown-preview[data-use-github-style] pre { padding: 16px; overflow: auto; font-size: 85%; line-height: 1.45; border-radius: 3px; background-color: rgb(247, 247, 247); }
.markdown-preview[data-use-github-style] .highlight pre { margin-bottom: 0px; word-break: normal; }
.markdown-preview[data-use-github-style] pre { word-wrap: normal; }
.markdown-preview[data-use-github-style] pre code, .markdown-preview[data-use-github-style] pre tt { display: inline; max-width: initial; padding: 0px; margin: 0px; overflow: initial; line-height: inherit; word-wrap: normal; border: 0px; background-color: transparent; }
.markdown-preview[data-use-github-style] pre code::before, .markdown-preview[data-use-github-style] pre tt::before, .markdown-preview[data-use-github-style] pre code::after, .markdown-preview[data-use-github-style] pre tt::after { content: normal; }
.markdown-preview[data-use-github-style] kbd { display: inline-block; padding: 3px 5px; font-size: 11px; line-height: 10px; color: rgb(85, 85, 85); vertical-align: middle; border-style: solid; border-width: 1px; border-color: rgb(204, 204, 204) rgb(204, 204, 204) rgb(187, 187, 187); border-radius: 3px; box-shadow: rgb(187, 187, 187) 0px -1px 0px inset; background-color: rgb(252, 252, 252); }
.markdown-preview[data-use-github-style] a { color: rgb(51, 122, 183); }
.markdown-preview[data-use-github-style] pre, .markdown-preview[data-use-github-style] code { color: inherit; }
.markdown-preview[data-use-github-style] pre, .markdown-preview[data-use-github-style] pre.editor-colors { padding: 0.8em 1em; margin-bottom: 1em; font-size: 0.85em; border-radius: 4px; overflow: auto; }
.scrollbars-visible-always .markdown-preview pre.editor-colors::shadow .vertical-scrollbar, .scrollbars-visible-always .markdown-preview pre.editor-colors::shadow .horizontal-scrollbar { visibility: hidden; }
.scrollbars-visible-always .markdown-preview pre.editor-colors:hover::shadow .vertical-scrollbar, .scrollbars-visible-always .markdown-preview pre.editor-colors:hover::shadow .horizontal-scrollbar { visibility: visible; }
.markdown-preview del { text-decoration: none; position: relative; }
.markdown-preview del::after { border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: black; content: ""; left: 0px; position: absolute; right: 0px; top: 50%; }
.markdown-preview .flash { animation: flash 1s ease-out 1; outline: rgba(255, 0, 0, 0) solid 1px; }
.markdown-preview .flash:not(li) { display: block; }
.markdown-preview:not([data-use-github-style]) { padding: 2em; font-size: 1.2em; color: rgb(56, 58, 66); overflow: auto; background-color: rgb(250, 250, 250); }
.markdown-preview:not([data-use-github-style]) > :first-child { margin-top: 0px; }
.markdown-preview:not([data-use-github-style]) h1, .markdown-preview:not([data-use-github-style]) h2, .markdown-preview:not([data-use-github-style]) h3, .markdown-preview:not([data-use-github-style]) h4, .markdown-preview:not([data-use-github-style]) h5, .markdown-preview:not([data-use-github-style]) h6 { line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; color: rgb(0, 0, 0); }
.markdown-preview:not([data-use-github-style]) h1 { font-size: 2.4em; font-weight: 300; }
.markdown-preview:not([data-use-github-style]) h2 { font-size: 1.8em; font-weight: 400; }
.markdown-preview:not([data-use-github-style]) h3 { font-size: 1.5em; font-weight: 500; }
.markdown-preview:not([data-use-github-style]) h4 { font-size: 1.2em; font-weight: 600; }
.markdown-preview:not([data-use-github-style]) h5 { font-size: 1.1em; font-weight: 600; }
.markdown-preview:not([data-use-github-style]) h6 { font-size: 1em; font-weight: 600; }
.markdown-preview:not([data-use-github-style]) strong { color: rgb(0, 0, 0); }
.markdown-preview:not([data-use-github-style]) del { color: rgb(94, 97, 110); }
.markdown-preview:not([data-use-github-style]) a, .markdown-preview:not([data-use-github-style]) a code { color: rgb(82, 111, 255); }
.markdown-preview:not([data-use-github-style]) img { max-width: 100%; }
.markdown-preview:not([data-use-github-style]) > p { margin-top: 0px; margin-bottom: 1.5em; }
.markdown-preview:not([data-use-github-style]) > ul, .markdown-preview:not([data-use-github-style]) > ol { margin-bottom: 1.5em; }
.markdown-preview:not([data-use-github-style]) blockquote { margin: 1.5em 0px; font-size: inherit; color: rgb(94, 97, 110); border-color: rgb(209, 209, 210); border-width: 4px; }
.markdown-preview:not([data-use-github-style]) hr { margin: 3em 0px; border-top-width: 2px; border-top-style: dashed; border-top-color: rgb(209, 209, 210); background: none; }
.markdown-preview:not([data-use-github-style]) table { margin: 1.5em 0px; }
.markdown-preview:not([data-use-github-style]) th { color: rgb(0, 0, 0); }
.markdown-preview:not([data-use-github-style]) th, .markdown-preview:not([data-use-github-style]) td { padding: 0.66em 1em; border: 1px solid rgb(209, 209, 210); }
.markdown-preview:not([data-use-github-style]) code { color: rgb(0, 0, 0); background-color: rgb(234, 234, 235); }
.markdown-preview:not([data-use-github-style]) pre.editor-colors { margin: 1.5em 0px; padding: 1em; font-size: 0.92em; border-radius: 3px; background-color: rgb(240, 240, 240); }
.markdown-preview:not([data-use-github-style]) kbd { color: rgb(0, 0, 0); border-width: 1px 1px 2px; border-style: solid; border-color: rgb(209, 209, 210) rgb(209, 209, 210) rgb(193, 193, 194); background-color: rgb(234, 234, 235); }
.markdown-preview[data-use-github-style] { font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; line-height: 1.6; word-wrap: break-word; padding: 30px; font-size: 16px; color: rgb(51, 51, 51); overflow: scroll; background-color: rgb(255, 255, 255); }
.markdown-preview[data-use-github-style] > :first-child { margin-top: 0px !important; }
.markdown-preview[data-use-github-style] > :last-child { margin-bottom: 0px !important; }
.markdown-preview[data-use-github-style] a:not([href]) { color: inherit; text-decoration: none; }
.markdown-preview[data-use-github-style] .absent { color: rgb(204, 0, 0); }
.markdown-preview[data-use-github-style] .anchor { position: absolute; top: 0px; left: 0px; display: block; padding-right: 6px; padding-left: 30px; margin-left: -30px; }
.markdown-preview[data-use-github-style] .anchor:focus { outline: none; }
.markdown-preview[data-use-github-style] h1, .markdown-preview[data-use-github-style] h2, .markdown-preview[data-use-github-style] h3, .markdown-preview[data-use-github-style] h4, .markdown-preview[data-use-github-style] h5, .markdown-preview[data-use-github-style] h6 { position: relative; margin-top: 1em; margin-bottom: 16px; font-weight: bold; line-height: 1.4; }
.markdown-preview[data-use-github-style] h1 .octicon-link, .markdown-preview[data-use-github-style] h2 .octicon-link, .markdown-preview[data-use-github-style] h3 .octicon-link, .markdown-preview[data-use-github-style] h4 .octicon-link, .markdown-preview[data-use-github-style] h5 .octicon-link, .markdown-preview[data-use-github-style] h6 .octicon-link { display: none; color: rgb(0, 0, 0); vertical-align: middle; }
.markdown-preview[data-use-github-style] h1:hover .anchor, .markdown-preview[data-use-github-style] h2:hover .anchor, .markdown-preview[data-use-github-style] h3:hover .anchor, .markdown-preview[data-use-github-style] h4:hover .anchor, .markdown-preview[data-use-github-style] h5:hover .anchor, .markdown-preview[data-use-github-style] h6:hover .anchor { padding-left: 8px; margin-left: -30px; text-decoration: none; }
.markdown-preview[data-use-github-style] h1:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h2:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h3:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h4:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h5:hover .anchor .octicon-link, .markdown-preview[data-use-github-style] h6:hover .anchor .octicon-link { display: inline-block; }
.markdown-preview[data-use-github-style] h1 tt, .markdown-preview[data-use-github-style] h2 tt, .markdown-preview[data-use-github-style] h3 tt, .markdown-preview[data-use-github-style] h4 tt, .markdown-preview[data-use-github-style] h5 tt, .markdown-preview[data-use-github-style] h6 tt, .markdown-preview[data-use-github-style] h1 code, .markdown-preview[data-use-github-style] h2 code, .markdown-preview[data-use-github-style] h3 code, .markdown-preview[data-use-github-style] h4 code, .markdown-preview[data-use-github-style] h5 code, .markdown-preview[data-use-github-style] h6 code { font-size: inherit; }
.markdown-preview[data-use-github-style] h1 { padding-bottom: 0.3em; font-size: 2.25em; line-height: 1.2; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); }
.markdown-preview[data-use-github-style] h1 .anchor { line-height: 1; }
.markdown-preview[data-use-github-style] h2 { padding-bottom: 0.3em; font-size: 1.75em; line-height: 1.225; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); }
.markdown-preview[data-use-github-style] h2 .anchor { line-height: 1; }
.markdown-preview[data-use-github-style] h3 { font-size: 1.5em; line-height: 1.43; }
.markdown-preview[data-use-github-style] h3 .anchor { line-height: 1.2; }
.markdown-preview[data-use-github-style] h4 { font-size: 1.25em; }
.markdown-preview[data-use-github-style] h4 .anchor { line-height: 1.2; }
.markdown-preview[data-use-github-style] h5 { font-size: 1em; }
.markdown-preview[data-use-github-style] h5 .anchor { line-height: 1.1; }
.markdown-preview[data-use-github-style] h6 { font-size: 1em; color: rgb(119, 119, 119); }
.markdown-preview[data-use-github-style] h6 .anchor { line-height: 1.1; }
.markdown-preview[data-use-github-style] p, .markdown-preview[data-use-github-style] blockquote, .markdown-preview[data-use-github-style] ul, .markdown-preview[data-use-github-style] ol, .markdown-preview[data-use-github-style] dl, .markdown-preview[data-use-github-style] table, .markdown-preview[data-use-github-style] pre { margin-top: 0px; margin-bottom: 16px; }
.markdown-preview[data-use-github-style] hr { height: 4px; padding: 0px; margin: 16px 0px; border: 0px none; background-color: rgb(231, 231, 231); }
.markdown-preview[data-use-github-style] ul, .markdown-preview[data-use-github-style] ol { padding-left: 2em; }
.markdown-preview[data-use-github-style] ul.no-list, .markdown-preview[data-use-github-style] ol.no-list { padding: 0px; list-style-type: none; }
.markdown-preview[data-use-github-style] ul ul, .markdown-preview[data-use-github-style] ul ol, .markdown-preview[data-use-github-style] ol ol, .markdown-preview[data-use-github-style] ol ul { margin-top: 0px; margin-bottom: 0px; }
.markdown-preview[data-use-github-style] li > p { margin-top: 16px; }
.markdown-preview[data-use-github-style] dl { padding: 0px; }
.markdown-preview[data-use-github-style] dl dt { padding: 0px; margin-top: 16px; font-size: 1em; font-style: italic; font-weight: bold; }
.markdown-preview[data-use-github-style] dl dd { padding: 0px 16px; margin-bottom: 16px; }
.markdown-preview[data-use-github-style] blockquote { padding: 0px 15px; color: rgb(119, 119, 119); border-left-width: 4px; border-left-style: solid; border-left-color: rgb(221, 221, 221); }
.markdown-preview[data-use-github-style] blockquote > :first-child { margin-top: 0px; }
.markdown-preview[data-use-github-style] blockquote > :last-child { margin-bottom: 0px; }
.markdown-preview[data-use-github-style] table { display: block; width: 100%; overflow: auto; word-break: keep-all; }
.markdown-preview[data-use-github-style] table th { font-weight: bold; }
.markdown-preview[data-use-github-style] table th, .markdown-preview[data-use-github-style] table td { padding: 6px 13px; border: 1px solid rgb(221, 221, 221); }
.markdown-preview[data-use-github-style] table tr { border-top-width: 1px; border-top-style: solid; border-top-color: rgb(204, 204, 204); background-color: rgb(255, 255, 255); }
.markdown-preview[data-use-github-style] table tr:nth-child(2n) { background-color: rgb(248, 248, 248); }
.markdown-preview[data-use-github-style] img { max-width: 100%; box-sizing: border-box; }
.markdown-preview[data-use-github-style] .emoji { max-width: none; }
.markdown-preview[data-use-github-style] span.frame { display: block; overflow: hidden; }
.markdown-preview[data-use-github-style] span.frame > span { display: block; float: left; width: auto; padding: 7px; margin: 13px 0px 0px; overflow: hidden; border: 1px solid rgb(221, 221, 221); }
.markdown-preview[data-use-github-style] span.frame span img { display: block; float: left; }
.markdown-preview[data-use-github-style] span.frame span span { display: block; padding: 5px 0px 0px; clear: both; color: rgb(51, 51, 51); }
.markdown-preview[data-use-github-style] span.align-center { display: block; overflow: hidden; clear: both; }
.markdown-preview[data-use-github-style] span.align-center > span { display: block; margin: 13px auto 0px; overflow: hidden; text-align: center; }
.markdown-preview[data-use-github-style] span.align-center span img { margin: 0px auto; text-align: center; }
.markdown-preview[data-use-github-style] span.align-right { display: block; overflow: hidden; clear: both; }
.markdown-preview[data-use-github-style] span.align-right > span { display: block; margin: 13px 0px 0px; overflow: hidden; text-align: right; }
.markdown-preview[data-use-github-style] span.align-right span img { margin: 0px; text-align: right; }
.markdown-preview[data-use-github-style] span.float-left { display: block; float: left; margin-right: 13px; overflow: hidden; }
.markdown-preview[data-use-github-style] span.float-left span { margin: 13px 0px 0px; }
.markdown-preview[data-use-github-style] span.float-right { display: block; float: right; margin-left: 13px; overflow: hidden; }
.markdown-preview[data-use-github-style] span.float-right > span { display: block; margin: 13px auto 0px; overflow: hidden; text-align: right; }
.markdown-preview[data-use-github-style] code, .markdown-preview[data-use-github-style] tt { padding: 0.2em 0px; margin: 0px; font-size: 85%; border-radius: 3px; background-color: rgba(0, 0, 0, 0.0392157); }
.markdown-preview[data-use-github-style] code::before, .markdown-preview[data-use-github-style] tt::before, .markdown-preview[data-use-github-style] code::after, .markdown-preview[data-use-github-style] tt::after { letter-spacing: -0.2em; content: " "; }
.markdown-preview[data-use-github-style] code br, .markdown-preview[data-use-github-style] tt br { display: none; }
.markdown-preview[data-use-github-style] del code { text-decoration: inherit; }
.markdown-preview[data-use-github-style] pre > code { padding: 0px; margin: 0px; font-size: 100%; word-break: normal; white-space: pre; border: 0px; background: transparent; }
.markdown-preview[data-use-github-style] .highlight { margin-bottom: 16px; }
.markdown-preview[data-use-github-style] .highlight pre, .markdown-preview[data-use-github-style] pre { padding: 16px; overflow: auto; font-size: 85%; line-height: 1.45; border-radius: 3px; background-color: rgb(247, 247, 247); }
.markdown-preview[data-use-github-style] .highlight pre { margin-bottom: 0px; word-break: normal; }
.markdown-preview[data-use-github-style] pre { word-wrap: normal; }
.markdown-preview[data-use-github-style] pre code, .markdown-preview[data-use-github-style] pre tt { display: inline; max-width: initial; padding: 0px; margin: 0px; overflow: initial; line-height: inherit; word-wrap: normal; border: 0px; background-color: transparent; }
.markdown-preview[data-use-github-style] pre code::before, .markdown-preview[data-use-github-style] pre tt::before, .markdown-preview[data-use-github-style] pre code::after, .markdown-preview[data-use-github-style] pre tt::after { content: normal; }
.markdown-preview[data-use-github-style] kbd { display: inline-block; padding: 3px 5px; font-size: 11px; line-height: 10px; color: rgb(85, 85, 85); vertical-align: middle; border-style: solid; border-width: 1px; border-color: rgb(204, 204, 204) rgb(204, 204, 204) rgb(187, 187, 187); border-radius: 3px; box-shadow: rgb(187, 187, 187) 0px -1px 0px inset; background-color: rgb(252, 252, 252); }
.markdown-preview[data-use-github-style] a { color: rgb(51, 122, 183); }
.markdown-preview[data-use-github-style] code { color: inherit; }
.markdown-preview[data-use-github-style] pre.editor-colors { padding: 0.8em 1em; margin-bottom: 1em; font-size: 0.85em; border-radius: 4px; overflow: auto; }
.scrollbars-visible-always .markdown-preview pre.editor-colors::shadow .vertical-scrollbar, .scrollbars-visible-always .markdown-preview pre.editor-colors::shadow .horizontal-scrollbar { visibility: hidden; }
.scrollbars-visible-always .markdown-preview pre.editor-colors:hover::shadow .vertical-scrollbar, .scrollbars-visible-always .markdown-preview pre.editor-colors:hover::shadow .horizontal-scrollbar { visibility: visible; }
.bracket-matcher .region {
border-bottom: 1px dotted lime;
position: absolute;
}
.spell-check-misspelling .region {
border-bottom: 2px dotted rgba(255, 51, 51, 0.75);
}
pre.editor-colors,
.host {
background-color: #fafafa;
color: #383a42;
}
pre.editor-colors .line.cursor-line,
.host .line.cursor-line {
background-color: rgba(56, 58, 66, 0.04);
}
pre.editor-colors .invisible,
.host .invisible {
color: #383a42;
}
pre.editor-colors .cursor,
.host .cursor {
border-left: 2px solid #526fff;
}
pre.editor-colors .selection .region,
.host .selection .region {
background-color: #ededed;
}
pre.editor-colors .bracket-matcher .region,
.host .bracket-matcher .region {
border-bottom: 1px solid #526fff;
box-sizing: border-box;
}
pre.editor-colors .invisible-character,
.host .invisible-character {
color: rgba(56, 58, 66, 0.2);
}
pre.editor-colors .indent-guide,
.host .indent-guide {
color: rgba(56, 58, 66, 0.2);
}
pre.editor-colors .wrap-guide,
.host .wrap-guide {
background-color: rgba(56, 58, 66, 0.2);
}
pre.editor-colors .gutter .line-number,
.host .gutter .line-number {
color: #9d9d9f;
-webkit-font-smoothing: antialiased;
}
pre.editor-colors .gutter .line-number.cursor-line,
.host .gutter .line-number.cursor-line {
color: #383a42;
background-color: #f2f2f2;
}
pre.editor-colors .gutter .line-number.cursor-line-no-selection,
.host .gutter .line-number.cursor-line-no-selection {
background-color: transparent;
}
pre.editor-colors .gutter .line-number .icon-right,
.host .gutter .line-number .icon-right {
color: #383a42;
}
pre.editor-colors .gutter:not(.git-diff-icon) .line-number.git-line-removed.git-line-removed::before,
.host .gutter:not(.git-diff-icon) .line-number.git-line-removed.git-line-removed::before {
bottom: -3px;
}
pre.editor-colors .gutter:not(.git-diff-icon) .line-number.git-line-removed::after,
.host .gutter:not(.git-diff-icon) .line-number.git-line-removed::after {
content: "";
position: absolute;
left: 0px;
bottom: 0px;
width: 25px;
border-bottom: 1px dotted rgba(255, 20, 20, 0.5);
pointer-events: none;
}
pre.editor-colors .gutter .line-number.folded,
.host .gutter .line-number.folded,
pre.editor-colors .gutter .line-number:after,
.host .gutter .line-number:after,
pre.editor-colors .fold-marker:after,
.host .fold-marker:after {
color: #383a42;
}
.comment {
color: #a0a1a7;
font-style: italic;
}
.comment .markup.link {
color: #a0a1a7;
}
.entity.name.type {
color: #c18401;
}
.entity.other.inherited-class {
color: #50a14f;
}
.keyword {
color: #a626a4;
}
.keyword.control {
color: #a626a4;
}
.keyword.operator {
color: #383a42;
}
.keyword.other.special-method {
color: #4078f2;
}
.keyword.other.unit {
color: #986801;
}
.storage {
color: #a626a4;
}
.storage.type.annotation,
.storage.type.primitive {
color: #a626a4;
}
.storage.modifier.package,
.storage.modifier.import {
color: #383a42;
}
.constant {
color: #986801;
}
.constant.variable {
color: #986801;
}
.constant.character.escape {
color: #0184bc;
}
.constant.numeric {
color: #986801;
}
.constant.other.color {
color: #0184bc;
}
.constant.other.symbol {
color: #0184bc;
}
.variable {
color: #e45649;
}
.variable.interpolation {
color: #ca1243;
}
.variable.parameter {
color: #383a42;
}
.string {
color: #50a14f;
}
.string.regexp {
color: #0184bc;
}
.string.regexp .source.ruby.embedded {
color: #c18401;
}
.string.other.link {
color: #e45649;
}
.punctuation.definition.comment {
color: #a0a1a7;
}
.punctuation.definition.method-parameters,
.punctuation.definition.function-parameters,
.punctuation.definition.parameters,
.punctuation.definition.separator,
.punctuation.definition.seperator,
.punctuation.definition.array {
color: #383a42;
}
.punctuation.definition.heading,
.punctuation.definition.identity {
color: #4078f2;
}
.punctuation.definition.bold {
color: #c18401;
font-weight: bold;
}
.punctuation.definition.italic {
color: #a626a4;
font-style: italic;
}
.punctuation.section.embedded {
color: #ca1243;
}
.punctuation.section.method,
.punctuation.section.class,
.punctuation.section.inner-class {
color: #383a42;
}
.support.class {
color: #c18401;
}
.support.type {
color: #0184bc;
}
.support.function {
color: #0184bc;
}
.support.function.any-method {
color: #4078f2;
}
.entity.name.function {
color: #4078f2;
}
.entity.name.class,
.entity.name.type.class {
color: #c18401;
}
.entity.name.section {
color: #4078f2;
}
.entity.name.tag {
color: #e45649;
}
.entity.other.attribute-name {
color: #986801;
}
.entity.other.attribute-name.id {
color: #4078f2;
}
.meta.class {
color: #c18401;
}
.meta.class.body {
color: #383a42;
}
.meta.method-call,
.meta.method {
color: #383a42;
}
.meta.definition.variable {
color: #e45649;
}
.meta.link {
color: #986801;
}
.meta.require {
color: #4078f2;
}
.meta.selector {
color: #a626a4;
}
.meta.separator {
background-color: #373b41;
color: #383a42;
}
.meta.tag {
color: #383a42;
}
.underline {
text-decoration: underline;
}
.none {
color: #383a42;
}
.invalid.deprecated {
color: #000000 !important;
background-color: #f2a60d !important;
}
.invalid.illegal {
color: #ffffff !important;
background-color: #ff1414 !important;
}
.markup.bold {
color: #986801;
font-weight: bold;
}
.markup.changed {
color: #a626a4;
}
.markup.deleted {
color: #e45649;
}
.markup.italic {
color: #a626a4;
font-style: italic;
}
.markup.heading {
color: #e45649;
}
.markup.heading .punctuation.definition.heading {
color: #4078f2;
}
.markup.link {
color: #a626a4;
}
.markup.inserted {
color: #50a14f;
}
.markup.quote {
color: #986801;
}
.markup.raw {
color: #50a14f;
}
.source.cs .keyword.operator {
color: #a626a4;
}
.source.css .property-name,
.source.css .property-value {
color: #696c77;
}
.source.css .property-name.support,
.source.css .property-value.support {
color: #383a42;
}
.source.gfm .markup {
-webkit-font-smoothing: auto;
}
.source.gfm .link .entity {
color: #4078f2;
}
.source.ini .keyword.other.definition.ini {
color: #e45649;
}
.source.java .storage.modifier.import {
color: #c18401;
}
.source.java .storage.type {
color: #c18401;
}
.source.java-properties .meta.key-pair {
color: #e45649;
}
.source.java-properties .meta.key-pair > .punctuation {
color: #383a42;
}
.source.js .keyword.operator {
color: #0184bc;
}
.source.js .keyword.operator.delete,
.source.js .keyword.operator.in,
.source.js .keyword.operator.of,
.source.js .keyword.operator.instanceof,
.source.js .keyword.operator.new,
.source.js .keyword.operator.typeof,
.source.js .keyword.operator.void {
color: #a626a4;
}
.source.json .meta.structure.dictionary.json > .string.quoted.json {
color: #e45649;
}
.source.json .meta.structure.dictionary.json > .string.quoted.json > .punctuation.string {
color: #e45649;
}
.source.json .meta.structure.dictionary.json > .value.json > .string.quoted.json,
.source.json .meta.structure.array.json > .value.json > .string.quoted.json,
.source.json .meta.structure.dictionary.json > .value.json > .string.quoted.json > .punctuation,
.source.json .meta.structure.array.json > .value.json > .string.quoted.json > .punctuation {
color: #50a14f;
}
.source.json .meta.structure.dictionary.json > .constant.language.json,
.source.json .meta.structure.array.json > .constant.language.json {
color: #0184bc;
}
.source.ruby .constant.other.symbol > .punctuation {
color: inherit;
}
.source.python .keyword.operator.logical.python {
color: #a626a4;
}
.source.python .variable.parameter {
color: #986801;
}
</style>
</head>
<body class='markdown-preview'><h1 id="self-driving-car-engineer-project-4-advanced-lane-line-detection">Self Driving Car Engineer Project 4 - Advanced Lane Line Detection</h1>
<h2 id="benjamin-s-llner-25-jun-2017">Benjamin Söllner, 25 Jun 2017</h2>
<hr>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\project_carnd_4_finding_lane_lines_400.png" alt="Fun Project Header Image"></p>
<hr>
<p>The goals / steps of this project are the following:</p>
<ul>
<li>Compute the camera calibration matrix and distortion coefficients given a set of chessboard images.</li>
<li>Apply a distortion correction to raw images.</li>
<li>Use color transforms, gradients, etc., to create a thresholded binary image.</li>
<li>Apply a perspective transform to rectify binary image ("birds-eye view").</li>
<li>Detect lane pixels and fit to find the lane boundary.</li>
<li>Determine the curvature of the lane and vehicle position with respect to center.</li>
<li>Warp the detected lane boundaries back onto the original image.</li>
<li>Output visual display of the lane boundaries and numerical estimation of lane curvature and vehicle position.</li>
</ul>
<h2 id="rubric-points">Rubric Points</h2>
<p>Here I will consider the <a href="https://review.udacity.com/#!/rubrics/571/view">rubric points</a> individually and describe how I addressed each point in my implementation. Code references are made to CELLs of the <a href="CarND 04 Advanced Lane Line Detection.ipynb">Python Notebook</a> (<a href="CarND 04 Advanced Lane Line Detection.html">HTML Version</a>). In the python notebook, you can also see the <em>Task #...</em>s from the rubric referenced that we will reference here.</p>
<h3 id="task-1-compute-the-camera-matrix-and-distortion-coefficients-provide-an-example-of-a-distortion-corrected-calibration-image-">Task #1: Compute the camera matrix and distortion coefficients. Provide an example of a distortion corrected calibration image.</h3>
<p>The camera matrix has been implemented in CELL 2. Chessboard corners have been found for all calibration images in line 26 ...</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>returncode</span><span>, </span><span>corners</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>cv2</span><span>.</span><span>findChessboardCorners</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>gray</span><span>, </span><span>(</span><span>cal_rows</span><span>,</span><span>cal_cols</span><span>)</span><span>, </span><span class="constant language python"><span>None</span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<p>... appended to the object points array after which an undistortion is performed in CELL 3 with said points (line 8f.) ...</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>cal_ret</span><span>, </span><span>cal_matrix</span><span>, </span><span>cal_dist</span><span>, </span><span>cal_rvecs</span><span>, </span><span>cal_tvecs</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="punctuation separator continuation line python"><span>\</span></span><span> </span></span></div><div class="line"><span class="source python"><span> </span><span class="meta function-call python"><span>cv2</span><span>.</span><span>calibrateCamera</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>cal_objpoints</span><span>, </span><span>cal_imgpoints</span><span>, </span><span>cal_test_image_size</span><span>, </span><span class="constant language python"><span>None</span></span><span>, </span><span class="constant language python"><span>None</span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<p>The calibration parameters (<code>cal_*</code> variables) are saved & restored via a pickle file which is used to undistort the images. A <code>undistort(...)</code> function is implemented in CELL 4 which calls <code>cv2.undistort(...)</code> with the correct paramaters (line 12):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="keyword control statement python"><span>return</span></span><span> </span><span class="meta function-call python"><span>cv2</span><span>.</span><span>undistort</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>image</span><span>, </span><span class="meta item-access python"><span>CAL_PICKLE</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="string quoted double single-line python"><span class="punctuation definition string begin python"><span>"</span></span><span>matrix</span><span class="punctuation definition string end python"><span>"</span></span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span>, </span><span class="meta item-access python"><span>CAL_PICKLE</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="string quoted double single-line python"><span class="punctuation definition string begin python"><span>"</span></span><span>dist</span><span class="punctuation definition string end python"><span>"</span></span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span>, </span><span class="constant language python"><span>None</span></span><span>, </span><span class="meta item-access python"><span>CAL_PICKLE</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="string quoted double single-line python"><span class="punctuation definition string begin python"><span>"</span></span><span>matrix</span><span class="punctuation definition string end python"><span>"</span></span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<p>Here is an example of this function applied to a checkerboard image:</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_1_undistortion_checkerboard.png" alt="Undistortion of Checkerboard Images"></p>
<h3 id="task-2-provide-an-example-of-a-distortion-corrected-image-">Task #2: Provide an example of a distortion-corrected image.</h3>
<p>The <code>undistort(...)</code>-function can be equally applied to the test images. Here is an example of that (see also CELL 5):</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_2_undistortion_image.png" alt="Undistortion of Test Image"></p>
<h3 id="task-3-perform-a-perspective-transform-and-provide-an-example-of-a-transformed-image-">Task #3: Perform a perspective transform and provide an example of a transformed image.</h3>
<p>Perspective transformation is done by identifying a trapezoid on the lower area of a straight-lane image and warping this image into a flat area, carefully trying to straighten out the lane lines.</p>
<p>This is done in CELL 6. The trapezoid is defined in a global variable <code>UNWARP_PLANE</code> (CELL 1), the vertical and horizontal margin is configured via <code>UNWARP_X_OFFSET</code> and <code>UNWARP_Y_OFFSET</code> (CELL 1). </p>
<p>The <code>unwarp(...)</code> function in CELL 6 can be applied to any image and unwarps it using these globally defined variables (see lines 22-24):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>transform_matrix</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>cv2</span><span>.</span><span>getPerspectiveTransform</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="meta function-call python"><span>np</span><span>.</span><span>float32</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>source</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span>, </span><span class="meta function-call python"><span>np</span><span>.</span><span>float32</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>dest</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span>inverse_matrix</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>cv2</span><span>.</span><span>getPerspectiveTransform</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="meta function-call python"><span>np</span><span>.</span><span>float32</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>dest</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span>, </span><span class="meta function-call python"><span>np</span><span>.</span><span>float32</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>source</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span>unwarped</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>cv2</span><span>.</span><span>warpPerspective</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>undistorted</span><span>, </span><span>transform_matrix</span><span>, </span><span>dim</span><span>, </span><span class="variable parameter function python"><span>flags</span></span><span class="keyword operator assignment python"><span>=</span></span><span>cv2</span><span>.</span><span>INTER_LINEAR</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<p>Here is an example of the undistorted and unwarped image:</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_3_unwarping.png" alt="Unwarping of Test Image"></p>
<h3 id="task-4-use-color-transforms-gradients-or-other-methods-to-create-a-thresholded-binary-image-provide-an-example-of-a-binary-image-result-">Task #4: Use color transforms, gradients or other methods to create a thresholded binary image. Provide an example of a binary image result.</h3>
<p>Several functions, that create threshold images have been created. CELL 7 defines <code>*_threshold(...)</code> functions that can be applied to an image and return different possible thresholds that could be logically combined:</p>
<ul>
<li><code>mag_threshold(...)</code> creates a Sobel-Magnitude threshold for every pixel with a kernel of (default) 5 and a threshold between 10 and 130 (as tuned by the global variable <code>THRESH_MAG</code>)</li>
<li><code>dir_threshold(...)</code> creates a Sobel-Directional threshold for every pixel with a kernel of (default) 5 and a threshold lower than 0.7 or higher than 1.5 (as tuned by the global variable <code>THRESH_DIR</code>)</li>
<li><code>s_threshold(...)</code> creates a S-of-HLS-channel threshold with a threshold between 15 and 255 (as tuned by the global variable <code>THRESH_S</code>)</li>
<li><code>l_threshold(...)</code> creates a S-of-HLS-channel threshold with a threshold between a defined upper and lower bound, e.g., 70 and 90</li>
<li><code>yellow_threshold(...)</code> aims to catch the yellow line images by applying thresholding in all three channels of the HSV space (CELL 7, lines 76-84)</li>
<li><code>white_threshold(...)</code> applies a mixture of thresholdings in the HSV, HLS and RGB space to catch white pixels and marks a union of all pixels found (CELL 7, lines 88-103)</li>
</ul>
<p>Below, you can see the filters in action for test image <code>test6.jpg</code>:</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_4_thresholds.png" alt="Binary Images of Different Thresholds"></p>
<p>A simple union of the <code>yellow_threshold(...)</code> and the <code>white_threshold(...)</code> pixels was sufficient to do the job, see the "Binary Image" below. All other thresholdings added too much noise. Also see below, in the second row, a mapping of the 6 thresholdings to two RGB images, in order to asess how certain thresholdings compliment each other:</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_4_thresholds_channels.png" alt="Thresholds mapped to RGB channels and output binary image"></p>
<h3 id="task-5-identify-lane-line-pixels-and-fit-their-positions-with-a-polynomial-">Task #5: Identify lane-line pixels and fit their positions with a polynomial?</h3>
<p>Lane line pixel finding was done with a combination of <em>slidewindow search</em> and <em>proximity search</em> as described <a href="https://classroom.udacity.com/nanodegrees/nd013/parts/fbf77062-5703-404e-b60c-95b78b2f3f9e/modules/2b62a1c3-e151-4a0e-b6b6-e424fa46ceab/lessons/40ec78ee-fb7c-4b53-94a8-028c5c60b858/concepts/c41a4b6b-9e57-44e6-9df9-7e4e74a1a49a">in the course</a>.</p>
<h4 id="slidewindow-search">Slidewindow Search</h4>
<p>In order to find the lower bounds where to start the slidewindow search, the aggregated brightness across the y-dimension has been taken across the lower half of the image (CELL 9, function <code>whiteness_half_across_y(...)</code>) and then global maxima have been searched left and right of the center of the sequence (CELL 9, function <code>find_peaks(...)</code>). Here is an image of this sequence, including the peaks (in red):</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_5_find_lane_line_base.png" alt=""></p>
<p>The vertical space of the image is divided into 7 sliding windows which follow the lane line progression from bottom of the image to the top. The lane line pixels are collected from the binary image retrieved by <code>find_lane_line_pixels(...)</code> across the sliding windows (see CELL 12, line 41 and 57)</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>w_left_idxs</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>(</span><span>(</span><span>nonzeroy</span><span> </span><span class="keyword operator comparison python"><span>>=</span></span><span> </span><span>w_y_lo</span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>&</span></span><span> </span><span>(</span><span>nonzeroy</span><span> </span><span class="keyword operator comparison python"><span><</span></span><span> </span><span>w_y_hi</span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>&</span></span><span> </span><span>(</span><span>nonzerox</span><span> </span><span class="keyword operator comparison python"><span>>=</span></span><span> </span><span>w_xleft_lo</span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>&</span></span><span> </span><span>(</span><span>nonzerox</span><span> </span><span class="keyword operator comparison python"><span><</span></span><span> </span><span>w_xleft_hi</span><span>)</span><span>)</span><span>.</span><span class="meta function-call python"><span>n</span><span>onzero</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span class="meta structure list python"><span class="punctuation definition list begin python"><span>[</span></span><span class="meta structure list item python"><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition list end python"><span>]</span></span></span></span></div></pre>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>w_right_idxs</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>(</span><span>(</span><span>nonzeroy</span><span> </span><span class="keyword operator comparison python"><span>>=</span></span><span> </span><span>w_y_lo</span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>&</span></span><span> </span><span>(</span><span>nonzeroy</span><span> </span><span class="keyword operator comparison python"><span><</span></span><span> </span><span>w_y_hi</span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>&</span></span><span> </span><span>(</span><span>nonzerox</span><span> </span><span class="keyword operator comparison python"><span>>=</span></span><span> </span><span>w_xright_lo</span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>&</span></span><span> </span><span>(</span><span>nonzerox</span><span> </span><span class="keyword operator comparison python"><span><</span></span><span> </span><span>w_xright_hi</span><span>)</span><span>)</span><span>.</span><span class="meta function-call python"><span>n</span><span>onzero</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span class="meta structure list python"><span class="punctuation definition list begin python"><span>[</span></span><span class="meta structure list item python"><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition list end python"><span>]</span></span></span></span></div></pre>
<p>In addition to the algorithm developed in the course, there is a "giveup" counter for the sliding windows: in case that a certain number of sliding windows does not find lane lines when moving up the image the search is preliminarily terminated. This was added in order to avoid falsely classifying especially the noisy area at the top of the images as lane line images, e.g. for the left lane line (CELL 12 lines 28ff.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>giveup_left</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="constant numeric integer decimal python"><span>0</span></span></span></div><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> [...]</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="keyword control repeat python"><span>for</span></span><span> </span><span>w</span><span> </span><span class="keyword operator logical python"><span>in</span></span><span> </span><span class="meta function-call python"><span class="support function builtin python"><span>range</span></span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>nwindows</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span>:</span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> [... iterate through sliding windows ...]</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control conditional python"><span>if</span></span><span> </span><span>giveup_left</span><span> </span><span class="keyword operator comparison python"><span><</span></span><span> </span><span>giveupafter</span><span>:</span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> [... find lane line pixels on the left ...]</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control conditional python"><span>if</span></span><span> </span><span class="meta function-call python"><span class="support function builtin python"><span>len</span></span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>w_left_idxs</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span> </span><span class="keyword operator comparison python"><span>></span></span><span> </span><span>minpix</span><span>:</span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> [... update sliding window center ...]</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control conditional python"><span>else</span></span><span>:</span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> or update counter of unsuccessful sliding windows</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span>giveup_left</span><span> </span><span class="keyword operator assignment augmented python"><span>+=</span></span><span> </span><span class="constant numeric integer decimal python"><span>1</span></span></span></div></pre>
<p>After the slidewindow search a second-order polynomial is fit through the points that had been found (CELL 12, lines 19ff., for the <code>LaneLine.sample_poly(...)</code> function, see CELL 10, lines 19f.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>left_fit_xs</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>left_line</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>fit_ys</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span>right_fit_xs</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>right_line</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>fit_ys</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> Sample the fitted polygon across a number of y points</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="meta function python"><span class="storage type function python"><span>def</span></span><span> </span><span class="entity name function python"><span>sample_poly</span></span><span class="punctuation definition parameters begin python"><span>(</span></span><span class="meta function parameters python"><span class="variable parameter function python"><span>self</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>ys</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>yoffset</span></span><span class="keyword operator assignment python"><span>=</span></span><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition parameters end python"><span>)</span></span><span class="punctuation section function begin python"><span>:</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control statement python"><span>return</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span class="keyword operator arithmetic python"><span>*</span></span><span>ys</span><span class="keyword operator arithmetic python"><span>*</span><span>*</span></span><span class="constant numeric integer decimal python"><span>2</span></span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span class="keyword operator arithmetic python"><span>*</span></span><span>ys</span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>2</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span>yoffset</span></span></div></pre>
<p>Here is a sample output of the slidewindow output:</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_5_slidewindow_search.png" alt="Slidewindow search output of the test images"></p>
<h4 id="proximity-search">Proximity Search</h4>
<p>In addition to the slidewindow search, once lanes have been found, subsequent lanes are searched for with a proximity search in the area of the old lane lines. The code for this can be found in CELL 13, e.g. lines 12ff.:</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>left_idxs</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>(</span><span>(</span><span>nonzerox</span><span> </span><span class="keyword operator comparison python"><span>></span></span><span> </span><span class="meta function-call python"><span>old_lane</span><span>.</span><span>left</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>nonzeroy</span><span>, </span><span class="variable parameter function python"><span>yoffset</span></span><span class="keyword operator assignment python"><span>=</span></span><span class="keyword operator arithmetic python"><span>-</span></span><span>pmargin</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>&</span></span><span> </span><span class="punctuation separator continuation line python"><span>\</span></span><span> </span></span></div><div class="line"><span class="source python"><span> </span><span>(</span><span>nonzerox</span><span> </span><span class="keyword operator comparison python"><span><</span></span><span> </span><span class="meta function-call python"><span>old_lane</span><span>.</span><span>left</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>nonzeroy</span><span>, </span><span class="variable parameter function python"><span>yoffset</span></span><span class="keyword operator assignment python"><span>=</span></span><span class="keyword operator arithmetic python"><span>+</span></span><span>pmargin</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span>)</span><span>)</span></span></div><div class="line"><span class="source python"><span>right_idxs</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>(</span><span>(</span><span>nonzerox</span><span> </span><span class="keyword operator comparison python"><span>></span></span><span> </span><span class="meta function-call python"><span>old_lane</span><span>.</span><span>right</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>nonzeroy</span><span>, </span><span class="variable parameter function python"><span>yoffset</span></span><span class="keyword operator assignment python"><span>=</span></span><span class="keyword operator arithmetic python"><span>-</span></span><span>pmargin</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>&</span></span><span> </span><span class="punctuation separator continuation line python"><span>\</span></span><span> </span></span></div><div class="line"><span class="source python"><span> </span><span>(</span><span>nonzerox</span><span> </span><span class="keyword operator comparison python"><span><</span></span><span> </span><span class="meta function-call python"><span>old_lane</span><span>.</span><span>right</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>nonzeroy</span><span>, </span><span class="variable parameter function python"><span>yoffset</span></span><span class="keyword operator assignment python"><span>=</span></span><span class="keyword operator arithmetic python"><span>+</span></span><span>pmargin</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span>)</span><span>)</span></span></div></pre>
<p>In the following image, you can see how the proximity search works (for this example for the sake of simplicity, we are just retrieving the lane lines on the very same image and then doing the proximity search on the same image):</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_5_proximity_search.png" alt="Proximity search output of the test images"></p>
<h4 id="combining-both-strategies">Combining Both strategies</h4>
<p>Both strategies (<code>slidewindow_search(...)</code> and <code>proximity_search(...)</code>) are combined (<code>combined_search(...)</code>, CELL 14). The following strategies are used to trade off both strategies and sanity-check both of them:</p>
<ul>
<li>Lanes are sanity checked with the <code>Lane.would_be_dangerous(...)</code> function. This function caculates if the lane at its base is between 3.7m and 4.3m, whether the "sanity" of the lane (the difference between its highest and lowest width) is smaller than 0.5m (CELL 11, lines, 46ff.):<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> Another sanity check to tell us whether the line would be too wide or too narrow</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="meta function python"><span class="storage type function python"><span>def</span></span><span> </span><span class="entity name function python"><span>would_be_dangerous</span></span><span class="punctuation definition parameters begin python"><span>(</span></span><span class="meta function parameters python"><span class="variable parameter function python"><span>self</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>ys</span></span></span><span class="punctuation definition parameters end python"><span>)</span></span><span class="punctuation section function begin python"><span>:</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>x_l</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>left</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="meta item-access python"><span>ys</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="keyword operator arithmetic python"><span>-</span></span><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>x_r</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>right</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="meta item-access python"><span>ys</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="keyword operator arithmetic python"><span>-</span></span><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>c_l</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>left</span><span>.</span><span>curvature</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="meta item-access python"><span>ys</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="keyword operator arithmetic python"><span>-</span></span><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>c_r</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>right</span><span>.</span><span>curvature</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="meta item-access python"><span>ys</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="keyword operator arithmetic python"><span>-</span></span><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>d</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="support function builtin python"><span>abs</span></span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>x_l</span><span class="keyword operator arithmetic python"><span>-</span></span><span>x_r</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span class="keyword operator arithmetic python"><span>*</span></span><span>LANE_X_M_PER_PIX</span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control statement python"><span>return</span></span><span> </span><span>(</span><span>(</span><span>d</span><span class="keyword operator comparison python"><span><</span></span><span class="constant numeric float python"><span>3.7</span></span><span>)</span><span> </span><span class="keyword operator logical python"><span>or</span></span><span> </span><span>(</span><span>d</span><span class="keyword operator comparison python"><span>></span></span><span class="constant numeric float python"><span>4.3</span></span><span>)</span><span> </span><span class="keyword operator logical python"><span>or</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>insanity</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>ys</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span class="keyword operator comparison python"><span>></span></span><span class="constant numeric float python"><span>0.5</span></span><span>)</span></span></div></pre>
</li>
<li>If either of the two methods do not find a lane (because the left or right lane does not contain lane line pixels or because the lane "would be dangerous"), the other strategy is used.</li>
<li>If no previous image & lane was provided, the slidewindow search will be used.</li>
<li><p>If a previous image & lane was provided, this lane is averaged with the newly found lane (CELL 14 line 19+24, the "+" and "/" operator is overloaded in the "Lane" and "LaneLine" class, see CELL 20 and 32):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>slidewindow_lane_avg</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>(</span><span>old_lane</span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span>slidewindow_lane</span><span>)</span><span class="keyword operator arithmetic python"><span>/</span></span><span class="constant numeric integer decimal python"><span>2</span></span></span></div></pre>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>proximity_lane_avg</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>(</span><span>old_lane</span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span>proximity_lane</span><span>)</span><span class="keyword operator arithmetic python"><span>/</span></span><span class="constant numeric integer decimal python"><span>2</span></span></span></div></pre>
</li>
<li><p>If both searches return results, the lane with the lowest "insanity" is used. As metric for "insanity" the difference between its highest and lowest width is used (see CELL 14 line 37ff.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>proximity_insanity</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>proximity_lane_avg</span><span>.</span><span>insanity</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>ys</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span>slidewindow_insanity</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>slidewindow_lane_avg</span><span>.</span><span>insanity</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>ys</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span class="keyword control conditional python"><span>if</span></span><span> </span><span>(</span><span>proximity_insanity</span><span> </span><span class="keyword operator comparison python"><span><</span></span><span> </span><span>slidewindow_insanity</span><span>)</span><span>:</span></span></div><div class="line"><span class="source python"><span> </span><span>next_lane</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>proximity_lane_avg</span></span></div></pre>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> "Insanity" of a lane is high in case the lane width varies a lot</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="meta function python"><span class="storage type function python"><span>def</span></span><span> </span><span class="entity name function python"><span>insanity</span></span><span class="punctuation definition parameters begin python"><span>(</span></span><span class="meta function parameters python"><span class="variable parameter function python"><span>self</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>ys</span></span></span><span class="punctuation definition parameters end python"><span>)</span></span><span class="punctuation section function begin python"><span>:</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>ds</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta structure list python"><span class="punctuation definition list begin python"><span>[</span></span><span class="punctuation definition list end python"><span>]</span></span></span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> iterate across y-values and collect all lane widths</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control repeat python"><span>for</span></span><span> </span><span>y</span><span> </span><span class="keyword operator logical python"><span>in</span></span><span> </span><span>ys</span><span>:</span></span></div><div class="line"><span class="source python"><span> </span><span>l</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>left</span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span class="keyword operator arithmetic python"><span>*</span></span><span>ys</span><span class="keyword operator arithmetic python"><span>*</span><span>*</span></span><span class="constant numeric integer decimal python"><span>2</span></span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>left</span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span class="keyword operator arithmetic python"><span>*</span></span><span>ys</span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>left</span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>2</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>r</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>right</span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span class="keyword operator arithmetic python"><span>*</span></span><span>ys</span><span class="keyword operator arithmetic python"><span>*</span><span>*</span></span><span class="constant numeric integer decimal python"><span>2</span></span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>right</span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span class="keyword operator arithmetic python"><span>*</span></span><span>ys</span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span class="meta item-access python"><span class="variable language python"><span>self</span></span><span>.</span><span>right</span><span>.</span><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>2</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="meta function-call python"><span>ds</span><span>.</span><span>append</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>r</span><span class="keyword operator arithmetic python"><span>-</span></span><span>l</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> get standard deviation of lane widths</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control statement python"><span>return</span></span><span> </span><span class="meta function-call python"><span>np</span><span>.</span><span>std</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>ds</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
</li>
<li><p>If both proximity search and slidewindow search return no lane, the previous line is kept.</p>
</li>
</ul>
<h3 id="task-6-calculate-the-radius-of-curvature-of-the-lane-and-the-position-of-the-vehicle-with-respect-to-center-">Task #6: Calculate the radius of curvature of the lane and the position of the vehicle with respect to center.</h3>
<p>In the code's <code>Lane</code> class, there are two functions to calculate the lane radius and current offset-from-center (CELL 11, 9ff. and 25ff.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> Curvature of a lane is defined as average curvature of the left + right lane line</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="meta function python"><span class="storage type function python"><span>def</span></span><span> </span><span class="entity name function python"><span>curvature</span></span><span class="punctuation definition parameters begin python"><span>(</span></span><span class="meta function parameters python"><span class="variable parameter function python"><span>self</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>y</span></span></span><span class="punctuation definition parameters end python"><span>)</span></span><span class="punctuation section function begin python"><span>:</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>l</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>left</span><span>.</span><span>curvature</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>y</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>r</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>right</span><span>.</span><span>curvature</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>y</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control statement python"><span>return</span></span><span> </span><span>(</span><span>l</span><span class="keyword operator arithmetic python"><span>+</span></span><span>r</span><span>)</span><span class="keyword operator arithmetic python"><span>/</span></span><span class="constant numeric integer decimal python"><span>2</span></span></span></div></pre>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> Calculate offset from center by looking at x_vehicle_center in respect to left and right lane position</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="meta function python"><span class="storage type function python"><span>def</span></span><span> </span><span class="entity name function python"><span>offset_from_center</span></span><span class="punctuation definition parameters begin python"><span>(</span></span><span class="meta function parameters python"><span class="variable parameter function python"><span>self</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>y</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>x_vehicle_center</span></span></span><span class="punctuation definition parameters end python"><span>)</span></span><span class="punctuation section function begin python"><span>:</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="storage modifier global python"><span>global</span></span><span> </span><span>LANE_X_M_PER_PIX</span></span></div><div class="line"><span class="source python"><span> </span><span>x_l</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>left</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>y</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>x_r</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span class="variable language python"><span>self</span></span><span>.</span><span>right</span><span>.</span><span>sample_poly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>y</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>x_lane_center</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>(</span><span>x_r</span><span class="keyword operator arithmetic python"><span>+</span></span><span>x_l</span><span>)</span><span class="keyword operator arithmetic python"><span>/</span></span><span class="constant numeric integer decimal python"><span>2</span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control statement python"><span>return</span></span><span> </span><span>(</span><span>x_lane_center</span><span class="keyword operator arithmetic python"><span>-</span></span><span>x_vehicle_center</span><span>)</span><span class="keyword operator arithmetic python"><span>*</span></span><span>LANE_X_M_PER_PIX</span></span></div></pre>
<p>The <code>curvature(...)</code> function of the <code>Lane</code> class relies on the <code>curvature(...)</code> function (CELL 10, lines 22ff.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> Calculate the curvature of the polygon</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="meta function python"><span class="storage type function python"><span>def</span></span><span> </span><span class="entity name function python"><span>curvature</span></span><span class="punctuation definition parameters begin python"><span>(</span></span><span class="meta function parameters python"><span class="variable parameter function python"><span>self</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>y</span></span></span><span class="punctuation definition parameters end python"><span>)</span></span><span class="punctuation section function begin python"><span>:</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="storage modifier global python"><span>global</span></span><span> </span><span>LANE_Y_M_PER_PIX</span></span></div><div class="line"><span class="source python"><span> </span><span class="storage modifier global python"><span>global</span></span><span> </span><span>LANE_X_M_PER_PIX</span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> re-fit the polygon in world-space</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span>fit</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>np</span><span>.</span><span>polyfit</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="variable language python"><span>self</span></span><span>.</span><span>ys</span><span class="keyword operator arithmetic python"><span>*</span></span><span>LANE_Y_M_PER_PIX</span><span>, </span><span class="variable language python"><span>self</span></span><span>.</span><span>xs</span><span class="keyword operator arithmetic python"><span>*</span></span><span>LANE_X_M_PER_PIX</span><span>, </span><span class="constant numeric integer decimal python"><span>2</span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control statement python"><span>return</span></span><span> </span><span>(</span><span>(</span><span class="constant numeric integer decimal python"><span>1</span></span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span>(</span><span class="constant numeric integer decimal python"><span>2</span></span><span class="keyword operator arithmetic python"><span>*</span></span><span class="meta item-access python"><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span class="keyword operator arithmetic python"><span>*</span></span><span>y</span><span class="keyword operator arithmetic python"><span>*</span></span><span>LANE_Y_M_PER_PIX</span><span> </span><span class="keyword operator arithmetic python"><span>+</span></span><span> </span><span class="meta item-access python"><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span>)</span><span class="keyword operator arithmetic python"><span>*</span><span>*</span></span><span class="constant numeric integer decimal python"><span>2</span></span><span>)</span><span class="keyword operator arithmetic python"><span>*</span><span>*</span></span><span class="constant numeric float python"><span>1.5</span></span><span>)</span><span> </span><span class="keyword operator arithmetic python"><span>/</span></span><span> </span><span class="meta function-call python"><span>np</span><span>.</span><span>absolute</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="constant numeric integer decimal python"><span>2</span></span><span class="keyword operator arithmetic python"><span>*</span></span><span class="meta item-access python"><span>fit</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<h3 id="task-7-plot-result-back-down-onto-the-road-such-that-the-lane-area-is-identified-clearly-">Task #7: Plot result back down onto the road such that the lane area is identified clearly.</h3>
<p>CELL 15 plots the lane as a polygon (<code>update_lane(...)</code>, line 13f.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>pts</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>np</span><span>.</span><span>hstack</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>(</span><span>right_pts</span><span>, </span><span>left_pts</span><span>)</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span class="meta function-call python"><span>cv2</span><span>.</span><span>fillPoly</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>image</span><span>, </span><span class="meta function-call python"><span>np</span><span>.</span><span>int_</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>pts</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span><span>, </span><span>laneColor</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<p>It also includes a stepping function that takes in a previous lane and an image and generates an output lane image and a new lane object (line 17ff.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> Stepping function: for a given new_image & old_lane, calculate a new_lane and a lane line image (lane_img)</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="meta function python"><span class="storage type function python"><span>def</span></span><span> </span><span class="entity name function python"><span>update_lane</span></span><span class="punctuation definition parameters begin python"><span>(</span></span><span class="meta function parameters python"><span class="variable parameter function python"><span>old_lane</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>new_image</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>laneColor</span></span><span class="keyword operator assignment python"><span>=</span></span><span>(</span><span class="constant numeric float python"><span>1.</span></span><span>, </span><span class="constant numeric float python"><span>1.</span></span><span>, </span><span class="constant numeric float python"><span>1.</span></span><span>)</span></span><span class="punctuation definition parameters end python"><span>)</span></span><span class="punctuation section function begin python"><span>:</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>new_lane</span><span>, </span><span>out_img</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>combined_search</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>old_lane</span><span>, </span><span>new_image</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>lane_img</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>np</span><span>.</span><span>float_</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span class="meta function-call python"><span>np</span><span>.</span><span>zeros_like</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>new_image</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="meta function-call python"><span>plot_lane</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>lane_img</span><span>, </span><span>new_lane</span><span>, </span><span>laneColor</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control statement python"><span>return</span></span><span> </span><span>new_lane</span><span>, </span><span>lane_img</span></span></div></pre>
<p>The image is used in the <code>update_warp(...)</code> function in CELL 16, where it's warped back onto the image and layed over with the respective metrics (line 26ff.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> Stepping function: for a given new_image & old_lane, calculate a new_lane and an output image</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> displaying the lane metrics and lane polygon</span><span> </span></span></span></div><div class="line"><span class="source python"><span class="meta function python"><span class="storage type function python"><span>def</span></span><span> </span><span class="entity name function python"><span>update_warp</span></span><span class="punctuation definition parameters begin python"><span>(</span></span><span class="meta function parameters python"><span class="variable parameter function python"><span>old_lane</span></span><span class="punctuation separator parameters python"><span>,</span></span><span> </span><span class="variable parameter function python"><span>new_image</span></span></span><span class="punctuation definition parameters end python"><span>)</span></span><span class="punctuation section function begin python"><span>:</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="storage modifier global python"><span>global</span></span><span> </span><span>UNWARP_INV_MATRIX</span></span></div><div class="line"><span class="source python"><span> </span><span>dim</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span>(</span><span class="meta item-access python"><span>new_image</span><span>.</span><span>shape</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>1</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span>, </span><span class="meta item-access python"><span>new_image</span><span>.</span><span>shape</span><span class="punctuation definition arguments begin python"><span>[</span></span><span class="meta item-access arguments python"><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition arguments end python"><span>]</span></span></span><span>)</span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> undistort image</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span>out_image</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>undistort</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>new_image</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> calculate lane and lane-image</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span>lane</span><span>, </span><span>lane_image</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>update_lane</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>old_lane</span><span>, </span><span>new_image</span><span>, </span><span class="variable parameter function python"><span>laneColor</span></span><span class="keyword operator assignment python"><span>=</span></span><span>(</span><span class="constant numeric float python"><span>1.</span></span><span>, </span><span class="constant numeric float python"><span>1.</span></span><span>, </span><span class="constant numeric float python"><span>1.</span></span><span>)</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> warp lane-image back onto original image</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span>warp_lane_image</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>cv2</span><span>.</span><span>warpPerspective</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>lane_image</span><span>, </span><span>UNWARP_INV_MATRIX</span><span>, </span><span>dim</span><span>, </span><span class="variable parameter function python"><span>flags</span></span><span class="keyword operator assignment python"><span>=</span></span><span>cv2</span><span>.</span><span>INTER_LINEAR</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span>out_image</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>cv2</span><span>.</span><span>addWeighted</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>out_image</span><span class="keyword operator arithmetic python"><span>/</span></span><span class="constant numeric float python"><span>255.</span></span><span>, </span><span class="constant numeric float python"><span>0.7</span></span><span>, </span><span>warp_lane_image</span><span>, </span><span class="constant numeric float python"><span>0.3</span></span><span>, </span><span class="constant numeric integer decimal python"><span>0</span></span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span class="punctuation whitespace comment leading python"><span> </span></span><span class="comment line number-sign python"><span class="punctuation definition comment python"><span>#</span></span><span> write metrics onto image</span><span> </span></span></span></div><div class="line"><span class="source python"><span> </span><span class="meta function-call python"><span>plot_metrics</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>out_image</span><span>, </span><span>lane</span><span>, </span><span class="variable parameter function python"><span>textColor</span></span><span class="keyword operator assignment python"><span>=</span></span><span>(</span><span class="constant numeric float python"><span>1.</span></span><span>, </span><span class="constant numeric float python"><span>1.</span></span><span>, </span><span class="constant numeric float python"><span>1.</span></span><span>)</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div><div class="line"><span class="source python"><span> </span><span class="keyword control statement python"><span>return</span></span><span> </span><span>lane</span><span>, </span><span>out_image</span></span></div></pre>
<p>Here are all test images with warped lanes and added metrics:</p>
<p><img src="H:\Dokumente\GitHub\CarND_04_AdvancedLaneFinding\writeup_images\task_7_plot_lane.png" alt="Warped lane onto and added metrics to test images"></p>
<h3 id="task-8-provide-a-link-to-your-final-video-output-your-pipeline-should-perform-reasonably-well-on-the-entire-project-video-wobbly-lines-are-ok-but-no-catastrophic-failures-that-would-cause-the-car-to-drive-off-the-road-">Task #8: Provide a link to your final video output. Your pipeline should perform reasonably well on the entire project video (wobbly lines are ok but no catastrophic failures that would cause the car to drive off the road!)</h3>
<p>CELL 17 provides a function <code>process_frame(...)</code> which stores the current lane line in a global variable <code>process_lane_buffer</code> and updates it with every step (line 14f.):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>process_lane_buffer</span><span>, </span><span>image</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>update_warp</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>process_lane_buffer</span><span>, </span><span>image</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<p>This is done since the <code>VideoClipFile.fl_image(...)</code> function only takes framewise processing functions that take and return exactly one argument, the (to-be-) transformed image (line 22):</p>
<pre class="editor-colors lang-python"><div class="line"><span class="source python"><span>video_out_clip</span><span> </span><span class="keyword operator assignment python"><span>=</span></span><span> </span><span class="meta function-call python"><span>video_in_clip</span><span>.</span><span>fl_image</span><span class="punctuation definition arguments begin python"><span>(</span></span><span class="meta function-call arguments python"><span>process_frame</span></span><span class="punctuation definition arguments end python"><span>)</span></span></span></span></div></pre>
<p>CELL 18 processes the whole video. Here's a <a href="./project_video_output.mp4">link to my video result</a>.</p>
<video width="960" height="540" controls><source src="./project_video_output.mp4"></source></video>
<h2 id="task-9-briefly-discuss-any-problems-issues-you-faced-in-your-implementation-of-this-project-where-will-your-pipeline-likely-fail-what-could-you-do-to-make-it-more-robust-">Task #9: Briefly discuss any problems / issues you faced in your implementation of this project. Where will your pipeline likely fail? What could you do to make it more robust?</h2>
<p>The main challenge was finding the right threshold (with lots of trials-and-errors over test images and the video).</p>
<p>Here are a few thoughts how this project could still be improved:</p>
<ul>
<li>Smoothing could be implemented over a larger number of lanes. This would need adaption of the data structure</li>
<li>Certain lane fits could be discarded as "totally insane" (like if curvature or lane width variation is too unrealistic)</li>
<li>Sobel or L/S threshold could be re-considered, if a low-pass filtering would be applied that removes noise from the related binary images</li>
<li>Some other form of outlier rejection of the binary image could be introduced.</li>
<li>Lane base detection could be implemented with local maxima</li>
<li>Heuristics could be implemented to detect when a driver is changing lanes over time, therefore shifting the middle of the lane to the side the driver is steering towards</li>
</ul>
<h2 id="files-submitted">Files Submitted</h2>
<p>My project includes the following files:</p>
<ul>
<li><a href="CarND%2004%20Advanced%20Lane%20Line%20Detection.ipynb"><code>CarND 04 Advanced Lane Line Detection.ipynb</code></a> / <a href="CarND%2004%20Advanced%20Lane%20Line%20Detection.html"><code>.html</code></a>: the (rendered) iPython notebook with the algorithm</li>
<li><a href="writeup_report.md"><code>writeup_report.md</code></a> / <a href="writeup_report.html"><code>.html</code></a>: the writeup of this project including the showcase images (you are reading it)</li>
<li><a href="project_video_output.mp4"><code>project_video_output.mp4</code></a>: the output video with lane line markings and lane metrics</li>
</ul></body>
</html>