Commit 83c2cd95 authored by Christian Brabetz's avatar Christian Brabetz
Browse files

Initial commit.

parents
*.mexw64
This diff is collapsed.
This diff is collapsed.
function draggable(h,varargin)
% DRAGGABLE - Make it so that a graphics object can be dragged in a figure.
% This function makes an object interactive by allowing it to be dragged
% accross a set of axes, following or not certain constraints. This
% allows for intuitive control elements which are not buttons or other
% standard GUI objects, and which reside inside an axis. Typical use
% involve markers on an axis, whose position alters the output of a
% computation or display
%
% >> draggable(h);
%
% makes the object with handle "h" draggable. Use the "Position" property
% of the object to retrieve its position, by issuing a get(h,'Position')
% command.
%
% >> draggable(h,...,motionfcn)
%
% where "motionfcn" is a function handle, executes the given function
% while the object is dragged. Handle h is passed to motionfcn as an
% argument. Argument "motionfcn" can be put anywhere after handle "h".
%
% >> draggable(h,...,constraint,p);
%
% enables the object with handle "h" to be dragged, with a constraint.
% Arguments "constraint" (a string) and "p" (a vector) can be put
% anywhere after handle "h".
%
% The argument "constraint" may be one of the following strings:
%
% 'n' or 'none': The object is unconstrained (default).
% 'h' or 'horizontal': The object can only be moved horizontally.
% 'v' or 'vertical': The object can only be moved vertically.
%
% The argument "p" is an optional parameter which depends upon the
% constraint type:
%
% Constraint p Description
% -----------------------------------------------------------------------
%
% 'none' [x1 x2 y1 y2] Drag range (for the object's outer
% limits, from x1 to x2 on the x-axis
% and from y1 to y2 on the y-axis).
% Default is the current axes range.
% Use "inf" if no limit is desired.
%
% 'horizontal' [xmin xmax] Drag range (for the object's outer
% limits). Default is the x-axis
% range. Use "inf" if no limit is
% desired.
%
% 'vertical' [ymin ymax] Drag range (for the object's outer
% limits). Default is the y-axis
% range. Use "inf" if no limit is
% desired.
%
% -----------------------------------------------------------------------
%
% >> draggable(h,...,renderer);
%
% where renderer is one of 'painters', 'zbuffer' or 'opengl', uses the
% corresponding renderer for the figure while the graphical object whose
% handle is h is being dragged. By default, zbuffer is used since it is
% the only renderer that offers both acceptable performance and a
% guaranteed correct behavior with draggable. The 'painters' renderer is
% too slow, while the 'opengl' renderer's behavior with draggable depends
% ont the graphics driver used and may differ from what is expected.
%
% >> draggable(h,'off')
%
% returns object h to its original, non-draggable state.
%
% See the source code (e.g. by issuing "type draggable" at the Matlab
% prompt) for implementation notes and the copyright notice.
% VERSION INFORMATION:
% 2003-11-20: Initially submitted to MatlabCentral.Com
% 2004-01-06: Addition of the renderer option, as proposed by Ohad Gal
% as a feedback on MatlabCentral.Com.
% 2004-02-18: Bugfix: now works with 1-element plots and line objects
% 2004-03-04: Bugfix: sanitized the way the object's new position is
% computed; it now always follow the mouse even after the
% mouse pointer was out of the axes.
% 2004-03-05: Bugfix: movement when mouse is out of the axes is now
% definitely correct ;)
% IMPLEMENTATION NOTES:
%
% This function uses the dragged object's "ButtonDownFcn" function and set it
% so that the objec becomes draggable. Any previous "ButtonDownFcn" is thus
% lost during operation, but is retrieved after issuing the draggable(h,'off')
% command.
%
% Information about the object's behavior is also stored in the object's
% 'UserData' property, using setappdata() and getappdata(). The original
% 'UserData' property is restored after issuing the draggable(h,'off')
% command.
%
% The corresponding figure's "WindowButtonDownFcn", "WindowButtonUpFcn" and
% "WindowButtonMotionFcn" functions. During operation, those functions are
% set by DRAGGABLE; however, the original ones are restored after the user
% stops dragging the object.
%
% By default, DRAGGABLE also switches the figure's renderer to 'zbuffer'
% during operation: 'painters' is not fast enough and 'opengl' sometimes
% produce curious results. However there may be a need to switch to another
% renderer, so the user can now specify a specific figure renderer during
% object drag (thanks to Ohad Gal for the suggestion).
%
% The "motionfcn" function handle is called at each displacement, after the
% object's position is updated, using "feval(motionfcn,h)", where h is the
% object's handle.
%
% TO DO:
%
% 1 - For now, DRAGGABLE allows only one object at a time to be draggable. In
% the future, draggable(h), where h is a vector of handles, will create a
% group of objects that will all be dragged when one of them is selected.
% ==============================================================================
% Copyright (C) 2003, 2004
% Francois Bouffard
% fbouffar@gel.ulaval.ca
% Universit� Laval, Qu�bec City
% ==============================================================================
% ==============================================================================
% Input arguments management
% ==============================================================================
% Initialization of some default arguments
user_renderer = 'zbuffer';
user_movefcn = [];
constraint = 'none';
p = [];
% At least the handle to the object must be given
Narg = nargin;
if Narg == 0
error('Not engough input arguments');
elseif prod(size(h))>1
error('Only one object at a time can be made draggable');
end;
% Fetching informations about the parent axes
axh = get(h,'Parent');
if iscell(axh)
axh = axh{1};
end;
fgh = get(axh,'Parent');
ax_xlim = get(axh,'XLim');
ax_ylim = get(axh,'YLim');
% Assigning optional arguments
Noptarg = Narg - 1;
for k = 1:Noptarg
current_arg = varargin{k};
if isa(current_arg,'function_handle');
user_movefcn = current_arg;
end;
if ischar(current_arg);
switch lower(current_arg)
case {'off'}
set_initial_state(h);
return;
case {'painters','zbuffer','opengl'}
user_renderer = current_arg;
otherwise
constraint = current_arg;
end;
end;
if isnumeric(current_arg);
p = current_arg;
end;
end;
% Assigning defaults for constraint
switch lower(constraint)
case {'n','none'}
if isempty(p); p = [ax_xlim ax_ylim]; end;
case {'h','horizontal'}
if isempty(p); p = ax_xlim; end;
case {'v','vertical'}
if isempty(p); p = ax_ylim; end;
otherwise
error('Unknown constraint type');
end;
% ==============================================================================
% Saving initial state and parameters, setting up the object callback
% ==============================================================================
% Saving object's and parent figure's initial state
setappdata(h,'initial_userdata',get(h,'UserData'));
setappdata(h,'initial_objbdfcn',get(h,'ButtonDownFcn'));
setappdata(h,'initial_renderer',get(fgh,'Renderer'));
setappdata(h,'initial_wbdfcn',get(fgh,'WindowButtonDownFcn'));
setappdata(h,'initial_wbufcn',get(fgh,'WindowButtonUpFcn'));
setappdata(h,'initial_wbmfcn',get(fgh,'WindowButtonMotionFcn'));
% Saving parameters
setappdata(h,'constraint_type',constraint);
setappdata(h,'constraint_parameters',p);
setappdata(h,'user_movefcn',user_movefcn);
setappdata(h,'user_renderer',user_renderer);
% Detecting if object's position is specified through the
% 'Position' or 'XData' and 'YData' properties
h_properties = get(h);
if isfield(h_properties,'Position')
setappdata(h,'position_type','rect');
else
setappdata(h,'position_type','xydata');
end;
% Setting the object's ButtonDownFcn
set(h,'ButtonDownFcn',@click_object);
% ==============================================================================
% FUNCTION click_object
% Executed when the object is clicked
% ==============================================================================
function click_object(obj,eventdata);
% obj here is the object to be dragged and gcf is the object's parent
% figure since the user clicked on the object
h = obj;
position_type = getappdata(h,'position_type');
if strcmp(position_type,'xydata')
setappdata(h,'initial_xdata',get(h,'XData'));
setappdata(h,'initial_ydata',get(h,'YData'));
else
setappdata(h,'initial_position',get(h,'Position'));
end;
setappdata(h,'initial_point',get(gca,'CurrentPoint'));
set(gcf,'WindowButtonDownFcn',{@activate_movefcn,h});
set(gcf,'WindowButtonUpFcn',{@deactivate_movefcn,h});
activate_movefcn(gcf,eventdata,h);
% set the pointer shape to close hand /LB UDEB PET Center
setappdata(h,'current_figure_pointer',get(gcf,'pointer'));
setptr(gcf,'closedhand');
% ==============================================================================
% FUNCTION activate_movefcn
% Activates the WindowButtonMotionFcn for the figure
% ==============================================================================
function activate_movefcn(obj,eventdata,h);
% obj here is the figure containing the object
set(obj,'Renderer',getappdata(h,'user_renderer'));
set(obj,'WindowButtonMotionFcn',{@movefcn,h});
% ==============================================================================
% FUNCTION deactivate_movefcn
% Deactivates the WindowButtonMotionFcn for the figure
% ==============================================================================
function deactivate_movefcn(obj,eventdata,h);
% obj here is the figure containing the object
% set the pointer shape to the original /LB UDEB PET Center
setptr(gcf, getappdata(h,'current_figure_pointer'));
set(obj,'WindowButtonMotionFcn',getappdata(h,'initial_wbmfcn'));
set(obj,'WindowButtonDownFcn',getappdata(h,'initial_wbdfcn'));
set(obj,'WindowButtonUpFcn',getappdata(h,'initial_wbufcn'));
set(obj,'Renderer',getappdata(h,'initial_renderer'));
% ==============================================================================
% FUNCTION set_initial_state
% Returns the object to its initial state
% ==============================================================================
function set_initial_state(h);
initial_objbdfcn = getappdata(h,'initial_objbdfcn');
initial_userdata = getappdata(h,'initial_userdata');
set(h,'ButtonDownFcn',initial_objbdfcn);
set(h,'UserData',initial_userdata);
% ==============================================================================
% FUNCTION movefcn
% Actual code for dragging the object
% ==============================================================================
function movefcn(obj,eventdata,h);
% obj here is the figure containing the object
% Retrieving data saved in the figure
position_type = getappdata(h,'position_type');
if strcmp(position_type,'xydata')
initial_xdata = getappdata(h,'initial_xdata');
initial_ydata = getappdata(h,'initial_ydata');
else
%initial_position = getappdata(h,'initial_position');
end;
initial_point = getappdata(h,'initial_point');
constraint = getappdata(h,'constraint_type');
p = getappdata(h,'constraint_parameters');
user_movefcn = getappdata(h,'user_movefcn');
% Getting current point
current_point = get(gca,'CurrentPoint');
% Retrieving (x,y) couple for current and initial points
cpt = current_point(1,1:2);
ipt = initial_point(1,1:2);
% Computing movement
dpt = cpt - ipt;
% Computing movement range and imposing movement constraints
% (p is always [xmin xmax ymin ymax])
switch lower(constraint)
case {'n','none'};
range = p;
case {'h','horizontal'}
dpt(2) = 0;
range = [p -inf inf];
case {'v','vertical'}
dpt(1) = 0;
range = [-inf inf p];
end;
% Computing new position.
% What we want is actually a bit complex: we want the object to adopt the new
% position, unless it gets out of range. If it gets out of range in a direction,
% we want it to stick to the limit in that direction. Also, if the object is out
% of range at the beginning of the movement, we want to be able to move it back
% into range, so that movement must then be allowed.
switch lower(position_type)
% Objects with rectangle-type position information
case 'rect'
% Retrieveing various quantities:
% initial_position is the position when the object was clicked
% oldpos is the current position, which will be updated
% newpos is the new (proposed) position
% old_obj_extent and new_pos extent are the extent occupied by
% the old and new objects
initial_position = getappdata(h,'initial_position');
oldpos = get(h,'Position');
old_obj_extent = [oldpos(1) oldpos(1)+oldpos(3) oldpos(2) oldpos(2)+oldpos(4)];
newpos = initial_position + [dpt 0 0];
new_obj_extent = [newpos(1) newpos(1)+newpos(3) newpos(2) newpos(2)+newpos(4)];
% Verifying if old and new objects breach the allowed range in any
% direction (see the function is_inside_range below)
old_inrange = is_inside_range(old_obj_extent,range);
new_inrange = is_inside_range(new_obj_extent,range);
% Modifying dpt to stick to range limit if range violation occured,
% but the movement won't get restricted if the object was out of range
% to begin with
if old_inrange(1) & ~new_inrange(1)
dpt(1) = range(1) - initial_position(1);
end
if old_inrange(2) & ~new_inrange(2)
dpt(1) = range(2) - initial_position(1) - initial_position(3);
end;
if old_inrange(3) & ~new_inrange(3)
dpt(2) = range(3) - initial_position(2);
end;
if old_inrange(4) & ~new_inrange(4)
dpt(2) = range(4) - initial_position(2) - initial_position(4);
end
% Computing the final new position and setting it
newpos = initial_position + [dpt 0 0];
set(h,'Position',newpos);
% Objects with line-type position information
case 'xydata'
% Retrieveing various quantities:
% initial_position is the position when the object was clicked
% oldpos is the current position, which will be updated
% newpos is the new (proposed) position
% old_obj_extent and new_pos extent are the extent occupied by
% the old and new objects
initial_xdata = getappdata(h,'initial_xdata');
initial_ydata = getappdata(h,'initial_ydata');
initial_position = [initial_xdata(:)' ; initial_ydata(:)'];
xdata = get(h,'XData');
ydata = get(h,'YData');
oldpos = [xdata(:)' ; ydata(:)'];
old_obj_extent = [min(xdata) max(xdata) min(ydata) max(ydata)];
newpos = initial_position + dpt'*ones(1,size(oldpos,2));
new_obj_extent = [min(newpos(1,:)) max(newpos(1,:)) min(newpos(2,:)) max(newpos(2,:))];
% Verifying if old and new objects breach the allowed range in any
% direction (see the function is_inside_range below)
old_inrange = is_inside_range(old_obj_extent,range);
new_inrange = is_inside_range(new_obj_extent,range);
% Modifying dpt to stick to range limit if range violation occured,
% but the movement won't get restricted if the object was out of range
% to begin with
if old_inrange(1) & ~new_inrange(1)
dpt(1) = range(1) - min(initial_xdata);
end
if old_inrange(2) & ~new_inrange(2)
dpt(1) = range(2) - max(initial_xdata);
end;
if old_inrange(3) & ~new_inrange(3)
dpt(2) = range(3) - min(initial_ydata);
end;
if old_inrange(4) & ~new_inrange(4)
dpt(2) = range(4) - max(initial_ydata);
end
% Computing the final new position and setting it
newpos = initial_position + dpt'*ones(1,size(oldpos,2));
set(h,'XData',newpos(1,:),'YData',newpos(2,:));
end;
% Calling user-provided function handle
if ~isempty(user_movefcn)
feval(user_movefcn,h);
end;
% ==============================================================================
% FUNCTION is_inside_range
% Checks if a rectangular object is entirely inside a rectangular range
% ==============================================================================
function inrange = is_inside_range(extent,range)
inrange = [extent(1)>=range(1) extent(2)<=range(2) ...
extent(3)>=range(3) extent(4)<=range(4)];
\ No newline at end of file
#include "mex.h"
#include "matrix.h"
#define max_Olli(a,b) \
( a > b ? a : b )
#define min_Olli(a,b) \
( a < b ? a : b )
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
/*called from matlab like:
a=findscratchesc(ysize,xsize,double(inputmatrix),region,threshold,cond);
where:
ysize => number of rows inputmatrix = size(inputmatrix,1)
xsize => number of colums inputmatrix = size(inputmatrix,2)
region => number of pixels to define mean arround pixel
threshold => between 0 and 1; deviation from mean condition
cond => 0=find dark scratches, 1=find bright scratches, 2=find both
a=outputmatrix
*/
#define inputmatrix(i,j) c[i+j*M]
#define outputmatrix(i,j) idxptr[i+j*M]
const mxArray *ysizegrid, *xsizegrid, *cgrid, *regiongrid, *thresgrid, *condgrid;
mxArray *idx;
double *idxptr;
double *xsizepnt, *ysizepnt, *c, *regionpnt, *threspnt, *condpnt;
int j, i, k, h, lowk, lowh, highk, highh, ysize, xsize, region, cond, M, counts;
double thres, mean;
mwSize dims[2];
/*catch pointer ysize*/
ysizegrid = prhs[0];
ysizepnt = mxGetPr(ysizegrid);
ysize=ysizepnt[0];
/*catch pointer xsize*/
xsizegrid = prhs[1];
xsizepnt = mxGetPr(xsizegrid);
xsize=xsizepnt[0];
/*catch pointer inputmatrix*/
cgrid = prhs[2];
c = mxGetPr(cgrid);
M = mxGetM(cgrid);
/*catch pointer region*/
regiongrid = prhs[3];
regionpnt = mxGetPr(regiongrid);
region=regionpnt[0];
/*catch pointer threshold*/
thresgrid = prhs[4];
threspnt = mxGetPr(thresgrid);
thres=threspnt[0];
/*catch pointer condition*/
condgrid = prhs[5];
condpnt = mxGetPr(condgrid);
cond=condpnt[0];
/*create output matrix a; size(a)= ysize, xsize*/
dims[0] = ysize; dims[1] = xsize;
plhs[0] = idx = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
if (idx==NULL)
{
dims[0] = 0; dims[1] = 0;
plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
return;
}
/*assign output to righthand pointer*/
idxptr = mxGetPr(idx);
/*find scratches in inputmatrix*/
for(i = 0; i < xsize; i++) {
for(j = 0; j < ysize; j++) {
lowk = max_Olli(j-region,0);
highk = min_Olli(j+region,ysize-1);
lowh = max_Olli(i-region,0);
highh = min_Olli(i+region,xsize-1);
mean = 0;
counts = 0;
for (k = lowk; k<=highk; k++) {
for (h = lowh ; h<=highh; h++) {
mean = mean + inputmatrix(k,h);
counts = counts + 1;
}
}
mean = (mean-inputmatrix(j,i))/(counts-1);
if(cond==0)
{
if(inputmatrix(j,i)<thres*1.1*mean) outputmatrix(j,i)=1;
}
else if(cond==1)
{
if(inputmatrix(j,i)*thres*1.25>mean) outputmatrix(j,i)=1;
}
else if(cond==2)
{
if((inputmatrix(j,i)<thres*1.1*mean)||(inputmatrix(j,i)*thres*1.25>mean)) outputmatrix(j,i)=1;
}
}
}
return;
}
function out = imoverlay(in, mask, color)
%IMOVERLAY Create a mask-based image overlay.
% OUT = IMOVERLAY(IN, MASK, COLOR) takes an input image, IN, and a binary
% image, MASK, and produces an output image whose pixels in the MASK
% locations have the specified COLOR.
%
% IN should be a grayscale or an RGB image of class uint8, uint16, int16,
% logical, double, or single. If IN is double or single, it should be in
% the range [0, 1]. If it is not in that range, you might want to use
% mat2gray to scale it into that range.
%
% MASK should be a two-dimensional logical matrix.
%
% COLOR should be a 1-by-3 vector of values in the range [0, 1]. [0 0 0]
% is black, and [1 1 1] is white.
%
% OUT is a uint8 RGB image.
%
% Examples
% --------
% Overlay edge detection result in green over the original image.
%
% I = imread('cameraman.tif');
% bw = edge(I, 'canny');
% rgb = imoverlay(I, bw, [0 1 0]);
% imshow(rgb)
%
% Treating the output of peaks as an image, overlay the values greater than
% 7 in red. The output of peaks is not in the usual grayscale image range
% of [0, 1], so use mat2gray to scale it.
%
% I = peaks;
% mask = I > 7;
% rgb = imoverlay(mat2gray(I), mask, [1 0 0]);
% imshow(rgb, 'InitialMagnification', 'fit')
% Steven L. Eddins
% Copyright 2006-2012 The MathWorks, Inc.
% If the user doesn't specify the color, use white.
DEFAULT_COLOR = [1 1 1];
if nargin < 3
color = DEFAULT_COLOR;
end
% Force the 2nd input to be logical.
mask = (mask ~= 0);
% Make the uint8 the working data class. The output is also uint8.
in_uint16 = im2uint16(in);
color_uint16 = im2uint16(color);
% Initialize the red, green, and blue output channels.
if ndims(in_uint16) == 2
% Input is grayscale. Initialize all output channels the same.
out_red = in_uint16;
out_green = in_uint16;
out_blue = in_uint16;
else
% Input is RGB truecolor.
out_red = in_uint16(:,:,1);
out_green = in_uint16(:,:,2);
out_blue = in_uint16(:,:,3);
end
% Replace output channel values in the mask locations with the appropriate
% color value.
out_red(mask) = color_uint16(1