├── Code ├── main.m └── roi_variables.mat ├── Input └── project_video.mp4 ├── Project Report.pdf ├── README.md └── Result.mp4 /Code/main.m: -------------------------------------------------------------------------------- 1 | %========================================================================== 2 | 3 | % MATLAB code for Project 1 (Perception Class) 4 | % Written by Yash Shah (115710498) 5 | % email ID: ysshah95@umd.edu 6 | 7 | %========================================================================== 8 | 9 | %% Initializing the Code 10 | 11 | clc 12 | close all 13 | clear all 14 | 15 | %-------------------------Importing the Video File------------------------- 16 | VideoFile = VideoReader('project_video.mp4'); 17 | 18 | %-------------------Loading Region of Interest Variables------------------- 19 | load('roi_variables', 'c', 'r'); 20 | 21 | %-----------------Defining Variables for saving Video File----------------- 22 | 23 | Output_Video=VideoWriter('Result_Yash'); 24 | Output_Video.FrameRate= 25; 25 | open(Output_Video); 26 | 27 | 28 | 29 | %% Initializing the loop to take frames one by one 30 | 31 | while hasFrame(VideoFile) 32 | 33 | %------------------Reading each frame from Video File------------------ 34 | frame = readFrame(VideoFile); 35 | % figure('Name','Original Image'), imshow(frame); 36 | 37 | frame = imgaussfilt3(frame); 38 | % figure('Name','Filtered Image'), imshow(frame); 39 | 40 | %% Masking the image for White and Yellow Color 41 | 42 | %--------------Define Thresholds for masking Yellow Color-------------- 43 | 44 | %----------------------Define thresholds for 'Hue'--------------------- 45 | channel1MinY = 130; 46 | channel1MaxY = 255; 47 | %------------------Define thresholds for 'Saturation'------------------ 48 | channel2MinY = 130; 49 | channel2MaxY = 255; 50 | %---------------------Define thresholds for 'Value'-------------------- 51 | channel3MinY = 0; 52 | channel3MaxY = 130; 53 | 54 | %-----------Create mask based on chosen histogram thresholds----------- 55 | Yellow=((frame(:,:,1)>=channel1MinY)|(frame(:,:,1)<=channel1MaxY))& ... 56 | (frame(:,:,2)>=channel2MinY)&(frame(:,:,2)<=channel2MaxY)&... 57 | (frame(:,:,3)>=channel3MinY)&(frame(:,:,3)<=channel3MaxY); 58 | 59 | % figure('Name','Yellow Mask'), imshow(Yellow); 60 | 61 | %--------------Define Thresholds for masking White Color--------------- 62 | 63 | %----------------------Define thresholds for 'Hue'--------------------- 64 | channel1MinW = 200; 65 | channel1MaxW = 255; 66 | %------------------Define thresholds for 'Saturation'------------------ 67 | channel2MinW = 200; 68 | channel2MaxW = 255; 69 | %---------------------Define thresholds for 'Value'-------------------- 70 | channel3MinW = 200; 71 | channel3MaxW = 255; 72 | 73 | %-----------Create mask based on chosen histogram thresholds----------- 74 | White=((frame(:,:,1)>=channel1MinW)|(frame(:,:,1)<=channel1MaxW))&... 75 | (frame(:,:,2)>=channel2MinW)&(frame(:,:,2)<=channel2MaxW)& ... 76 | (frame(:,:,3)>=channel3MinW)&(frame(:,:,3)<=channel3MaxW); 77 | 78 | % figure('Name','White Mask'), imshow(White); 79 | 80 | %% Detecting edges in the image using Canny edge function 81 | 82 | frameW = edge(White, 'canny', 0.2); 83 | frameY = edge(Yellow, 'canny', 0.2); 84 | 85 | 86 | %% Neglecting closed edges in smaller areas 87 | 88 | frameY = bwareaopen(frameY,15); 89 | frameW = bwareaopen(frameW,15); 90 | 91 | % figure('Name','Detecting Edges of Yellow mask'), imshow(frameY); 92 | % figure('Name','Detecting Edges of White mask'), imshow(frameW); 93 | 94 | %% Deciding ROI Points and Extracting ROI 95 | 96 | %--------------Deciding ROI points by plotting it on image------------- 97 | 98 | % figure(1) 99 | % imshow(frame); 100 | % [r c] = ginput(10); 101 | 102 | %---------Extracting Region of Interest from Yellow Edge Frame--------- 103 | 104 | roiY = roipoly(frameY, r, c); 105 | [R , C] = size(roiY); 106 | for i = 1:R 107 | for j = 1:C 108 | if roiY(i,j) == 1 109 | frame_roiY(i,j) = frameY(i,j); 110 | else 111 | frame_roiY(i,j) = 0; 112 | end 113 | end 114 | end 115 | 116 | % figure('Name','Filtering ROI from Yellow mask'), imshow(frame_roiY); 117 | 118 | %---------Extracting Region of Interest from White Edge Frame---------- 119 | 120 | roiW = roipoly(frameW, r, c); 121 | [R , C] = size(roiW); 122 | for i = 1:R 123 | for j = 1:C 124 | if roiW(i,j) == 1 125 | frame_roiW(i,j) = frameW(i,j); 126 | else 127 | frame_roiW(i,j) = 0; 128 | end 129 | end 130 | end 131 | 132 | % figure('Name','Filtering ROI from White mask'), imshow(frame_roiW); 133 | 134 | %% Applying Hough Tansform to get straight lines from Image 135 | 136 | %----------Applying Hough Transform to White and Yellow Frames--------- 137 | 138 | [H_Y,theta_Y,rho_Y] = hough(frame_roiY); 139 | [H_W,theta_W,rho_W] = hough(frame_roiW); 140 | 141 | %--------Extracting Hough Peaks from Hough Transform of frames--------- 142 | 143 | P_Y = houghpeaks(H_Y,2,'threshold',2); 144 | P_W = houghpeaks(H_W,2,'threshold',2); 145 | 146 | %----------Plotting Hough Transform and detecting Hough Peaks---------- 147 | 148 | % figure('Name','Hough Peaks for White Line') 149 | % imshow(imadjust(rescale(H_W)),[],'XData',theta_W,'YData',rho_W,'InitialMagnification','fit'); 150 | % xlabel('\theta (degrees)') 151 | % ylabel('\rho') 152 | % axis on 153 | % axis normal 154 | % hold on 155 | % colormap(gca,hot) 156 | % 157 | % x = theta_W(P_W(:,2)); 158 | % y = rho_W(P_W(:,1)); 159 | % plot(x,y,'s','color','blue'); 160 | % hold off 161 | % 162 | % 163 | % figure('Name','Hough Peaks for Yellow Line') 164 | % imshow(imadjust(rescale(H_Y)),[],'XData',theta_Y,'YData',rho_Y,'InitialMagnification','fit'); 165 | % xlabel('\theta (degrees)') 166 | % ylabel('\rho') 167 | % axis on 168 | % axis normal 169 | % hold on 170 | % colormap(gca,hot) 171 | % 172 | % x = theta_W(P_Y(:,2)); 173 | % y = rho_W(P_Y(:,1)); 174 | % plot(x,y,'s','color','blue'); 175 | % hold off 176 | 177 | %--------------Extracting Lines from Detected Hough Peaks-------------- 178 | 179 | lines_Y = houghlines(frame_roiY,theta_Y,rho_Y,P_Y,'FillGap',3000,'MinLength',20); 180 | 181 | % figure('Name','Hough Lines found in image'), imshow(frame), hold on 182 | % max_len = 0; 183 | % for k = 1:length(lines_Y) 184 | % xy = [lines_Y(k).point1; lines_Y(k).point2]; 185 | % plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green'); 186 | % 187 | % % Plot beginnings and ends of lines 188 | % plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow'); 189 | % plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red'); 190 | % end 191 | 192 | 193 | lines_W = houghlines(frame_roiW,theta_W,rho_W,P_W,'FillGap',3000,'MinLength',20); 194 | 195 | % max_len = 0; 196 | % for k = 1:2 197 | % xy = [lines_W(k).point1; lines_W(k).point2]; 198 | % plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green'); 199 | % 200 | % % Plot beginnings and ends of lines 201 | % plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow'); 202 | % plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red'); 203 | % end 204 | % hold off 205 | 206 | %% Plotting best fitting line after Extrapolation 207 | 208 | %-----------------Extract start and end points of lines---------------- 209 | 210 | leftp1 = [lines_Y(1).point1; lines_Y(1).point2]; 211 | leftp2 = [lines_Y(2).point1; lines_Y(2).point2]; 212 | 213 | rightp1 = [lines_W(1).point1; lines_W(1).point2]; 214 | rightp2 = [lines_W(2).point1; lines_W(2).point2]; 215 | 216 | if leftp1(1,1) < leftp2(1,1) 217 | left_plot(1,:) = leftp1(1,:); 218 | else 219 | left_plot(1,:) = leftp2(1,:); 220 | end 221 | 222 | if leftp1(2,2) < leftp2(2,2) 223 | left_plot(2,:) = leftp1(2,:); 224 | else 225 | left_plot(2,:) = leftp2(2,:); 226 | end 227 | 228 | if rightp1(1,2) < rightp2(1,2) 229 | right_plot(1,:) = rightp1(1,:); 230 | else 231 | right_plot(1,:) = rightp2(1,:); 232 | end 233 | 234 | if rightp1(2,1) > rightp2(2,2) 235 | right_plot(2,:) = rightp1(2,:); 236 | else 237 | right_plot(2,:) = rightp2(2,:); 238 | end 239 | 240 | % right_plot = rightp1; 241 | % left_plot = leftp1; 242 | 243 | %----------------Calculate slope of left and right lines--------------- 244 | 245 | slopeL = (left_plot(2,2)-left_plot(1,2))/(left_plot(2,1)-left_plot(1,1)); 246 | slopeR = (right_plot(2,2)-right_plot(1,2))/(right_plot(2,1)-right_plot(1,1)); 247 | 248 | %------Make equations of left and right lines to extrapolate them------ 249 | 250 | xLeftY = 1; % x is on the left edge 251 | yLeftY = slopeL * (xLeftY - left_plot(1,1)) + left_plot(1,2); 252 | xRightY = 550; % x is on the reight edge. 253 | yRightY = slopeL * (xRightY - left_plot(2,1)) + left_plot(2,2); 254 | 255 | xLeftW = 750; % x is on the left edge 256 | yLeftW = slopeR * (xLeftW - right_plot(1,1)) + right_plot(1,2); 257 | xRightW = 1300; % x is on the reight edge. 258 | yRightW = slopeR * (xRightW - right_plot(2,1)) + right_plot(2,2); 259 | 260 | %------Making a transparent Trapezoid between 4 poits of 2 lines------- 261 | 262 | points = [xLeftY yLeftY; xRightY yRightY ;xLeftW yLeftW; xRightW yRightW ]; 263 | number = [1 2 3 4]; 264 | 265 | %% Turn Prediction 266 | 267 | %------------------Turn Prediction--------------- 268 | 269 | Yellow_dir = cross([left_plot(1,1), left_plot(1,2), 1], [left_plot(2,1), left_plot(2,2), 1]); 270 | Yellow_dir = Yellow_dir ./ sqrt(Yellow_dir(1)^2 + Yellow_dir(2)^2); 271 | theta_y = atan2(Yellow_dir(2), Yellow_dir(1)); 272 | rho_y = Yellow_dir(3); 273 | yellow_line = [cos(theta_y), sin(theta_y), rho_y]; 274 | 275 | %-------------Finding vanishing point using cross poduct--------------- 276 | white_dir = cross([right_plot(1,1),right_plot(1,2),1], [right_plot(2,1),right_plot(2,2),1]); 277 | white_dir = white_dir ./ (sqrt(white_dir(1)^2 + white_dir(2)^2)); 278 | theta_w = atan2(white_dir(2),white_dir(1)); 279 | rho_w = white_dir(3); 280 | white_line = [cos(theta_w), sin(theta_w), rho_w]; 281 | 282 | line1 = [0, 1, -left_plot(2,1)]; 283 | point_on_w_lane = cross(line1,white_line); 284 | point_on_w_lane = point_on_w_lane ./ point_on_w_lane(3); 285 | line2 = [0, 1, -left_plot(2,2)]; 286 | point_on_w_lane_2 = cross(line2,white_line); 287 | point_on_w_lane_2 = point_on_w_lane_2 ./ point_on_w_lane_2(3); 288 | 289 | vanishing_point = cross(yellow_line, white_line); 290 | vanishing_point = vanishing_point ./ vanishing_point(3); 291 | vanishing_ratio = vanishing_point(1) / size(frame, 2); 292 | 293 | if vanishing_ratio > 0.47 && vanishing_ratio < 0.49 294 | direction = 'Turn Left'; 295 | elseif vanishing_ratio >= 0.49 && vanishing_ratio <= 0.51 296 | direction = 'Go Straight'; 297 | else 298 | direction = 'Turn Right'; 299 | end 300 | 301 | %% Plotting Everything on the image 302 | 303 | %--Plot the extrapolated lines, Trapezoid and direction on each frame-- 304 | 305 | figure('Name','Final Output') 306 | imshow(frame); 307 | hold on 308 | plot([xLeftY, xRightY], [yLeftY, yRightY], 'LineWidth',8,'Color','red'); 309 | plot([xLeftW, xRightW], [yLeftW, yRightW], 'LineWidth',8,'Color','red'); 310 | text(650, 65, direction,'horizontalAlignment', 'center', 'Color','red','FontSize',20) 311 | patch('Faces', number, 'Vertices', points, 'FaceColor','green','Edgecolor','green','FaceAlpha',0.4) 312 | hold off 313 | 314 | %------------------Save each frame to the Output File------------------ 315 | writeVideo(Output_Video,getframe); 316 | 317 | end 318 | 319 | %---------------------Closing Save Video File Variable--------------------- 320 | close(Output_Video) -------------------------------------------------------------------------------- /Code/roi_variables.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysshah95/Lane-Detection-using-MATLAB/2a7c5c37b716d7d46335d4f4a8853596ee4f6d79/Code/roi_variables.mat -------------------------------------------------------------------------------- /Input/project_video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysshah95/Lane-Detection-using-MATLAB/2a7c5c37b716d7d46335d4f4a8853596ee4f6d79/Input/project_video.mp4 -------------------------------------------------------------------------------- /Project Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysshah95/Lane-Detection-using-MATLAB/2a7c5c37b716d7d46335d4f4a8853596ee4f6d79/Project Report.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lane Detection 2 | 3 | In this project, MATLAB is used as an Image Processing Tool to detect Lanes on the road. The following techniques are used for lane detection. 4 | 5 | • Color Masking 6 | • Canny Edge Detection 7 | • Region of Interest Selection 8 | • Hough Transform Line detection 9 | 10 | ## Pre-processing the Image 11 | 12 | The first step is to import the video file and initialize the variables to be use din the code. Some variables are also imported from the .mat file to be used in the code. 13 | 14 | #### Initializing the loop to take frames one by one 15 | 16 | First the frame is read and them filtered using a Gaussian Filter. 17 | 18 | while hasFrame(VideoFile) 19 | 20 | %------------------Reading each frame from Video File------------------ 21 | frame = readFrame(VideoFile); 22 | figure('Name','Original Image'), imshow(frame); 23 | 24 | frame = imgaussfilt3(frame); 25 | figure('Name','Filtered Image'), imshow(frame); 26 | 27 | ![third_main_01](https://user-images.githubusercontent.com/31979840/36962601-337ce20e-201e-11e8-8bb9-6658713a0eaa.png) 28 | 29 | Fig 1: Original Image 30 | 31 | ![third_main_02](https://user-images.githubusercontent.com/31979840/36962730-b1cc677e-201e-11e8-8da7-576e5c6b7953.png) 32 | 33 | Fig 2: Filtered Image 34 | #### Masking the image for White and Yellow Color 35 | 36 | The frame is masked with yellow and white color to detect the lane lines perfectly. 37 | 38 | %--------------Define Thresholds for masking Yellow Color-------------- 39 | 40 | %----------------------Define thresholds for 'Hue'--------------------- 41 | channel1MinY = 130; 42 | channel1MaxY = 255; 43 | %------------------Define thresholds for 'Saturation'------------------ 44 | channel2MinY = 130; 45 | channel2MaxY = 255; 46 | %---------------------Define thresholds for 'Value'-------------------- 47 | channel3MinY = 0; 48 | channel3MaxY = 130; 49 | 50 | %-----------Create mask based on chosen histogram thresholds----------- 51 | Yellow=((frame(:,:,1)>=channel1MinY)|(frame(:,:,1)<=channel1MaxY))& ... 52 | (frame(:,:,2)>=channel2MinY)&(frame(:,:,2)<=channel2MaxY)&... 53 | (frame(:,:,3)>=channel3MinY)&(frame(:,:,3)<=channel3MaxY); 54 | 55 | figure('Name','Yellow Mask'), imshow(Yellow); 56 | 57 | %--------------Define Thresholds for masking White Color--------------- 58 | 59 | %----------------------Define thresholds for 'Hue'--------------------- 60 | channel1MinW = 200; 61 | channel1MaxW = 255; 62 | %------------------Define thresholds for 'Saturation'------------------ 63 | channel2MinW = 200; 64 | channel2MaxW = 255; 65 | %---------------------Define thresholds for 'Value'-------------------- 66 | channel3MinW = 200; 67 | channel3MaxW = 255; 68 | 69 | %-----------Create mask based on chosen histogram thresholds----------- 70 | White=((frame(:,:,1)>=channel1MinW)|(frame(:,:,1)<=channel1MaxW))&... 71 | (frame(:,:,2)>=channel2MinW)&(frame(:,:,2)<=channel2MaxW)& ... 72 | (frame(:,:,3)>=channel3MinW)&(frame(:,:,3)<=channel3MaxW); 73 | 74 | figure('Name','White Mask'), imshow(White); 75 | 76 | ![third_main_03](https://user-images.githubusercontent.com/31979840/36962750-cbdb6f7a-201e-11e8-9caf-125f2f7dd5ec.png) 77 | 78 | Fig 3: Yellow Mask 79 | 80 | ![third_main_04](https://user-images.githubusercontent.com/31979840/36962769-e773c6d8-201e-11e8-882e-ad4417614587.png) 81 | 82 | Fig 4: White Mask 83 | 84 | ## Edge Detection 85 | 86 | In this section, edges are obtained from the masked image and closed edges with smaller areas are neglected. 87 | 88 | frameW = edge(White, 'canny', 0.2); 89 | frameY = edge(Yellow, 'canny', 0.2); 90 | 91 | 92 | 93 | #### Neglecting closed edges in smaller areas 94 | 95 | frameY = bwareaopen(frameY,15); 96 | frameW = bwareaopen(frameW,15); 97 | 98 | figure('Name','Detecting Edges of Yellow mask'), imshow(frameY); 99 | figure('Name','Detecting Edges of White mask'), imshow(frameW); 100 | 101 | ![third_main_05](https://user-images.githubusercontent.com/31979840/36962811-0308eb08-201f-11e8-8edd-6ad85c217ed9.png) 102 | 103 | Fig 5: Detecting Edges of Yellow Mask 104 | 105 | ![third_main_06](https://user-images.githubusercontent.com/31979840/36962826-0a661a88-201f-11e8-873b-8d627e97f257.png) 106 | 107 | Fig 6: Detecting Edges of White Mask 108 | 109 | ## Extraction of Region of Interest 110 | 111 | As guided in the pipeline for the implementation of the project 1 the region of interest is extracted using the 'roipoly' function and selecting the points from the frame. 112 | 113 | #### Deciding ROI Points and Extracting ROI 114 | %--------------Deciding ROI points by plotting it on image------------- 115 | 116 | % figure(1) 117 | % imshow(frame); 118 | % [r c] = ginput(10); 119 | 120 | %---------Extracting Region of Interest from Yellow Edge Frame--------- 121 | 122 | roiY = roipoly(frameY, r, c); 123 | [R , C] = size(roiY); 124 | for i = 1:R 125 | for j = 1:C 126 | if roiY(i,j) == 1 127 | frame_roiY(i,j) = frameY(i,j); 128 | else 129 | frame_roiY(i,j) = 0; 130 | end 131 | end 132 | end 133 | 134 | figure('Name','Filtering ROI from Yellow mask'), imshow(frame_roiY); 135 | 136 | %---------Extracting Region of Interest from White Edge Frame---------- 137 | 138 | roiW = roipoly(frameW, r, c); 139 | [R , C] = size(roiW); 140 | for i = 1:R 141 | for j = 1:C 142 | if roiW(i,j) == 1 143 | frame_roiW(i,j) = frameW(i,j); 144 | else 145 | frame_roiW(i,j) = 0; 146 | end 147 | end 148 | end 149 | 150 | figure('Name','Filtering ROI from White mask'), imshow(frame_roiW); 151 | 152 | 153 | ![third_main_07](https://user-images.githubusercontent.com/31979840/36963131-0ea92c56-2020-11e8-87e5-0cfe445d8932.png) 154 | 155 | Fig 7: Filtering ROI from Yellow Mask 156 | 157 | ![third_main_08](https://user-images.githubusercontent.com/31979840/36963142-1616979e-2020-11e8-9380-66ff72860e13.png) 158 | 159 | Fig 8: Filtering ROI from White Mask 160 | 161 | ## Hough Transform 162 | In this section I have used the hough function to get the hough transfrom of the binary edge detected image, which gives us the hough values and then I have plotted the hough plot as shown in the figure below. 163 | 164 | #### Applying Hough Tansform to get straight lines from Image 165 | 166 | %----------Applying Hough Transform to White and Yellow Frames--------- 167 | 168 | [H_Y,theta_Y,rho_Y] = hough(frame_roiY); 169 | [H_W,theta_W,rho_W] = hough(frame_roiW); 170 | 171 | %--------Extracting Hough Peaks from Hough Transform of frames--------- 172 | 173 | P_Y = houghpeaks(H_Y,2,'threshold',2); 174 | P_W = houghpeaks(H_W,2,'threshold',2); 175 | 176 | %----------Plotting Hough Transform and detecting Hough Peaks---------- 177 | 178 | figure('Name','Hough Peaks for White Line') 179 | imshow(imadjust(rescale(H_W)),[],'XData',theta_W,'YData',rho_W,'InitialMagnification','fit'); 180 | xlabel('\theta (degrees)') 181 | ylabel('\rho') 182 | axis on 183 | axis normal 184 | hold on 185 | colormap(gca,hot) 186 | 187 | x = theta_W(P_W(:,2)); 188 | y = rho_W(P_W(:,1)); 189 | plot(x,y,'s','color','blue'); 190 | hold off 191 | 192 | 193 | figure('Name','Hough Peaks for Yellow Line') 194 | imshow(imadjust(rescale(H_Y)),[],'XData',theta_Y,'YData',rho_Y,'InitialMagnification','fit'); 195 | xlabel('\theta (degrees)') 196 | ylabel('\rho') 197 | axis on 198 | axis normal 199 | hold on 200 | colormap(gca,hot) 201 | 202 | x = theta_W(P_Y(:,2)); 203 | y = rho_W(P_Y(:,1)); 204 | plot(x,y,'s','color','blue'); 205 | hold off 206 | 207 | %--------------Extracting Lines from Detected Hough Peaks-------------- 208 | 209 | lines_Y = houghlines(frame_roiY,theta_Y,rho_Y,P_Y,'FillGap',3000,'MinLength',20); 210 | 211 | figure('Name','Hough Lines found in image'), imshow(frame), hold on 212 | max_len = 0; 213 | for k = 1:length(lines_Y) 214 | xy = [lines_Y(k).point1; lines_Y(k).point2]; 215 | plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green'); 216 | 217 | % Plot beginnings and ends of lines 218 | plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow'); 219 | plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red'); 220 | end 221 | 222 | 223 | lines_W = houghlines(frame_roiW,theta_W,rho_W,P_W,'FillGap',3000,'MinLength',20); 224 | 225 | max_len = 0; 226 | for k = 1:2 227 | xy = [lines_W(k).point1; lines_W(k).point2]; 228 | plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green'); 229 | 230 | % Plot beginnings and ends of lines 231 | plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow'); 232 | plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red'); 233 | end 234 | hold off 235 | 236 | ![third_main_09](https://user-images.githubusercontent.com/31979840/36963175-31075426-2020-11e8-8a91-e86800eb4910.png) 237 | 238 | Fig 9: Hough peaks found for yellow lines 239 | 240 | ![third_main_10](https://user-images.githubusercontent.com/31979840/36963178-33f75924-2020-11e8-9976-b85d9f524f4b.png) 241 | 242 | Fig 10: Hough peaks found for white lines 243 | 244 | ![third_main_11](https://user-images.githubusercontent.com/31979840/36963179-340bd430-2020-11e8-88b2-e72d95977bc3.png) 245 | 246 | Fig 11: Hough lines found in image 247 | 248 | ## Extrapolation of Lines 249 | 250 | In this section the lines that are found in hough lines are extrapolated on the main filtered image. 251 | 252 | 253 | 254 | 255 | #### Plotting best fitting line after Extrapolation 256 | %-----------------Extract start and end points of lines---------------- 257 | 258 | leftp1 = [lines_Y(1).point1; lines_Y(1).point2]; 259 | leftp2 = [lines_Y(2).point1; lines_Y(2).point2]; 260 | 261 | rightp1 = [lines_W(1).point1; lines_W(1).point2]; 262 | rightp2 = [lines_W(2).point1; lines_W(2).point2]; 263 | 264 | if leftp1(1,1) < leftp2(1,1) 265 | left_plot(1,:) = leftp1(1,:); 266 | else 267 | left_plot(1,:) = leftp2(1,:); 268 | end 269 | 270 | if leftp1(2,2) < leftp2(2,2) 271 | left_plot(2,:) = leftp1(2,:); 272 | else 273 | left_plot(2,:) = leftp2(2,:); 274 | end 275 | 276 | if rightp1(1,2) < rightp2(1,2) 277 | right_plot(1,:) = rightp1(1,:); 278 | else 279 | right_plot(1,:) = rightp2(1,:); 280 | end 281 | 282 | if rightp1(2,1) > rightp2(2,2) 283 | right_plot(2,:) = rightp1(2,:); 284 | else 285 | right_plot(2,:) = rightp2(2,:); 286 | end 287 | 288 | % right_plot = rightp1; 289 | % left_plot = leftp1; 290 | 291 | %----------------Calculate slope of left and right lines--------------- 292 | 293 | slopeL = (left_plot(2,2)-left_plot(1,2))/(left_plot(2,1)-left_plot(1,1)); 294 | slopeR = (right_plot(2,2)-right_plot(1,2))/(right_plot(2,1)-right_plot(1,1)); 295 | 296 | %------Make equations of left and right lines to extrapolate them------ 297 | 298 | xLeftY = 1; % x is on the left edge 299 | yLeftY = slopeL * (xLeftY - left_plot(1,1)) + left_plot(1,2); 300 | xRightY = 550; % x is on the reight edge. 301 | yRightY = slopeL * (xRightY - left_plot(2,1)) + left_plot(2,2); 302 | 303 | xLeftW = 750; % x is on the left edge 304 | yLeftW = slopeR * (xLeftW - right_plot(1,1)) + right_plot(1,2); 305 | xRightW = 1300; % x is on the reight edge. 306 | yRightW = slopeR * (xRightW - right_plot(2,1)) + right_plot(2,2); 307 | 308 | %------Making a transparent Trapezoid between 4 poits of 2 lines------- 309 | 310 | points = [xLeftY yLeftY; xRightY yRightY ;xLeftW yLeftW; xRightW yRightW ]; 311 | number = [1 2 3 4]; 312 | 313 | ## Turn Prediction 314 | 315 | In this section, I have predicted where to turn by looking at the vanishing point found from the extrapolated lines. 316 | 317 | %------------------Turn Prediction--------------- 318 | 319 | Yellow_dir = cross([left_plot(1,1), left_plot(1,2), 1], [left_plot(2,1), left_plot(2,2), 1]); 320 | Yellow_dir = Yellow_dir ./ sqrt(Yellow_dir(1)^2 + Yellow_dir(2)^2); 321 | theta_y = atan2(Yellow_dir(2), Yellow_dir(1)); 322 | rho_y = Yellow_dir(3); 323 | yellow_line = [cos(theta_y), sin(theta_y), rho_y]; 324 | 325 | %-------------Finding vanishing point using cross poduct--------------- 326 | white_dir = cross([right_plot(1,1),right_plot(1,2),1], [right_plot(2,1),right_plot(2,2),1]); 327 | white_dir = white_dir ./ (sqrt(white_dir(1)^2 + white_dir(2)^2)); 328 | theta_w = atan2(white_dir(2),white_dir(1)); 329 | rho_w = white_dir(3); 330 | white_line = [cos(theta_w), sin(theta_w), rho_w]; 331 | 332 | line1 = [0, 1, -left_plot(2,1)]; 333 | point_on_w_lane = cross(line1,white_line); 334 | point_on_w_lane = point_on_w_lane ./ point_on_w_lane(3); 335 | line2 = [0, 1, -left_plot(2,2)]; 336 | point_on_w_lane_2 = cross(line2,white_line); 337 | point_on_w_lane_2 = point_on_w_lane_2 ./ point_on_w_lane_2(3); 338 | 339 | vanishing_point = cross(yellow_line, white_line); 340 | vanishing_point = vanishing_point ./ vanishing_point(3); 341 | vanishing_ratio = vanishing_point(1) / size(frame, 2); 342 | 343 | if vanishing_ratio > 0.47 && vanishing_ratio < 0.49 344 | direction = 'Turn Left'; 345 | elseif vanishing_ratio >= 0.49 && vanishing_ratio <= 0.51 346 | direction = 'Go Straight'; 347 | else 348 | direction = 'Turn Right'; 349 | end 350 | 351 | #### Plotting Everything on the image 352 | 353 | %--Plot the extrapolated lines, Trapezoid and direction on each frame-- 354 | 355 | figure('Name','Final Output') 356 | imshow(frame); 357 | hold on 358 | plot([xLeftY, xRightY], [yLeftY, yRightY], 'LineWidth',8,'Color','red'); 359 | plot([xLeftW, xRightW], [yLeftW, yRightW], 'LineWidth',8,'Color','red'); 360 | text(650, 65, direction,'horizontalAlignment', 'center', 'Color','red','FontSize',20) 361 | patch('Faces', number, 'Vertices', points, 'FaceColor','green','Edgecolor','green','FaceAlpha',0.4) 362 | hold off 363 | 364 | %------------------Save each frame to the Output File------------------ 365 | writeVideo(Output_Video,getframe); 366 | end 367 | 368 | %---------------------Closing Save Video File Variable--------------------- 369 | close(Output_Video) 370 | 371 | ![third_main_12](https://user-images.githubusercontent.com/31979840/36963180-341ae542-2020-11e8-80ed-033f29750bf7.png) 372 | 373 | Fig12 : Final Image 374 | -------------------------------------------------------------------------------- /Result.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ysshah95/Lane-Detection-using-MATLAB/2a7c5c37b716d7d46335d4f4a8853596ee4f6d79/Result.mp4 --------------------------------------------------------------------------------