Code covered by the BSD License  

Highlights from
FindCirclesGUI

image thumbnail
from FindCirclesGUI by Brett Shoelson
Launches a GUI environment for the detection of circles in an image.

FindCirclesGUI.m
function FindCirclesGUI(inputImage)
% 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.
%
% (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
% Copyright 2011-2012 MathWorks, Inc.
%
% See Also: IMFINDCIRCLES, VISCIRCLES

if nargin < 1
    fname = 'coins.png';
    inputImage = imread('coins.png');
elseif ischar(inputImage)
    fname = inputImage;
    inputImage = imread(inputImage);
else
    fname = 'Original';
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',...
    'pos',[0.1875 0.05 0.625 0.85],...
    'color',bgc,...
    'menubar','none');

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');

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');

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',...
    'XLimMode','auto',...
    'YLimMode','auto',...
    'Visible','off');

ImgObj = imshow(inputImage);
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 = 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 = 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','VisualizationOptionsPanel',...
    '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','LineWidthText');

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','LineWidthValBox');

circleColor = [0 1 1];
circleColorButton = uicontrol(...
    'Parent',VisualizationPanel,...
    'style','pushbutton',...
    'pos',[0.7 0.45 0.15 0.35],...
    'cdata',reshape(kron(circleColor,ones(25,25)),25,25,3),...
    'callback',@changeCircleColor);
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','ClearPreviousBox');

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','UseWhiteBGBox');

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','ProcessButton');

ProcessImmediatelyBox = uicontrol(...
    'Parent',ProcessOptionsPanel,...
    'Callback','',...
    'Units','Normalized',...
    'Position',[0.05 0.8 0.9 0.15],...
    'String','Process Immediately',...
    'Style','checkbox',...
    'Value',1,...
    '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','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','30',...
    'Style','edit',...
    'Tag','MaxRadiusBox');

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

    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);
    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')==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)
        filterspec = imgformats(1);
        [filename,pathname] = uigetfile(filterspec, 'Select new image.');
        set(gcbo,'state','off');
        if ~ischar(pathname)
            return
        end
        fname = fullfile(pathname,filename);
        inputImage = imread(fname);
        cla(ImageAxis);
        ImgObj = imshow(inputImage,'parent',ImageAxis);
        expandAxes(ImageAxis);
        ImgTitle = title(fname);
        % Note: I can't figure out why the following line is
        % needed, but the axis is sometimes not updating
        % limits properly when I load a new image.
        % (XLIMMODE, etc. are somehow manual at this point. WHY???)
        %set(ImageAxis','XLimMode','manual','YLimMode','manual');
        set(ImageAxis,'XLim',0.5+[0 size(inputImage,2)],'YLim',0.5+[0 size(inputImage,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)
        set(CommentsBox,'string','Processing...please wait.');
        drawnow
        cboTag = get(varargin{1},'tag');
        processImmediately = get(ProcessImmediatelyBox,'value');
        if processImmediately || strcmp(cboTag,'ProcessButton');
            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 toggleEdgeThreshSlider(varargin)
        if get(varargin{1},'value') == 1
            set(EdgeSlider,'enable','off');
        else
            set(EdgeSlider,'enable','on');
        end
    end
end

Contact us