Concrete Crack Width Measurement

34 visualizaciones (últimos 30 días)
Ilgin Sandalci
Ilgin Sandalci el 12 de Jul. de 2020
Comentada: Image Analyst el 21 de Mayo de 2024
Hi,
I have many images of cracked concrete samples. I have to calculate the average widths of cracks. My supervisor suggested me to use ImageJ for this issue. However I have never used imageJ before. I will be really appreciate if anyone help me and offer me a method and so on. Thanks in advance.
Also I attached the image of cracked concrete sample.

Respuesta aceptada

Image Analyst
Image Analyst el 13 de Jul. de 2020
See my Image Segmentation Tutorial. My File Exchange
What I might do is to use bwskel() to get the length of the crack. Then use regionprops() to get the area. Then divide the two to get the mean width. Also search the forum for cracks - it's been seen here several times before.

Más respuestas (3)

Image Analyst
Image Analyst el 14 de Jul. de 2020
Ilgin, your last post does not exactly scream "I know I can do this!" So I'm giving you a start with this little snippet:
% Code to detect dark cracks in a concrete image and compute the average width of the cracks.
% By Image Analyst
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 = 22;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'concrete.jpeg';
% Get the full filename, with path prepended.
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
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
% grayImage = rgb2gray(grayImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
grayImage = grayImage(:, :, 1); % Take red channel.
end
% Crop it to the right lines.
% grayImage = grayImage(1750:2250, 800:end);
subplot(2, 2, 1);
imshow(grayImage, []);
impixelinfo;
title('Red Channel Image', 'FontSize', fontSize, 'Interpreter', 'None');
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
subplot(2, 2, 2);
imhist(grayImage);
grid on;
title('Histogram of Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Do a morphological opening filter
se = strel('disk', 9, 0);
filteredImage = imopen(grayImage, se);
subplot(2, 2, 3);
imshow(filteredImage);
impixelinfo;
title('Opened Image', 'FontSize', fontSize, 'Interpreter', 'None');
subplot(2, 2, 2);
imhist(filteredImage);
grid on;
title('Histogram of Morphologically Opened Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION OF IMAGE
% Get a binary image by interactively thresholding using the function at
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image
% 60 seems good for this image.
lowThreshold = 0;
highThreshold = 60;
% [lowThreshold, highThreshold] = threshold(lowThreshold, highThreshold, filteredImage)
mask = filteredImage > lowThreshold & filteredImage < highThreshold;
mask = imfill(mask, 'holes');
minAcceptableArea = 10000;
mask = bwareafilt(mask, [minAcceptableArea, inf]);
subplot(2, 2, 4);
imshow(mask, []);
impixelinfo;
caption = sprintf('Binary Image of Cracks larger than %d', minAcceptableArea);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
% Measure the areas
props = regionprops(mask, 'Area');
allAreas = [props.Area]
out = bwferet(mask)
averageLengths = sort(allAreas ./ out.MaxDiameter, 'descend')
message = sprintf('The average width = %.2f pixels.', averageLengths(1));
fprintf('%s\n', message);
caption = sprintf('Binary Image of Cracks larger than %d\nAverage width of largest = %.2f pixels', minAcceptableArea, averageLengths(1));
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
uiwait(helpdlg(message));
  15 comentarios
yasmin ismail
yasmin ismail el 10 de Nov. de 2022
Editada: yasmin ismail el 10 de Nov. de 2022
and can you explain the following
props = regionprops(mask, 'Area'); this one to return area measurment
allAreas = [props.Area]; this one not clear
out = bwferet(mask) this also not clear
Image Analyst
Image Analyst el 10 de Nov. de 2022
@yasmin ismail I explained the bwareafilt in my last comment.
bwferet is explained in the help but it is basically the caliper width of blobs.
props is a structure and putting brackets around one of the fields is a shortcut way to extract and concatenate all the structure fields, from each structure in the structure array, into a 1-D list of all the numbers.
regionprops is the main function in the Image Processing Toolbox to make various measurements on the segmented (binary/logical) mask image.
Have you gone through my Image Segmentation Tutorial?

Iniciar sesión para comentar.


yasmin ismail
yasmin ismail el 5 de Mzo. de 2023
Editada: Image Analyst el 6 de Mzo. de 2023
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 = 10;
% Read in image and convert to gray scale.
rgbImage = imread('7002-9.jpg');
I = rgb2gray(rgbImage);
subplot(2,2,1);
imshow(I);
title('7001-21');
% Take histogram.
subplot(2,2,2);
histogram(I);
grid on; %to make grid line
title('histogram Gray image');
% Binarize image.
threshold = 145;
xline(threshold, 'Color', 'r', 'LineWidth',2)
mask=I < threshold;
mask = imfill(mask, 'holes');
% Filter image.
se=strel('sphere',1);
filteredImage = imopen(mask, se);
subplot(2, 2, 3);
imshow(filteredImage);
title('Opened Image');
%%% Measure the areas to determin minAcceptableArea show the histogram of
%%% area
% props = regionprops(filteredImage, 'Area');
% allAreas = sort([props.Area], 'descend');
% histogram(allAreas)
%%Look at the histogram. What area do you think is the minimum size to be a valid crack?
minAcceptableArea = 20;
mask = bwareafilt(filteredImage, [minAcceptableArea, inf]);
subplot(2, 2, 4);
imshow(mask);
%
% % Measure size of crack.
props = regionprops(mask, 'Area');
allAreas = [props.Area];
out=bwferet(mask)
% Measure the areas to know the area not to be considered
% props = regionprops(mask, 'Area');
% allAreas = sort([props.Area], 'descend')
% Get width = area / maximum length
averageWidths = sort(allAreas ./ out.MaxDiameter, 'descend');
message = sprintf('The average width = %.2f pixels.', averageWidths(1));
fprintf('%s\n', message);
caption = sprintf('Binary Image of Cracks larger than %d\nAverage width of largest = %.2f pixels', minAcceptableArea, averageWidths(1));
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
uiwait(helpdlg(message));
I got the answer of crack width as shown in attachment. My question is, as you see after filteration, there are discontinuous lines of cracks. How can I connect between them to be continuous?
  9 comentarios
Image Analyst
Image Analyst el 7 de Mzo. de 2023
@yasmin ismail, so we don't keep bothering @Ilgin Sandalci with emails on your problem, please start your own discussion thread and I'll help you there when I get more time.
yasmin ismail
yasmin ismail el 7 de Mzo. de 2023
I am very sorry @llgin Sandalci I didnt know that my questions are sending to him
and I have already post my questions in new discussion.
Hope @Image Analyst have time to answer them
Sorry again

Iniciar sesión para comentar.


Joey
Joey el 21 de Mayo de 2024
The comments on using MATLAB to measure crack widths in concrete is interesting! The approach of using image processing techniques to analyze crack pixels is innovative. It seems like a potentially efficient way to quantify crack size in concrete samples.
The discussion mentions a minimum acceptable area for cracks being filtered out (minAcceptableArea = 10000). Is there a specific reason for choosing this threshold value?
  1 comentario
Image Analyst
Image Analyst el 21 de Mayo de 2024
You can pick whatever size you want. Some cracks are just too minor to worry about fixing/patching so might as well ignore them and just concentrate on the larger ones.
Several companies and universities (Texas) have built vehicles to scan roadways as they drive along and analyze the road underneath them.

Iniciar sesión para comentar.

Community Treasure Hunt

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

Start Hunting!

Translated by