Udacity Advanced Lane Lines Project: Measuring speed
How to use lane markers as a rudimentary speedometer
I just finished Project #4 for the Udacity Self-Driving Car Engineer nano degree, Advanced Lane Lines. In this project, we use Python and the computer vision library OpenCV to identify lane markers on the road in dash cam images. It was very cool to watch the result once I (finally) got it working.
To complete the project, we have to measure the lane curvature and offset of the vehicle from the lane center. As I was completing this I realized it should also be possible to measure the speed of the vehicle, by tracking how quickly the dashed lane markers pass our field of view.

This is possible because these lane lines are a standardized length (10 feet) and are separated by a standardized distance (a 30-foot gap, for a total separation of 40 feet). Interestingly, many drivers vastly underestimate their length, which gives the false impression that you’re driving much slower than you really are.
To do this, I modified the sliding-window code that detects the centroids of the lane markers in the binary image of detected lane pixels. The main method of the relevant part of the sliding window code calculates a one-dimensional histogram of the pixels in each window by summing pixels vertically, and then uses this to find the mean index of non-zero values:
hist = np.sum(im_window,axis=0)
nonzero = np.flatnonzero(hist)
centroid = int(nonzero.mean())
It’s easy to modify this to also create a horizontally-oriented histogram for one of the windows— i.e, summing pixels along the other axis (sideways). Since the lane markers are longer than the window is high (if you use at least 8 sliding windows), when a lane marker is present in the window, there will be no rows without pixels, and this horizontal histogram will have all non-zero values.

We can easily test for when this occurs for a given window (I used the bottom one) and then count frames until it happens again. (We have to wait for at least 2–3 frames before triggering on the next occurrence because each lane marker will fill a window vertically for several frames of the video.)
Once we have a count of the number of frames between lane markers, we can convert that to a vehicle speed. We need to know the frame rate of the video, which we can get from a parameter of our video clip:
clip = VideoFileClip(‘./project_video.mp4’)
FRAMES_PER_SECOND = clip.fps
The final step is just to divide the physical distance between lane markers (40 feet) by the number of frames we counted before seeing the next lane marker, and then multiply by the frame rate. (We also need to convert from feet to km and seconds to hours to get a value in km/h.) In my case, this yielded vehicle speeds of about 110 km/h, or 68 mph — very reasonable for California highway driving!
You can see the rest of my project, and the writeup, on GitHub.
