Lane Detection on the GPU by Using the houghlines Function

This example shows how to generate CUDA® MEX for a MATLAB® function that can detect and output lane marker boundaries on an image. The example takes an RGB image as input and uses the rgb2gray, ordfilt2, hough, houghpeaks, and houghlines functions that are part of Image Processing Toolbox™ to produce the lane-detected output image.

Prerequisites

  • CUDA enabled NVIDIA® GPU with compute capability 3.2 or higher.

  • NVIDIA CUDA toolkit and driver.

  • Image Processing Toolbox.

  • Environment variables for the compilers and libraries. For information on the supported versions of the compilers and libraries, see Third-party Products. For setting up the environment variables, see Setting Up the Prerequisite Products.

Verify GPU Environment

To verify that the compilers and libraries necessary for running this example are set up correctly, use the coder.checkGpuInstall function.

envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

The lane_detection_houghlines Entry-Point Function

The lane_detection_houghlines.m entry-point function takes an intensity image as input and returns the lane-detected image.

type lane_detection_houghlines
function [lines] = lane_detection_houghlines(inputImage)%#codegen

%  Copyright 2019 The MathWorks, Inc.
coder.gpu.kernelfun;

% Convert RGB image to grayscale image.
if size(inputImage,3)==3
    grayImage = rgb2gray(inputImage);
else
    grayImage = inputImage;
end

% Edge detection using ordfilt2.
input = grayImage(240:end,1:end);
dom = ones(2);
minOrder = 1;
maxOrder = 4;
padopt = 'zeros';

MinImg = ordfilt2(input,minOrder,dom,padopt);
MaxImg = ordfilt2(input,maxOrder,dom,padopt);

% Edge detected output.
outImage = MaxImg - MinImg;
BW = imbinarize(outImage);

[H,T,R] = hough(BW);
P  = houghpeaks(H,20,'threshold',1);
lines = houghlines(BW,T,R,P,'FillGap',200,'MinLength',150);

Generate CUDA MEX for the lane_detection_houghlines Function

Create a GPU code configuration object and run the codegen function.

inputImage = imread('highway.png');
inputResizedImage = imresize(inputImage,[480 640]);
cfg = coder.gpuConfig('mex');
codegen -args {inputResizedImage} -config cfg lane_detection_houghlines -o lane_detection_houghlines_gpu_mex

Run the Generated CUDA MEX

Run the generated lane_detection_houghlines_mex with an input image and plot the input and lane-detected images.

[lines] = lane_detection_houghlines_gpu_mex(inputResizedImage);

% Plot images.
inputImageVGAsize = imresize(inputImage,[480 640]);
outputImage = imresize(inputImage,[480 640]);
p1  = subplot(1, 2, 1);
p2 = subplot(1, 2, 2);
imshow(inputImageVGAsize, 'Parent', p1);
imshow(outputImage, 'Parent', p2);hold on
max_len = 0;
for k = 1:length(lines)
    if ((lines(k).theta <= 60 && lines(k).theta >10)||(lines(k).theta <= -10 && lines(k).theta > -50) )
        xy = [lines(k).point1; (lines(k).point2)];
        plot(xy(:,1),xy(:,2)+240,'LineWidth',2,'Color','green');

        % Plot beginning and end of lines.
        plot(xy(1,1),xy(1,2)+240,'x','LineWidth',2,'Color','yellow');
        plot(xy(2,1),xy(2,2)+240,'x','LineWidth',2,'Color','red');

        % Determine the endpoints of the longest line segment.
        len = norm(lines(k).point1 - lines(k).point2);
        if ( len > max_len)
            max_len = len;
            xy_long = xy;
        end
    end
end
title(p1, 'Input Image');
title(p2, 'Lane Detected Output Image');