Can a GUI track commands and output them in a report?
    6 views (last 30 days)
  
       Show older comments
    
I've made a GUI environment for image processing. I want to be able to generate reports from this GUI, and I want to include the processing commands I used (with parameters) in the report. Is there any way to make MATLAB do this?
0 Comments
Accepted Answer
  Sean de Wolski
      
      
 on 31 Jan 2013
        Alright, you piqued my interest. Save this in a file called morphScriptGUI.m
Then run it normally and enjoy:
classdef morphScriptGUI < handle
%Create a new morphScriptGUI object.  
%
%
%Sean de Wolski - MathWorks 1/31/2013
%
      properties  (Access = private)
          %Properties
          I
          hFig
          hList
          hSlide
          hReport
          hAx
          thresh = 100;
          op
      end
      methods
          %Constructor
          function obj =   morphScriptGUI()
              %Read an image.
              obj.I = imread('coins.png');
              %Build the GUI
              obj.hFig = figure('menubar','none','toolbar','none',...
                              'Name','MathWorks Rocks!');
              obj.hAx  = axes('Units','Normalized','Parent',obj.hFig,...
                              'Position',[0.1 0.25 0.5 0.5]);
              obj.hList = uicontrol('Style','ListBox',...
                                    'String',{'None','Dilate','Erode'},...
                                    'Units','Normalized',...
                                    'Position',[0.7 0.7 0.2 0.2],...
                                    'Parent',obj.hFig,...
                                    'Callback',@obj.changeOp);
              obj.hSlide = uicontrol('Style','Slider',...
                                    'Min',0,'Max',255,'Value',100,...
                                    'Units','Normalized',...
                                    'Position',[0.65 0.35 0.3 0.1],...
                                    'Parent',obj.hFig,...
                                    'Callback',@obj.changeThresh);
              obj.hReport = uicontrol('Style','Pushbutton',...
                                    'Units','Normalized',...
                                    'Position',[0.7 0.1 0.2 0.1],...
                                    'Parent',obj.hFig,...
                                    'String','Make Script',...
                                    'Callback',@obj.makeScript);            
              uicontrol('Style','Text','Units','Normalized',...
                                    'Position',[0.65 0.5 0.3 0.05],...
                                    'Parent',obj.hFig,...
                                    'String','Threshold Value [0 255]'); 
              obj.op = @(x)x; %default is nothing
              obj.thresh = get(obj.hSlide,'Value'); %default 100                       
              %Decorations:
              bgc = get(obj.hFig,'color');
              iconAx = axes('Units','Normalized','position',[0.95 0 0.05 0.05],...
                                     'Parent',obj.hFig,...
                                     'HandleVisibility','off');
              uicontrol('Style','Text','Backgroundcolor',bgc,...
                                     'Foregroundcolor',[0 0 0.5],...
                                     'Units','Normalized',...
                                     'String','Sean de Wolski - MathWorks',...
                                     'Position',[0.7 0 0.25 0.04],'Fontsize',8);
              [icon, map] = imread('matlabicon.gif'); %pull in the matlab icon
              map(1,:) = bgc;  %adjust the background so it's the same as our figure
              iconRGB = ind2rgb(icon,map);
              imshow(iconRGB,map,'parent',iconAx); %show it
              %Draw initial image:
              updateImage(obj);
          end       
      end
      methods (Access = private)
          function obj = updateImage(obj)
              %show image
              imshow(obj.op(obj.I > obj.thresh),'Parent',obj.hAx);  %apply operation and show it                        
          end
          function makeScript(obj,~,~)
              %Allow user to name file
              S = inputdlg('Name Your Script:','File Name',1,{'GUIoperations.m'});
              if isempty(S);
                  msgbox('No Script Written');
                  return
              end
              S = S{1};
              h = waitbar(0,'Opening File'); drawnow;
              %Open it
              fid = fopen(S,'a');
              waitbar(0.33,h,'Writing File'); drawnow;
              %Write to it
              fprintf(fid,'\n%%%%Script Auto Generated by GUI\n%%Written on %s.\n\n',datestr(now));
              fprintf(fid,'I = imread(''coins.png''); %%read image\n');
              fprintf(fid,'BW = I > %g; %%Threshold image\n',obj.thresh);
              fprintf(fid,'op = %s; %%Operation\n',func2str(obj.op));
              fprintf(fid,'BWop = op(BW); %%perform operation\n\n');
              waitbar(0.66,h,'Writing File'); drawnow;   
              fprintf(fid,'%%%%Show Results:\nfigure;\n');
              fprintf(fid,'subplot(131);\nimshow(I);\ntitle(''Original'')\n');
              fprintf(fid,'subplot(132);\nimshow(BW);\ntitle(''Thresholded'')\n');
              fprintf(fid,'subplot(133);\nimshow(BWop);\ntitle(''Morphologically Altered'')\n');           
              fclose(fid);  %clean up
              waitbar(0.9,h,'Opening File in Editor'); drawnow;            
              edit(S);      %Open it in editor            
              close(h);
          end
          function obj = changeOp(obj,~,~)
              %Update the current operation
              operations = {@(x,~)x, ... %do nothing
                  @(x)imdilate(x,strel('disk',5)),... %dilate
                  @(x)imerode(x,strel('disk',5))}; % erode
              obj.op = operations{get(obj.hList,'Value')}; 
              updateImage(obj)
          end
          function obj = changeThresh(obj,~,~)
              %Get value for threshold and save it.
              obj.thresh = get(obj.hSlide,'Value');
              updateImage(obj);
          end
      end   
  end
5 Comments
  Sean de Wolski
      
      
 on 7 Feb 2013
				It is possible though it will be difficult. Notice how many if/else statements I have above :). There's one, and it's only to check the user's input to make sure they didn't hit "cancel" on an optional question dialog.
Thus what you need to do is store the commands in a a generalized format. I did this using anonymous functions. Every operation you can do with this GUI has a generic function handle that can be inserted if that selection is picked. From here, you could do 100 operations and as long as you pick the order correctly, everything will work out. Above, I only let you pick two things, threshold and operation. But there's no reason you couldn't have 100 things and just loop over them.
More Answers (1)
  Sean de Wolski
      
      
 on 31 Jan 2013
        
      Edited: Sean de Wolski
      
      
 on 31 Jan 2013
  
      This questions is a little too vague to answer explicitly but let me throw an idea out there:
If you are trying to report the state of all of your sliders etc. and images in the GUI, you could have a button that generates a *.m file with snapshots of the figure at different states and text comments etc. This could then be published using publish(). You could write equivalent commands into this *.m file.
E.g. if one button does a morphological erosion of an image with a strel selected from a listbox and shows it. You could write the following code to the *.m file.
st = strel('diamond',4); %diamond is string{value} from listbox
Ieroded = imerode(I,st);
imshow(Ieroded);
Use fprintf() to write code automatically.
5 Comments
  Sean de Wolski
      
      
 on 31 Jan 2013
				It depends on your GUI. You would get() all of the various information about the inputs, variables and operations you are receiving and then fprintf() it.
If I have tim elater, I'll make a simple example.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
