MATLAB: Count and measure lines in Image of porous media

digital image processingimageMATLAB

Hi,
my goal is to count and measure (length, position in the image) the black thin lines in the attached image. I tried already several appoaches, the most promising was with the hough transformation (see attached code), but still not good enough.
Had anybody a simililar problem or an idea how to solve the task?
Thanks a lot!
clear variables
close all
%Read Iimage
I = imread('Find_gaps.PNG');
%binarize image
BW = im2bw(I);
%get edges
BW = edge(BW,'canny');
figure, imshow(BW)
%Hough transformation and find peaks
[H,theta,rho] = hough(BW);
figure
imshow(imadjust(rescale(H)),[],...
'XData',theta,...
'YData',rho,...
'InitialMagnification','fit');
xlabel('\theta (degrees)')
ylabel('\rho')
axis on
axis normal
hold on
colormap(gca,hot)
P = houghpeaks(H,20,'threshold',ceil(0.3*max(H(:))));
x = theta(P(:,2));
y = rho(P(:,1));
plot(x,y,'s','color','black');
lines = houghlines(BW,theta,rho,P,'FillGap',5,'MinLength',10);
%Plot
figure, imshow(I), hold on
max_len = 0;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
% Determine the endpoints of the longest line segment
len = norm(lines(k).point1 - lines(k).point2);
if ( len > max_len)
max_len = len;
xy_long = xy;
end
end
% highlight the longest line segment
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','red');
Find_gaps.PNG

Best Answer

Have you tried doing a closing on the image with imclose(), and then use xor() to find the difference, then use regionprops to count the lines and get their length?
Not sure how good a job your algorithm did. It would have been nice if you had plotted the lines over the image in red so we could see.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
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;
% Check that user has the Image Processing Toolbox installed.
hasIPT = license('test', 'image_toolbox');
if ~hasIPT
% User does not have the toolbox installed.
message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');
reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');
if strcmpi(reply, 'No')
% User said No, so exit.
return;
end
end
%===============================================================================
% Read in a demo image.
folder = pwd; %fileparts(which('peppers.png')); % Determine where demo folder is (works with all versions).
baseFileName = 'find_gaps.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
fprintf('This image is RGB. I will change it to binary.\n');
grayImage = grayImage(:, :, 2);
end
% Make it binary
binaryImage = grayImage > 128;
clear('grayImage');
% Display the original image.

subplot(2, 2, 1);
imshow(binaryImage);
axis('on', 'image');
title('Binary Image', 'FontSize', fontSize);
impixelinfo;
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'Outerposition', [0, 0.1, 1, 0.9]);
% Do a closing on it
se = true(3);
binaryImage2 = imclose(binaryImage, se);
% Display it.

subplot(2, 2, 2);
imshow(binaryImage2, []);
axis('on', 'image');
title('Closing', 'FontSize', fontSize);
% Now do an xor
binaryImage2 = xor(binaryImage, binaryImage2);
% Label each individual blob.
[labeledImage, numRegions] = bwlabel(binaryImage2);
% Let's assign each blob a different color to visually show the user the distinct blobs.
coloredLabels = label2rgb (labeledImage, 'hsv', 'k', 'shuffle'); % pseudo random color labels
% Display it.
subplot(2, 2, 3);
imshow(coloredLabels, []);
axis('on', 'image');
caption = sprintf('XOR Found %d Lines', numRegions);
title(caption, 'FontSize', fontSize);
props = regionprops(labeledImage, 'Area', 'Centroid');
% Sort in order of decreasing area.
[allAreas, sortOrder] = sort([props.Area], 'Descend');
% Sort props the same way.
props = props(sortOrder);
% Display the original image.
subplot(2, 2, 4);
imshow(binaryImage);
axis('on', 'image');
title('Line Centroids Marked with *', 'FontSize', fontSize);
hold on;
% Display centroids over each line.
for k = 1 : length(props)
x = props(k).Centroid(1);
y = props(k).Centroid(2);
plot(x, y, 'r*', 'MarkerSize', 15, 'LineWidth', 2);
fprintf('Blob #%d is at (%.1f, %.1f) and has length %d.\n', ...
k, x, y, allAreas(k));
end
0001 Screenshot.png