Azzera filtri
Azzera filtri

GUI - Batch Image Processing help!

1 visualizzazione (ultimi 30 giorni)
Ellis Berry
Ellis Berry il 14 Mar 2016
Risposto: Image Analyst il 14 Mar 2016
Hi everyone, So I've got a challenging problem. I have made a GUI and basically I want press 'pushbutton1' and load a folder of images to process. These image names will be loaded onto listbox1 to see and then, I want to press 'pushbutton3' to run the main code. This code, which works fine in editor, processes all the images and outputs them to another folder. Now, the trouble I'm having is putting this code into a gui. So I want the 'inDir' to be whatever folder I chose from pushbutton1? But I cant get it to work. This is my code so far:
function varargout = GUI_2(varargin)
%GUI_2 M-file for GUI_2.fig
% GUI_2, by itself, creates a new GUI_2 or raises the existing
% singleton*.
%
% H = GUI_2 returns the handle to a new GUI_2 or the handle to
% the existing singleton*.
%
% GUI_2('Property','Value',...) creates a new GUI_2 using the
% given property value pairs. Unrecognized properties are passed via
% varargin to GUI_2_OpeningFcn. This calling syntax produces a
% warning when there is an existing singleton*.
%
% GUI_2('CALLBACK') and GUI_2('CALLBACK',hObject,...) call the
% local function named CALLBACK in GUI_2.M with the given input
% arguments.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help GUI_2
% Last Modified by GUIDE v2.5 02-Mar-2016 16:10:54
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @GUI_2_OpeningFcn, ...
'gui_OutputFcn', @GUI_2_OutputFcn, ...
'gui_LayoutFcn', [], ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before GUI_2 is made visible.
function GUI_2_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin unrecognized PropertyName/PropertyValue pairs from the
% command line (see VARARGIN)
% Choose default command line output for GUI_2
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes GUI_2 wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = GUI_2_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on selection change in listbox1.
function listbox1_Callback(hObject, eventdata, handles)
% hObject handle to listbox1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,'String')) returns listbox1 contents as cell array
% contents{get(hObject,'Value')} returns selected item from listbox1
% --- Executes during object creation, after setting all properties.
function listbox1_CreateFcn(hObject, eventdata, handles)
% hObject handle to listbox1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: listbox controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --- Load up the listbox with tif files in folder handles.handles.ImageFolder
% get the folder
folder_name = uigetdir;
% get what is inside the folder
Infolder = dir(folder_name);
MyListOfFiles = {Infolder(~[Infolder.isdir]).name};
set(handles.listbox1,'String', MyListOfFiles);
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
[file,path]=uiputfile('*.jpg','Save Destination');
% --- Executes on button press in pushbutton3. %MAIN!!
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
if(nargin<2)
outDir = 'H:\Documents\DIP\Batch_processed_HSV';
end
if(nargin<1)
inDir = 'MyListOfFiles';
end
includeSubdirectories = true;
% All extensions that can be read by IMREAD
imreadFormats = imformats;
supportedExtensions = [imreadFormats.ext];
% Add dicom extensions
supportedExtensions{end+1} = 'dcm';
supportedExtensions{end+1} = 'ima';
supportedExtensions = strcat('.',supportedExtensions);
% Allow the 'no extension' specification of DICOM
supportedExtensions{end+1} = '';
% Create a image data store that can read all these files
imds = datastore(inDir,...
'IncludeSubfolders', includeSubdirectories,...
'Type','image',...
'FileExtensions',supportedExtensions);
imds.ReadFcn = @readSupportedImage;
% Process each image using trial_3 (Image Processing toolbox app that let
% me set the HSV thresholds).
for imgInd = 1:numel(imds.Files)
inImageFile = imds.Files{imgInd};
% Output has the same sub-directory structure and file extension as
% input
outImageFile = strrep(inImageFile, inDir, outDir);
try
% Read
im = imds.readimage(imgInd);
% Process
im = trial_3(im);
% Create (sub)directory if needed
outSubDir = fileparts(outImageFile);
createDirectory(outSubDir);
% Write
if(isdicom(inImageFile))
dicommeta = dicominfo(inImageFile);
dicomwrite(im, outImageFile, dicommeta, 'CreateMode', 'copy');
else
imwrite(im, outImageFile);
end
disp(['PASSED:', inImageFile]);
catch allExceptions
disp(['FAILED:', inImageFile]);
disp(getReport(allExceptions,'basic'));
end
end
%Specify the folder where the files (Pictures) live.
myFolder='H:\Documents\DIP\Batch_Processed_HSV';
%Get a list of all files in the folder with the desired file name pattern.
filePattern=fullfile(myFolder, '*.JPG');
theFiles=dir(filePattern);
Interval=input('Enter the time interval for the camera (Seconds):') %Prompt for user to enter camera interval.
for k=1:length(theFiles)
baseFileName=theFiles(k).name;
fullFileName=fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
image=imread(fullFileName);
white=nnz(image);
black=(numel(image)-white);
if black>(numel(image)*0.0193); %if black pixels is more than 1.94% of pixels in image, experiment complete. Value can be altered.
disp('The experiment is complete at this stage!')
fprintf('The number of Black Pixels is:');
disp(numel(image)-white);
disp('Time of Picture (Secs): ');
disp((k-1)*Interval); %Here, "Interval" is a variable chosen by user (15 secs, 30 secs etc)
else
disp('The experiment is not complete yet.')
fprintf('The number of Black Pixels is:');
disp(numel(image)-white);
end
end
% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
msgbox('Thankyou for using the Image Processing Tool');
pause(3);
close();
close();
% --- Executes on selection change in listbox2.
function listbox2_Callback(hObject, eventdata, handles)
% hObject handle to listbox2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,'String')) returns listbox2 contents as cell array
% contents{get(hObject,'Value')} returns selected item from listbox2
% --- Executes during object creation, after setting all properties.
function listbox2_CreateFcn(hObject, eventdata, handles)
% hObject handle to listbox2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: listbox controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function edit2_Callback(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit2 as text
% str2double(get(hObject,'String')) returns contents of edit2 as a double
% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
and this is the error message I get once I click pushbutton3:
GUI_2
Undefined function or variable 'inDir'.
Error in GUI_2>pushbutton3_Callback (line 149)
imds = datastore(inDir,...
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in GUI_2 (line 42)
gui_mainfcn(gui_State, varargin{:});
Error in matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)GUI_2('pushbutton3_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
The GUI works fine in loading the image names to listbox1, but implementing this batch image processing code into the GUI is hard. Many thanks,
Ellis

Risposte (2)

Geoff Hayes
Geoff Hayes il 14 Mar 2016
Ellis - look closely at pushbutton3_Callback
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
if(nargin<2)
outDir = 'H:\Documents\DIP\Batch_processed_HSV';
end
if(nargin<1)
inDir = 'MyListOfFiles';
end
The number of arguments in, nargin, will always be three so inDir and outDir will never be defined. (I don't see this callback being called anywhere else in your code, so am assuming that the only time it is called is when the user presses the third push button.) And so when you call the datastore function, inDir is not defined and you observe an error.
Now you mention that you want to use the folder that has been chosen in the pushbutton1_Callback. Presumably, this is
folder_name = uigetdir;
The "trick" to sharing data between callbacks is to use the handles structure. We save the data to this structure in one callback and access it in another callback. In your case, we could do
function pushbutton1_Callback(hObject, eventdata, handles)
folder_name = uigetdir;
Infolder = dir(folder_name);
MyListOfFiles = {Infolder(~[Infolder.isdir]).name};
set(handles.listbox1,'String', MyListOfFiles);
% update handles with the inDir
handles.inDir = folder_name;
guidata(hObject,handles);
And that is it - we create the field in handles, assigning folder_name to it. Then we save the updated handles object using guidata. You can then access this field in your other callback as
function pushbutton3_Callback(hObject, eventdata, handles)
if isfield(handles,'inData')
inData = handles.inData;
% etc.
end
I think that is what you want. I am a little confused by how you set
inDir = 'MyListOfFiles';
as if you want to set this variable to the list of files that you obtained in the first callback. If this is the case, then you can access these files directly from the listbox as
MyListOfFiles = get(handles.listbox1,'Data');
or maybe as
MyListOfFiles = get(handles.listbox1,'String');
depending upon your version of MATLAB. (I am using R2014a and so have the Data property.)
Try the above and see what happens!

Image Analyst
Image Analyst il 14 Mar 2016
In the pushbutton1 callback, just do
handles.imageFolder = folder_name;
Then, in any other function or callback, when you create the filenames with fullfile(), use handles.imageFolder
thisFileName = fullfile(handles.imageFolder, baseFileName);

Categorie

Scopri di più su Migrate GUIDE Apps in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by