Problem applying an algorithm to multiple images.

1 view (last 30 days)
Vihan P
Vihan P on 28 Apr 2021
Edited: Vihan P on 28 Apr 2021
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.
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

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!