-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkalmanInitLinearMotion.m
executable file
·188 lines (156 loc) · 6.84 KB
/
kalmanInitLinearMotion.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
function [kalmanFilterInfo,errFlag] = kalmanInitLinearMotion(frameInfo,...
probDim,costMatParam)
%KALMANINITLINEARMOTION initializes Kalman filter state vector and covariance matrix for features in a frame
%
%SYNOPSIS [kalmanFilterInfo,errFlag] = kalmanInitLinearMotion(frameInfo,...
% probDim,costMatParam)
%
%INPUT frameInfo : Structure with fields (for 1 frame):
% .allCoord : Image coordinate system x,dx,y,dy,[z,dz] of
% detected features and their uncertainties (in
% pixels).
% .num : Number of features in frame.
% probDim : Problem dimension. 2 (for 2D) or 3 (for 3D).
% costMatParam : Linking cost matrix parameters. In addition
% to the fields needed for costMatLinearMotionLink,
% if it has the field
% .kalmanInitParam, then sub-fields within will be used for
% initialization.
% .convergePoint: Convergence point (x, y, [z]
% coordinates) of tracks if motion is
% radial, in image coordinate system.
% Should be a row vector. If supplied,
% radial form is assumed and value is
% used to estimate initial velocities. If
% not supplied, then initial velocity is
% taken as zero.
% .searchRadiusFirstIteration: max number of pixels to
% use in the first frame pair where the
% search is essentially a nearest
% neighbor. here we use this parameter to
% get the initial noise variance. in
% kathryn's alternate function
% costMatLinearMotionLink_EB3.m, the
% min/max search radii are not applied in
% the first iteration so that this
% initial radius can be sufficiently big
% if features are moving quickly (ie
% faster than the max search radius)
% .initVelocity : Initial velocity guess (vx, vy, [vz]),
% in whatever units coordinates are in
% per frame.
%
%OUTPUT kalmanFilterInfo: Structure with fields:
% .stateVec : State vector for each feature.
% .stateCov : State covariance matrix for each feature.
% .noiseVar : Variance of state noise for each feature.
% errFlag : 0 if function executes normally, 1 otherwise.
%
%
%Khuloud Jaqaman, March 2007
%% Output
kalmanFilterInfo = [];
errFlag = 0;
%% Input
%check whether correct number of input arguments was used
if nargin < 3
disp('--kalmanInitLinearMotion: Incorrect number of input arguments!');
errFlag = 1;
return
end
%extract min. and max. search radii and brownStdMult from costMatParam
minSearchRadius = costMatParam.minSearchRadius;
maxSearchRadius = costMatParam.maxSearchRadius;
brownStdMult = costMatParam.brownStdMult;
%check whether additional initialization parameters were input
if isfield(costMatParam,'kalmanInitParam')
initParam = costMatParam.kalmanInitParam;
if isfield(initParam,'convergePoint')
convergePoint = initParam.convergePoint;
else
initParam.convergePoint = [];
convergePoint = [];
end
if isfield(initParam,'initVelocity')
initVelGuess = initParam.initVelocity;
else
initParam.initVelocity = [];
initVelGuess = [];
end
% calculate noiseVarInit from max search radius (if given) or from
% min/max search radii
if isfield(initParam,'searchRadiusFirstIteration') && ~isempty(initParam.searchRadiusFirstIteration)
searchRadiusFirstIteration = initParam.searchRadiusFirstIteration;
noiseVarInit = -(searchRadiusFirstIteration/brownStdMult)^2 / probDim; %negative to flag as first appearance
else
noiseVarInit = (maxSearchRadius / brownStdMult) ^ 2 / probDim;
% noiseVarInit = (mean([minSearchRadius maxSearchRadius]) / brownStdMult) ^ 2 / probDim;
end
else
initParam.convergePoint = [];
convergePoint = [];
initVelGuess = [];
noiseVarInit = (mean([minSearchRadius maxSearchRadius]) / brownStdMult) ^ 2 / probDim;
end
if ~isempty(convergePoint)
[nRow,nCol] = size(convergePoint);
if nRow ~= 1 && nCol == 1
convergePoint = convergePoint';
end
nCol = size(convergePoint,2);
if nCol ~= probDim
disp('--kalmanInitLinearMotion: initParam.convergePoint of wrong dimension!');
errFlag = 1;
end
end
if ~isempty(initVelGuess)
[nRow,nCol] = size(initVelGuess);
if nRow ~= 1 && nCol == 1
initVelGuess = initVelGuess';
end
nCol = size(initVelGuess,2);
if nCol ~= probDim
disp('--kalmanInitLinearMotion: initParam.initVelocity of wrong dimension!');
errFlag = 1;
end
end
%exit if there are problems with input
if errFlag
disp('--kalmanInitLinearMotion: Please fix input parameters.');
return
end
%% Initialization
%find number of features in frame
numFeatures = frameInfo.num;
%estimate initial velocity
if isempty(initVelGuess) %if there is no initial guess for velocity
if isempty(convergePoint) %if there is no convergence point information
%assume zero initial velocity
velocityInit = zeros(numFeatures,probDim);
else %if there is a convergence point
%assign initial speed
speedInit = 1;
%get displacement and distance of features from convergence point
displacement = repmat(convergePoint,numFeatures,1) - ...
frameInfo.allCoord(1:2:end);
distance = sqrt(sum(displacement.^2,2));
%calculate initial velocity
velocityInit = speedInit * displacement ./ repmat(distance,1,probDim);
end
else %if there is an initial guess for velocity
velocityInit = repmat(initVelGuess,numFeatures,1);
end
%initialize state vector
kalmanFilterInfo.stateVec = [frameInfo.allCoord(:,1:2:end) velocityInit];
%initialize state covariance matrix
for iFeature = 1 : numFeatures
posVar = frameInfo.allCoord(iFeature,2:2:end).^2;
posVar = max(eps,posVar);
kalmanFilterInfo.stateCov(:,:,iFeature) = diag([posVar 4*ones(1,probDim)]);
end
%initialize state noise variance
for iFeature = 1 : numFeatures
kalmanFilterInfo.noiseVar(:,:,iFeature) = diag(...
ones(2*probDim,1)*noiseVarInit);
end
%% %%%% ~~ the end ~~ %%%%