Available/free parking space detection image analysis algorithm

I'm working on a project with a jpg file attached, can you help?

5 件のコメント

Rik
Rik 2020 年 5 月 12 日
Have a read here and here. It will greatly improve your chances of getting an answer.
Mehmed Saad
Mehmed Saad 2020 年 5 月 12 日
have a look at regionprops and edge in MATLAB help
Walter Roberson
Walter Roberson 2020 年 5 月 12 日
Some other people have discussed this in the past.
Mehmed Saad
Mehmed Saad 2020 年 5 月 13 日
You cannot, at the very same time, be grateful and unhappy, or ungrateful and happy.”
Mokokoma Mokhonoana
Image Analyst
Image Analyst 2021 年 7 月 17 日
You seem to have detached your JPG image file.

サインインしてコメントする。

 採用された回答

Image Analyst
Image Analyst 2020 年 5 月 12 日

3 投票

OK, not sure how far you've gotten with my last suggestion, but I've whipped together something while I was watching a Mathworks webinar on deep learning this afternoon. You probably already have this by now, but for what it's worth, here's what I have:
% Demo to find available parking spaces. By Image Analyst, May 12, 2020.
% Requires 3 images: 'Parking Lot without Cars.jpg', 'Parking Lot with Cars.jpg', 'Parking Lot Mask.png'
% Clean up.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clearvars;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
fprintf('Beginning to run %s.m ...\n', mfilename);
%-----------------------------------------------------------------------------------------------------------------------------------
% Read in reference image with no cars (empty parking lot).
folder = pwd;
baseFileName = 'Parking Lot without Cars.jpg';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbEmptyImage = imread(fullFileName);
[rows, columns, numberOfColorChannels] = size(rgbEmptyImage);
% Display the test image full size.
subplot(2, 3, 2);
imshow(rgbEmptyImage, []);
axis('on', 'image');
caption = sprintf('Reference Image : "%s"', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
%-----------------------------------------------------------------------------------------------------------------------------------
% Read in test image (image with cars parked on the parking lot).
folder = pwd;
baseFileName = 'Parking Lot with Cars.jpg';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbTestImage = imread(fullFileName);
[rows, columns, numberOfColorChannels] = size(rgbTestImage);
% Display the original image full size.
subplot(2, 3, 1);
imshow(rgbTestImage, []);
axis('on', 'image');
caption = sprintf('Test Image : "%s"', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Set up figure properties:
% Enlarge figure to full screen.
hFig1 = gcf;
hFig1.Units = 'Normalized';
hFig1.WindowState = 'maximized';
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
hFig1.Name = 'Demo by Image Analyst';
%-----------------------------------------------------------------------------------------------------------------------------------
% Read in mask image that defines where the spaces are.
folder = pwd;
baseFileName = 'Parking Lot Mask.png';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
maskImage = imread(fullFileName);
[rows, columns, numberOfColorChannels] = size(maskImage);
% Create a binary mask from seeing where the min value is 255.
mask = min(maskImage, [], 3) == 255;
% Display the test image full size.
subplot(2, 3, 3);
imshow(mask, []);
axis('on', 'image');
caption = sprintf('Mask Image : "%s"', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
%-----------------------------------------------------------------------------------------------------------------------------------
% Find the cars.
% First, get the absolute difference image.
diffImage = imabsdiff(rgbEmptyImage, rgbTestImage);
% Display the gray scale image.
subplot(2, 3, 4);
imshow(diffImage, []);
axis('on', 'image');
caption = sprintf('Difference Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Convert to gray scale and mask it with the spaces mask.
diffImage = rgb2gray(diffImage);
diffImage(~mask) = 0;
% Get a histogram of the image so we can see where to threshold it at.
subplot(2, 3, 5);
histogram(diffImage(diffImage>0));
% Display the gray scale image.
imshow(diffImage, []);
axis('on', 'image');
caption = sprintf('Gray Scale Difference Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Threshold the image to find pixels that are substantially different from the background.
kThreshold = 40; % Determined by examining the histogram.
parkedCars = diffImage > kThreshold;
% Fill holes.
parkedCars = imfill(parkedCars, 'holes');
% Get convex hull.
parkedCars = bwconvhull(parkedCars, 'objects');
% Display the mask image.
subplot(2, 3, 6);
imshow(parkedCars, []);
impixelinfo;
axis('on', 'image');
caption = sprintf('Parked Cars Binary Image with Threshold = %.1f', kThreshold);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
%-----------------------------------------------------------------------------------------------------------------------------------
% Measure the percentage of white pixels within each rectangular mask.
props = regionprops(mask, parkedCars, 'MeanIntensity', 'Centroid', 'BoundingBox');
centroids = vertcat(props.Centroid);
%-----------------------------------------------------------------------------------------------------------------------------------
% Optional sorting by row with kmeans. Only appropriate for parking lot with rectangular grid aligned with image edges.
% Sort y centroids
numRows = 4; % There are 4 rows in the parking lot to park in.
[indexesY, clusterCenterY] = kmeans(centroids(:, 2), numRows);
% Put lines across at the y centroids of the spaces in the mask rows.
for k = 1 : numRows
yline(clusterCenterY(k), 'Color', 'g', 'LineWidth', 2);
end
% Put yellow bounding boxes for each space (whether taken or available).
for k = 1 : length(props)
rectangle('Position', props(k).BoundingBox, 'EdgeColor', 'y');
end
% Now the clusters are not necessarily sorted with cluster 1 at the top, cluster 2 right below it, cluster 3 below that, and cluster 4 at the bottom.
% So we need to sort the clusters by the y value of the cluster center.
[~, sortOrder] = sort(clusterCenterY, 'ascend');
% Now sort the indexes and we will have them going from top to bottom.
originalIndexes = indexesY; % Save a copy so we can compare to make sure it did it correctly.
fprintf('\nOriginal Class Number New Class #\n');
for k = 1 : length(indexesY)
currentClass = indexesY(k);
newClass = find(sortOrder == currentClass);
fprintf(' %d %d\n', newClass, currentClass);
indexesY(k) = newClass;
% text(centroids(k, 1), centroids(k, 2)-15, num2str(currentClass), 'Color', 'r');
% text(centroids(k, 1), centroids(k, 2)+15, num2str(newClass), 'Color', 'g');
end
% comparedLabels = [originalIndexes(:), indexesY(:)];
newLabels = 1 : length(props); % Look up table so we can map the original index to a new sorted index.
pointer = 0;
for k = 1 : numRows
% For this class (row of parking), get the elements of props that are in this row (y value).
thisClass = find(indexesY == k);
% The x centroid values are already sorted from left to right so we're ok there - no need to sort.
newLabels((pointer + 1) : (pointer + length(thisClass))) = thisClass;
pointer = pointer + length(thisClass);
end
% Now that we have the new sort order, apply it.
props = props(newLabels);
% Re-extract these vectors with the new order.
percentageFilled = [props.MeanIntensity]
centroids = vertcat(props.Centroid);
%-----------------------------------------------------------------------------------------------------------------------------------
%-----------------------------------------------------------------------------------------------------------------------------------
% Place a red x on the image if the space is filled, and a green circle if the space is available to be parked on (it's empty).
% Go through each rectangle and say whether it's filled with a car or not.
% We'll say it's filled if 10% of the pixels are filled.
hFig2 = figure;
imshow(rgbTestImage);
hFig2.WindowState = 'maximized';
% Give a name to the title bar.
hFig2.Name = 'Demo by ImageAnalyst';
hold on;
for k = 1 : length(props)
x = centroids(k, 1);
y = centroids(k, 2);
blobLabel = sprintf('%d', k);
if percentageFilled(k) > 0.10
% It has a car in that rectangle.
plot(x, y, 'rx', 'MarkerSize', 30, 'LineWidth', 4);
% Put up the blob label.
text(x, y+20, blobLabel, 'Color', 'r', 'FontSize', 15, 'FontWeight', 'bold');
else
% No car is parked there. The space is available.
plot(x, y, 'g.', 'MarkerSize', 40, 'LineWidth', 4);
% Put up the blob label.
text(x, y+20, blobLabel, 'Color', 'g', 'FontSize', 15, 'FontWeight', 'bold');
end
end
title('Marked Spaces. Green Spot = Available. Red X = Taken.', 'FontSize', fontSize);
fprintf('Done running %s.m ...\n', mfilename);

12 件のコメント

Image Analyst
Image Analyst 2020 年 5 月 28 日
I manually painted/created it in Photoshop based on the original image.
Chaitra B P
Chaitra B P 2021 年 7 月 16 日
編集済み: Chaitra B P 2021 年 7 月 16 日
But if i implement this then it is showing error that parking lot without car.jpg is does not exist in the search path folder
what should be done?
Rik
Rik 2021 年 7 月 16 日
Then you didn't actually implement it. How can you call what you did implementing if you didn't have the two required images? This code doesn't magically know where there are cars, it uses the three images that were attached. You need to recreate them for your situation.
Chaitra B P
Chaitra B P 2021 年 7 月 16 日
編集済み: Chaitra B P 2021 年 7 月 16 日
I just copy pasted in the matlab, then it showed me the warning as the above mentioned and I didnt get the output
Chaitra B P
Chaitra B P 2021 年 7 月 16 日
編集済み: Image Analyst 2021 年 7 月 17 日
@Rik, yes, I got the output now.
Thank You
Ahmed Al-Zamily
Ahmed Al-Zamily 2021 年 10 月 15 日
Hello bro, when i run this program. It doesn't work I don't know what the problem !! .. can you help me ?
Rik
Rik 2021 年 10 月 15 日
編集済み: Rik 2021 年 10 月 15 日
@Ahmed Al-Zamily You are using R2017a, which didn't have the WindowState parameter (that option was introduced in R2018a). You can use my maximize function instead to maximize your figure window.
%Replace this:
hFig1.WindowState = 'maximized';
hFig2.WindowState = 'maximized';
%With this:
maximize(hFig1)
maximize(hFig2)
Ahmed Al-Zamily
Ahmed Al-Zamily 2021 年 10 月 15 日
@Rik if i update to 2021 is it this problems will solved ?
Rik
Rik 2021 年 10 月 15 日
If you don't want to do this small edit, yes. You will need R2018a or newer.
I haven't tested this code myself, but I see no reason why it wouldn't work on R2021a or R2021b.
Ahmed Al-Zamily
Ahmed Al-Zamily 2021 年 10 月 15 日
@Rik when I edit the code. Now This problem appeared.
M2017a
Rik
Rik 2021 年 10 月 15 日
You should be able to read the documentation for the yline function in the newest release here. You can reproduce the same effect with a call to line (if you prefer plot you will need to use hold('on') as well). You will need to provide the x-limits yourself (the xlim function will come in handy). the main difference is that yline will respond to changes to your x-limits, while a line object will not.
Whenever you get such an error this is the strategy. Try to find it in the documentation for the latest release to see what it does, then find out how you can achieve the same results in your release.
Sudhish
Sudhish 2024 年 11 月 23 日
@Rik is there any other similar dataset which takes images as a drone view because any other view point will make the code less efficent as I ve realised after researching and understanding it, or if you could send me more images that ll really help me out.
Thank You

サインインしてコメントする。

その他の回答 (2 件)

Image Analyst
Image Analyst 2020 年 5 月 12 日

0 投票

Look up the prior posts like Walter suggested. One way might be to have a template setup (like a binary image mask with a bunch of rectangles). Then you have one image for a completely empty lot, measure the MeanIntensity with regionprops() for each space. Then do the same with your test image and see if the mean intensities are significantly different enough. You could also subtract the background from the test image and see how many blobs there are and if any blob centroid is contained within a template rectangle.
MUHAMMAD BILAL
MUHAMMAD BILAL 2021 年 11 月 24 日

0 投票

So this code only works for the 3 images you attached? I need to run this code on three differnent images other than this. Can anyone provide me 3 images other than attached ones.

11 件のコメント

Image Analyst
Image Analyst 2021 年 11 月 24 日
Who cares what images other people have? The only ones that matter are the ones for your parking lot. So just use them and make templates from them. My code should then work if you have the right template image.
MUHAMMAD BILAL
MUHAMMAD BILAL 2021 年 11 月 25 日
Glad you replied. Sir can u suggest me some code for masking like the one you used for your image.
Walter Roberson
Walter Roberson 2021 年 11 月 25 日
What difficulty did you encounter using the code he already posted, just changing the file names?
MUHAMMAD BILAL
MUHAMMAD BILAL 2021 年 11 月 25 日
He is using test images. He applied masking in one of the image. I just want to know about masking he applied?
Walter Roberson
Walter Roberson 2021 年 11 月 25 日
What about the masking do you want to know, or what about the masking is failing for you?
He is not computing the mask image. He (someone) went out and took a picture when there were no cars, and that is the mask image.
Cars block out the floor, so the code looks for places that do not look like the image with no cars, and which are sufficiently large to be interesting. That code is going to stay the same even if you have a completely different garage layout.
Image Analyst
Image Analyst 2021 年 11 月 25 日
Honestly I just used a photo-editing program (Photoshop) to paint white wherever there was a parking space, and black wherever it was not a space. That was easiest for me. You can write a program to do it in MATLAB if you want (using drawpolygon and poly2mask) but a paint program is easier.
MUHAMMAD BILAL
MUHAMMAD BILAL 2021 年 11 月 25 日
Great. Thanks for your time and responding back to me. Actually i am using your code for my project. But project require 2 set of images. I have used the one's you attached. I am looking for 3 more images like yours. Thanks again.
Image Analyst
Image Analyst 2021 年 11 月 25 日
Just do a Google image search for "parking lot overhead", or something like that, to get similar images.
MUHAMMAD BILAL
MUHAMMAD BILAL 2021 年 11 月 25 日
Thanks for your time sir.
Sudhish
Sudhish 2024 年 11 月 23 日
hey did you get a dataset for this? @MUHAMMAD BILAL
Image Analyst
Image Analyst 2024 年 11 月 23 日
I'm presuming if it's really his project, that he has a camera looking down on the parking lot that he wants to inspect, and snaps photos several times a day. Isn't that what you have, @Sudhish. If not, and it's some class project, then the class should provide you with a set of input images. Or else collect them yourself.

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeConvert Image Type についてさらに検索

製品

リリース

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by