Code covered by the MathWorks Limited License

Highlights from
Cascade Training GUI: Specify Ground Truth

image thumbnail

Cascade Training GUI: Specify Ground Truth

by

 

08 Mar 2013 (Updated )

Interactive GUI for managing the selection and positioning of rectangular ROIs in a list of images.

addROI(varargin)
function roi = addROI(varargin)
% ADDROI: Create imrect with pushbutton- and context menu-deletion
%         and createPositionConstraint (disallows creating beyond image
%         edge)
%
% Calls IMRECT to generate a standard IMROI, but modifies the object's
% context menu, and adds a (simulated) pushbutton "x" for deleting the
% object. The creation of the imrect is also constrained to be within the
% bounds of the image (axis), and the setPositionConstraint constrains
% dragging to within the bounds of the axis by default.
%
% SYNTAX:
%   roi = addROI(parent) creates a new rectangular region of interest in
%   the axes specified by PARENT.
%
%   roi = addROI(parent,param,val,...) sets additional properties.
%         (See IMRECT for details.)
%
% Brett Shoelson, PhD
% brett.shoelson@mathworks.com
% 
% Note: Includes modification by Roland Michaely. (Better positioning, look
%       of "X" closing box.)
%
% See also: IMRECT, IMROI

%   Copyright 2010-2013 The Mathworks Inc

roi = imrect(varargin{:});
if isempty(roi)
    % Escape character pressed
    return
end
roiPos = roi.getPosition;

% Simulate a "close ROI button" in the parent axes
parentAx = ancestor(get(roi,'parent'),'axes');
sz = 40;xOffset = 0;yOffset=0;
% I call this delButton, but it's really a text block/buttondownfcn.
% (uicontrols can't be children of axes.)
delButton = text('parent',parentAx,...
    'pos',[roiPos(1)+roiPos(3)+xOffset roiPos(2)+yOffset sz],... 
    'string','\fontsize{4} \bf\fontsize{6}X\rm\fontsize{4} ',...
    'tag','delButton',...
    'edgecolor','w',...
    'color','w',...
    'backgroundcolor',[0.7 0 0],...'r',...
    'horizontalalignment','center',...
    'buttondownfcn',@deleteROI);
roi.addNewPositionCallback(@repositionButton);

% Add a context menu for region deletion
l = findobj(roi,'type','line');
uic = unique( cell2mat(get(l,'UIContextMenu')) );
for u=1:numel(uic)
    uimenu( uic(u), 'Label', 'Delete', 'Callback', @deleteROI )
end

% USER: Set position constraint here:
%fcn = makeConstrainToRectFcn('imrect',get(gca,'XLim'),get(gca,'YLim'));
fcn = makeConstrainToRectFcn('imrect',get(parentAx,'XLim'),get(parentAx,'YLim'));
setPositionConstraintFcn(roi,fcn);

% Here I create my own position constraint, so that the user cannot draw an
% ROI outside the bounds of the image. (The setPositionConstraintFcn
% disallows _moving_ the ROI beyond the edge of the image, but not
% _creating_ it beyond the edge.)
rp = roi.getPosition;
xl = get(parentAx,'xlim');
yl = get(parentAx,'ylim');
needsOverride = [rp(1) < xl(1), rp(1)+rp(3) > xl(2), rp(2) < yl(1), rp(2)+rp(4) > yl(2)];
if needsOverride(1) %Drawn beyond left axis edge
    roi.setPosition([xl(1) rp(2) rp(3)-(xl(1)-rp(1)) rp(4)])
    rp = roi.getPosition;
end
if needsOverride(2) %Drawn beyond right axis edge
    roi.setPosition([rp(1) rp(2) xl(2)-rp(1) rp(4)]);
    rp = roi.getPosition;
end
if needsOverride(3) %Drawn above top axis edge
    roi.setPosition([rp(1) yl(1) rp(3) rp(4)-(yl(1)-rp(2))]);
    rp = roi.getPosition;
end
if needsOverride(4) %Drawn below bottom axis edge
    roi.setPosition([rp(1) rp(2) rp(3) yl(2)-rp(2)])
end

% USER: Add (addditional) newPosition callbacks here:

% NESTED SUBFUNCTIONS
    function deleteROI(src,evt) %#ok
        delete(delButton)
        delete(roi);
    end

    function repositionButton(newPos) 
        set(delButton,'pos',[newPos(1)+newPos(3)+xOffset newPos(2)+yOffset sz])
        % check if upper left border is outside axes
        if newPos(1)+xOffset < min(get(parentAx,'xLim')) || ...
                newPos(1)+xOffset > max(get(parentAx,'xLim'))|| ...
                newPos(2)+yOffset < min(get(parentAx,'yLim'))|| ...
                newPos(2)+yOffset >max(get(parentAx,'yLim'))
            set(delButton,'Visible','off')
        else
            set(delButton,'Visible','on')
        end
    end

end % EOF

Contact us