%% Pedestrian Detection
%  
% This example shows code generation for pedestrian detection
% application that uses deep learning. Pedestrian detection is a key 
% issue in computer vision. Pedestrian detection has several applications 
% in the fields of autonomous driving, surveillance, robotics, and so on.
%
%   Copyright 2018 - 2019 The MathWorks, Inc.

%% Prerequisites
% * CUDA(R) enabled NVIDIA(R) GPU with compute capability 3.2 or higher.
% * NVIDIA CUDA toolkit and driver.
% * NVIDIA cuDNN.
% * 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>.
% * GPU Coder Interface for Deep Learning Libraries support package. To install
% this support package, use the <matlab:matlab.addons.supportpackage.internal.explorer.showSupportPackages('GPU_DEEPLEARNING_LIB','tripwire') Add-On Explorer>.

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

%% The Pedestrian Detection Network
% The pedestrian detection network was trained by using images of 
% pedestrians and non-pedestrians. This network is trained in MATLAB(R) by using 
% the <matlab:edit(fullfile(matlabroot,'examples','deeplearning_shared','main','trainPedNet.m'))
% trainPedNet.m> helper script. A sliding window approach crops patches from an
% image of size [64 32]. Patch dimensions are obtained from a heatmap, which  
% represents the distribution of pedestrians in the images in the data set. 
% It indicates the presence of pedestrians at various scales and locations in the images.  
% In this example, patches of pedestrians close to the camera are cropped and processed.
% Non-Maximal Suppression (NMS) is applied on the obtained 
% patches to merge them and detect complete pedestrians.
%
% <<../PedNetworkBlock.png>> 
%%
%
% The pedestrian detection network contains 12 layers which include 
% convolution, fully connected, and classification output layers.
load('PedNet.mat');
PedNet.Layers

%% The |pedDetect_predict| Entry-Point Function
% 
% The <matlab:edit(fullfile(matlabroot,'examples','deeplearning_shared','main','pedDetect_predict.m')) pedDetect_predict.m>
% entry-point function takes an image input and performs prediction on an 
% image by using the deep learning network saved in the |PedNet.mat| file.
% The function loads the network object from the |PedNet.mat| file into a persistent
% variable _pednet_. Then function reuses the persistent object on subsequent
% calls. 
%
type('pedDetect_predict.m')

%% Generate CUDA MEX for the |pedDetect_predict| Function
%
%
% Create a GPU Configuration object for a MEX target and set the target 
% language to C++. Use the
% <docid:gpucoder_ref#mw_e8e85f8e-8dde-45b6-9ec5-f121a79dc48f coder.DeepLearningConfig>
% function to create a |CuDNN| deep learning configuration object and
% assign it to the |DeepLearningConfig| property of the GPU code
% configuration object. To generate CUDA MEX, use the |codegen| command and 
% specify the size of the input image. This value corresponds to the input 
% layer size of pedestrian detection network.

% Load an input image.
im = imread('test.jpg');
im = imresize(im,[480,640]);

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg pedDetect_predict -args {im} -report

%% Run Generated MEX 
% Call |pednet_predict_mex| on the input image.
imshow(im);
ped_bboxes = pedDetect_predict_mex(im);

%%
% Display the final predictions.
outputImage = insertShape(im,'Rectangle',ped_bboxes,'LineWidth',3);
imshow(outputImage);

%% Classification on Video
%
% The included helper file 
% <matlab:edit(fullfile(matlabroot,'examples','deeplearning_shared','main','pedDetect_predict.m')) pedDetect_predict.m>
% grabs frames from a video, performs prediction, and displays the classification results on each of the captured video frames.
%%
%    v = VideoReader('LiveData.avi');
%    fps = 0;
%    while hasFrame(v)
%       % Read frames from video
%       im = readFrame(v);      
%       im = imresize(im,[480,640]);
%    
%       % Call MEX function for pednet prediction
%       tic;    
%       ped_bboxes = pedDetect_predict_mex(im);
%       newt = toc;
%       
%       % fps 
%       fps = .9*fps + .1*(1/newt);
%    
%       % display
%       outputImage = insertShape(im,'Rectangle',ped_bboxes,'LineWidth',3);
%       imshow(outputImage)
%       pause(0.2)
%    end
%% 
%
% Clear the static network object that was loaded in memory. 
clear mex;
