%% Lane Detection on the GPU by Using the |houghlines| Function
% This example shows how to generate CUDA(R) MEX for a MATLAB(R) function 
% that can detect and output lane marker boundaries on an image. 
% The example takes an RGB image as input and uses the <docid:matlab_ref#buiz8mj-1 rgb2gray>, 
% <docid:images_ref#bupba70-1 ordfilt2>, <docid:images_ref#buwew0l-1 hough>, 
% <docid:images_ref#buw9d0p-1 houghpeaks>, and <docid:images_ref#buwgo_f-1 houghlines> 
% functions that are part of Image Processing Toolbox(TM) to produce the 
% lane-detected output image.

% Copyright 2019 The MathWorks, Inc.

%% Prerequisites
% * CUDA enabled NVIDIA(R) 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 
% <docid:gpucoder_gs#mw_aa8b0a39-45ea-4295-b244-52d6e6907bff
% Third-Party Products>. For setting up the environment variables, see 
% <docid:gpucoder_gs#mw_453fbbd7-fd08-44a8-9113-a132ed383275
% Environment Variables>.

%% Create a Folder and Copy Relevant Files
% The following line of code creates a folder in your current working 
% folder (pwd) and copies all the relevant files into this folder. If you 
% do not want to perform this operation or if you cannot generate files in 
% this folder, change your current working folder.
gpucoderdemo_setup('gpucoderdemo_lane_detection_houghlines');


%% Verify GPU Environment
% To verify that the compilers and libraries necessary for running this example
% are set up correctly, use the <docid:gpucoder_ref#mw_0957d820-192f-400a-8045-0bb746a75278 coder.checkGpuInstall>
% function.
envCfg = coder.gpuEnvConfig('host');
envCfg.BasicCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

%% The |lane_detection_houghlines| Entry-Point Function
% The <matlab:edit(fullfile(matlabroot,'toolbox','gpucoder','gpucoderdemos','gpucoderdemo_lane_detection_houghlines','lane_detection_houghlines.m')) lane_detection_houghlines.m>
% function takes an intensity image as input and returns the lane-detected 
% image. 

type lane_detection_houghlines

%% 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');

%% Cleanup
% Remove the temporary files and return to the original folder.
cleanup

displayEndOfDemoMessage(mfilename)
