Determining crack length from images
18 views (last 30 days)
Show older comments
Hello all,
I have been looking at several Q/As on here about detecting cracks and measuring their lengths from images (and eventually video). I think I have a good start, but I am struggling to segment the image so I can remove unnecessary information. I have used the image segmentation tool, but the cracks are so small that it is difficult to keep them in the binary image without a lot of extra stuff.
The end goal is to measure the length of the crack from its initiation point (in this case the center of the image), and then the angle from horizontal to calculate the horizontal growth of the crack (vertical does not matter for what I am doing). I have attached a sample image and the code I have developed so far, but I was wondering if anyone had insight into how I could better segment this image and make the measurements?
If there is a good way to identify the end point and draw a line from the origin to the end of the crack that would probably be perfect.
list = dir("/MATLAB Drive/Images/");
nFiles = numel(list)-2;
tlX_left = 275;
tlY_left = 850;
tlX_right = 2050;
tlY_right = 850;
width = 1600;
height = 300;
for i = 1:nFiles
filename = fullfile(list(i+2).folder,list(i+2).name);
I = imread(filename);
[BW, maskedImage] = segmentImage(I);
BW2_left = imcrop(BW, [tlX_left tlY_left width height]);
BW2_right = imcrop(BW, [tlX_right tlY_right width height]);
imshowpair(BW2_left,BW2_right, "montage")
end
function [BW,maskedImage] = segmentImage(RGB)
%segmentImage Segment image using auto-generated code from Image Segmenter app
% Threshold image with adaptive threshold
BW = imbinarize(im2gray(RGB), 'adaptive', 'Sensitivity', 0.000000, 'ForegroundPolarity', 'bright');
% Dilate mask with default
radius = 3;
decomposition = 0;
se = strel('disk', radius, decomposition);
BW = imdilate(BW, se);
% Create masked image.
maskedImage = RGB;
maskedImage(repmat(~BW,[1 1 3])) = 0;
end
0 Comments
Answers (1)
Pratyush Swain
on 9 Feb 2024
Edited: Pratyush Swain
on 9 Feb 2024
Hi Alexander,
I can infer from the information given that there is a need for better segmentation of image in order to remove noises and small objects. One aspect where the image can be processed better is by leveraging the "bwareaopen" function.It helps to remove remove small objects from binary image.
Result after using "bwareaopen" function:
Previous Result:
After segmentation, we can apply hough transforms to image in order to detect the crack lines:
% Existing implementation
I = imread(filename);
[BW, maskedImage] = segmentImage(I);
BW2_left = imcrop(BW, [tlX_left tlY_left width height]);
BW2_right = imcrop(BW, [tlX_right tlY_right width height]);
% -------------------------
RGB_left = imcrop(I, [tlX_left tlY_left width height]);
RGB_right = imcrop(I, [tlX_right tlY_right width height]);
% Using bwareaopen to eliminate small noises
BW2_left = bwareaopen(BW2_left, 100); % Adjust the size threshold as needed
BW2_right = bwareaopen(BW2_right, 100);
figure,
imshowpair(BW2_left,BW2_right, "montage")
% Extracting Hough Lines
lines_left = HoughLines(BW2_left);
lines_right = HoughLines(BW2_right);
%Draw hough lines for BW2_left
figure, imshow(RGB_left), hold on
max_len = 0;
for k = 1:length(lines_left)
xy = [lines_left(k).point1; lines_left(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','red');
% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','green');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','green');
% Determine the endpoints of the longest line segment
len = norm(lines_left(k).point1 - lines_left(k).point2);
if ( len > max_len)
max_len = len;
xy_long = xy;
end
end
% Display max length on left hand side image
disp("max length on left side: ")
disp(max_len)
hold off
img_frame = getframe(gca);
BW2_left = img_frame.cdata;
% Draw hough lines for BW2_right
figure, imshow(RGB_right), hold on
max_len = 0;
for k = 1:length(lines_right)
xy = [lines_right(k).point1; lines_right(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','red');
% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','green');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','green');
% Determine the endpoints of the longest line segment
len = norm(lines_right(k).point1 - lines_right(k).point2);
if ( len > max_len)
max_len = len;
xy_long = xy;
end
end
% Display max length on right hand side image
disp("max length on right side: ")
disp(max_len)
hold off
img_frame = getframe(gca);
BW2_right = img_frame.cdata;
% Show final result
figure,
imshowpair(BW2_left,BW2_right, "montage")
Extracting Hough lines implementation:
function lines = HoughLines(BW)
% Canny edges
BWc = edge(BW,'canny');
[H,T,R] = hough(BWc);
% Hough Peaks
P = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
% Hough lines (parameters can be adjusted)
lines = houghlines(BW,T,R,P,'FillGap',5,'MinLength',7);
end
Final result:
These results can be improved more with better segmentation techniques and parameter tuning.
For more information on "bwareopen" function and "Hough Transforms", please refer to following links:
0 Comments
See Also
Categories
Find more on Image Processing Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!