Extract the center of the coarse curve of binary image
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I want to extract the center of a series of curves, as shown in the figure below, which looks roughly like the red line in the figure
0 commentaires
Réponse acceptée
Image Analyst
le 25 Déc 2020
Try inverting the binary image and then using bwskel(). Demo attached.
3 commentaires
Image Analyst
le 28 Déc 2020
Here's an attempt at it. Continue to refine it (because I can't spend the time to do the whole thing for you).
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;
fprintf('Beginning to run %s.m ...\n', mfilename);
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'fingerprint.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(4, 1, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% Crop the image out of the screenshot
grayImage = grayImage(85:378, 9:1088);
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION
% Binarize the image
binaryImage = grayImage < 128;
% Display the binary image.
subplot(4, 1, 2);
cla;
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
%--------------------------------------------------------------------------------------------------------
% Label the image so we can process each ride individually.
[labeledImage, numRegions] = bwlabel(binaryImage);
for k = 1 : numRegions
fprintf('Processing ridge #%d of %d\n', k, numRegions);
% Get this ridge
thisRidge = ismember(labeledImage, k);
%--------------------------------------------------------------------------------------------------------
% SKELETONIZATION
% Now skeletonize
skelImage = bwskel(thisRidge, '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(4, 1, 3);
imshow(skelImage, []);
title('Original Skeleton Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
drawnow;
% 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(thisRidge, 'MinBranchLength', MinBranchLength);
% Display the skeleton image.
subplot(4, 1, 4);
imshow(skelImage, []);
title('Skeleton Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
drawnow;
% Get the coordinates of the skeleton
[r, c] = find(skelImage);
% Save them into a cell array (because they are all different sizes).
x{k} = c;
y{k} = r;
% Overlay the skeleton on the original image.
subplot(4, 1, 1);
imshow(imoverlay(binaryImage, skelImage, 'r'));
hold on;
plot(c, r, 'r.', 'LineWidth', 4);
title('Binary Image with Skeleton Overlaid', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
end
% Show final results.
hFig2 = figure;
imshow(grayImage);
title('Final Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
drawnow;
hold on;
for k = 1 : numRegions
thisx = x{k};
thisy = y{k};
plot(thisx, thisy, 'r.', 'LineWidth', 4);
end
fprintf('Done running %s.m ...\n', mfilename);
msgbox('Done!');
Plus de réponses (0)
Voir également
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!