function [ outputImg ] = isolatePlate( inputImg ) % ISOLATEPLATE Draw a box around a license plate in the input image % More info. % Params %SIZE_THRESHOLD = 60; TRUE = 1; FALSE = 0; % Show the original inputImg = im2double( inputImg ); %figure, imshow( inputImg ), title( 'Original Image' ); %%%%% Image Prep % Convert To Grayscale Using the NTSC standard red = immultiply( inputImg(:,:,1), 299 ); green = immultiply( inputImg(:,:,2), 587 ); blue = immultiply( inputImg(:,:,3), 114 ); newImg = red + green + blue; newImg = imdivide( newImg, 1000 ); % Smooth the image smoother = ones( 6, 6 ); newImg = imfilter( newImg, smoother ); newImg = imdivide( newImg, 36 ); %figure, imshow( newImg ), title( 'Grayscale Image' ); flipImg = rot90( newImg ); % create a new light gray image so we can see the boxes. lightGray = imdivide( newImg, 4 ); lightGray = imadd( lightGray, 0.749 ); % % Find the center of the red data, to find the column that the license % % plate should cross % % scaledRed = mat2gray( red ); % scaledBlue = mat2gray( blue ); % scaledGreen = mat2gray( green ); % % % threadhold the red values... % redMap = scaledRed > 0.30 & scaledGreen < 0.40 & scaledBlue < 0.40; % % se = strel( 'disk', 5 ); % redMap = imclose( redMap, se ); % % [row,column] = find( redMap ); % redColumn = sum( column ) / size( column, 1 ); % redRow = sum( row ) / size( row, 1 ); % % figure, imshow( imcomplement( redMap ) ), title( 'Red Map' ); % rectangle( 'Position', [ redColumn 1 1 size( red, 1 ) ] ); % rectangle( 'Position', [ 0 redRow size( red, 2 ) 1 ] ); %%%%% Vertical Edge Detection % Create our mask - a Sobel for vertical edge detection mask = fspecial( 'sobel' ); mask = rot90( mask, 1 ); % Do the actual detection vEdges = imfilter( newImg, mask ); hEdges = rot90( imfilter( flipImg, mask ), -1 ); vEdgesScaled = immultiply( vEdges, 0.7 ); hEdgesScaled = immultiply( hEdges, 0.3 ); edges = imadd( vEdgesScaled, hEdgesScaled ); % Show what we have so far %figure, imshow( vEdges ), title( 'Vertical Edges' ); %figure, imshow( hEdges ), title( 'Horizontal Edges' ); %figure, imshow( edges ), title( 'Edges' ); %%%%% Edge Density Map Generation % Create our mask of ones to add up the edge values %densityMask = ones( 3, 15 ); densityMask = ones( 3, 15 ); % Sum it up edgeMap = imfilter( edges, densityMask ); edgeMap = imdivide( edgeMap, 45 ); % Show what we have so far %figure, imshow( edgeMap ), title( 'Edge Map' ); %%%%% Binarization / Clean Up / Dilation % Binarize!!!! Use Otsu's Method. It's fast. level = graythresh( edgeMap ); binary = im2bw( edgeMap, level ); % Show what we have so far %figure, imshow( binary ), title( 'Binarized Edge Map' ); % Clean Up by getting rid of small horizontal lines se = strel( 'disk', 2 ); cleanImage = imopen( binary, se ); % Show what we have so far %cleanImage = binary; % skipping the clean up step...don't seem to need it %figure, imshow( cleanImage ), title( 'Cleaned Image' ); % Dilate the Image %se = ones( 1, 9 ); %se = ones( 100, 100 ); se = strel( 'disk', 13 ); dilated = imdilate( cleanImage, se ); % Show what we have so far %figure, imshow( dilated ), title( 'Dilated Image' ); %%%%% License Plate Location % find all the 8-connected regions in the dilated binary image [labeled, num] = bwlabel( dilated ); %figure, imshow( lightGray ), title( 'Original Image - All Connected Regions' ); figure, imshow( inputImg ), title( 'Original Image - All Connected Regions' ); % Feature Extraction % here we will loop through the dilated image... info = []; imgWidth = size( newImg, 2 ); imgHeight = size( newImg, 1 ); for k = 1:1:num % get the indices of one connected region (current k value for this % iteration) [row,column] = find( labeled == k ); % get the top left row&column topLeftRow = min( row ); topLeftColumn = min( column ); % BR row&column bottomRightRow = max( row ); bottomRightColumn = max( column ); % get the size of...yeah... numPixels = size( row, 1 ); % numbers! width = bottomRightColumn - topLeftColumn + 1; height = bottomRightRow - topLeftRow + 1; % Check whether the box is within another box % structure of each row: TL row, TL col, BR row, BR col, numpixels, % width, height. Note that it's 7 columns... newRow = [ topLeftRow topLeftColumn bottomRightRow bottomRightColumn numPixels width height ]; % add it to our dater structure to store it! ratio = width / height; area = width * height; % check aspect ratio if ( ratio > 1.3 & ratio < 2.35 ) % check min. size through area if ( area > 16000 ) % check max size through percent of image if ( width < 0.7 * imgWidth & height < 0.7 * imgHeight ) info = cat( 1, info, newRow ); rectangle( 'Position', [ min( column ) min( row ) width + 1 height + 1 ] ); end end end end % Combination of Candidate Regions %figure, imshow( imcomplement( inputImg ) ), title( 'Original Image - Regions To Connect' ); %figure, imshow( lightGray ), title( 'Original Image - Regions To Connect' ); densityV = []; % looop through all of the regions have tracked % for oneIndex = 1:1:size( info, 1 ) % % compare each row to the one after it, so loop over all rows after % % this one...like that handshaking problem thingy where everyone has to % % shake everyone else's hand. % for twoIndex = (oneIndex + 1):1:size( info, 1 ) % % get the two items to compare.... % oneInfo = info( oneIndex, : ); % twoInfo = info( twoIndex, : ); % % % Check whether they're overlapping % overlap = TRUE; % % % we use these cases to determine if the boxes overlap. If all of % % the points are outside, and if it's not than there is an overlap. % case1 = oneInfo( 1 ) + oneInfo( 7 ) < twoInfo( 1 ); % case2 = oneInfo( 1 ) > twoInfo( 1 ) + twoInfo( 7 ); % case3 = oneInfo( 2 ) + oneInfo( 6 ) < twoInfo( 2 ); % case4 = oneInfo( 2 ) > twoInfo( 2 ) + twoInfo( 6 ); % % % find out what we have here... % if case1 % overlap = FALSE; % elseif case2 % overlap = FALSE; % elseif case3 % overlap = FALSE; % elseif case4 % overlap = FALSE; % else % overlap = TRUE; % end % % % If they overlap, check their connected density % if overlap % % overlapping region boundaries - vertical... % topRow = min( oneInfo( 1 ), twoInfo( 1 ) ); % insideTop = max( oneInfo( 1 ), twoInfo( 1 ) ); % insideBottom = min( oneInfo( 3 ), twoInfo( 3 ) ); % bottomRow = max( oneInfo( 3 ), twoInfo( 3 ) ); % % % vertical overlap... % overlap = ( bottomRow - topRow + 1 ) - ( bottomRow - insideBottom ) - ( insideTop - topRow ); % % % find the overlapping region's boundaries...horizontal... % leftColumn = min( oneInfo( 2 ), twoInfo( 2 ) ); % insideLeft = max( oneInfo( 2 ), twoInfo( 2 ) ); % insideRight = min( oneInfo( 4 ), twoInfo( 4 ) ); % rightColumn = max( oneInfo( 4 ), twoInfo( 4 ) ); % % % horizontal overlap... % dis = ( rightColumn - leftColumn + 1 ) - ( insideLeft - leftColumn ) - ( rightColumn - insideRight ); % % % find the % minH = min( oneInfo( 7 ), twoInfo( 7 ) ); % sqr = sqrt( oneInfo( 6 ) * twoInfo( 6 ) ); % % density = ( overlap / minH ) - ( dis / sqr ); % % % thresholding for density... % if ( density > 0.7 ) % % note: we have an error here when height is 0. Height % % shouldn't be zero though :-( % r1 = rectangle( 'Position', [ oneInfo( 2 ) oneInfo( 1 ) oneInfo( 6 ) oneInfo( 7 ) ] ); % r2 = rectangle( 'Position', [ twoInfo( 2 ) twoInfo( 1 ) twoInfo( 6 ) twoInfo( 7 ) ] ); % % r1 % r2 % % r1.EraseMode = 'xor'; % r2.EraseMode = 'xor'; % % end % % % keep track of the densities... % densityV = cat( 1, densityV, density ); % end % end % end % output these values for testing... % densityV % max( densityV ) % min( densityV ) % Show what we have so far... %figure, imshow( labeled ), title( 'Regions of Binary Image' ); % create final image % final = zeros( size( inv, 1 ), size( inv, 2 ) ); % for k = 1:1:size( iregions ) % final = final | ( labeled == iregions( k ) ); % end % todo: Hough transform! % now return the processed image... outputImg = inputImg;