function nlfdemo(action,s);
%NLFDEMO Demonstrates non-linear filtering in the Image Processing Toolbox.

%	Copyright (c) 1993 by The MathWorks, Inc.
%	$Revision: 1.4 $  $Date: 1993/10/21 12:59:32 $

% Possible actions:
% initialize
% reload
% eval
% demobutton
% info
% closehelp

if nargin<1,
    action='initialize';
end;

if strcmp(action,'initialize'),
    oldFigNumber=watchon;

    figNumber=figure( ...
	'Name','2-D Non-linear Filtering Demo', ...
        'NumberTitle','off', ...
	'Visible','off');

    figDefaultAxesPos=[0.10 0.45 0.60 0.45];
    set(figNumber,'DefaultAxesPosition',figDefaultAxesPos);

    imageHndl = axes( ...
	'Units','normalized', ...
        'Position',figDefaultAxesPos);
    
    %===================================
    % Set up the MiniCommand Window
    top=0.35;
    left=0.05;
    right=0.70;
    bottom=0.05;
    labelHt=0.05;
    spacing=0.005;
    promptStr=str2mat(' ',' % Press the buttons at the right to see', ...
	' % examples of the types of non-linear filtering ', ...
    ' % operations you can perform with the image ', ...
    ' % processing toolbox.');
    % First, the MiniCommand Window frame
    frmBorder=0.02;
    frmPos=[left-frmBorder bottom-frmBorder ...
	(right-left)+2*frmBorder (top-bottom)+2*frmBorder];
    uicontrol( ...
        'Style','frame', ...
        'Units','normalized', ...
        'Position',frmPos, ...
	'BackgroundColor',[0.50 0.50 0.50]);
    % Then the text label
    labelPos=[left top-labelHt (right-left) labelHt];
    uicontrol( ...
	'Style','text', ...
        'Units','normalized', ...
        'Position',labelPos, ...
        'BackgroundColor',[0.50 0.50 0.50], ...
	'ForegroundColor',[1 1 1], ...
        'String','MiniCommand Window');
    % Then the editable text field
    mcwPos=[left bottom (right-left) top-bottom-labelHt-spacing];
    mcwHndl=uicontrol( ...
	'Style','edit', ...
        'Units','normalized', ...
        'Max',10, ...
        'BackgroundColor',[1 1 1], ...
        'Position',mcwPos, ...
	'Callback','nlfdemo(''eval'')', ...
        'String',promptStr);

    %====================================
    % Information for all buttons
    labelColor=[0.8 0.8 0.8];
    top=0.95;
    btnWid=0.20;
    btnHt=0.07;
    right=0.95;
    left=right-btnWid;
    % Spacing between the button and the next command's label
    spacing=0.03;

    %====================================
    % The CONSOLE frame
    frmBorder=0.02;
    yPos=0.05-frmBorder;
    frmPos=[left-frmBorder yPos btnWid+2*frmBorder 0.9+2*frmBorder];
    uicontrol( ...
        'Style','frame', ...
        'Units','normalized', ...
        'Position',frmPos, ...
	'BackgroundColor',[0.50 0.50 0.50]);
    
    %====================================
    % The RELOAD IMAGE button
    btnNumber=1;
    yPos=top-(btnNumber-1)*(btnHt+spacing);
    labelStr='Reload image';
    callbackStr='nlfdemo(''reload'')';
    
    % Generic popup button information
    btnPos=[left yPos-btnHt btnWid btnHt];
    reloadHndl = uicontrol( ...
	'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'String',labelStr, ...
        'Callback',callbackStr);

    top = top - spacing/2;
    %====================================
    % The EQUALIZE button
    btnNumber=2;
    yPos=top-(btnNumber-1)*(btnHt+spacing);
    labelStr='Scale';
    callbackStr='nlfdemo(''demobutton'')';
    cmdStr=str2mat( ...
        ' % Locally scale image in blocks using blkproc', ...
		' I = getimage;', ...
		' J = blkproc(I,[8 8],''mat2gray'');', ...
		' imshow(J,64)' ...
    );
    
    % Generic button information
    btnPos=[left yPos-btnHt btnWid btnHt];
    blkHndl = uicontrol( ...
		'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
    	'String',labelStr, ...
		'Callback',callbackStr, ...
	'UserData',cmdStr);

    %====================================
    % The PIXELIZE button
    btnNumber=3;
    yPos=top-(btnNumber-1)*(btnHt+spacing);
    labelStr='Pixelize';
    callbackStr='nlfdemo(''demobutton'')';
    cmdStr=str2mat( ...
        ' % Pixelize image using colfilt ', ...
        ' % with distinct blocks.', ...
		' I = getimage;', ...
		' J = colfilt(I,[4 4],''distinct'',''ones(16,1)*mean(x)'');', ...
		' imshow(J,64)' ...
    );
    
    % Generic popup button information
    btnPos=[left yPos-btnHt btnWid btnHt];
    uicontrol( ...
	'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'String',labelStr, ...
        'Callback',callbackStr, ...
	'UserData',cmdStr);

    %====================================
    % The MAX button
    btnNumber=4;
    yPos=top-(btnNumber-1)*(btnHt+spacing);
    labelStr='GrayDilate';
    callbackStr='nlfdemo(''demobutton'')';
    cmdStr=str2mat( ...
        ' % Example of gray scale dilation.', ...
		' % Apply max to 3-by-3 sliding blocks.', ...
		' I = getimage;', ...
        ' J = colfilt(I,[3 3],''sliding'',''max'');', ...
		' imshow(J,64)' ...
    );
    
    % Generic popup button information
    btnPos=[left yPos-btnHt btnWid btnHt];
    uicontrol( ...
	'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'String',labelStr, ...
        'Callback',callbackStr, ...
	'UserData',cmdStr);

    %====================================
    % The VARIANCE button
    btnNumber=5;
    yPos=top-(btnNumber-1)*(btnHt+spacing);
    labelStr='StandardDev';
    callbackStr='nlfdemo(''demobutton'')';
	cmdStr=str2mat( ...
        ' % Compute standard deviation image', ...
		' I = getimage; ', ...
		' J = colfilt(I,[3 3],''sliding'',''std(x)'');', ...
        ' imshow(mat2gray(J),64)' ...
    );
    
    % Generic popup button information
    btnPos=[left yPos-btnHt btnWid btnHt];
    uicontrol( ...
	'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'String',labelStr, ...
        'Callback',callbackStr, ...
	'UserData',cmdStr);

    %====================================
    % The Max Derivative button
    btnNumber=6;
    yPos=top-(btnNumber-1)*(btnHt+spacing);
    labelStr='Max Deriv';
    callbackStr='nlfdemo(''demobutton'')';
	cmdStr=str2mat( ...
        ' % Compute maximum directional derivative image', ...
		' I = getimage; h = fspecial(''sobel''); j=sqrt(-1);', ...
		' dx = filter2(-h'',I); dy = filter2(h,I); ', ...
		' phi = angle(dx+j*dy); J = cos(phi).*dx + sin(phi).*dy; ', ... 
        ' imshow(mat2gray(J),64)' ...
    );
    
    % Generic popup button information
    btnPos=[left yPos-btnHt btnWid btnHt];
    uicontrol( ...
	'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'String',labelStr, ...
        'Callback',callbackStr, ...
	'UserData',cmdStr);

    %====================================
    % The MASKED FILTER button
    btnNumber=7;
    yPos=top-(btnNumber-1)*(btnHt+spacing);
    labelStr='Masked Filter';
    callbackStr='nlfdemo(''demobutton'')';
	cmdStr=str2mat( ...
        ' % Masked Filter an image', ...
		' I = getimage; h = fspecial(''sobel''); [m,n] = size(I);', ...
        ' [x,y] = meshgrid((0:n-1)-n/2,(0:m-1)-m/2); ', ...
		' mask = sqrt(x.^2+y.^2) < m/2.5; ', ...
        ' J = mfilter2(I,mask,''mat2gray(filter2(P1,x))'',h);', ...
        ' imshow(J,64)' ...
    );
    
    % Generic popup button information
    btnPos=[left yPos-btnHt btnWid btnHt];
    uicontrol( ...
	'Style','pushbutton', ...
        'Units','normalized', ...
        'Position',btnPos, ...
        'String',labelStr, ...
        'Callback',callbackStr, ...
	'UserData',cmdStr);

    %====================================
    % The INFO button
    uicontrol( ...
	'Style','push', ...
        'Units','normalized', ...
        'Position',[left bottom+btnHt+spacing btnWid btnHt], ...
        'String','Info', ...
        'Callback','nlfdemo(''info'')');

    %====================================
    % The CLOSE button
    uicontrol( ...
	'Style','push', ...
        'Units','normalized', ...
        'Position',[left bottom btnWid btnHt], ...
        'String','Close', ...
        'Callback','close(gcf)');

	% Place data in axes
    load trees
    I=ind2gray(imresize(X,.5),map);
    imshow(I,64); title('Original Image')
	set(imageHndl,'UserData',I)

    % Now uncover the figure
    set(figNumber,'Visible','on','UserData',[mcwHndl blkHndl imageHndl]);
    watchoff(oldFigNumber);
    figure(figNumber);

elseif strcmp(action,'reload'),
    hndlList=get(gcf,'UserData');
    imageHndl = hndlList(3);
    I = get(imageHndl,'UserData');
    if isempty(I), 
      I = getimage(imageHndl);
      if isempty(I), 
        disp([7,'Figure must contain an image for demo.']), return
      end
      if ~isgray(I),
        if isind(I),
          I = ind2gray(I,colormap);
        else
          I = mat2gray(I);
        end
        axes(imageHndl)
      end
    end
    imshow(I,64), set(imageHndl,'UserData',I)
    title('Original image')
	
elseif strcmp(action,'demobutton'),
    hndlList=get(gcf,'UserData');
	mcwHndl = hndlList(1);
	blkHndl = hndlList(2);
	v = get(blkHndl,'value');
	cmdStr=get(gco,'UserData');
    set(mcwHndl,'String',cmdStr);
    nlfdemo('eval')

elseif strcmp(action,'eval'),
    hndlList=get(gcf,'UserData');
	mcwHndl = hndlList(1);
	blkHndl = hndlList(2);
    imageHndl = hndlList(3);
    I = get(imageHndl,'UserData');
    if isempty(I), 
      I = getimage(imageHndl);
      if isempty(I), 
        disp([7,'Figure must contain an image for demo.']), return
      end
      if ~isgray(I),
        if isind(I),
          I = ind2gray(I,colormap);
        else
          I = mat2gray(I);
        end
        axes(imageHndl)
      end
      imshow(I,64)
    end
    cmdStr=get(mcwHndl,'String');
    evalmcw(mcwHndl);
    set(imageHndl,'UserData',I)
    title('Filtered image')

elseif strcmp(action,'info'),
    ttlStr=get(gcf,'Name');
dum = [ ...
         ' Toolbox. Pressing the various buttons allows  '  
         ' you to, among other things, equalize,         '
         ' pixelize, dilate, or masked filter a gray     '
		 ' scale image.  There are also buttons to       '
		 ' compute the standard deviation, maximum       '
		 ' directional derivative in each 3-by-3 sliding '
		 ' block in the image. Each of these operations  '
		 ' are described in more detail below.           '
		 '                                               '];
    hlpStr1= ...                                             
        ['                                               '  
         ' This demo lets you explore non-linear         '  
         ' filtering using some of the commands          '  
         ' available to you in the Image Processing      '
		 ' Toolbox.  Each button in the demo is described'
		 ' below.                                        '
		 '                                               '
		 ' Press the RELOAD IMAGE button to return to    '
		 ' the original image.                           '
		 '                                               '
         ' The SCALE button scales each distinct 8-by-8  '
		 ' in the current image to fill the full         '
		 ' intensity range.                              '
		 '                                               '
		 ' The PIXELIZE button replaces each 4-by-4 block'
		 ' with its average.                             '];
	hlpStr2 = [...
		 '                                               '
         ' The GRAYDILATE button replaces each pixel with'
		 ' the maximum value in its local 3-by-3         '
		 ' neighborhood.                                 '
		 '                                               '
		 ' The STANDARDDEV button replaces each pixel    '
		 ' the standard deviation in its local 3-by-3    '
		 ' neighborhood.                                 '
		 '                                               '
		 ' The MAX DERIV button replaces each pixel with '
		 ' an estimate of the maximum directional        '
		 ' derivative of the intensity at that point.    '
         '                                               '
		 ' The MASKED FILTER button creates a circular   '
		 ' mask and applies a Sobel filter to the image  '
		 ' underneath the mask.                          '];
	hlpStr3 = [...
         '                                               '
         ' You can install your own image as the original'
         ' image using IMSHOW from the command line.     '
         ' Color images will be converted to gray when   '
		 ' a button is pressed.  Your image will become  '
		 ' the original image.                           '
         '                                               '
         ' If you like, you can even directly edit the   '  
         ' commands in the MiniCommand Window.           '  
         ' Type control-return to execute code in the    '  
         ' MiniCommand Window.                           '  
         '                                               '  
         ' File name: nlfdemo.m                          '];
    myFig = gcf;
    helpfun(ttlStr,hlpStr1,hlpStr2,hlpStr3);

    % Protect against gcf changing -- Change close button behind
    % helpfun's back
    ch = get(gcf,'ch');
    for i=1:length(ch),
      if strcmp(get(ch(i),'type'),'uicontrol'),
        if strcmp(lower(get(ch(i),'String')),'close'),
          callbackStr = [get(ch(i),'callback') ...
            '; nlfdemo(''closehelp'',' num2str(myFig) ')'];
          set(ch(i),'callback',callbackStr)
          return
        end
      end
    end
    return

elseif strcmp(action,'closehelp'),
    % Restore close button help behind helpfun's back
    ch = get(gcf,'ch');
    for i=1:length(ch),
      if strcmp(get(ch(i),'type'),'uicontrol'),
        if strcmp(lower(get(ch(i),'String')),'close'),
          callbackStr = get(ch(i),'callback');
          k = findstr('; nlfdemo(',callbackStr);
          callbackStr = callbackStr(1:k-1);
          set(ch(i),'callback',callbackStr)
          break;
        end
      end
    end
    ch = get(0,'ch');
    if ~isempty(find(ch==s)), figure(s), end % Make sure figure exists
   
end;    % if strcmp(action, ...
