From 0e995bc1b07a7a4a6fb35535fee3a689edd77e29 Mon Sep 17 00:00:00 2001 From: TianyuChe Date: Sun, 3 Dec 2023 08:38:21 +0800 Subject: [PATCH 1/3] folderSelect --- LungAnalyze.m | 298 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 249 insertions(+), 49 deletions(-) diff --git a/LungAnalyze.m b/LungAnalyze.m index b732e7a..acfb096 100644 --- a/LungAnalyze.m +++ b/LungAnalyze.m @@ -1,64 +1,264 @@ -% Lung CT Image Analyzer App - +% % 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('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('You can choose to continue analyzing more images or exit the app.'); disp("--------------------------------------------------------------------------------"); +% + +% % 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 -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: '); +%% +% Specify the folder where the files live. +% Prompt the user to manually input the folder path +% Initialize myFolder to an empty string +% Initialize myFolder to an empty string +myFolder = ''; - % Check if the user wants to exit - if image_number == 0 - disp('Exiting program.'); - break; % Exit the while loop +% 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 = num_of_circles/13; + 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); - % 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 +% 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 - % 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 + + +%% +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); - % Ask the user if they want to continue - continue_choice = input('Do you want to generate another lung image? (yes/no): ', 's'); + % 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); + circle1 = 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); + circle2 = viscircles(centersStrong5, radiiStrong5,'EdgeColor','r'); + + else + disp("No circles found."); + end +end + +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 + + 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 From 185e8b871ca78516ea07c9ce3cb5974b457cf890 Mon Sep 17 00:00:00 2001 From: TianyuChe Date: Sun, 3 Dec 2023 08:41:09 +0800 Subject: [PATCH 2/3] Update LungAnalyze.m --- LungAnalyze.m | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/LungAnalyze.m b/LungAnalyze.m index acfb096..183549e 100644 --- a/LungAnalyze.m +++ b/LungAnalyze.m @@ -1,13 +1,13 @@ % % 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('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('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("--------------------------------------------------------------------------------"); +% 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: '); % @@ -67,20 +67,15 @@ %% % Specify the folder where the files live. -% Prompt the user to manually input the folder path -% Initialize myFolder to an empty string -% 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)); +myFolder = 'samples-normal'; +% 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. @@ -104,7 +99,8 @@ lungs_img = imread(fullFileName); num_of_circles = check_circles(lungs_img, [0.22 0.6], 0.84, [0.21 0.55], 0.88); - imgPercent = num_of_circles/13; + 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}; @@ -189,7 +185,7 @@ function listboxCallback(src, event) max_len = min([length(radii) 3]); % only display up to the x strongest circles centersStrong5 = centers(1:max_len,:); radiiStrong5 = radii(1:max_len); - circle1 = viscircles(centersStrong5, radiiStrong5,'EdgeColor','b'); + viscircles(centersStrong5, radiiStrong5,'EdgeColor','b'); else disp("No circles found."); end @@ -209,7 +205,7 @@ function listboxCallback(src, event) max_len = min([length(radii) 3]); % only display up to the x strongest circles centersStrong5 = centers(1:max_len,:); radiiStrong5 = radii(1:max_len); - circle2 = viscircles(centersStrong5, radiiStrong5,'EdgeColor','r'); + viscircles(centersStrong5, radiiStrong5,'EdgeColor','r'); else disp("No circles found."); From f339eb011bc2cff41ded5b6cac1dcbcadcd7deab Mon Sep 17 00:00:00 2001 From: TianyuChe Date: Sun, 3 Dec 2023 08:41:51 +0800 Subject: [PATCH 3/3] Update LungAnalyze.m --- LungAnalyze.m | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/LungAnalyze.m b/LungAnalyze.m index 183549e..c8c28b1 100644 --- a/LungAnalyze.m +++ b/LungAnalyze.m @@ -65,17 +65,18 @@ % % % Image Processing Toolbox Add-On -%% -% Specify the folder where the files live. -myFolder = 'samples-normal'; -% 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; +% 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.