www.pudn.com > 2006606081519.rar > cpselect.m
function h = cpselect(varargin)
%CPSELECT Control point selection tool.
% CPSELECT is a graphical user interface that enables you to select
% control points from two related images.
%
% CPSELECT(INPUT,BASE) returns control points in CPSTRUCT. INPUT is the
% image that needs to be warped to bring it into the coordinate system of
% the BASE image. INPUT and BASE can be either variables that contain
% grayscale images or strings that identify files containing grayscale
% images.
%
% CPSELECT(INPUT,BASE,CPSTRUCT_IN) starts CPSELECT with an initial set of
% control points that are stored in CPSTRUCT_IN. This syntax allows you to
% restart CPSELECT with the state of control points previously saved in
% CPSTRUCT_IN.
%
% CPSELECT(INPUT,BASE,XYINPUT_IN,XYBASE_IN) starts CPSELECT with
% a set of initial pairs of control points. XYINPUT_IN and XYBASE_IN are
% M-by-2 matrices that store the INPUT and BASE coordinates respectively.
%
% H = CPSELECT(INPUT,BASE,...) returns a handle H to the tool. CLOSE(H)
% closes the tool.
%
% Class Support
% -------------
% The input images can be of class uint8, uint16, double, or logical.
%
% Examples
% --------
% Start tool with saved images:
% aerial = imread('westconcordaerial.png');
% cpselect(aerial(:,:,1),'westconcordorthophoto.png')
%
% Start tool with workspace images and points:
% I = checkerboard;
% J = imrotate(I,30);
% base_points = [11 11; 41 71];
% input_points = [14 44; 70 81];
% cpselect(J,I,input_points,base_points);
%
% Notes on Platform Support
% -------------------------
% CPSELECT requires Java and is not available on any platform that does
% not support Java. In addition, CPSELECT is not available on the
% Macintosh platform even with Java.
%
% Notes on Memory Usage
% ---------------------
% To increase the amount of memory available to CPSELECT, you must put a
% file called 'java.opts' in your startup directory.
%
% See also CPCORR, CP2TFORM, CPSTRUCT2PAIRS, IMTRANSFORM, IMTOOL.
% Copyright 1993-2004 The MathWorks, Inc.
% $Revision: 1.24.4.10 $ $Date: 2004/08/10 01:39:03 $
% Input-output specs
% ------------------
% INPUT,BASE: filenames each containing a grayscale or truecolor image
%
% OR
%
% real, full matrix
% can be intensity: 2-D
% uint8, uint16, double, or logical
%
% Note: INPUT can be a filename while BASE is a variable or vice versa.
%
% CPSTRUCT: structure containing control point pairs with fields:
% inputPoints
% basePoints
% inputBasePairs
% ids
% inputIdPairs
% baseIdPairs
% isInputPredicted
% isBasePredicted
%
% XYINPUT_IN, XYBASE_IN: M-by-2 matrices with control point coordinates.
% real, full, finite
global DEBUG_CPSELECT
if DEBUG_CPSELECT & strcmpi(computer,'sgi') %#ok
disp('Inside cpselect, about to call javachk.');
end
% Don't run on platforms with incomplete Java support
if ~IsJavaAvailable
eid = sprintf('Images:%s:cpselectNotAvailableOnThisPlatform',mfilename);
error(eid,'%s','CPSELECT is not available on this platform.');
end
% should have failed by now on SGI
if DEBUG_CPSELECT & strcmpi(computer,'sgi') %#ok
disp('Inside cpselect, just called javachk.');
end
[input, base, cpstruct] = ParseInputs(varargin{:});
% get names to label images
inputImageName = get_image_title(varargin{1},inputname(1));
baseImageName = get_image_title(varargin{2},inputname(2));
inputImage2D = im2java2d(input);
baseImage2D = im2java2d(base);
% import Java classes used here
import com.mathworks.toolbox.images.cpselect.ControlPointSelectionTool;
hh = ControlPointSelectionTool(inputImageName,baseImageName,...
inputImage2D,baseImage2D);
legendFrame = hh.getLegendFrame;
legendSize = legendFrame.getSize;
legendLocation = hh.getLocation;
legendLocation.translate(-legendSize.width,0);
% clip legendLocation to be on screen
screen_size = get(0,'ScreenSize');
screen_width = screen_size(3);
screen_height = screen_size(4);
legendLocation.x = max(0,min(legendLocation.x,screen_width- ...
legendSize.width));
legendLocation.y = max(0,min(legendLocation.y,screen_height- ...
legendSize.height));
legendFrame.setLocation(legendLocation);
legendFrame.show; % show legend after tool is showing
legendFrame.setVisible(true);
hh.toFront;
if ~isempty(cpstruct)
[inputBasePairs,inputPoints,basePoints] = cpstruct2java(cpstruct);
hh.loadControlPoints(inputBasePairs,inputPoints,basePoints);
end
% preload m-code. Does not noticably speed up code. Maybe problem is with JMI
try
cpsave;
cppredict;
catch
% do not error
end
if (nargout > 0)
% Only return handle if caller requested it.
h = hh;
end
%-------------------------------
% Function ParseInputs
%
function [input, base, cpstruct] = ParseInputs(varargin)
% defaults
cpstruct = [];
iptchecknargin(2,4,nargin,mfilename);
input = parseImage(varargin{1},1,'INPUT');
base = parseImage(varargin{2}, 2,'BASE');
switch nargin
case 2
% CPSTRUCT = CPSELECT(INPUT,BASE)
return;
case 3
% CPSTRUCT = CPSELECT(INPUT,BASE,CPSTRUCT)
% TO DO: add more validation on cpstruct
if iscpstruct(varargin{3})
cpstruct = varargin{3};
else
eid = sprintf('Images:%s:CPSTRUCTMustBeStruct',mfilename);
msg = sprintf('%s: CPSTRUCT must be a structure.',upper(mfilename));
error(eid,msg);
end
case 4
% CPSTRUCT = CPSELECT(INPUT,BASE,XYINPUT_IN,XYINPUT_OUT)
xyinput_in = varargin{3};
xybase_in = varargin{4};
iptcheckinput(xyinput_in,{'double'},...
{'real','nonsparse','finite','2d'},mfilename,'XYINPUT_IN',3);
iptcheckinput(xybase_in, {'double'},...
{'real','nonsparse','finite','2d'},mfilename,'XYBASE_IN',4);
eid = sprintf('Images:%s:expectedMby2',mfilename);
msg = sprintf('%s: XYINPUT_IN and XYBASE_IN must be M-by-2.',upper(mfilename));
if size(xyinput_in,1) ~= size(xybase_in,1) || ...
size(xyinput_in,2) ~= 2 || size(xybase_in,2) ~= 2
error(eid,msg);
end
cpstruct = xy2cpstruct(xyinput_in,xybase_in);
end
%-------------------------------
% Function ParseImage
%
function [img] = parseImage(arg,argnumber,argname)
img = [];
if ischar(arg)
try
info = imfinfo(arg);
if strmatch(info.ColorType,'indexed')
eid = sprintf('Images:%s:imageMustBeGrayscale',mfilename);
msg = sprintf('%s: %s must be a grayscale image.',upper(mfilename),arg);
error(eid,msg);
end
img = imread(arg);
catch
eid = sprintf('Images:%s:imageNotValid',mfilename);
msg = sprintf('%s: %s must be a valid image file.',upper(mfilename),arg);
error(eid,msg);
end
else
img = arg;
end
iptcheckinput(img,{'uint8','uint16','double','logical'},...
{'real','nonsparse','2d'},...
mfilename,argname,argnumber);
%-------------------------------
% Function xy2cpstruct
%
function cpstruct = xy2cpstruct(xyinput_in,xybase_in)
% Create a cpstruct given two lists of equal numbers of points.
M = size(xyinput_in,1);
ids = (0:M-1)';
isPredicted = zeros(M,1);
% assign fields to cpstruct
cpstruct.inputPoints = xyinput_in;
cpstruct.basePoints = xybase_in;
cpstruct.inputBasePairs = repmat((ids+1),1,2);
cpstruct.ids = ids;
cpstruct.inputIdPairs = cpstruct.inputBasePairs;
cpstruct.baseIdPairs = cpstruct.inputBasePairs;
cpstruct.isInputPredicted = isPredicted;
cpstruct.isBasePredicted = isPredicted;
%
%-------------------------------
%
function [inputBasePairsVector, inputPointsVector, basePointsVector] = ...
cpstruct2java(cpstruct)
import java.util.Vector;
import com.mathworks.toolbox.images.cpselect.CPVector;
import com.mathworks.toolbox.images.cpselect.ControlPoint;
import com.mathworks.toolbox.images.cpselect.ControlPointPair;
% initialize empty vectors
inputPointsVector = CPVector;
basePointsVector = CPVector;
inputBasePairsVector = Vector;
inputPointsVector = fillPointsVector(cpstruct.inputPoints);
basePointsVector = fillPointsVector(cpstruct.basePoints);
nPairs = length(cpstruct.ids);
for i = 1:nPairs
inputBasePairsVector.addElement(ControlPointPair(cpstruct.ids(i)))
end
% loop over inputIdPairs to setInputPoint for pairs
nPairs = size(cpstruct.inputIdPairs,1);
for i = 1:nPairs
[p,pair,input_index] = getPointPair(i,inputBasePairsVector,cpstruct.inputIdPairs,...
cpstruct.ids,inputPointsVector);
pair.setInputPoint(p);
if cpstruct.isInputPredicted(input_index)
setPredictedPoint(pair,p);
end
end
% loop over baseIdPairs to setBasePoint for pairs
nPairs = size(cpstruct.baseIdPairs,1);
for i = 1:nPairs
[p,pair,base_index] = getPointPair(i,inputBasePairsVector,cpstruct.baseIdPairs,...
cpstruct.ids,basePointsVector);
pair.setBasePoint(p);
if cpstruct.isBasePredicted(base_index)
setPredictedPoint(pair,p);
end
end
%
%-----------------------------------------------------
%
function setPredictedPoint(pair,p)
if isempty( pair.getPredictedPoint )
pair.setPredictedPoint(p);
else
wid = sprintf('Images:%s:predictedAlreadySet',mfilename);
msg = sprintf('%s: Predicted point was already set for this pair.',upper(mfilename));
warning(wid,msg);
end
%
%-----------------------------------------------------
%
function [point,pair,point_index] = getPointPair(i,inputBasePairsVector,pointIdPairs,ids,pointsVector)
import com.mathworks.toolbox.images.cpselect.ControlPoint;
id_index = pointIdPairs(i,2);
point_index = pointIdPairs(i,1);
id = ids(id_index);
pair = inputBasePairsVector.elementAt(id);
point = pointsVector.elementAt(point_index-1);
point.setPair(pair);
%
%-----------------------------------------------------
%
function [pointsVector] = fillPointsVector(points)
import com.mathworks.toolbox.images.cpselect.ControlPoint;
import com.mathworks.toolbox.images.cpselect.CPVector;
pointsVector = CPVector;
nPoints = size(points,1);
for i = 1:nPoints
x = points(i,1) - 1; % subtract 1 to account for
y = points(i,2) - 1; % zero-based Java coordinates
pointsVector.addElement(ControlPoint(x,y))
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function java_available = IsJavaAvailable
java_available = false;
ismac = strcmpi(computer,'mac'); % disable on Mac
if isempty(javachk('swing')) && ~ismac
java_available = true;
end