⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ice_stand_alone.m

📁 Image Processing Toolbox
💻 M
📖 第 1 页 / 共 4 页
字号:
function varargout = ice(varargin)
%ICE Interactive Color Editor.
%
%   OUT = ICE('Property Name', 'Property Value', ...) transforms
%   an image's color components based on interactively specified
%   mapping functions. Inputs are Property Name/Property Value pairs: 
%
%     Name            Value
%     ------------    -------------------------------------------------
%     'image'         An RGB or monochrome input image to be transformed
%                     by interactively specified mappings.
%     'space'         The color space of the components to be modified.
%                     Possible values are 'rgb', 'cmy', 'hsi',
%                     'hsv', 'ntsc' (or 'yiq'), 'ycbcr'. When omitted,
%                     the RGB color space is assumed.
%     'wait'          If 'on' (the default), OUT is the mapped input image
%                     and ICE returns to the calling function or workspace
%                     when closed. If 'off', OUT is the handle of the mapped
%                     input image and ICE returns immediately.
%
%   EXAMPLES:
%     ice                                  % Demo curves mode
%     ice('image', f)                      % Map RGB or mono image
%     ice('image', f, 'space', 'hsv')      % Map HSV of RGB image
%     g = ice('image', f, 'wait', 'off');  % Return with handles of g
%
%   ICE displays one popup menu selectable mapping function at a time.
%   Each image component is mapped by a dedicated curve (e.g., R, G,
%   or B) and then bt an all-component curve (e.g., RGB). Each curve's
%   control points are depicted as circles that can be moved, added,
%   or deleted with a three-button mouse:
%
%     Mouse Button    Editing Operation
%     ------------    -------------------------------------------------
%     Left            Move control point by pressing and dragging.
%     Middle          Add and position a control point by pressing
%                     and dragging. (Optionally Shift-Left)
%     Right           Deleted a control point. (Optionally Control-Left)
%
%   Checkboxes determine how  mapping function are computed, whether
%   the input image and reference pseudo- and full-color bars are
%   mapped, and the displayed reference curve information (e.g., PDF):
%
%     Checkbox        Function
%     ------------    -------------------------------------------------
%     Smooth          Checked for cubic spline (smooth curve) interpo-
%                     lation. If unchecked, piecewise linear.
%     Clamp Ends      Checked to force the starting and ending curve
%                     slopes in cubic spline interpolation to 0. No
%                     effect on piecewise linear.
%     Show PDF        Display probablity density function(s) [i.e.,
%                     histogram(s)] of the image components effected by
%                     the mapping function.
%     Show CDF        Display cumulative distributions function(s)
%                     instead of PDFs.
%                     <Note: Show PDF/CDF are mutually exclusive.>
%     Map Image       If checked, image mapping is enabled; else not.
%     Map Bars        If checked, pseudo- and full-color bar mapping is
%                     enabled; else display th eunmapped bars (a gray
%                     wedge and hue wedge, respectively).
%
%   Mapping functions can be initialized via pushbuttons:
%
%     Button          Function
%     ------------    -------------------------------------------------
%     Reset           Init the currently displayed mapping function
%                     and uncheck all curve parameters.
%     Reset All       Initalize all mapping functions.

%   Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins
%   Digital Image Processing Using MATLAB, Prentice-Hall, 2004
%   $Revision: 1.2 $  $Date: 2003/02/19 22:10:00 $

gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @ice_OpeningFcn, ...
                   'gui_OutputFcn',  @ice_OutputFcn, ...
                   'gui_LayoutFcn',  @ice_LayoutFcn, ...
                   'gui_Callback',   []);
if nargin & isstr(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end

%-------------------------------------------------------------------%
function ice_OpeningFcn(hObject, eventdata, handles, varargin)
%  When ICE is opened, perform basic initialization (e.g., setup
%  globals, ...) before it is made visible.

% Set ICE globals to defaults.
handles.updown = 'none';            % Mouse updown state
handles.plotbox = [0 0 1 1];        % Plot area parameters in pixels
handles.set1 = [0 0; 1 1];          % Curve 1 control points
handles.set2 = [0 0; 1 1];          % Curve 2 control points
handles.set3 = [0 0; 1 1];          % Curve 3 control points
handles.set4 = [0 0; 1 1];          % Curve 4 control points
handles.curve = 'set1';             % Structure name of selected curve
handles.cindex = 1;                 % Index of selected curve
handles.node = 0;                   % Index of selected control point
handles.below = 1;                  % Index of node below control point
handles.above = 2;                  % Index of node above control point
handles.smooth = [0; 0; 0; 0];      % Curve smoothing states
handles.slope = [0; 0; 0; 0];       % Curve end slope control states
handles.cdf = [0; 0; 0; 0];         % Curve CDF states
handles.pdf = [0; 0; 0; 0];         % Curve PDF states
handles.output = [];                % Output image handle
handles.df = [];                    % Input PDFs and CDFs
handles.colortype = 'rgb';          % Input image color space
handles.input = [];                 % Input image data
handles.imagemap = 1;               % Image map enable
handles.barmap = 1;                 % Bar map enable
handles.graybar = [];               % Pseudo (gray) bar image
handles.colorbar = [];              % Color (hue) bar image

% Process Property Name/Property Value input argument pairs.
wait = 'on';
if(nargin > 3)
    for i = 1: 2: (nargin - 3),
        if nargin - 3 == i break;  end
        switch lower(varargin{i})
            case 'image'
            if ndims(varargin{i + 1}) == 3
                handles.input = varargin{i + 1};
            elseif ndims(varargin{i + 1}) == 2
                handles.input = cat(3, varargin{i + 1}, ...
                    varargin{i + 1}, varargin{i + 1});  end;
            handles.input = double(handles.input);
            inputmax = max(handles.input(:));
            if inputmax > 255   handles.input = handles.input / 65535;
            elseif inputmax > 1
            handles.input = handles.input / 255;    end
        
            case 'space'
                handles.colortype = lower(varargin{i + 1});
                switch handles.colortype
                    case 'cmy',  list = {'CMY' 'Cyan' 'Magenta' 'Yellow'};
                    case {'ntsc', 'yiq'}
                        list = {'YIQ' 'Luminance' 'Hue' 'Saturation'};
                        handles.colortype = 'ntsc';
                    case 'ycbcr',    list = {'YCbCr' 'Luminance' 'Blue' ...
                        'Difference'  'Red Difference'};
                    case 'hsv',  list = {'HSV' 'Hue' 'Saturation' 'Value'};
                    case 'hsi',  list = {'HSI' 'Hue' 'Saturation' 'Intensity'};
                    otherwise
                        list = {'RGB' 'Red' 'Green' 'Blue'};
                        handles.colortype = 'rgb';
                end
                set(handles.component_popup, 'String', list);
            
            case 'wait', wait = lower(varargin{i + 1});
        end
    end
end
   
% Create pseudo- and full-color mapping bars (grays and hues). Store a
% color space converted 1x128x3 line of each bar for mapping.
xi = 0: 1/127: 1;          x = 0: 1 / 6: 1;     x = x';
y = [1 1 0 0 0 1 1; 0 1 1 1 0 0 0; 0 0 0 1 1 1 0]';
gb = repmat(xi, [1 1 3]);       cb = interp1q(x, y, xi');
cb = reshape(cb, [1 128 3]);
if ~strcmp(handles.colortype, 'rgb')
    gb = eval(['rgb2' handles.colortype '(gb)']);
    cb = eval(['rgb2' handles.colortype '(cb)']);   end
gb = round(255 * gb);     gb = max(0, gb);      gb = min(255, gb);
cb = round(255 * cb);     cb = max(0, cb);      cb = min(255, cb);
handles.graybar = gb;     handles.colorbar = cb;

% Do color space transforms, clamp to [0, 255], compute histograms
% and cumulative distribution functions, and create output figure.
if size(handles.input, 1)
    if ~strcmp(handles.colortype, 'rgb')
        handles.input = eval(['rgb2' handles.colortype ...
            '(handles.input)']);    end
    handles.input = round(255 * handles.input);
    handles.input = max(0, handles.input);
    handles.input = min(255, handles.input);
    for i = 1: 3
        color = handles.input(:, :, i);
        df = hist(color(:), 0: 255);
        handles.df = [handles.df; df / max(df(:))];
        df = df / sum(df(:));   df = cumsum(df);
        handles.df = [handles.df; df];
    end
    figure;     handles.output = gcf;
end

% Compute ICE's screen position and display image/graph.
set(0, 'Units', 'pixels');      ssz = get(0, 'Screensize');
set(handles.ice, 'Units', 'pixels');
uisz = get(handles.ice, 'Position');
if size(handles.input, 1)
    fsz = get(handles.output, 'Position');
    bc = (fsz(4) - uisz(4)) / 3;
    if bc > 0    bc = bc + fsz(2);
    else bc = fsz(2) + fsz(4) - uisz(4) - 10;  end
    lc = fsz(1) + (size(handles.input, 2) / 4) + (3 * fsz(3) / 4);
    lc = min(lc, ssz(3) - uisz(3) - 10);
    set(handles.ice, 'Position', [lc bc 463 391]);
else
    bc = round((ssz(4) - uisz(4)) / 2) - 10;
    lc = round((ssz(3) - uisz(3)) / 2) - 10;
    set(handles.ice, 'Position', [lc bc uisz(3) uisz(4)]);
end
set(handles.ice, 'Units', 'normalized');
graph(handles);     render(handles);

% Update handles and Make ICE wait before exit if required.
guidata(hObject, handles);
if strcmpi(wait, 'on')  uiwait(handles.ice);    end

%-------------------------------------------------------------------%
function varargout = ice_OutputFcn(hObject, eventdata, handles)
%  After ICE is closed, get the image data of the current figure
%  for the output. If 'handles' exists, ICE isn抰 closed (there was
%  no 'uiwait') so output figure handle.

if max(size(handles)) == 0
    figh = get(gcf);
    imageh = get(figh.Children);
    if max(size(imageh)) > 0
        image = get(imageh.Children);
        varargout{1} = image.CData;
    end
else    varargout{1} = hObject;  end

%-------------------------------------------------------------------%
function ice_WindowButtonDownFcn(hObject, eventdata, handles)
%  Start mapping function control point editing. Do move, add, or
%  delete for left, middle, and right button mouse clicks ('normal',
%  'extend', and 'alt' cases) over plot area.

set(handles.curve_axes, 'Units', 'pixels');
handles.plotbox = get(handles.curve_axes, 'Position');
set(handles.curve_axes, 'Units', 'normalized');
[inplot, x, y] = cursor(hObject, handles);
if inplot
    nodes = getfield(handles, handles.curve);
    i = find(x >= nodes(:, 1));      below = max(i);
    above = min(below + 1, size(nodes, 1));
    if (x - nodes(below, 1)) > (nodes(above, 1) - x)    node = above;
    else  node = below;    end
    deletednode = 0;
    
    switch get(hObject, 'SelectionType')
        case 'normal'
        if node == above    above = min(above + 1, size(nodes, 1));
        elseif node == below    below = max(below - 1, 1);      end
        if node == size(nodes, 1)   below = above;
        elseif node == 1    above = below;      end
        if x > nodes(above, 1)  x = nodes(above, 1);
        elseif x < nodes(below, 1)  x = nodes(below, 1);    end
        handles.node = node;    handles.updown = 'down';
        handles.below = below;  handles.above = above;
        nodes(node, :) = [x y];
        case 'extend'
            if ~length(find(nodes(:, 1) == x))
                nodes = [nodes(1: below, :); [x y]; nodes(above: end, :)];
                handles.node = above;   handles.updown = 'down';
                handles.below = below;  handles.above = above + 1;
            end
        case 'alt'
            if (node ~= 1) & (node ~= size(nodes, 1))
                nodes(node, :) = [];    deletednode = 1;    end
            handles.node = 0;
            set(handles.input_text, 'String', '');
            set(handles.output_text, 'String', '');
    end

    handles = setfield(handles, handles.curve, nodes);
    guidata(hObject, handles);
    graph(handles);
    if deletednode  render(handles);    end
end

%-------------------------------------------------------------------%
function ice_WindowButtonMotionFcn(hObject, eventdata, handles)
%  Do nothing unless a mouse 'down' event has occurred. If it has,
%  modify control point and make new mapping function. 

if ~strcmpi(handles.updown, 'down') return;  end
[inplot, x, y] = cursor(hObject, handles);
if inplot
    nodes = getfield(handles, handles.curve);
    nudge = handles.smooth(handles.cindex) / 256;
    if (handles.node ~= 1) & (handles.node ~= size(nodes, 1))
        if x >= nodes(handles.above, 1)
            x = nodes(handles.above, 1) - nudge;
        elseif x <= nodes(handles.below, 1)
            x = nodes(handles.below, 1) + nudge;    end
    else
        if x > nodes(handles.above, 1)
            x = nodes(handles.above, 1);
        elseif x < nodes(handles.below, 1)
            x = nodes(handles.below, 1);    end
    end
    nodes(handles.node, :) = [x y];
    handles = setfield(handles, handles.curve, nodes);
    guidata(hObject, handles);
    graph(handles);
end

%-------------------------------------------------------------------%
function ice_WindowButtonUpFcn(hObject, eventdata, handles)
%  Terminate ongoing control point move or add operation. Clear
%  coordinate text below plot and update display.

update = strcmpi(handles.updown, 'down');
handles.updown = 'up';      handles.node = 0;
guidata(hObject, handles);
if update
    set(handles.input_text, 'String', '');
    set(handles.output_text, 'String', '');
    render(handles);
end

%-------------------------------------------------------------------%
function component_popup_Callback(hObject, eventdata, handles)
%  Accept color component selection, update component specific

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -