Find lane lines

ImageLines expects an input image where the "line" pixels are white and the other pixels are dark, so unless you're looking at bubble chamber images, you're expected to do some preprocessing, like this:

img = Import["https://i.stack.imgur.com/SJBKi.jpg"];
binary = MorphologicalBinarize[img, .9];
HighlightImage[img, binary]

enter image description here

With this image, we can find the lane lines:

lines = ImageLines[Thinning@binary];
HighlightImage[img, {Pink, Thickness[0.005], Line /@ lines}]

enter image description here


I played around a bit and the main functions I think help are RemoveBackground, Binarize and GradientFilter. Finally, using the right arguments to ImageLines help you decide how distinct the lines need to be. The code I ended up with is this:

Note img is your original image

(*DeleteSmallComponents removes the small artifacts from binarizing*)
filtered = DeleteSmallComponents[
   (*Brightens the processed image*)
   ImageAdjust[

    (*Takes the change in brightness, can be used as an edge filter*)
    GradientFilter[

     Binarize[

      (*Removes the sky as its brightness is confusing ImageLines*)
      RemoveBackground[
       img,
       Lighter@Blue
       ],

       (*Binarizing threshold*)
      .84
      ],
      (*GradientFilter pixel radius*)
     1
     ]
    ],

   (*Number of small components to delete*)
   20
   ];


lines = ImageLines[
  (*Another gradient filter to define a bit more clearly*)
  GradientFilter[filtered, 1], 
  (*Threshold for lines*)
  0.03, 
  (*How distinct/different the lines should be*)
  0.1
];

HighlightImage[img, {Pink, Thickness[0.005], Line /@ lines}]

RoadLines


The existing answers are based on the ImageLines function, here I'm providing an answer based on the geometric transformations, which can work in curved roads as well.

We take an image of a straight road first

i = ImageTrim[Import["https://github.com/udacity/CarND-Advanced-Lane-Lines/raw/master/test_images/straight_lines2.jpg"], {{0, 50}, {1280, 718}}];
{width, height} = ImageDimensions[i];

Then use the same method as in here to remove the perspective distortion from the image. We define a perspective distorted rectangle in the original image and then find a geometric transformation that transforms this distorted rectangle to an undistorted one. The same transformation will take us from the original image to the undistorted image.

pts1 = {{289, 3}, {431, 106}, {869, 106}, {1034, 3}};
wdWidth = 200;
aspect = 5;
wdHeight = 80;
pts2 = {{width/2 - wdWidth/2, 0}, {width/2 - wdWidth/2, 
    wdHeight}, {width/2 + wdWidth/2, wdHeight}, {width/2 + wdWidth/2, 
    0}};
t = FindGeometricTransform[pts2, pts1][[2]]

This compares the original and the undistorted image

Row@{Show[i, 
   Graphics[{PointSize[Large], Red, Point[pts1], Transparent, 
     EdgeForm[Red], Polygon[pts1]}], ImageSize -> Large], 
  Show[ImagePerspectiveTransformation[i, t, PlotRange -> Full], 
   Graphics[{PointSize[Large], Green, Point[pts2], Transparent, 
     EdgeForm[Green], Polygon[pts2]}], ImageSize -> Large]}

enter image description here

Now we can binarize the image and get the lane pixels

iwrap = ImageTrim[
  ImagePerspectiveTransformation[i, t, 
   PlotRange -> Full], {{width/2 - wdWidth/2 - wdWidth/4, 
    0}, {width/2 + wdWidth/2 + wdWidth/4, height}}];
ibinary = Binarize[iwrap];
{newWidth, newHeight} = Reverse[ImageData[ibinary] // Dimensions];
idx = Position[ImageData[ibinary], 1];
leftIdx = Select[idx, #[[2]] < 150 &];
rightIdx = Complement[idx, leftIdx];

and fit the pixel positions using quadratic form.

leftModel = Fit[leftIdx, {x^2, x, 1}, x]
rightModel = Fit[rightIdx, {x^2, x, 1}, x]

This shows the lane lines in the undistorted image

Show[ImagePerspectiveTransformation[i, t, PlotRange -> Full], 
 Plot[{leftModel, rightModel}, {x, 1, 670}, PlotStyle -> Thick] /. 
  Line[pts_] :> 
   Line[pts /. {x_, y_} -> {y + (width - newWidth)/2, height - x}], 
 ImageSize -> Large]

enter image description here

Now we can change back to the perspective image using the inverse transform and plot the lane

plane = Cases[
   Plot[{leftModel, rightModel}, {x, 1, 670}, PlotStyle -> Thick] /. 
    Line[pts_] :> 
     Line[pts /. {x_, y_} -> {y + (width - newWidth)/2, height - x}], 
   Line[pt_] :> Line[pt], ∞];
t2 = FindGeometricTransform[pts1, pts2][[2]];

Show[i, Graphics[{Green, Opacity[0.25], 
   Polygon[Join[Reverse[#[[1]]], #[[2]]] &@(plane /. 
       Line[pts_] :> t2 /@ pts)], Blue, Opacity[0.5], 
   Thickness[0.003], plane /. Line[pts_] :> Line[t2 /@ pts]}]]

enter image description here

Since this method doesn't depend on the ImageLines, it can also work for a curved road:

enter image description here