Code covered by the BSD License  

Highlights from
imcensor

image thumbnail

imcensor

by

 

GUI to censor parts of an image

imcensor(I)
function [C] = imcensor(I)
%Function with GUI to allow user to censor part of an image
%SCd 01/25/2011
%
%Usage: 
%   -C = imcensor(I);
%   -C = imcensor;
%   
%       The user will then select the parts of the image 
%       to censor and the censor function.
%
%Input Arguments:
%   -I: mxn or mxnxp image of any class.
%   -none: User will be allowed to pick an image file from directory.
%
%Output Arguments:
%   -C: I with the selected parts censored by user.
%


    %Error Checking/Warnings Off/Preallocation:
    warning('off','Images:BLKPROC:DeprecatedFunction');
    warning('off','MATLAB:mat2cell:TrailingUnityVectorArgRemoved');   
    if nargin == 0
        [fn, pn] =uigetfile({'*.jpg';'*.jpeg';'*.tif';'*.gif';'*.bmp';'*.tiff';'*.png';},'Select Image','multiselect','off');
        I = imread([pn fn]);
    end
    assert(ndims(I)<=3,'The size of the first input argument, I, is supposed to be 2 or 3-dimensional.\n  It was size: [%s]',num2str(size(I)));
    assert(isnumeric(I),'The image is expected to be numeric.');
    I2 = I;      %No censor yet!
    Istore = I;  %Save in case of restart
    
    %Make GUI:
    H.FigH = figure('units','pixels', 'position',[300 300 700 650],'menubar','none',...
         'name','Censor Your Image','numbertitle','off','resize','off',...
         'deletefcn',{@closeFun});
    H.CloseH = uicontrol('style','pushbutton','units','pixels','string','Finished!','position',[530 10 150 35],...
         'fontsize',14,'callback',{@closeFun});
    H.RestartH = uicontrol('style','pushbutton', 'units','pixels','string',...
        'Restart','position',[530 50 150 35],'fontsize',14,'callback',{@restartFun});
    H.GoH = uicontrol('style','togglebutton','value',true,'unit','pixels',...
        'string','Go!','position',[470 20 50 50],'fontsize',18,'callback',{@goFun});    
    H.CenFunH = uipanel('Title','Censor Function','FontSize',10,'units','pixels',...
        'Position',[10 10 445 65],'BackgroundColor','white');
    H.BlockMeanH = uicontrol('parent',H.CenFunH,'style','radio','string','Block Mean',...
        'Value',true,'units','pixels','position',[5 25 95 20],'fontsize',10);
    H.VertMeanH = uicontrol('parent',H.CenFunH,'style','radio','string','Vertical mean',...
        'Value',false,'units','pixels','position',[105 25 105 20],'fontsize',10);
    H.HorzMeanH = uicontrol('parent',H.CenFunH,'style','radio','string','Horizontal mean',...
        'Value',false,'units','pixels','position',[215 25 125 20],'fontsize',10);
    H.BlackoutH = uicontrol('parent',H.CenFunH,'style','radio','string','Blackout',...
        'Value',false,'units','pixels','position',[335 25 95 20],'fontsize',10);
    H.blkszT = uicontrol('parent',H.CenFunH,'style','text','string','Block Size:',...
        'units','pixels','position',[2 2 95 20],'fontsize',9,'backgroundcolor','white');
    H.blkszH = uicontrol('parent',H.CenFunH,'style','edit','string','8',...
        'units','pixels','position',[85 4 35 20],'fontsize',10,'backgroundcolor','white');    
    H.A1 = axes('parent',H.FigH,'units','pixels','position',[10 85 680 505],'xtick',[],'ytick',[]);
    set(H.A1,'userdata',imshow(I));
    H.directions = uicontrol('style','pushbutton','string','Directions','callback',...
        {@showDirections}, 'position',[10 600 80 35]);
    H.credits = uicontrol('style','pushbutton','string','Credits','callback',...
        {@showCredits}, 'position',[610 600 80 35]);
    set(H.BlockMeanH,'callback',{@blockMean});
    set(H.VertMeanH,'callback',{@vertMean});
    set(H.HorzMeanH,'callback',{@horzMean});
    set(H.BlackoutH,'callback',{@Blackout});
    set(H.CloseH,'callback',{@closeFun});
    set(H.blkszH,'callback',{@getBlkSz});
    
    %Default blockMean/size
    blksz = 8;
    cenFun = @(x)cell2mat(cellfun(@(x)blkproc(x,[blksz blksz],@(x)ones(blksz)*nanM(x(:))),mat2cell(x,size(x,1),size(x,2),ones(1,size(x,3))),'uni',false));
    
    %Functional Functions:
    function applyCensor(I)
        %Get vertices and create logical of non-ROI
        [x y] = getpts(H);
        M = ~repmat(poly2mask(x,y,size(I,1),size(I,2)),[1 1 size(I,3)]);
        %New Image with map areas set to nan
        I2 = double(I);
        I2(M) = nan;
        %Apply Censor and set nan areas back to original values
        I2 = cast(cenFun(I2),class(I));
        I2(M) = I(M);
        %Update figure
        set(H.A1,'userdata',imshow(I2));
        set(H.GoH,'value',true,'enable','on');
    end
    uiwait(H.FigH)
    function closeFun(varargin)
        %Save current image as output image/Delete GUI
        C = I2;
        delete(H.FigH)
    end
    function restartFun(varargin)
        %Restore the original image
        I2 = Istore;
        I  = Istore;
        set(H.A1,'userdata',imshow(I2));
        set(H.GoH,'value',true);
    end
    function getBlkSz(varargin)
        %Get the current blocksize
        blksz = round(str2double(get(H.blkszH,'string')));
        if ~isnumeric(blksz)||any(isnan(blksz))||blksz<1
            set(H.blkszH,'string','8');
            blksz = 8;
        end    
        blockMean;
    end    
    function goFun(varargin)
        %Start selecting points
        set(H.GoH,'Value',false,'enable','off');
        applyCensor(I2);
    end    
    function showDirections(varargin)
        %Directions
        HM = msgbox(sprintf('Click Go to begin selecting one region\nClick with the left mouse button at the vertices of the parts you wish to censor.\nClick the right mouse button when done with a polygon\nThe selected censor function is what will be used to cover the selected polygon.'),'Directions:');
        uiwait(HM);
    end    
    function showCredits(varargin)
        %Credits
        HM = msgbox(sprintf('Sean de Wolski, University of Maine (Jan, 2011) \n\nI made this as an exercise in creating GUIs without GUIDE.\nThanks to Matt Fig for the informative FEX GUI tutorials.'),'Credits:');
        uiwait(HM);
    end
    function blockMean(varargin)
        %Blockmean function as censor function/radio trip
        cenFun = @(x)cell2mat(cellfun(@(x)blkproc(x,[blksz blksz],@(x)ones(blksz)*nanM(x(:))),mat2cell(x,size(x,1),size(x,2),ones(1,size(x,3))),'uni',false));
        set(H.BlockMeanH,'value',true);
        set(H.VertMeanH,'value',false);
        set(H.HorzMeanH,'value',false);
        set(H.BlackoutH,'value',false);
    end
    function vertMean(varargin)
        %Vertical mean function as censor function/radio trip
        cenFun = @(x)bsxfun(@times,ones(size(x)),nanM(x,1));
        set(H.BlockMeanH,'value',false);
        set(H.VertMeanH,'value',true);
        set(H.HorzMeanH,'value',false);
        set(H.BlackoutH,'value',false);
    end
    function horzMean(varargin)
        %Horizontal mean function as censor function/radio trip
        cenFun = @(x)bsxfun(@times,ones(size(x)),nanM(x,2));
        set(H.BlockMeanH,'value',false);
        set(H.VertMeanH,'value',false);
        set(H.HorzMeanH,'value',true);
        set(H.BlackoutH,'value',false);
    end
    function Blackout(varargin)
        %Blackout function as censor function/radio trip
        cenFun = @(x)zeros(size(x));
        set(H.BlockMeanH,'value',false);
        set(H.VertMeanH,'value',false);
        set(H.HorzMeanH,'value',false);
        set(H.BlackoutH,'value',true);
    end
    function [x y] = getpts(H)
        %Ask for points using ginput
        set(H.FigH,'currentaxes',H.A1)
        cnt = 0;
        x = zeros(100,1);
        y = zeros(100,1);
        while 1
            cnt = cnt+1;
            [x(cnt) y(cnt) b] = ginput(1);
            if b==3
                %truncate to used points
                x = x(1:cnt-1);
                y = y(1:cnt-1);
                break;
            end
        end
        %Remove points outside image
        x(y>size(I,1)|y<0) = [];
        y(y>size(I,1)|y<0) = [];
        y(x>size(I,2)|x<0) = [];
        x(x>size(I,2)|x<0) = [];
        if length(x)<3
            Hm = msgbox('3 Points are necessary to define a polygon');
            uiwait(Hm);
        end
    end
end
function X = nanM(X,dim)
   %mean treating nans as empty
   if nargin == 1; dim = 1; end
   nnnan = sum(~isnan(X),dim);
   X(isnan(X)) = 0;
   X = sum(X,dim)./nnnan;
end   
   

Contact us