How to detect the crack and calculate its length ?
68 次查看(过去 30 天)
显示 更早的评论
This is my crack concrete image :
I've been trying to create the code, shown below
clear
clc
close all
img = imread('beton1.jpg');
BW=rgb2gray(img);
p = edge(BW, 'sobel');
binaryImage = bwmorph(p,'skel','inf');
measurements = regionprops(binaryImage, 'Area');
totalCrackLength = sum(binaryImage(:));
figure(1);
imshow(img);
figure(2);
imshow(p);
figure(3);
imshow(binaryImage);
And this is the result :
The result comes with so much noise and i cannot see the result of length measurement. I thought it will comes up with skeleton line and show the length beneath of the line.
The question is,
- How to reduce the noise and focus on the crack to make a better result ?
- How to measure the length of the crack ?
- How to see the result of the measurement ? Is it comes with same windows figure or it comes separated ?
0 个评论
回答(2 个)
Image Analyst
2020-9-14
Try bwskel(). Here is a full demo. Adapt as needed.
% This demo computes the tortuosity and average width of a snake-like shape by dividing the actual longest spine distance by the straight line distance between the endpoints.
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 = 15;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'tortuosity.png';
% 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);
end
% Display the image.
hFig = figure;
subplot(1, 4, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION
% Binarize the image
binaryImage = imbinarize(grayImage);
% Fill holes, if any.
binaryImage = imfill(binaryImage, 'holes');
% Take the largest blob only.
binaryImage = bwareafilt(binaryImage, 1);
% Display the binary image.
subplot(1, 4, 1);
cla;
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
%--------------------------------------------------------------------------------------------------------
% SKELETONIZATION
% Now skeletonize
skelImage = bwskel(binaryImage, 'MinBranchLength', 10); % First guess. Strangely bwskel() doesn't seem to have any short spurs, no matter what MinBranchLength is.
% skelImage = bwmorph(binaryImage, 'skel', inf); % First guess. Will have short spurs. Shouldn't use this, but going to just for the demo.
% Display the original skeleton image, with annoying spurs
subplot(1, 4, 2);
imshow(skelImage, []);
title('Original Skeleton Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
% First get the area of the skeleton and take half of it to get the MinBranchLength.
% This should give use the longest spine path only, and get rid of all spurs (at least for THIS demo image).
MinBranchLength = round(sum(skelImage(:))/2)
% Now take the skeleton again using that min branch length we just computed.
skelImage = bwskel(binaryImage, 'MinBranchLength', MinBranchLength);
% Display the skeleton image.
subplot(1, 4, 3);
imshow(skelImage, []);
title('Skeleton Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
% Overlay the skeleton on the original image.
subplot(1, 4, 1);
imshow(imoverlay(binaryImage, skelImage, 'r'));
title('Binary Image with Skeleton Overlaid', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% TORTUOSITY COMPUTATION
% Find the endpoints
endpointImage = bwmorph(skelImage, 'endpoints');
[rows, columns] = find(endpointImage)
% Draw a red line between them.
subplot(1, 4, 3);
hold on;
plot(columns, rows, 'r-', 'LineWidth', 2);
% Find the spine length.
% (Would be more accurate to find the spine length by traversing it.)
spineLength = sum(skelImage(:))
% Compute the straight line distance.
straightLineDistance = sqrt((columns(2) - columns(1))^2 + (rows(2) - rows(1))^2)
% Compute the tortuosity
tortuosity = spineLength / straightLineDistance
caption = sprintf('Skeleton Image. Tortuosity = %f', tortuosity);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% AVERAGE WIDTH COMPUTATION
% Compute the Euclidean Distance Transform
edtImage = bwdist(~binaryImage);
subplot(1, 4, 4);
imshow(edtImage, []);
title('Distance Transform', 'FontSize', fontSize, 'Interpreter', 'None');
% Extract the distances only along the skeleton image to extract only radii along spine.
radii = edtImage(skelImage);
% These are the half widths. Multiply by 2 to get the full widths.
averageWidth = 2 * mean(radii)
caption = sprintf('Distance Transform. Mean Width = %.1f', averageWidth);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
2 个评论
Aniq Anuar
2022-1-26
what is the meaning of the minbranchlength? is it possible if we use it to detect defect cracks on the bearing?
KALYAN ACHARJYA
2020-9-14
编辑:KALYAN ACHARJYA
2020-9-14
[S T]=graythresh(grayImage);
bwImage=imbinarize(grayImage,T);
SE = strel('diamond',1)
bwImage=imerode(bwImage,SE);
bwImage=bwareafilt(~bwImage,1);
bwImage=imdilate(~bwImage,SE);
imshow(bwImage);
2 个评论
KALYAN ACHARJYA
2020-9-14
编辑:KALYAN ACHARJYA
2020-9-14
1. How to reduce the noise and focus on the crack to make a better result ?
Done
2.How to measure the length of the crack ?
Are you asking ecudian distance between start crack point and end point? Please note it gives the shortest path.
More: pdist2
%% Distance Part
boundaries=bwboundaries(~bwImage);
dist=pdist2(cell2mat(boundaries),cell2mat(boundaries));
max_dist=max(dist(:))
% Important Note: #Please Verify
3.How to see the result of the measurement ? Is it comes with same windows figure or it comes separated ?
Sorry, the question is not clear for me, please modify.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!