Kmeans clustering to detect pothole

10 views (last 30 days)
Hi All.
How to segment the picture to get pothole using K means clustering. can you share the code and step to do it.
What im doing right now is resize it to 300x300 then convert it to grayscale and Gaussian noise filteration.Thank you
%%image acquisition
Im= imread('69.jpg');
a=imresize(Im,[300 300])
%% RGB to Grayscale
b = rgb2gray(a);
subplot(221);
imshow(b)
impixelinfo
%%Gaussian filter
c= imnoise (b,'gaussian',0.01,0.003);
subplot(222)
imshow(c)
impixelinfo
%%Image Segmentation (Canny_edge))
BW = c > 160;
BW = imclearborder(BW);
BW = bwpropfilt(BW, 'Area',[2500, 20000]);
se = strel('sphere',5);
BW = imdilate(BW,se);
subplot (224)
imshow(BW)
% BW: Circles and long keyhole shaped cavity
% ~BW: Background
%% bounding box
labeledImage = bwlabel(BW);
measurements = regionprops(labeledImage, 'BoundingBox', 'Area');
for k = 1 : length(measurements)
thisBB = measurements(k).BoundingBox;
rectangle('Position', [thisBB(1),thisBB(2),thisBB(3),thisBB(4)],...
'EdgeColor','r','LineWidth',2 )
end
subplot (223)
imshow(labeledImage)

Accepted Answer

KALYAN ACHARJYA
KALYAN ACHARJYA on 15 May 2023
Edited: KALYAN ACHARJYA on 15 May 2023
Please change the k number of segments, which works best in your case.
I= imread('image_pathhole.jpeg');
k=3;
[L,Centers] = imsegkmeans(I,k);
result= labeloverlay(Im,L);
imshow(result); title("Labeled Image")
# By Changing the minimum area size-
BW = bwpropfilt(BW, 'Area',[100, 20000]);
In segmentation, achieving acceptable correct results based on trying in multiple ways, which is most appropriate in the case. In some cases simple methods have more impressive results.

More Answers (3)

Walter Roberson
Walter Roberson on 15 May 2023
Edited: Walter Roberson on 15 May 2023
In order to do kmeans clustering, you need a 2D array of information about characteristics for each location you are clustering. Each location being clustered needs to have its own row in the array.
In classic examples such as the Fisher Iris dataset, the information reflects different physical characteristics such as the width of the petals. The Fisher Iris dataset does not include any information about where geographically any particular sample was collected -- so generally speaking it is not always necessary to include position information.
When it comes to images, it is common that the only information you have for a pixel is the row number, column number, and either grayscale or R G B components. In some cases such as determining the dominent coloring, the position within the image is irrelevant (the same colors would be dominent if you were to sort the pixels somehow.) In such a case you would just include the color information with no position information.
In a case such as yours, if the task were to determine potholes filled with water instead of potholes then it could help a lot if you had a multispectral image with an infrared channel.
But you haven't defined "pothole". What is a "pothole" for this purpose? If there were a single isolated wet pixel, would that constitute a "pothole" by itself? Or is there a minimum physical size of adjacent pixels to determine a pothole? If there were a long narrow crack in the road, could that be considered a pothole, or is there a minimum length and width to be considered a pothole ? If there is a dry dent in the road, should that be considered a pothole?
If geography does not matter, if you can determine potholes on a pixel-by-pixel basis without reference to adjacent pixels, then you will need to construct an information array that includes, for every pixel, the x and y coordinates of the pixel, as well as any intensity information you have available for the pixel -- it might help to use RGB instead of grayscale. For example,
[r, c, s] = find(b); %where b is your grayscale image
data = [r, c, s];
[idx, centers] = kmeans(data, NUMBER_OF_CLUSTERS);
Frankly, the results should be expected to be crud. Chances are high that you want to determine "pothole" by some kind of region information, such as by searching for objects with particular aspect ratios.

DGM
DGM on 15 May 2023
Edited: DGM on 15 May 2023
I don't know why you'd use kmeans to do this. The absolute color of any pixel doesn't really tell you much about whether it belongs to a pothole. You might be able to use local contrast information to find the holes, but something tells me you already know this.
inpictrgb = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1383684/image.jpeg');
inpict = im2gray(inpictrgb);
% get rough mask
G = imgradient(inpict);
mk = G < 70; % find smooth regions
% clean up the rough mask
se = strel('rectangle',[5 11]);
mk = imopen(mk,se);
mk = imclose(mk,se);
mk = bwpropfilt(mk,'orientation',[-10 10]);
mk = bwareaopen(mk,1000);
imshow(mk,'border','tight')

Image Analyst
Image Analyst on 15 May 2023
@Muhammad Zulkifli I agree with DGM and Walter's answers above, with the caveat that it will work only with potholes filled with water that has uniform color inside. In other words, probably just for that one image and would not be robust in general for other images. For example if the potholes are dry/empty, this approach (looking for smooth uniformly colored regions) would not work.
Really the only robust (or more robust) approach (to work with water-filled or empty potholes) would be if you somehow had topographic (height) data. Even then, if hte road wasn't flat with fairly large depressions, but was just overall very lumpy/bumpy, then defining what a pothole even is becomes very tricky or arbitrary.
But if this is not a real world problem, but just some practice or homework problem for a class and all you have are images that look very similar to this one, then the above 3 approaches may work. Just don't expect to go to your Department of Transportation for a pothole detection proposal to sell road-scanning vehicles with such a simple algorithm.

Community Treasure Hunt

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

Start Hunting!