/matlab_tools/Converted/kvwmdd.m
Objective C | 394 lines | 394 code | 0 blank | 0 comment | 6 complexity | d421a36b9f21d1d2d6e08f89da7acbab MD5 | raw file
Possible License(s): BSD-3-Clause
- %kvwmdd 'Weighted Minimum Distance Detector (K1)'
- % This MatLab function was automatically generated by a converter (KhorosToMatLab) from the Khoros vwmdd.pane file
- %
- % Parameters:
- % InputFile: i1 'Input Image ', required: 'Input Image'
- % InputFile: i2 'Input Center/Class Image', required: 'Input Cluster Center/Class Image'
- % InputFile: i3 'Input Variance Image ', required: 'Input Variance Image'
- % Double: k 'Scaling Factor ', default: 1: ' Scaling factor'
- % Integer: b 'Border Width ', default: 0: ' Border width in pixels'
- % OutputFile: o 'Output Classified Image ', required: 'Output specifying which vector belongs to which cluster'
- %
- % Example: o = kvwmdd({i1, i2, i3}, {'i1','';'i2','';'i3','';'k',1;'b',0;'o',''})
- %
- % Khoros helpfile follows below:
- %
- % PROGRAM
- % vwmdd - Weighted Minimum Distance Detector (K1)
- %
- % DESCRIPTION
- % .I vwmdd
- % is an Weighted minimum distance detector or Classifier.
- % The main idea behind this detector is that it will distinguish
- % a single class form the rest of the data. However, it will
- % also work to distinguish multiple classes from each other.
- % .SH Theory
- %
- % To classify or detect spatial patterns in an image, we must
- % have a template to compare against. Creating a template can be thought
- % of as training on representative (ideal) data. This can be done
- % by using a clustering algorithm on the representative data.
- % Clustering routines such as vkmeans, vquant, isodata, etc can
- % be used to create a template. The idea here is to over
- % cluster the representative data, and quantize that into k classes.
- % Pseudo color in editimage, and kasc2val can be used to
- % create a class image. When the clustering is performed, two
- % items need to be computed; (1) the cluster center values, and
- % (2) the variances for each axis in the cluster. The variances
- % can be obtained by looking at the diagonal of the covariance
- % matrix.
- %
- % Explained below is a method of creating a the class assignments for
- % each cluster center. The class assignments may, for example, quantize
- % the space from 12 clusters to 2 classes. Example
- %
- % \f(CW
- %
- % Cluster Center Class
- % 1 --------------------- 2
- % 2 --------------------- 2
- % 3 --------------------- 1
- % 4 --------------------- 2
- % .
- % .
- % .
- % 12 --------------------- 1
- %
- %
- % "
- %
- %
- % This routine expects an image that contains the diagonal terms of the
- % covariance matrix, called the variance image, and an image that
- % contains the cluster center values and class assignment for
- % each cluster center. And of course the image to be classified.
- % This detector is to approximate the following equation:
- %
- % \f(CW
- %
- % (X - Mi)~ Inv(C) (X - Mi) (1)
- %
- % "
- %
- % where Mi is the mean, inv(C) is the inverse of the Covariance matrix,
- % and X is the data points, and ~ denotes transpose. This can be written as
- %
- % \f(CW
- %
- % (d1 d2 ... dn)~ - Q1 - (d1 d2 ... dn) (2)
- % | Q2 |
- % | . 0 |
- % | . |
- % | 0 . |
- % | Qn |
- % - -
- %
- % Which equals
- %
- % sq(d1) sq(d2) sq(dn)
- % ------ + ------ + ..... + ------ (3)
- % Q1 Q2 Qn
- %
- % Notation:
- % sq => square
- % Qi => the ith variance
- % di => the ith (X - Mi) value
- % the matrix is actually the inverse of C
- %
- % "
- %
- % Since the inverse of the Covariance matrix can not be easily determined,
- % we only consider the diagonal terms or simply the variance terms.
- %
- % There are two methods for detecting classes in the input image. Each data
- % point is put through a test based on the ideas above. The detector works
- % in two modes as follows:
- %
- % (1) uses the summed method -s option set to yes. This is an approximation
- % to method (2).
- %
- % \f(CW
- %
- % sq( || X - Mi || ) <
- % Vi = ------------------ > 1
- % K x sq(Si)
- %
- % where: sq( || X - Mi || ) = sq(di)
- % = Euclidean Distance Squared
- % sq(Si) = trace(C)
- % the trace of C is the sum of the
- % diagonal terms (variances).
- % K is a Constant
- % "
- %
- %
- % (2) non summed method (default).
- %
- % \f(CW
- %
- % sq(d1) sq(d2) sq(dn) <
- % Vi = ------ + ------ + ..... + ------ > 1
- % Q1 x K Q2 x K Qn x K
- %
- % where: sq(dj) = sq( || xj - Mi || )
- % = Euclidean Distance Squared of the
- % jth element of the vector X.
- % Qj = the jth variance element of the variance
- % vector for the ith cluster center.
- % K = Constant
- %
- % "
- %
- % In both cases the constant K is used. This is used to adjust the
- % variance value(s). If K is large, Qi can increase such that
- % Vi is always less than 1. There are no specific rules as to
- % the optimal value for K.
- %
- % The data point X is put through the test for each cluster, the
- % data point X is assigned to a Class based on the following criteria:
- %
- % 1.
- % choose the smallest Vi value, where Vi is the result for cluster i.
- %
- % 2.
- % If Vi is greater than 1, assign X to the NULL class (NULL class is always 0).
- % Otherwise assign Vi to class that corresponds to the ith cluster.
- %
- % This routine accepts three images as the
- % input. The image that corresponds to the -i1 argument is the image
- % that needs to be classified. This image can be have as many data
- % bands as necessary. The number of data bands depicts the dimensionality
- % of the vectors. Each pixel in the image is a vector with dimensionality
- % of the number of data bands.
- %
- % The second input image corresponds to the -i2 argument and is
- % the prototype image. This image contains two pieces of information.
- % (1) the cluster center values for each cluster center, and (2) the
- % class assignments for each cluster center.
- % The last data band of this image contains the class assignments for
- % each cluster center value. This image must contain the same
- % number of data bands as the other input image plus an extra data
- % band that represents the class mapping. This
- % image would most likely have been created by vkmeans or some other
- % routine that will give cluster centers. This image contains vectors that
- % correspond to the prototype of each class.
- %
- % As stated above the center image's last data band is a class data band. The
- % class data band simply maps each cluster center vector to a final class.
- %
- % At this point most class images must be created manually.
- % A class image can be created by using pseudo color in editimage
- % on the resulting clustered image from the
- % vkmeans routine. Vcustom can then be used to create the class image. Finally
- % vinset can be used to add the class image data to the center image. Normally
- % one would over cluster using vkmeans then reduce the space down. So vkmeans
- % might produce 100 clusters but, really only 3 classes are desired. Pseudo
- % color in editimage and kasc2val can be used to reduce the space down and
- % create a class image. The class data might map cluster center vectors 1-50
- % to class 1, vectors 51-60 to class 2 and vectors 61-100 to class 3.
- % When the vwmdd routine is run, the result would be a classified image of
- % three classes.
- %
- % The third input image corresponds to the -i3 argument. This image
- % contains the variance values for each cluster center. This image
- % contains the same number of data bands as the input image (-i1 image), and
- % contains the same number of vectors as the center image (-i2 image).
- % Each element in the variance vector is the variance value along an
- % axis in the n-dimensional space. The variance values can be
- % found by computing the diagonal of the covariance matrix for each
- % cluster. The cluster center values would be used as the mean values.
- % Note, vkmeans will compute this image for you.
- %
- % The scale factor (-k) must be chosen by trial and error. It has been
- % found that if the summed method is being used a small (1.0 - 3.0) value
- % for k is sufficient. If the average method is not being used a larger
- % k (8.0 - 10.0) value is sufficient. Note, this may change based on the
- % data, so these ranges are only a starting point.
- %
- % The border option (-b) allows the user to specify a border width,
- % in pixels, encompassing the image. The border region is skipped
- % by vwmdd when classification is performed.
- % This useful if neighborhood operators have been used
- % previously and have not updated edge pixels.
- %
- % All input images must be of data storage type FLOAT.
- %
- % This routine was written with the help of and ideas from
- % Dr. Don Hush, University of New Mexico, Dept. of EECE.
- %
- %
- %
- % EXAMPLES
- % .begin code
- % vwmdd -i1 aerial_image.xv -i2 centers_class -i3 variance -b 5 -k 8.0 -o test
- % .end code
- %
- % aerial_image is a 5 band image; thus, each vector has
- % dimensionality of 5, centers_class image is a 6 band image,
- % 5 bands that contain the cluster center values and 1
- % class band. The border that vwmdd will ignore is 5
- % pixels wide. The output image will be a single band image called
- % test. The scalar to multiply the denominator by is 8.0.
- % By default the non-summing method is used.
- %
- % "SEE ALSO"
- % vkmeans(1)
- %
- % RESTRICTIONS
- % All input images must be of data storage type FLOAT.
- %
- % REFERENCES
- %
- % COPYRIGHT
- % Copyright (C) 1993 - 1997, Khoral Research, Inc. ("KRI") All rights reserved.
- %
- function varargout = kvwmdd(varargin)
- if nargin ==0
- Inputs={};arglist={'',''};
- elseif nargin ==1
- Inputs=varargin{1};arglist={'',''};
- elseif nargin ==2
- Inputs=varargin{1}; arglist=varargin{2};
- else error('Usage: [out1,..] = kvwmdd(Inputs,arglist).');
- end
- if size(arglist,2)~=2
- error('arglist must be of form {''ParameterTag1'',value1;''ParameterTag2'',value2}')
- end
- narglist={'i1', '__input';'i2', '__input';'i3', '__input';'k', 1;'b', 0;'o', '__output'};
- maxval={0,0,0,2,100,0};
- minval={0,0,0,2,0,0};
- istoggle=[0,0,0,1,1,0];
- was_set=istoggle * 0;
- paramtype={'InputFile','InputFile','InputFile','Double','Integer','OutputFile'};
- % identify the input arrays and assign them to the arguments as stated by the user
- if ~iscell(Inputs)
- Inputs = {Inputs};
- end
- NumReqOutputs=1; nextinput=1; nextoutput=1;
- for ii=1:size(arglist,1)
- wasmatched=0;
- for jj=1:size(narglist,1)
- if strcmp(arglist{ii,1},narglist{jj,1}) % a given argument was matched to the possible arguments
- wasmatched = 1;
- was_set(jj) = 1;
- if strcmp(narglist{jj,2}, '__input')
- if (nextinput > length(Inputs))
- error(['Input ' narglist{jj,1} ' has no corresponding input!']);
- end
- narglist{jj,2} = 'OK_in';
- nextinput = nextinput + 1;
- elseif strcmp(narglist{jj,2}, '__output')
- if (nextoutput > nargout)
- error(['Output nr. ' narglist{jj,1} ' is not present in the assignment list of outputs !']);
- end
- if (isempty(arglist{ii,2}))
- narglist{jj,2} = 'OK_out';
- else
- narglist{jj,2} = arglist{ii,2};
- end
- nextoutput = nextoutput + 1;
- if (minval{jj} == 0)
- NumReqOutputs = NumReqOutputs - 1;
- end
- elseif isstr(arglist{ii,2})
- narglist{jj,2} = arglist{ii,2};
- else
- if strcmp(paramtype{jj}, 'Integer') & (round(arglist{ii,2}) ~= arglist{ii,2})
- error(['Argument ' arglist{ii,1} ' is of integer type but non-integer number ' arglist{ii,2} ' was supplied']);
- end
- if (minval{jj} ~= 0 | maxval{jj} ~= 0)
- if (minval{jj} == 1 & maxval{jj} == 1 & arglist{ii,2} < 0)
- error(['Argument ' arglist{ii,1} ' must be bigger or equal to zero!']);
- elseif (minval{jj} == -1 & maxval{jj} == -1 & arglist{ii,2} > 0)
- error(['Argument ' arglist{ii,1} ' must be smaller or equal to zero!']);
- elseif (minval{jj} == 2 & maxval{jj} == 2 & arglist{ii,2} <= 0)
- error(['Argument ' arglist{ii,1} ' must be bigger than zero!']);
- elseif (minval{jj} == -2 & maxval{jj} == -2 & arglist{ii,2} >= 0)
- error(['Argument ' arglist{ii,1} ' must be smaller than zero!']);
- elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} < minval{jj})
- error(['Argument ' arglist{ii,1} ' must be bigger than ' num2str(minval{jj})]);
- elseif (minval{jj} ~= maxval{jj} & arglist{ii,2} > maxval{jj})
- error(['Argument ' arglist{ii,1} ' must be smaller than ' num2str(maxval{jj})]);
- end
- end
- end
- if ~strcmp(narglist{jj,2},'OK_out') & ~strcmp(narglist{jj,2},'OK_in')
- narglist{jj,2} = arglist{ii,2};
- end
- end
- end
- if (wasmatched == 0 & ~strcmp(arglist{ii,1},''))
- error(['Argument ' arglist{ii,1} ' is not a valid argument for this function']);
- end
- end
- % match the remaining inputs/outputs to the unused arguments and test for missing required inputs
- for jj=1:size(narglist,1)
- if strcmp(paramtype{jj}, 'Toggle')
- if (narglist{jj,2} ==0)
- narglist{jj,1} = '';
- end;
- narglist{jj,2} = '';
- end;
- if ~strcmp(narglist{jj,2},'__input') && ~strcmp(narglist{jj,2},'__output') && istoggle(jj) && ~ was_set(jj)
- narglist{jj,1} = '';
- narglist{jj,2} = '';
- end;
- if strcmp(narglist{jj,2}, '__input')
- if (minval{jj} == 0) % meaning this input is required
- if (nextinput > size(Inputs))
- error(['Required input ' narglist{jj,1} ' has no corresponding input in the list!']);
- else
- narglist{jj,2} = 'OK_in';
- nextinput = nextinput + 1;
- end
- else % this is an optional input
- if (nextinput <= length(Inputs))
- narglist{jj,2} = 'OK_in';
- nextinput = nextinput + 1;
- else
- narglist{jj,1} = '';
- narglist{jj,2} = '';
- end;
- end;
- else
- if strcmp(narglist{jj,2}, '__output')
- if (minval{jj} == 0) % this is a required output
- if (nextoutput > nargout & nargout > 1)
- error(['Required output ' narglist{jj,1} ' is not stated in the assignment list!']);
- else
- narglist{jj,2} = 'OK_out';
- nextoutput = nextoutput + 1;
- NumReqOutputs = NumReqOutputs-1;
- end
- else % this is an optional output
- if (nargout - nextoutput >= NumReqOutputs)
- narglist{jj,2} = 'OK_out';
- nextoutput = nextoutput + 1;
- else
- narglist{jj,1} = '';
- narglist{jj,2} = '';
- end;
- end
- end
- end
- end
- if nargout
- varargout = cell(1,nargout);
- else
- varargout = cell(1,1);
- end
- global KhorosRoot
- if exist('KhorosRoot') && ~isempty(KhorosRoot)
- w=['"' KhorosRoot];
- else
- if ispc
- w='"C:\Program Files\dip\khorosBin\';
- else
- [s,w] = system('which cantata');
- w=['"' w(1:end-8)];
- end
- end
- [varargout{:}]=callKhoros([w 'vwmdd" '],Inputs,narglist);