Problem applying an algorithm to multiple images.
7 views (last 30 days)
Show older comments
I am trying to find out the minimum distance between two bones, and apply that minimum distance to multiple images. I tried to jot three pieces together: 1. That loads multiple images from the location of my folder, 2. A procedure that finds the minimum distance between two bones for 1 sample(image), 3. Took a sample set out of the whole dataset, and apply the minimum distance from the previous step to all the samples(images). I keep getting the error: Index exceeds the number of array elements (1). I tried to fix the code in multiple ways, but I couldn't find an appropriate solution, I dont know where am I going wrong with the code. Please help me debug this code and run it for multiple images. I am attaching the code sample and a sample dataset along with it for you to review. Thank you.
Credits: @Image Analyst
function test10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
myFolder = 'D:\MathWorks_MATLAB_R2020a_v9.8.0.1323502\MathWorks_MATLAB_R2020a_v9.8.0.1323502\pq';
% Check to make sure that folder actually exists. Warn user if it doesn't.
if ~isfolder(myFolder)
errorMessage = sprintf('Error: The following folder does not exist:\n%s\nPlease specify a new folder.', myFolder);
uiwait(warndlg(errorMessage));
myFolder = uigetdir(); % Ask for a new one.
if myFolder == 0
% User clicked Cancel
return;
end
end
% Get a list of all files in the folder with the desired file name pattern.
filePattern = fullfile(myFolder, '*.png'); % Change to whatever pattern you need.
theFiles = dir(filePattern);
for k = 1 : length(theFiles)
baseFileName = theFiles(k).name;
fullFileName = fullfile(theFiles(k).folder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
% Now do whatever you want with this file name,
% such as reading it in as an image array with imread()
imageArray = imread(fullFileName);
%imshow(imageArray); % Display image.
%drawnow; % Force display to update immediately.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows, columns, numberOfColorBands] = size(imageArray);
% Display the original image.
subplot(2, 2, 1);
imshow(imageArray);
axis on;
title('Original Gray Scale Image');
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Binarize the image
binaryImage = imbinarize(imageArray);
% Display the image.
subplot(2, 2, 2);
imshow(binaryImage);
title('Binary Image');
% Fill the outline to make it solid so we don't get boundaries
% on both the inside of the shape and the outside of the shape.
binaryImage = imfill(binaryImage, 'holes');
% Display the image.
subplot(2, 2, 3);
imshow(binaryImage);
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
% Plot the borders of all the coins on the original grayscale image using the coordinates returned by bwboundaries.
hold on;
boundaries = bwboundaries(binaryImage);
numberOfBoundaries = size(boundaries, 1);
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'r', 'LineWidth', 3);
end
title('Filled Binary Image with Boundaries');
hold off;
% Define object boundaries
numberOfBoundaries = size(boundaries, 1)
boundary1 = boundaries{1};
boundary2 = boundaries{2};
boundary1x = boundary1(:, 2);
boundary1y = boundary1(:, 1);
x1=1;
y1=1;
x2=1;
y2=1;
overallMinDistance = inf; % Initialize.
index1 = 1;
index2 = 1;
for k = 1 : length(boundary2)
boundary2x = boundary2(k, 2);
boundary2y = boundary2(k, 1);
% For this blob, compute distances from boundaries to edge.
allDistances = sqrt((boundary1x - boundary2x).^2 + (boundary1y - boundary2y).^2);
% Find closest point, min distance.
[minDistance(k), indexOfMin] = min(allDistances);
if minDistance(k) < overallMinDistance
overallMinDistance = minDistance(k);
x1 = boundary1x(indexOfMin);
y1 = boundary1y(indexOfMin);
x2 = boundary2x;
y2 = boundary2y;
index2 = k;
index1 = indexOfMin;
end
end
% Report to command window.
fprintf('Min Distance from sqrt() method = %f at index %d of boundary 1 and index %d of boundary 2.\n', ...
overallMinDistance, index1, index2);
hFig = figure;
h1 = subplot(1, 2, 1);
imshow(binaryImage);
axis on;
title('Closest Distance from sqrt()');
h2 = subplot(1, 2, 2);
imshow(binaryImage);
axis on;
title('Closest Distances from pdist2()');
hFig.WindowState = 'maximized';
hold on;
% Draw a line between point 1 and 2
line(h1, [x1, x2], [y1, y2], 'Color', 'y', 'LineWidth', 3);
%======================================================================================
% For comparison, use pdist2()
allDistances2 = pdist2(boundary1, boundary2);
minDistance2 = min(allDistances2(:));
% Find all points that have that min distance - there may be several that have it.
[r, c] = find(allDistances2 == minDistance2)
boundary1x = boundary1(:, 2);
boundary1y = boundary1(:, 1);
boundary2x = boundary2(:, 2);
boundary2y = boundary2(:, 1);
for k = 1 : length(r)
% Report to command window.
index1 = r(k);
index2 = c(k);
fprintf('Min Distance from pdist2() method = %f at index %d of boundary 1 and index %d of boundary 2.\n', ...
minDistance2, index1, index2);
xLine = [boundary1x(index1), boundary2x(index2)];
yLine = [boundary1y(index1), boundary2y(index2)];
line(h2, xLine, yLine, 'Color', 'm', 'LineWidth', 1.5);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bones = 84; % Number of images you have for each person
people = 5; % Number of people you have
% Preallocate array for each person's minimum distance
personal_min_dist = zeros(people,1);
% Preallocate array for each bone's minimum distance
% This assumes that you have the exact same number of
% images for each person. If not, this array may need
% to change size inside the loop
bones_min_dist = zeros(bones,1)
for person = 1:people
% Get the set of images for each person
personal_bones_data = imageArray(person)
% Your actual setup here will depend on how your data is stored
for image = 1:bones
% Get minimum distance for each image using ImageAnalyst's function
bones_min_dist(image) = minDistance2(personal_bones_data(image))
end
% Get bone distance as mean of all distances for a person
personal_bone_dist(person) = mean(bones_min_dist);
end
end
0 Comments
Answers (0)
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!