Code covered by the BSD License  

Highlights from
SegmentTool: An Interactive GUI for Segmenting Images

image thumbnail

SegmentTool: An Interactive GUI for Segmenting Images

by

 

09 Nov 2012 (Updated )

Interactively find the best approach to segmenting (masking) your image

FindCirclesGUI.m
function FindCirclesFigHndl = FindCirclesGUI(inputImage,radiusRange)
% Detect and mark circles in an image
%
% SYNTAX:
%
% FindCirclesGUI
%    Launches the GUI environment with the default image
%    ('coins.png') pre-loaded.
%
% FindCirclesGUI(inputImage)
%    Allows user to specify input image, or the name of an
%    input image.
%
% FindCirclesGUI(...,radiusRange)
%    Allows user to specify radius range as [minRadius maxRadius]
%
% (Note that OUTPUTS are supported via an "EXPORT" button.)
%
% CLASS SUPPORT:
%    inputImage can be any valid image format readable by
%    IMREAD. Color (RGB) images are supported, but circle
%    detection is performed on the RGB2GRAY representation.
%    (See help for IMFINDCIRCLES for details.)
%
% Note: This version _does not use_ the helper function
%    VISCIRCLES, which can be very slow when a lot of
%    circles are detected. Instead, it uses a custom plot
%    function for visualization.
%
% Copyright The MathWorks, Inc. 2011.
% Written by Brett Shoelson, PhD
% brett.shoelson@mathworks.com
% Comments and suggestions welcome!
% V 1.0; 12/15/2011
% V 1.1; 2/4/2012
%     Added Default-Reset and Acknowledgements buttons
% V 1.2; 2/7/2013
%     Now defaults to "process immediately" = false;
%     Also, takes optional input argument specifying initial radius range
% Copyright 2011-2012 MathWorks, Inc.
%
% See Also: IMFINDCIRCLES, VISCIRCLES

 if verLessThan('images','8.0')
     beep
     disp('SORRY! FindCirclesGUI requires Image Processing Toolbox Ver. 8.0 (MATLAB R2012a) or later!');
     %return
 end

if nargin < 1 || isempty(inputImage)
    fname = 'coins.png';
    inputImage = imread('coins.png');
elseif ischar(inputImage)
    fname = inputImage;
    inputImage = imread(inputImage);
else
    fname = 'Original';
end

if nargin < 2
    minRadius = 20;
    maxRadius = 30;
else
    minRadius = radiusRange(1);
    maxRadius = radiusRange(2);
end

bgc = [0.55 0.65 0.65];
tbc = 240/255; %toolbar color, approximately

FindCirclesFig = figure(...
    'numbertitle','off',...
    'windowstyle','normal',...
    'name','Find Circles GUI',...
    'units','Normalized',...
    'Position',[0.1875 0.05 0.625 0.85],...
    'color',bgc,...
    'tag','FindCirclesFig',...
    'menubar','none');
FindCirclesFigHndl = FindCirclesFig;

ht                       = uitoolbar(FindCirclesFig);
% tmp = ones(14,13);
% tmp(6:9,[1:3,6:8,11:13]) = 0;
% tmp                      = label2rgb(tmp,tbc*ones(3),[0 0 0]);
tmp                        = im2double(imread('file_open.png'));
tmp(tmp==0)              = NaN;
loadImageTool              = uitoggletool(ht,...
    'CData',               tmp,...
    'oncallback',          @GetNewFile,...
    'offcallback',         '',...
    'Tooltipstring',       'Load new image',...
    'Tag',                 'loadImageTool'); %#ok<*NASGU>

tmp                      = im2double(imread('tool_zoom_in.png'));
tmp(tmp==0)              = NaN;
zoomTool                 = uitoggletool(ht,...
    'CData',               tmp,...
    'oncallback',          'zoom;set(gcbo,''state'',''off'')',...
    'offcallback',         '',...
    'Tooltipstring',       'Toggle zoom state');

tmp                      = imread('distance_tool.gif');
tmp                      = label2rgb(tmp,tbc*ones(3),[0 0 0]);
distanceTool             = uitoggletool(ht,...
    'CData',               tmp,...
    'oncallback',          'imdistline;set(gcbo,''state'',''off'')',...
    'offcallback',         '',...
    'Tooltipstring',       'Add IMDISTLINE Tool');

tmp = imcomplement(tmp);
delDistanceTool           = uitoggletool(ht,...
    'CData',               tmp,...
    'oncallback',          @clearDistlineTools,...
    'offcallback',         '',...
    'Tooltipstring',       'Clear IMDISTLINE Tool(s)');

tmp = ones(11);
tmp([1:3,9:13,21:23,33,89,99:101,109:113,119:121]) = 0;
tmp(6,:) = 0;tmp(:,6) = 0;
tmp2                      = label2rgb(tmp,tbc*ones(3),[0 0 1]);
markObjectsTool           = uitoggletool(ht,...
    'CData',               tmp2,...
    'oncallback',          @markPoints,...
    'offcallback',         '',...
    'Tooltipstring',       'Manually count objects');

tmp2                      = label2rgb(~tmp,tbc*ones(3),[0 0 1]);
markObjectsTool           = uitoggletool(ht,...
    'CData',               tmp2,...
    'oncallback',          @clearMarkedPoints,...
    'offcallback',         '',...
    'Tooltipstring',       'Clear counting marks');

tmp = imread('DefaultD.png');
defaultButton = uitoggletool(ht,...
    'CData',               tmp,...
    'separator',           'on',...
    'oncallback',          @resetDefaults,...
    'Tooltipstring',       'Resets all uicontrols/parameters to defaults.');

tmp = imread('logo.png');
infoButton = uitoggletool(ht,...
    'CData',               tmp,...
    'separator',           'on',...
    'oncallback',          @acknowledge,...
    'Tooltipstring',       'Acknowledgements');

set(FindCirclesFig,...
    'defaultuicontrolunits','Normalized',...
    'defaultuicontrolbackgroundcolor',bgc,...
    'defaultuicontrolfontsize',9);

ImageAxis = axes(...
    'Parent',FindCirclesFig,...
    'Units','Normalized',...
    'Position',[0.05 0.35 0.9 0.6 ],...
    'Color',bgc,...
    'Tag','ImageAxis',...
    'Handlevisibility','Callback',...
    'XLimMode','auto',...
    'YLimMode','auto',...
    'Visible','off');

ImgObj = imshow(inputImage,'parent',ImageAxis);
ImgTitle = title(fname);
expandAxes(ImageAxis);

%[objpos,objdim] = distributeObjects(4,0.05,0.95,0.025);
objpos = [0.05 0.28125 0.5125 0.74375];
objdim = 0.20625;

CommentsPanel = uipanel(...
    'Parent',FindCirclesFig,...
    'Title','Comments/Status',...
    'Tag','CommentsPanel',...
    'Units','Normalized',...
    'Position',[objpos(1) 0.03 0.9 0.05]);

CommentsBox = uicontrol(...
    'Parent',CommentsPanel,...
    'Style','Edit',...
    'String','Welcome to FindCirclesGUI!  2012 The MathWorks, Inc.',...
    'Tag','CommentsBox',...
    'Units','Normalized',...
    'Fontsize',12,...
    'Position',[0 -0.01 1 1.06],...
    'Enable','Inactive');

SensitivityPanel = uipanel(...
    'Parent',FindCirclesFig,...
    'Title','Sensitivity',...
    'Tag','SensitivityPanel',...
    'Units','Normalized',...
    'Position',[objpos(1) 0.0925 objdim 0.125]);

[SensitivitySlider, ~, SensitivityEdt] = sliderPanel(...
    'Parent'  , SensitivityPanel, ...
    'Title'   , '', ...
    'Position', [0.05 0.05 0.9 0.9], ...
    'Backgroundcolor', bgc,...
    'Min'     , 0, ...
    'Max'     , 1, ...
    'Value'   , 0.85, ...
    'NumFormat','%0.2f',...
    'Callback', @processFindCircles);
set(findobj(SensitivityPanel,'style','slider'),...
    'TooltipString',...
    sprintf('A high sensitivity value leads to detecting more\ncircles, including weak or partially obscured ones at\nthe risk of a higher false detection rate.\nDefault value: 0.85.'));

EdgeThresholdPanel = uipanel(...
    'Parent',FindCirclesFig,...
    'Title','Edge Threshold',...
    'Tag','EdgeThresholdPanel',...
    'Units','Normalized',...
    'Position',[objpos(2) 0.0925 objdim 0.125]);

[EdgeThresholdSlider,~,EdgeThresholdEdt] = sliderPanel(...
    'Parent'  , EdgeThresholdPanel, ...
    'Title'   , '', ...
    'Position', [0.05 0.25 0.9 0.7], ...
    'Backgroundcolor', bgc,...
    'Min'     , 0, ...
    'Max'     , 1, ...
    'Value'   , 0.3, ...
    'NumFormat','%0.2f',...
    'Callback', @processFindCircles);
EdgeSlider = findobj(EdgeThresholdSlider,'style','slider');
set(EdgeSlider,...
    'Enable','Off',...
    'TooltipString',...
    sprintf('Specifies the gradient threshold for determining edge pixels.\nA high EdgeThreshold value leads to detecting only those circles\nthat have relatively strong edges. A low EdgeThreshold value will,\nin addition, lead to detecting circles with relatively faint edges.\n'));
UseDefaultEdgeThresh = uicontrol(...
    'Parent',EdgeThresholdPanel,...
    'Callback',@toggleEdgeThreshSlider,...
    'Units','Normalized',...
    'Position',[0.05 0.025 0.45 0.2],...
    'String','Use Default',...
    'Style','checkbox',...
    'Value',1,...
    'Tag','UseDefaultEdgeThresh',...
    'TooltipString','When checked, edge threshold will be automatically determined using Graythresh.');

VisualizationPanel = uipanel(...
    'Parent',FindCirclesFig,...
    'Title','Visualization Options',...
    'Tag','VisualizationPanel',...
    'Position',[objpos(3) 0.0925 objdim*1.3 0.125]);

LineWidthText = uicontrol(...
    'Parent',VisualizationPanel,...
    'Callback','',...
    'Units','Normalized',...
    'Position',[0.05 0.525 0.35 0.4],...
    'String','Line Width',...
    'Style','text',...
    'HorizontalAlignment','Left',...
    'Tag','LineWidthText');

lineWidthVal = 2;
LineWidthValBox =  uicontrol(...
    'Parent',VisualizationPanel,...
    'Callback',@processFindCircles,...
    'Units','Normalized',...
    'Position',[0.4 0.55 0.2 0.4],...
    'String',[0.5;1.0;1.5;2.0;3.0;4.0;8.0],...
    'Style','popupmenu',...
    'Value',lineWidthVal,...
    'Fontsize',10,...
    'Tag','LineWidthValBox');

LineStyleText = uicontrol(...
    'Parent',VisualizationPanel,...
    'Callback','',...
    'Units','Normalized',...
    'Position',[0.05 0.225 0.35 0.4],...
    'String','Line Style',...
    'Style','text',...
    'HorizontalAlignment','Left',...
    'Tag','LineStyleText');

LineStyleValBox =  uicontrol(...
    'Parent',VisualizationPanel,...
    'Callback',@processFindCircles,...
    'Units','Normalized',...
    'Position',[0.4 0.25 0.2 0.4],...
    'String',{'-','--','-.',':'},...
    'Style','popupmenu',...
    'Value',2,...
    'Fontsize',10,...
    'Tag','LineStyleValBox');

circleColor = [0 1 1];
circleColorButton = uicontrol(...
    'Parent',VisualizationPanel,...
    'style','pushbutton',...
    'Position',[0.7 0.45 0.15 0.35],...
    'cdata',reshape(kron(circleColor,ones(25,25)),25,25,3),...
    'callback',@changeCircleColor,...
    'tag','circleColorButton');
setappdata(circleColorButton,'circleColor',circleColor);

ClearPrevious = uicontrol(...
    'Parent',VisualizationPanel,...
    'Callback','',...
    'Units','Normalized',...
    'Position',[0.05 0.025 0.45 0.2],...
    'String','Clear previous circles',...
    'Style','checkbox',...
    'Value',1,...
    'Tag','ClearPrevious');

UseWhiteBG = uicontrol(...
    'Parent',VisualizationPanel,...
    'Callback',@processFindCircles,...
    'Units','Normalized',...
    'Position',[0.55 0.025 0.45 0.2],...
    'String','White Background',...
    'Style','checkbox',...
    'Value',0,...
    'Tag','UseWhiteBG');

ObjectPolarityPanel = uibuttongroup(...
    'Parent',FindCirclesFig,...
    'Title','Object Polarity',...
    'Tag','ObjectPolarityPanel',...
    'Units','Normalized',...
    'Position',[objpos(1) 0.2275 objdim 0.0625],...
    'SelectedObject',[],...
    'SelectionChangeFcn',@processFindCircles,...
    'OldSelectedObject',[]);

BrightButton = uicontrol(...
    'Parent',ObjectPolarityPanel,...
    'Units','Normalized',...
    'Position',[0.05 0.25 0.425 0.5],...
    'String','Bright',...
    'Style','radiobutton',...
    'TooltipString','Circles are brighter than the background.',...
    'Value',1,...
    'Tag','Bright');

DarkButton = uicontrol(...
    'Parent',ObjectPolarityPanel,...
    'Units','Normalized',...
    'Position',[0.50 0.25 0.425 0.5],...
    'String','Dark',...
    'Style','radiobutton',...
    'TooltipString','Circles are darker than the background.',...
    'Tag','Dark');

MethodPanel = uibuttongroup(...
    'Parent',FindCirclesFig,...
    'Title','Method',...
    'Tag','MethodPanel',...
    'Units','Normalized',...
    'Position',[objpos(2) 0.2275 objdim 0.0625],...
    'SelectedObject',[],...
    'SelectionChangeFcn',@processFindCircles,...
    'OldSelectedObject',[]);

PhaseCodeButton = uicontrol(...
    'Parent',MethodPanel,...
    'Units','Normalized',...
    'Position',[0.05 0.25 0.425 0.5],...
    'String','Phase Code',...
    'Style','radiobutton',...
    'Value',1,...
    'Tag','PhaseCode',...
    'Tooltipstring',...
    sprintf('Specifies use of Atherton and Kerbyson''s Phase Coding method\nfor computing the accumulator array. (This is the Default.)'));

TwoStageButton = uicontrol(...
    'Parent',MethodPanel,...
    'Units','Normalized',...
    'Position',[0.5 0.25 0.425 0.5],...
    'String','Two-Stage',...
    'Style','radiobutton',...
    'Tag','TwoStage',...
    'Tooltipstring',...
    sprintf('Specifies use of the Two-stage Circular Hough Transform method\nfor computing the accumulator array.'));

ProcessOptionsPanel = uibuttongroup(...
    'Parent',FindCirclesFig,...
    'Title','Process Options',...
    'Tag','ProcessOptionsPanel',...
    'Units','Normalized',...
    'Position',[0.8 0.0925 0.15 0.125],...
    'SelectedObject',[],...
    'SelectionChangeFcn',@processFindCircles,...
    'OldSelectedObject',[]);

ProcessButton = uicontrol(...
    'Parent',ProcessOptionsPanel,...
    'Callback',@processFindCircles,...
    'FontSize',9,...
    'Units','Normalized',...
    'Position',[0.05 0.4 0.9 0.3],...
    'String','Process Now',...
    'Tag','ProcessButton');

ExportButton = uicontrol(...
    'Parent',ProcessOptionsPanel,...
    'Callback',@exportResults,...
    'FontSize',9,...
    'Units','Normalized',...
    'Position',[0.05 0.05 0.9 0.3],...
    'String','Export/Save Results',...
    'Tag','ExportButton');

ProcessImmediatelyBox = uicontrol(...
    'Parent',ProcessOptionsPanel,...
    'Callback','',...
    'Units','Normalized',...
    'Position',[0.05 0.8 0.9 0.15],...
    'String','Process Immediately',...
    'Style','checkbox',...
    'Value',0,...
    'Tag','ProcessImmediatelyBox');

RadiusRangePanel = uipanel(...
    'Parent',FindCirclesFig,...
    'Title','Radius Range',...
    'Tag','RadiusRangePanel',...
    'Units','Normalized',...
    'Position',[objpos(3) 0.2275 1-objpos(3)-objpos(1) 0.0625]);

MinRadiusText = uicontrol(...
    'Parent',RadiusRangePanel,...
    'Style','text',...
    'Units','Normalized',...
    'Position',[0.2 0.1 0.2 0.5],...
    'String','Minimum Radius',...
    'HorizontalAlignment','Left',...
    'Tag','MinRadiusText');

MaximumRadiusText = uicontrol(...
    'Parent',RadiusRangePanel,...
    'Style','text',...
    'Units','Normalized',...
    'Position',[0.7 0.1 0.2 0.5],...
    'String','Maximum Radius',...
    'HorizontalAlignment','Left',...
    'Tag','MaximumRadiusText');

MinRadiusBox = uicontrol(...
    'Parent',RadiusRangePanel,...
    'BackgroundColor',[1 1 1],...
    'Callback',@processFindCircles,...
    'FontSize',10,...
    'Units','Normalized',...
    'Position',[0.05 0.15 0.125 0.6],...
    'String',minRadius,...%'20',...
    'Style','edit',...
    'Tag','MinRadiusBox');

MaxRadiusBox = uicontrol(...
    'Parent',RadiusRangePanel,...
    'Units','Normalized',...
    'BackgroundColor',[1 1 1],...
    'Callback',@processFindCircles,...
    'FontSize',10,...
    'Position',[0.55 0.15 0.125 0.6],...
    'String',maxRadius,...%'30',...
    'Style','edit',...
    'Tag','MaxRadiusBox');

set(findobj(FindCirclesFig,'type','uipanel'),...
    'Units','Normalized',...
    'BorderType', 'etchedin',...
    'FontSize',8,...
    'ForegroundColor',[0 0 0],...
    'TitlePosition','lefttop',...
    'backgroundColor',bgc)

if ~nargout
    clear FindCirclesFigHndl
end
%%% SUBFUNCTIONS

    function acknowledge(varargin)
        mssg = {'',...
            '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ',...
            '',...
            'I would like to acknowledge and thank the following for',...
            'suggestions, reviews, and critiques of this tool:',...
            '',...
            'Jiro Doke',...
            'Simone Haemmerle',...
            'Steve Kuznicki',...
            'Grant Martin',...
            'Jeff Mather',...
            'Alex Taylor',...
            'Spandan Tiwari',...
            'Ashish Uthama',...
            'The Image Processing Toolbox Development Team',...
            '',...
            'Comments and suggestions are welcome,',...
            'and should be addressed to me at:',...
            '',...
            'brett.shoelson@mathworks.com',...
            '',...
            ' 2012 MathWorks, Inc.',...
            '',...
            '',...
            '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~        ~          ~',...
            ''};
        h = msgbox(mssg,'ImageRegistrationGUI Acknowledgments','help','modal') ;
        msghndl = findobj(h,'tag','MessageBox');
        set(msghndl,'color',[0 0 0.7],'fontweight','b','fontname','helvetica')
        set(gcbo,'state','off')
    end


    function changeCircleColor(varargin)%circleColor =
        circleColor = getappdata(circleColorButton,'circleColor');
        circleColor = uisetcolor(circleColor);
        set(circleColorButton,'cdata',reshape(kron(circleColor,ones(25,25)),25,25,3));
        setappdata(circleColorButton,'circleColor',circleColor);
        processFindCircles(gcbo)
    end

    function myhandle = circles(radii,centers,lineWidthVal,lineStyleVal,circColor)
        % Plots multiple circles as a single line object
        % Written by Brett Shoelson, PhD
        resolution = 2;
        theta=0:resolution:360;
        
        x_circle = bsxfun(@times,radii,cos(theta*pi/180));
        x_circle = bsxfun(@plus,x_circle,centers(:,1));
        x_circle = cat(2,x_circle,nan(size(x_circle,1),1));
        x_circle =  x_circle';
        x_circle = x_circle(:);
        
        y_circle = bsxfun(@times,radii,sin(theta*pi/180));
        y_circle = bsxfun(@plus,y_circle,centers(:,2));
        y_circle = cat(2,y_circle,nan(size(y_circle,1),1));
        y_circle =  y_circle';
        y_circle = y_circle(:);
        
        hold on;
        myhandle = plot(ImageAxis,...
            x_circle,y_circle);
        set(myhandle,...
            'linewidth',lineWidthVal,...
            'linestyle',lineStyleVal,...
            'color',circColor,...
            'tag','mycircles');
%         try
%             mycircs = findall(gcf,'tag','mycircles');
%             if ~isempty(mycircs)
%                 while true
%                     pause(1)
%                     if strcmp(get(mycircs(1),'visible'),'on')
%                         set(mycircs(1),'visible','off');
%                     else
%                         set(mycircs(1),'visible','on');
%                     end
%                 end
%             end
%         catch
%             disp('no flicker')
%         end
    end

    function clearDistlineTools(varargin)
        delete(findall(FindCirclesFig,'tag','imline'));
        set(gcbo,'state','off');
    end

    function clearMarkedPoints(varargin)
        delete(findall(FindCirclesFig,'tag','impoint'));
        set(gcbo,'state','off');
    end

    function exportResults(varargin)
        radii = getappdata(FindCirclesFig,'radii');
        if isempty(radii)
            set(CommentsBox,'string','No circles detected!');
            return
        end
        hasCVST = exist('vision.ShapeInserter','class')==8;
        if hasCVST
            prompt={'Export/save CENTERS as:',...
                'Export/save RADII as:',...
                'Export/save METRIC as:',...
                'Export/save IMAGE as:'};
            defaultanswer={'centers','radii','metric','ImgOut'};
        else
            prompt={'Export/save CENTERS as:',...
                'Export/save RADII as:',...
                'Export/save METRIC as:'};
            defaultanswer={'centers','radii','metric'};
        end
        name='Export/save Options (Variable Names)';
        answer=inputdlg(prompt,name,1,defaultanswer);
        if isempty(answer)
            return
        end
        centers = getappdata(FindCirclesFig,'centers');
        assignin('base',answer{1},centers);
        assignin('base',answer{2},radii);
        assignin('base',answer{3},getappdata(FindCirclesFig,'metric'));
        if hasCVST
            if size(inputImage,3) == 1
                tmpImage = cat(3,inputImage,inputImage,inputImage);
            else
                tmpImage = inputImage;
            end
            tmpImage = im2double(tmpImage);
            h = vision.ShapeInserter;
            h.Shape = 'Circles';
            h.Fill = false;
            h.BorderColor = 'Custom';
            %h.CustomBorderColor = intmax(class(inputImage))*cast(circleColor,class(inputImage));%im2uint16(circleColor);
            h.CustomBorderColor = im2uint8(circleColor);
            h.Antialiasing = true;
            tmp = step(h,tmpImage,uint16([centers radii]));
            for ii = 2:round(lineWidthVal)
                tmp = step(h,tmp,uint16([centers radii+ii-1]));
            end
            assignin('base',answer{4},tmp);
        end
        MinRadius = str2double(get(MinRadiusBox,'string'));
        MaxRadius = str2double(get(MaxRadiusBox,'string'));
        Sensitivity = get(SensitivitySlider,'value');
        UseDefaultEdge = get(UseDefaultEdgeThresh,'value');
        Method = get(get(MethodPanel,'SelectedObject'),'Tag');
        ObjectPolarity = get(get(ObjectPolarityPanel,'SelectedObject'),'Tag');
        if UseDefaultEdge == 1
            EdgeThreshold = '[]';
            fprintf('[%s,%s,%s] = imfindcircles(imread(''%s''),[%d %d],...\n   ''Sensitivity'',%0.2f,...\n   ''EdgeThreshold'',%s,...\n   ''Method'',''%s'',...\n   ''ObjectPolarity'',''%s'');\n\n',...
                answer{1},answer{2},answer{3},fname,MinRadius,MaxRadius,Sensitivity,EdgeThreshold,Method,ObjectPolarity)
        else
            EdgeThreshold = get(EdgeThresholdSlider,'value');
            fprintf('[%s,%s,%s] = imfindcircles(imread(''%s''),[%d %d],...\n   ''Sensitivity'',%0.2f,...\n   ''EdgeThreshold'',%0.2f,...\n   ''Method'',''%s'',...\n   ''ObjectPolarity'',''%s'');\n\n',...
                answer{1},answer{2},answer{3},fname,MinRadius,MaxRadius,Sensitivity,EdgeThreshold,Method,ObjectPolarity)
        end
        disp('Variables written to base workspace');
        set(CommentsBox,'string',sprintf('%d circles detected. Variables written (with requested names) to base workspace.',numel(radii)));
    end

    function GetNewFile(varargin)
        set(gcbo,'state','off');
        [img,cmap,fname,fpath,userCanceled] = getNewImage(false);
        if userCanceled
            return
        end
        if ~isempty(cmap)
            inputImage = ind2rgb(img,cmap);
        else
            inputImage = img;
        end
        cla(ImageAxis);
        ImgObj = imshow(inputImage,'parent',ImageAxis); %#ok
        originalImg = imshow(img,'parent',ImageAxis);
        expandAxes(ImageAxis);
        ImgTitle = title(fname,'interpreter','none'); %#ok
        set(ImageAxis,'XLim',0.5+[0 size(img,2)],'YLim',0.5+[0 size(img,1)]);
        processFindCircles(gcbo)
    end

    function markPoints(varargin)
        markImagePoints(ImageAxis,'markedPoints',[0 110 110]/255);
        %         waitfor(FindCirclesFig,'currentcharacter')
        %         drawnow;
        set(gcbo,'state','off');
        set(FindCirclesFig,'currentcharacter','1') % double('1') = 49
        while double(get(FindCirclesFig,'currentcharacter')) == 49
            pause(0.5);
        end
        markedPoints = evalin('base','markedPoints');
        set(CommentsBox,'string',sprintf('%d points marked. (Locations written to "markedPoints" in base workspace.)', size(markedPoints,1)));
    end

    function processFindCircles(varargin)
        drawnow
        cboTag = '';
        try %If processing is from Default-Reset, there is no input argument
            cboTag = get(varargin{1},'tag');
        end
        processImmediately = get(ProcessImmediatelyBox,'value');
        if processImmediately || strcmp(cboTag,'ProcessButton');
            set(CommentsBox,'string','Processing...please wait.');
            clearPrev = get(ClearPrevious,'value');
            if clearPrev
                delete(findobj(FindCirclesFig,'tag','FindCirclesVis'));
            end
            MinRadius = str2double(get(MinRadiusBox,'string'));
            MaxRadius = str2double(get(MaxRadiusBox,'string'));
            if MinRadius > MaxRadius
                set(CommentsBox,'string','MinRadius must not be bigger than MaxRadius!');
                return
            end
            Sensitivity = get(SensitivitySlider,'value');
            UseDefaultEdge = get(UseDefaultEdgeThresh,'value');
            if UseDefaultEdge == 1
                EdgeThreshold = [];
            else
                EdgeThreshold = get(EdgeThresholdSlider,'value');
            end
            Method = get(get(MethodPanel,'SelectedObject'),'Tag');
            ObjectPolarity = get(get(ObjectPolarityPanel,'SelectedObject'),'Tag');
            [centers,radii,metric] = imfindcircles(inputImage,[MinRadius MaxRadius],...
                'Sensitivity',Sensitivity,...
                'EdgeThreshold',EdgeThreshold,...
                'Method',Method,...
                'ObjectPolarity',ObjectPolarity);
            setappdata(FindCirclesFig,'centers',centers);
            setappdata(FindCirclesFig,'radii',radii);
            setappdata(FindCirclesFig,'metric',metric);
            if numel(radii)>0
                useWhiteBGVal = get(UseWhiteBG,'value');
                %For visualization
                lineWidthVal = get(LineWidthValBox,'string');
                tmp = get(LineWidthValBox,'value');
                lineWidthVal = str2double(lineWidthVal(tmp,:));
                lineStyleVal = get(LineStyleValBox,'string');
                tmp = get(LineStyleValBox,'value');
                lineStyleVal = lineStyleVal{tmp};
                circleColor = getappdata(circleColorButton,'circleColor');
                if useWhiteBGVal
                    hndls = circles(radii,centers,...
                        lineWidthVal+1,'-',[1 1 1]);
                    set(hndls,'tag','FindCirclesVis');
                end
                hndls = circles(radii,centers,...
                    lineWidthVal,lineStyleVal,circleColor);
                set(hndls,'tag','FindCirclesVis');
                set(CommentsBox,'string',sprintf('%d circles detected.',numel(radii)));
            else
                set(CommentsBox,'string','No circles detected with these settings!');
            end
        else
            return
        end
    end

    function resetDefaults(varargin)
        set(gcbo,'state','off');
        %Defaults
        set(SensitivitySlider,'value',0.85);
        set(SensitivityEdt,'string',0.85);
        %
        set(EdgeThresholdSlider,'value',0.3);
        set(EdgeThresholdEdt,'string',0.3);
        %
        set(BrightButton,'Value',1);
        set(DarkButton,'value',0);
        %
        set(PhaseCodeButton,'Value',1)
        set(TwoStageButton,'Value',0);
        %
        set(MinRadiusBox,'String','20');
        set(MaxRadiusBox,'String','30');
        %
        processFindCircles
        set(CommentsBox,'string','Parameters reset to default values. (Visualization options not changed)');
    end

    function toggleEdgeThreshSlider(varargin)
        if get(varargin{1},'value') == 1
            set(EdgeSlider,'enable','off');
        else
            set(EdgeSlider,'enable','on');
        end
    end
end

Contact us