Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
307 changes: 252 additions & 55 deletions LungAnalyze.m
Original file line number Diff line number Diff line change
@@ -1,64 +1,261 @@
% Lung CT Image Analyzer App

disp('Welcome to the Lung CT Image Analyzer App!');
disp('This app allows you to view and analyze lung CT images.');
disp('You can choose a lung CT image (1-20) for analysis, and');
disp('the app will display the original image and perform edge detection.');
disp('You can choose to continue analyzing more images or exit the app.');
disp("--------------------------------------------------------------------------------");

while true
% Ask the user for the lung CT image number
image_number = input('Enter the lung CT image number to view (1-20), or enter 0 to exit: ');

% Check if the user wants to exit
if image_number == 0
disp('Exiting program.');
break; % Exit the while loop
% % Lung CT Image Analyzer App
%
% disp('Welcome to the Lung CT Image Analyzer App!');
% disp('This app allows you to view and analyze lung CT images.');
% disp('You can choose a lung CT image (1-20) for analysis, and');
% disp('the app will display the original image and perform edge detection.');
% disp('You can choose to continue analyzing more images or exit the app.');
% disp("--------------------------------------------------------------------------------");
%
% while true
% % Ask the user for the lung CT image number
% image_number = input('Enter the lung CT image number to view (1-20), or enter 0 to exit: ');
%
% % Check if the user wants to exit
% if image_number == 0
% disp('Exiting program.');
% break; % Exit the while loop
% end
%
% % Validate the input
% if image_number < 1 || image_number > 20
% disp('Invalid input. Please enter a number between 1 and 20.');
% continue; % Skip the rest of the loop and ask for input again
% end
%
% % Construct the image filename
% image_filename = sprintf('test_lungs_%02d.jpg', image_number);
%
% % Try to load the image
% try
% % Image Processing Toolbox Add-On
% lungs_img = imread(image_filename);
%
% grayImg = rgb2gray(lungs_img);
%
% detection_types = ["Sobel", "Prewitt", "Roberts", "Log", "Canny", "Canny_old", "Zerocross", "Approxcanny"];
%
% figure;
% subplot(3, 3, 1);
% imshow(grayImg);
% title("Original Image");
%
% plot_number = 2;
% for type = detection_types
% edges = edge(grayImg, type);
% subplot(3, 3, plot_number);
% plot_number = plot_number + 1;
% imshow(edges);
% title(type);
% end
% catch
% % Catch any errors during image loading or processing
% disp('Error loading or processing the image. Please choose another image.');
% continue; % Skip the rest of the loop and ask for input again
% end
%
% % Ask the user if they want to continue
% continue_choice = input('Do you want to generate another lung image? (yes/no): ', 's');
%
% if ~strcmpi(continue_choice, 'yes')
% disp('Exiting program.');
% break; % Exit the while loop
% end
% end
%
% % Image Processing Toolbox Add-On

% Initialize myFolder to an empty string
myFolder = '';

% Keep prompting the user until a valid folder is provided
while ~isfolder(myFolder)
% Prompt the user to manually input the folder path
myFolder = input('Enter the folder path: ', 's');

% Check if the folder exists
if ~isfolder(myFolder)
errorMessage = sprintf('Error: The following folder does not exist:\n%s\nPlease specify a valid folder.', myFolder);
uiwait(warndlg(errorMessage));
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);
close all;
itemNames = cell(0);
fileNames = cell(0);
circlePercentage = zeros(0);
for k = 1 : length(theFiles)
baseFileName = theFiles(k).name;

fullFileName = fullfile(theFiles(k).folder, baseFileName);



fprintf(1, 'Now reading %s\n', fullFileName);
disp(fullFileName);
% Now do whatever you want with this file name,
% such as reading it in as an image array with imread()

lungs_img = imread(fullFileName);
num_of_circles = check_circles(lungs_img, [0.22 0.6], 0.84, [0.21 0.55], 0.88);
imgPercent = round(num_of_circles/ (13+(k/10)), 4);

circlePercentage(k) = imgPercent;
itemNames(k) = {[baseFileName ' ' num2str(imgPercent*100) '% likely to have mass']};
fileNames(k) = {fullFileName};
end


[~, sortedIndices] = sort(circlePercentage, 'descend');

itemNames = itemNames(sortedIndices);
fileNames = fileNames(sortedIndices);
circlePercentage = circlePercentage(sortedIndices);


%%
% Create a figure
fig = figure('Name', 'GUI', 'units', 'normalized', 'Position', [0.2, 0.2, 0.6, 0.6]);

% Create a listbox
listbox = uicontrol('Style', 'listbox', 'units', 'normalized', 'Position', [0.1, 0.1, 0.8, 0.8], 'String', itemNames, 'UserData', fileNames, 'Callback', @listboxCallback);

% Callback function for listbox selection
function listboxCallback(src, event)
% Get the selected item from the listbox
index = get(src, 'Value');
items = get(src, 'String');
UserData = get(src, 'UserData');
selected_item = items{index};
filename = UserData{index};
disp(filename);
fprintf(1, 'Now reading %s\n', filename);
if(not(isempty(filename)))
lungs_img = imread(filename);
find_circles(lungs_img, selected_item, [0.22 0.6], 0.84, [0.21 0.55], 0.88);
end

end


%%
function [num_of_circles] = find_circles(img, img_name, intensity_bw, circle_sens_bw, intensity_edge, circle_sens_edge)
% find_circles tries to detect circles in the img based on the provided
% thresholds
% find_circles(img, [min_in max_in], circle_sens) adjusts img contrast
% based on [min_in max_in] and detects circles based on circle_sens
% Inputs:
% img : the image to detect circles in
% intensity : [min = 0...1 max = 0...1], min < max; a double vector representing the
% thresholds to base contrast adjustment on
% circle_sens : 0...1; the threshold for circle detection. Greater values
% are less sensitive
% method : the filter to use circle detection on
arguments
img
img_name
intensity_bw (1,2) double = [0.2 0.6]
circle_sens_bw double {mustBeInRange(circle_sens_bw,0,1)} = 0.85
intensity_edge (1,2) double = [0.2 0.6]
circle_sens_edge double {mustBeInRange(circle_sens_edge,0,1)} = 0.85
end
figure('Name', img_name);
set(gcf, 'Position', [360, 360, 1280, 540]);
subplot(1,3,1);
imshow(img);
title("Original");

img = im2gray(img);

% Validate the input
if image_number < 1 || image_number > 20
disp('Invalid input. Please enter a number between 1 and 20.');
continue; % Skip the rest of the loop and ask for input again
% detect circles
% method = 'bw';
img_adjusted_bw = imadjust(img, intensity_bw);
subplot(1,3,2);
% imshow(img_adjusted)
% title("Contrast Adjusted");

img_BW = imbinarize(img_adjusted_bw);
imshow(img_adjusted_bw)
title("Contrast adjusted");
num_of_circles = 0;
[centers, radii] = imfindcircles(img_BW,[9 50], 'ObjectPolarity','bright', 'Sensitivity', circle_sens_bw);
if not(isempty(centers))
num_of_circles = num_of_circles + length(centers);
max_len = min([length(radii) 3]); % only display up to the x strongest circles
centersStrong5 = centers(1:max_len,:);
radiiStrong5 = radii(1:max_len);
viscircles(centersStrong5, radiiStrong5,'EdgeColor','b');
else
disp("No circles found.");
end

% method = 'edge';
img_adjusted_edge = imadjust(img, intensity_edge);
subplot(1,3,3);

img_BW = imbinarize(img_adjusted_edge);
edges = edge(img_BW, 'canny');
imshow(edges)
title("Edge detection");
[centers, radii] = imfindcircles(edges,[9 50], 'ObjectPolarity','bright', 'Sensitivity', circle_sens_edge);

if not(isempty(centers))
num_of_circles = num_of_circles + length(centers);
max_len = min([length(radii) 3]); % only display up to the x strongest circles
centersStrong5 = centers(1:max_len,:);
radiiStrong5 = radii(1:max_len);
viscircles(centersStrong5, radiiStrong5,'EdgeColor','r');

else
disp("No circles found.");
end
end

% Construct the image filename
image_filename = sprintf('test_lungs_%02d.jpg', image_number);

% Try to load the image
try
% Image Processing Toolbox Add-On
lungs_img = imread(image_filename);

grayImg = rgb2gray(lungs_img);

detection_types = ["Sobel", "Prewitt", "Roberts", "Log", "Canny", "Canny_old", "Zerocross", "Approxcanny"];

figure;
subplot(3, 3, 1);
imshow(grayImg);
title("Original Image");

plot_number = 2;
for type = detection_types
edges = edge(grayImg, type);
subplot(3, 3, plot_number);
plot_number = plot_number + 1;
imshow(edges);
title(type);
end
catch
% Catch any errors during image loading or processing
disp('Error loading or processing the image. Please choose another image.');
continue; % Skip the rest of the loop and ask for input again
function [num_of_circles] = check_circles(img, intensity_bw, circle_sens_bw, intensity_edge, circle_sens_edge)
% find_circles tries to detect circles in the img based on the provided
% thresholds
% find_circles(img, [min_in max_in], circle_sens) adjusts img contrast
% based on [min_in max_in] and detects circles based on circle_sens
% Inputs:
% img : the image to detect circles in
% intensity : [min = 0...1 max = 0...1], min < max; a double vector representing the
% thresholds to base contrast adjustment on
% circle_sens : 0...1; the threshold for circle detection. Greater values
% are less sensitive
% method : the filter to use circle detection on
arguments
img
intensity_bw (1,2) double = [0.2 0.6]
circle_sens_bw double {mustBeInRange(circle_sens_bw,0,1)} = 0.85
intensity_edge (1,2) double = [0.2 0.6]
circle_sens_edge double {mustBeInRange(circle_sens_edge,0,1)} = 0.85
end

% Ask the user if they want to continue
continue_choice = input('Do you want to generate another lung image? (yes/no): ', 's');
img = im2gray(img);

img_adjusted_bw = imadjust(img, intensity_bw);

img_BW = imbinarize(img_adjusted_bw);

num_of_circles = 0;
[centers, radii] = imfindcircles(img_BW,[9 50], 'ObjectPolarity','bright', 'Sensitivity', circle_sens_bw);
if not(isempty(centers))
max_len = min([length(radii) 3]); % only display up to the x strongest circles
centersStrong5 = centers(1:max_len,:);
num_of_circles = num_of_circles + length(centersStrong5);
end

img_adjusted_edge = imadjust(img, intensity_edge);

if ~strcmpi(continue_choice, 'yes')
disp('Exiting program.');
break; % Exit the while loop
img_BW = imbinarize(img_adjusted_edge);
edges = edge(img_BW, 'canny');
[centers, radii] = imfindcircles(edges,[9 50], 'ObjectPolarity','bright', 'Sensitivity', circle_sens_edge);

if not(isempty(centers))
max_len = min([length(radii) 3]); % only display up to the x strongest circles
centersStrong5 = centers(1:max_len,:);
num_of_circles = num_of_circles + length(centersStrong5);
end
end