Filter löschen
Filter löschen

How to separate road from parking lot when they have same colour

1 Ansicht (letzte 30 Tage)
Hi, i'm a university student that is working on a image-processing project. The project is about free parking-lot detection using matlab. I'm struggling finding a solution that may be able to logically separate the road from the parking lots beacause they seem to have the same colour.
Is it possible to do it without training a neural network? If yes, how?
I have already read this link: https://it.mathworks.com/matlabcentral/answers/524849-available-free-parking-space-detection-image-analysis-algorithm that has been used as the core of the code but i modified it by creating a binary mask on matlab by myself (without using photoshop as it was done in that case) got by colour thresholding, adding a black frame and using erosion operations on the binary image.
I've attached a pdf with the testing results obtained on different parking lots and i would like to solve the "case 6" without being forced to manually draw a black rectangle in the middle to cover the road.

Akzeptierte Antwort

Image Analyst
Image Analyst am 12 Mär. 2023
Not too hard. You don't need a neural network. You can just use traditional methods. Try this (untested)
  1. Threshold (segment) the image to get the white lines only in stripeMask
  2. Use any to determine which rows have a white stripe in them. stripeRows = any(stripeMask, 2)
  3. Use false and true to get a binary image with a band across the middle that is just the road alone and has no stripes in it. roadMask = false(rows, columns); roadMask(stripeRows, :) = true; topRoadRow = find(~stripeRows, 1, 'first'); bottomRoadRow = find(~stripeRows, 1, 'last')
  4. Use any() to get columns in the upper part that do not have a white pixel in the mask. spaceMask = false(rows, columns); spaceColumns = any(mask(1:topRoadRow, :), 1)
  5. Make those columns true in the mask from line 1 down to the top of the road band across the middle. spaceMask(1:topRoadRow - 1, spaceColumns) = true
  6. Repeat Steps 4 and 5 for the bottom part of the image (below the center roadway).
If you can't figure it out, attach the image of your empty parking lot. The algorithm works only for cases where the road and parking spaces are fairly well aligned with the image, not at a big angle.
For convenience for others, I'm attaching my original demo from the link you gave.
  3 Kommentare
Image Analyst
Image Analyst am 14 Mär. 2023
Well I think you could have gotten it if you'd tried a little longer. Anyway, here's what I got:
% Optional initialization steps
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 18;
%-------------------------------------------------------------------
rgbImage = imread('empty_lot.jpg');
%[rgbImage,rect] = imcrop(rgbImage);
rgbImage = imcrop(rgbImage,[439.5 325.5 669 159]);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows, columns, numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(4, 1, 1);
imshow(rgbImage);
title('Original Color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'Outerposition', [0, 0, 1, 1]);
%-----------------------------------------------------------------------
% Extract the individual red, green, and blue color channels.
[redChannel, greenChannel, blueChannel] = imsplit(rgbImage);
%-----------------------------------------------------------------------
% Thresholding
lowThreshold = 180;
highThreshold = 255;
% Interactively and visually set a threshold on a gray scale image.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
% [lowThreshold, highThreshold] = threshold(lowThreshold, highThreshold, blueChannel);
stripeMask = (blueChannel >= lowThreshold );
% Display the image.
subplot(4, 1, 2);
imshow(stripeMask);
title('Stripe Mask', 'FontSize', fontSize);
%-----------------------------------------------------------------------
% Find the area of all the stripes so we can determine what is the minimum
% size of a valid stripe.
props = regionprops(stripeMask, 'Area');
allAreas = sort([props.Area])
% Looks like noise is less than 10 pixels and valid strips are at least 100 pixels.
% So let's throw out any blobs less than, say, 70 pixels.
stripeMask = bwareaopen(stripeMask, 70);
% Update image.
imshow(stripeMask);
title('Stripe Mask', 'FontSize', fontSize);
%-----------------------------------------------------------------------
stripeRows = any(stripeMask, 2);
% Assume two striped regions and take the 2 longest stripe regions
stripeRows = bwareafilt(stripeRows, 2);
% Create a mask for only the road running between the two striped regions.
roadMask = false(rows, columns);
roadMask(~stripeRows, :) = true;
subplot(4, 1, 3);
imshow(roadMask);
title('Road Mask', 'FontSize', fontSize);
%-----------------------------------------------------------------------
% Find the beginning and end of each stripe region.
props = regionprops(stripeRows, 'PixelList');
% First get the bottom of the top rows.
topRoadRow = max(props(1).PixelList(:, 2))
% First get the top of the bottom rows.
bottomRoadRow = min(props(2).PixelList(:, 2))
% Initialize a space mask as all true except where the road is.
spaceMask = true(rows, columns);
spaceMask(roadMask) = false;
%-----------------------------------------------------------------------
% Now let's find the stripes in the top row and whatever columns they appear in,
% let's erase from there down to the top road row.
props = regionprops(stripeMask, 'PixelList');
for k = 1 : numel(props) % For each stripe.
thisStripesPixels = props(k).PixelList;
x = thisStripesPixels(:, 1);
y = thisStripesPixels(:, 2);
column1 = min(x);
column2 = max(x);
% Erase between those columns down to topRoadRow.
if min(y) < topRoadRow
% It's a strip on the top.
spaceMask(1 : topRoadRow, column1 : column2) = false;
% That will draw lines in the top.
else
% It's a stripe on the bottom.
spaceMask(bottomRoadRow : end, column1 : column2) = false;
% That will draw lines in the bottom.
end
end
%------------------------------------------------------------------------
% Display the image.
subplot(4, 1, 4);
imshow(spaceMask); %stripeMask is fine, roadMask works, spaceMask is totally black,
axis on;
title('Space Mask', 'FontSize', fontSize);
% Let them mouse around and see the values.
hPixelInfo = impixelinfo();
% Reposition the status label.
set(hPixelInfo, 'Unit', 'Normalized', 'Position', [.81 .89 .2 .1]);
Christian Loconsole
Christian Loconsole am 14 Mär. 2023
Bearbeitet: Christian Loconsole am 14 Mär. 2023
Thank you for everything!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by