Concrete Crack Width Measurement

49 views (last 30 days)
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.

Accepted Answer

Image Analyst
Image Analyst on 13 Jul 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.

More Answers (2)

Image Analyst
Image Analyst on 14 Jul 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 Comments
yasmin ismail
yasmin ismail on 10 Nov 2022
Edited: yasmin ismail on 10 Nov 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 on 10 Nov 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?

Sign in to comment.


yasmin ismail
yasmin ismail on 5 Mar 2023
Edited: Image Analyst on 6 Mar 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 Comments
Image Analyst
Image Analyst on 7 Mar 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 on 7 Mar 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

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!