Lane detection library - mintforpeople/robobo-programming GitHub Wiki

Lane detection in Python

Lane detection uses the frames captured by the smartphone's camera to detect the lane limits present in the scene. To use this method it is necessary to first create an instance of the Robobo class, send the IP of our smartphone, and connect it. Then, the readLanePro() method is called and it returns an object containing all the information.

readLanePro( )

Reads the last detected pro Lane (2nd degree polynomials)

Returns 
	(LanePro) A LanePro object


The steps followed are shown below:

IP = "10.113.36.145"
rob = Robobo(IP)
rob.connect( )
# Start Lane Detection method
rob.startLaneDetection()

obj = rob.readLanePro( )

# Stop Lane Detection method
rob.stopLaneDetection()

The returned object contains 3 fields:

  • The second order polynomial coefficients of the left lane.
  • The second order polynomial coefficients of the right lane.
  • The reverse transform matrix to the original frame.

This method first detects all the lines in the scene and applies a filter to discard those that are not horizontal. Then, the method detects straight lanes and curve lanes, and it returns the three coefficients (‘a’, ‘b’ and ‘c’) of a second order polynomial with the form:

y= a x^2+ bx+c

The method transform the original frame in a birds’s eye view perspective. The reverse transformation matrix allows us to draw our lanes correctly by adjusting the perspective of the image. Each value can be accessed individually by typing the following:

a = obj.coeffs1[“a”]
b = obj.coeffs1[“b”]
c = obj.coeffs1[“c”]


Usage example

The following script shows an example where we call the method readLanePro() and extract the two coefficients and the reverse matrix. Those values are sent to a function that allows drawing the lanes that the Robobo is detecting. This example uses the video streaming library, that must be downloaded from: https://github.com/mintforpeople/robobo-python-video-stream

import cv2
import numpy as np
import Robobo
import RoboboVideo

def draw_line_pro(coeffs1, coeffs2, M, frame):
    
    # Get height and width to the frame
    try:
        height, width, _ = frame.shape
        # Mask for draw the lines
        mask = np.zeros_like(frame)

        # Create an Array with numbers to 0 at   height -1
        plot_y = np.linspace(0, height - 1, height)

        # Arrays evaluating the coefficients
        left_x = coeffs1['a'] * plot_y  2 \
                + coeffs1['b'] * plot_y \
                + coeffs1['c']
        right_x = coeffs2['a'] * plot_y  2 + \
                coeffs2['b'] * plot_y + \
                coeffs2['c']

        #Draw the lanes (blue for left lane and red for right lane)
        cv2.polylines(mask, [np.int32(np.stack((left_x,plot_y), axis=1))], False, (255, 0, 0), 20)
        cv2.polylines(mask, [np.int32(np.stack((right_x, plot_y), axis=1))], False, (0, 0, 255), 20)
        # Warp the perspective
        mask = cv2.warpPerspective(mask, np.float32(M), (width, height))  
        # Add the lane to the original frame
        img = cv2.addWeighted(frame, 1., mask, 0.5, 0)
        
    except ValueError:
        pass

    return img

IP = '192.168.0.17'
rob = Robobo(IP)
rob.connect()
video = RoboboVideo(IP)
video.connect()
rob.setLaneColorInversion(False)
rob.startLaneDetection()

while True:

  frame = video.getImage()
  #obtein the coefficients to the left and right lane and the reverse transformation matrix
  obj = rob.readLanePro()
  frame = draw_line_pro(obj.coeffs1, obj.coeffs2, obj.minv, frame)
  #show the frame draw
  cv2.imshow('smartphone camera', frame) 

  #if you press the key 'q', the script ends
  if cv2.waitKey(1) & 0xFF == ord('q'):
    video.disconnect()
    cv2.destroyAllWindows()
    break

rob.stopLaneDetection()

The following image shows the script output (bottom) when the robot detects the lanes in a curve, as shown in the top part. We have used the three coefficients (a,b,c) to draw the two lanes in the original image.