📄 ice_stand_alone.m
字号:
% parameters on GUI, and draw the selected mapping function.
c = get(hObject, 'Value');
handles.cindex = c;
handles.curve = strcat('set', num2str(c));
guidata(hObject, handles);
set(handles.smooth_checkbox, 'Value', handles.smooth(c));
set(handles.slope_checkbox, 'Value', handles.slope(c));
set(handles.pdf_checkbox, 'Value', handles.pdf(c));
set(handles.cdf_checkbox, 'Value', handles.cdf(c));
graph(handles);
%-------------------------------------------------------------------%
function smooth_checkbox_Callback(hObject, eventdata, handles)
% Accept smoothing parameter for currently selected color
% component and redraw mapping function.
if get(hObject, 'Value')
handles.smooth(handles.cindex) = 1;
nodes = getfield(handles, handles.curve);
nodes = spreadout(nodes);
handles = setfield(handles, handles.curve, nodes);
else handles.smooth(handles.cindex) = 0; end
guidata(hObject, handles);
set(handles.ice, 'Pointer', 'watch');
graph(handles); render(handles);
set(handles.ice, 'Pointer', 'arrow');
%-------------------------------------------------------------------%
function reset_pushbutton_Callback(hObject, eventdata, handles)
% Init all display parameters for currently selected color
% component, make map 1:1, and redraw it.
handles = setfield(handles, handles.curve, [0 0; 1 1]);
c = handles.cindex;
handles.smooth(c) = 0; set(handles.smooth_checkbox, 'Value', 0);
handles.slope(c) = 0; set(handles.slope_checkbox, 'Value', 0);
handles.pdf(c) = 0; set(handles.pdf_checkbox, 'Value', 0);
handles.cdf(c) = 0; set(handles.cdf_checkbox, 'Value', 0);
guidata(hObject, handles);
set(handles.ice, 'Pointer', 'watch');
graph(handles); render(handles);
set(handles.ice, 'Pointer', 'arrow');
%-------------------------------------------------------------------%
function slope_checkbox_Callback(hObject, eventdata, handles)
% Accept slope clamp for currently selected color component and
% draw function if smoothing is on.
if get(hObject, 'Value')
handles.slope(handles.cindex) = 1;
else handles.slope(handles.cindex) = 0; end
guidata(hObject, handles);
if handles.smooth(handles.cindex)
set(handles.ice, 'Pointer', 'watch');
graph(handles); render(handles);
set(handles.ice, 'Pointer', 'arrow'); end
%-------------------------------------------------------------------%
function resetall_pushbutton_Callback(hObject, eventdata, handles)
% Init display parameters for color components, make all maps 1:1,
% and redraw display.
for c = 1: 4
handles.smooth(c) = 0; handles.slope(c) = 0;
handles.pdf(c) = 0; handles.cdf(c) = 0;
handles = setfield(handles, ['set' num2str(c)], [0 0; 1 1]);
end
set(handles.smooth_checkbox, 'Value', 0);
set(handles.slope_checkbox, 'Value', 0);
set(handles.pdf_checkbox, 'Value', 0);
set(handles.cdf_checkbox, 'Value', 0);
guidata(hObject, handles);
set(handles.ice, 'Pointer', 'watch');
graph(handles); render(handles);
set(handles.ice, 'Pointer', 'arrow');
%-------------------------------------------------------------------%
function pdf_checkbox_Callback(hObject, eventdata, handles)
% Accept PDF (probability density function or histogram) display
% parameter for currently selected color component and redraw
% mapping function if smoothing is on. If set, clear CDF display.
function pdf_checkbox_Callback(hObject, eventdata, handles)
if get(hObject, 'Value')
handles.pdf(handles.cindex) = 1;
set(handles.cdf_checkbox, 'Value', 0);
handles.cdf(handles.cindex) = 0;
else handles.pdf(handles.cindex) = 0; end
guidata(hObject, handles); graph(handles);
%-------------------------------------------------------------------%
function cdf_checkbox_Callback(hObject, eventdata, handles)
% Accept CDF (cumulative distribution function) display parameter
% for selected color component and redraw mapping function if
% smoothing is on. If set, clear CDF display.
if get(hObject, 'Value')
handles.cdf(handles.cindex) = 1;
set(handles.pdf_checkbox, 'Value', 0);
handles.pdf(handles.cindex) = 0;
else handles.cdf(handles.cindex) = 0; end
guidata(hObject, handles); graph(handles);
%-------------------------------------------------------------------%
function mapbar_checkbox_Callback(hObject, eventdata, handles)
% Accept changes to bar map enable state and redraw bars.
handles.barmap = get(hObject, 'Value');
guidata(hObject, handles); render(handles);
%-------------------------------------------------------------------%
function mapimage_checkbox_Callback(hObject, eventdata, handles)
% Accept changes to the image map state and redraw image.
function mapimage_checkbox_Callback(hObject, eventdata, handles)
handles.imagemap = get(hObject, 'Value');
guidata(hObject, handles); render(handles);
%-------------------------------------------------------------------%
function graph(handles)
% Interpolate and plot mapping functions and optional reference
% PDF(s) or CDF(s).
nodes = getfield(handles, handles.curve);
c = handles.cindex; dfx = 0: 1/255: 1;
colors = ['k' 'r' 'g' 'b'];
% For piecewise linear interpolation, plot a map, map + PDF/CDF, or
% map + 3 PDFs/CDFs.
if ~handles.smooth(handles.cindex)
if (~handles.pdf(c) & ~handles.cdf(c)) | ...
(size(handles.df, 2) == 0)
plot(nodes(:, 1), nodes(:, 2), 'b-', ...
nodes(:, 1), nodes(:, 2), 'ko', ...
'Parent', handles.curve_axes);
elseif c > 1
i = 2 * c - 2 - handles.pdf(c);
plot(dfx, handles.df(i, :), [colors(c) '-'], ...
nodes(:, 1), nodes(:, 2), 'k-', ...
nodes(:, 1), nodes(:, 2), 'ko', ...
'Parent', handles.curve_axes);
elseif c == 1
i = handles.cdf(c);
plot(dfx, handles.df(i + 1, :), 'r-', ...
dfx, handles.df(i + 3, :), 'g-', ...
dfx, handles.df(i + 5, :), 'b-', ...
nodes(:, 1), nodes(:, 2), 'k-', ...
nodes(:, 1), nodes(:, 2), 'ko', ...
'Parent', handles.curve_axes);
end
% Do the same for smooth (cubic spline) interpolations.
else
x = 0: 0.01: 1;
if ~handles.slope(handles.cindex)
y = spline(nodes(:, 1), nodes(:, 2), x);
else y = spline(nodes(:, 1), [0; nodes(:, 2); 0], x); end
i = find(y > 1); y(i) = 1;
i = find(y <0); y(i) = 0;
if (~handles.pdf(c) & ~handles.cdf(c)) | ...
(size(handles.df, 2) == 0)
plot(nodes(:, 1), nodes(:, 2), 'ko', x, y, 'b-', ...
'Parent', handles.curve_axes);
elseif c > 1
i = 2 * c - 2 - handles.pdf(c);
plot(dfx, handles.df(i, :), [colors(c) '-'], ...
nodes(:, 1), nodes(:, 2), 'ko', x, y, 'k-', ...
'Parent', handles.curve_axes);
elseif c == 1
i = handles.cdf(c);
plot(dfx, handles.df(i + 1, :), 'r-', ...
dfx, handles.df(i + 3, :), 'g-', ...
dfx, handles.df(i + 5, :), 'b-', ...
nodes(:, 1), nodes(:, 2), 'ko', x, y, 'k-', ...
'Parent', handles.curve_axes);
end
end
% Put legend if more than two curves are shown.
s = handles.colortype;
if strcmp(s, 'ntsc')
s = 'yiq'; end
if (c == 1) & (handles.pdf(c) | handles.cdf(c))
s1 = ['-- ' upper(s(1))];
if length(s) == 3
s2 = ['-- ' upper(s(2))]; s3 = ['-- ' upper(s(3))];
else
s2 = ['-- ' upper(s(2)) s(3)]; s3 = ['-- ' upper(s(4)) s(5)];
end
else s1 = ''; s2 = ''; s3 = ''; end
set(handles.red_text, 'String', s1);
set(handles.green_text, 'String', s2);
set(handles.blue_text, 'String', s3);
%-------------------------------------------------------------------%
function [inplot, x, y] = cursor(h, handles)
% Translate the mouse position to a coordinate with respect to
% the current plot area, check for the mouse in the area and if so
% save the location and write the coordinates below the plot.
set(h, 'Units', 'pixels');
p = get(h, 'CurrentPoint');
x = (p(1, 1) - handles.plotbox(1)) / handles.plotbox(3);
y = (p(1, 2) - handles.plotbox(2)) / handles.plotbox(4);
if x > 1.05 | x < -0.05 | y > 1.05 | y < -0.05
inplot = 0;
else
x = min(x, 1); x = max(x, 0);
y = min(y, 1); y = max(y, 0);
nodes = getfield(handles, handles.curve);
x = round(256 * x) / 256;
inplot = 1;
set(handles.input_text, 'String', num2str(x, 3));
set(handles.output_text, 'String', num2str(y, 3));
end
set(h, 'Units', 'normalized');
%-------------------------------------------------------------------%
function y = render(handles)
% Map the input image and bar components and convert them to RGB
% (if needed) and display.
set(handles.ice, 'Interruptible', 'off');
set(handles.ice, 'Pointer', 'watch');
ygb = handles.graybar; ycb = handles.colorbar;
yi = handles.input; mapon = handles.barmap;
imageon = handles.imagemap & size(handles.input, 1);
for i = 2: 4
nodes = getfield(handles, ['set' num2str(i)]);
t = lut(nodes, handles.smooth(i), handles.slope(i));
if imageon yi(:, :, i - 1) = t(yi(:, :, i - 1) + 1); end
if mapon ygb(:, :, i - 1) = t(ygb(:, :, i - 1) + 1);
ycb(:, :, i - 1) = t(ycb(:, :, i - 1) + 1); end
end
t = lut(handles.set1, handles.smooth(1), handles.slope(1));
if imageon yi = t(yi + 1); end
if mapon ygb = t(ygb + 1); ycb = t(ycb + 1); end
if ~strcmp(handles.colortype, 'rgb')
if size(handles.input, 1)
yi = yi / 255;
yi = eval([handles.colortype '2rgb(yi)']);
yi = uint8(255 * yi); end
ygb = ygb / 255; ycb = ycb / 255;
ygb = eval([handles.colortype '2rgb(ygb)']);
ycb = eval([handles.colortype '2rgb(ycb)']);
ygb = uint8(255 * ygb); ycb = uint8(255 * ycb);
else
yi = uint8(yi); ygb = uint8(ygb); ycb = uint8(ycb); end
if size(handles.input, 1)
figure(handles.output); imshow(yi); end
ygb = repmat(ygb, [32 1 1]); ycb = repmat(ycb, [32 1 1]);
axes(handles.gray_axes); imshow(ygb);
axes(handles.color_axes); imshow(ycb);
figure(handles.ice);
set(handles.ice, 'Pointer', 'arrow');
set(handles.ice, 'Interruptible', 'on');
%-------------------------------------------------------------------%
function t = lut(nodes, smooth, slope)
% Create a 256 element mapping function from a set of control
% points. The output values are integers in the interval [0, 255].
% Use piecewise linear or cubic spline with or without zero end
% slope interpolation.
t = 255 * nodes; i = 0:255;
if ~smooth t = [t; 256 256]; t = interp1q(t(:, 1), t(:, 2), i');
else
if ~slope t = spline(t(:, 1), t(:, 2), i);
else t = spline(t(:, 1), [0; t(:, 2); 0], i); end
end
t = round(t); t = max(0, t); t = min(255, t);
%-------------------------------------------------------------------%
function out = spreadout(in)
% Make all x values unique.
% Scan forward for non-unique x's and bump the higher indexed x--
% but don't exceed 1. Scan the entire range.
nudge = 1 / 256;
for i = 2: size(in, 1) - 1
if in(i, 1) <= in(i - 1, 1)
in(i, 1) = min(in(i - 1, 1) + nudge, 1); end
end
% Scan in reverse for non-unique x's and decrease the lower indexed
% x -- but don't go below 0. Stop on the first non-unique pair.
if in(end, 1) == in(end - 1, 1)
for i = size(in, 1): -1: 2
if in(i, 1) <= in(i - 1, 1)
in(i - 1, 1) = max(in(i, 1) - nudge, 0);
else break; end
end
end
% If the first two x's are now the same, init the curve.
if in(1, 1) == in(2, 1) in = [0 0; 1 1]; end
out = in;
% --- Creates and returns a handle to the GUI figure.
function h1 = ice_LayoutFcn(policy)
% policy - create a new figure or use a singleton. 'new' or 'reuse'.
persistent hsingleton;
if strcmpi(policy, 'reuse') & ishandle(hsingleton)
h1 = hsingleton;
return;
end
h1 = figure(...
'Units','characters',...
'Color',[0.87843137254902 0.874509803921569 0.890196078431373],...
'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],...
'IntegerHandle','off',...
'InvertHardcopy',get(0,'defaultfigureInvertHardcopy'),...
'MenuBar','none',...
'Name','ICE - Interactive Color Editor',...
'NumberTitle','off',...
'PaperPosition',get(0,'defaultfigurePaperPosition'),...
'Position',[0.8 65.2307692307693 92.6 30.0769230769231],...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -