4 #include "SearchMethod.h" 6 #define ESMH_MAX_ITERS 10 7 #define ESMH_EPSILON 0.01 8 #define ESMH_JAC_TYPE 0 9 #define ESMH_HESS_TYPE 0 10 #define ESMH_SEC_ORD_HESS false 11 #define ESMH_ENABLE_SPI false 12 #define ESMH_SPI_THRESH 10 13 #define ESMH_DEBUG_MODE false 19 enum class JacType{ Original, DiffOfJacs };
21 Original, SumOfStd, SumOfSelf,
22 InitialSelf, CurrentSelf, Std
39 JacType _jac_type, HessType _hess_type,
bool _sec_ord_hess,
40 bool _enable_spi,
double _spi_thresh,
42 max_iters = _max_iters;
45 hess_type = _hess_type;
46 sec_ord_hess = _sec_ord_hess;
47 enable_spi = _enable_spi;
48 spi_thresh = _spi_thresh;
49 debug_mode = _debug_mode;
53 max_iters(ESMH_MAX_ITERS),
epsilon(ESMH_EPSILON),
54 jac_type(static_cast<JacType>(ESMH_JAC_TYPE)),
55 hess_type(static_cast<HessType>(ESMH_HESS_TYPE)),
56 sec_ord_hess(ESMH_SEC_ORD_HESS),
57 enable_spi(ESMH_ENABLE_SPI), spi_thresh(ESMH_SPI_THRESH),
58 debug_mode(ESMH_DEBUG_MODE){
60 max_iters = params->max_iters;
61 epsilon = params->epsilon;
62 jac_type = params->jac_type;
63 hess_type = params->hess_type;
64 sec_ord_hess = params->sec_ord_hess;
65 enable_spi = params->enable_spi;
66 spi_thresh = params->spi_thresh;
67 debug_mode = params->debug_mode;
72 template<
class AM,
class SSM>
78 typedef ParamType::JacType JacType;
79 typedef ParamType::HessType HessType;
96 VectorXd rel_pix_diff;
99 Matrix24d prev_corners;
103 MatrixXd init_pix_hessian, curr_pix_hessian, mean_pix_hessian;
112 ESMH(
const ParamType *esm_params,
117 printf(
"Using ESM tracker with:\n");
118 printf(
"max_iters: %d\n", params.max_iters);
119 printf(
"epsilon: %f\n", params.
epsilon);
120 printf(
"jac_type: %d\n", params.
jac_type);
121 printf(
"hess_type: %d\n", params.hess_type);
122 printf(
"sec_ord_hess: %d\n", params.sec_ord_hess);
123 printf(
"enable_spi: %d\n", params.enable_spi);
124 printf(
"spi_thresh: %f\n", params.spi_thresh);
125 printf(
"debug_mode: %d\n", params.debug_mode);
127 printf(
"appearance model: %s\n", am.name.c_str());
128 printf(
"state space model: %s\n", ssm.name.c_str());
137 case JacType::Original:
138 printf(
"Using original ESM Jacobian\n");
140 case JacType::DiffOfJacs:
141 printf(
"Using Difference of Jacobians\n");
144 throw utils::InvalidArgument(
"Invalid Jacobian type provided");
147 const char *hess_order = params.sec_ord_hess ?
"Second" :
"First";
148 switch(params.hess_type){
149 case HessType::Original:
150 printf(
"Using %s order original ESM Hessian\n", hess_order);
152 case HessType::SumOfStd:
153 printf(
"Using Sum of %s order Standard Hessians\n", hess_order);
155 case HessType::SumOfSelf:
156 printf(
"Using Sum of %s order Self Hessians\n", hess_order);
158 case HessType::InitialSelf:
159 printf(
"Using %s order Initial Self Hessian\n", hess_order);
161 case HessType::CurrentSelf:
162 printf(
"Using %s order Current Self Hessian\n", hess_order);
165 printf(
"Using %s order Standard Hessian\n", hess_order);
168 throw utils::InvalidArgument(
"Invalid Hessian type provided");
171 ssm_update.resize(ssm.getStateSize());
172 jacobian.resize(ssm.getStateSize());
173 hessian.resize(ssm.getStateSize(), ssm.getStateSize());
175 init_pix_jacobian.resize(am.getNPix(), ssm.getStateSize());
176 curr_pix_jacobian.resize(am.getNPix(), ssm.getStateSize());
178 if(params.
jac_type == JacType::Original || params.hess_type == HessType::Original){
179 mean_pix_jacobian.resize(am.getNPix(), ssm.getStateSize());
181 if(params.hess_type == HessType::SumOfSelf){
182 init_self_hessian.resize(ssm.getStateSize(), ssm.getStateSize());
184 if(params.sec_ord_hess){
185 init_pix_hessian.resize(ssm.getStateSize()*ssm.getStateSize(), am.getNPix());
186 if(params.hess_type != HessType::InitialSelf){
187 curr_pix_hessian.resize(ssm.getStateSize()*ssm.getStateSize(), am.getNPix());
188 if(params.hess_type == HessType::Original){
189 mean_pix_hessian.resize(ssm.getStateSize()*ssm.getStateSize(), am.getNPix());
195 void initialize(
const cv::Mat &corners)
override{
197 ssm.initialize(corners);
198 am.initializePixVals(ssm.getPts());
200 if(params.enable_spi){
201 if(!ssm.supportsSPI())
202 throw utils::InvalidArgument(
"ESM::initialize : SSM does not support SPI");
203 if(!am.supportsSPI())
204 throw utils::InvalidArgument(
"ESM::initialize : AM does not support SPI");
206 printf(
"Using Selective Pixel Integration\n");
207 pix_mask.resize(am.getNPix());
208 ssm.setSPIMask(pix_mask.data());
209 am.setSPIMask(pix_mask.data());
212 ssm.initializeGradPts(am.getGradOffset());
213 am.initializePixGrad(ssm.getGradPts());
214 ssm.cmptInitPixJacobian(init_pix_jacobian, am.getInitPixGrad());
216 if(params.sec_ord_hess){
217 ssm.initializeHessPts(am.getHessOffset());
218 am.initializePixHess(ssm.getPts(), ssm.getHessPts());
219 ssm.cmptInitPixHessian(init_pix_hessian, am.getInitPixHess(), am.getInitPixGrad());
221 am.initializeSimilarity();
225 if(params.hess_type == HessType::InitialSelf || params.hess_type == HessType::SumOfSelf){
226 if(params.sec_ord_hess){
227 am.cmptSelfHessian(hessian, init_pix_jacobian, init_pix_hessian);
229 am.cmptSelfHessian(hessian, init_pix_jacobian);
231 if(params.hess_type == HessType::SumOfSelf){
232 init_self_hessian = hessian;
235 ssm.getCorners(cv_corners_mat);
238 void update()
override{
241 for(
int iter_id = 0; iter_id < params.max_iters; iter_id++){
243 am.updatePixVals(ssm.getPts());
245 if(params.enable_spi){
246 rel_pix_diff = (am.getInitPixVals() - am.getCurrPixVals()) / max_pix_diff;
247 pix_mask = rel_pix_diff.cwiseAbs().array() < params.spi_thresh;
250 ssm.updateGradPts(am.getGradOffset());
251 am.updatePixGrad(ssm.getGradPts());
253 ssm.cmptInitPixJacobian(curr_pix_jacobian, am.getCurrPixGrad());
255 if(params.
jac_type == JacType::Original || params.hess_type == HessType::Original){
256 mean_pix_jacobian = (init_pix_jacobian + curr_pix_jacobian) / 2.0;
258 if(params.sec_ord_hess && params.hess_type != HessType::InitialSelf){
259 ssm.updateHessPts(am.getHessOffset());
260 am.updatePixHess(ssm.getPts(), ssm.getHessPts());
261 ssm.cmptInitPixHessian(curr_pix_hessian, am.getCurrPixHess(), am.getCurrPixGrad());
264 am.updateSimilarity();
271 case JacType::Original:
274 am.cmptCurrJacobian(jacobian, mean_pix_jacobian);
276 case JacType::DiffOfJacs:
278 am.cmptDifferenceOfJacobians(jacobian, init_pix_jacobian, curr_pix_jacobian);
282 switch(params.hess_type){
283 case HessType::InitialSelf:
285 case HessType::Original:
286 if(params.sec_ord_hess){
287 mean_pix_hessian = (init_pix_hessian + curr_pix_hessian) / 2.0;
288 am.cmptCurrHessian(hessian, mean_pix_jacobian, mean_pix_hessian);
290 am.cmptCurrHessian(hessian, mean_pix_jacobian);
293 case HessType::SumOfStd:
294 if(params.sec_ord_hess){
295 am.cmptSumOfHessians(hessian, init_pix_jacobian, curr_pix_jacobian,
296 init_pix_hessian, curr_pix_hessian);
298 am.cmptSumOfHessians(hessian, init_pix_jacobian, curr_pix_jacobian);
302 case HessType::SumOfSelf:
303 if(params.sec_ord_hess){
304 am.cmptSelfHessian(hessian, curr_pix_jacobian, curr_pix_hessian);
306 am.cmptSelfHessian(hessian, curr_pix_jacobian);
308 hessian = (hessian + init_self_hessian) * 0.5;
310 case HessType::CurrentSelf:
311 if(params.sec_ord_hess){
312 am.cmptSelfHessian(hessian, curr_pix_jacobian, curr_pix_hessian);
314 am.cmptSelfHessian(hessian, curr_pix_jacobian);
318 if(params.sec_ord_hess){
319 am.cmptCurrHessian(hessian, curr_pix_jacobian, curr_pix_hessian);
321 am.cmptCurrHessian(hessian, curr_pix_jacobian);
325 ssm_update = -hessian.colPivHouseholderQr().solve(jacobian.transpose());
326 prev_corners = ssm.getCorners();
327 ssm.compositionalUpdate(ssm_update);
328 double update_norm = (prev_corners - ssm.getCorners()).squaredNorm();
329 if(update_norm < params.
epsilon){
334 ssm.getCorners(cv_corners_mat);
MatrixXd init_pix_jacobian
N x S jacobians of the pixel values w.r.t the SSM state vector where N = resx * resy is the no...
Definition: ESMH.h:102
MatrixXd hessian
S x S Hessian of the AM error norm w.r.t. SSM state vector.
Definition: ESMH.h:108
Definition: StateSpaceModel.h:35
double epsilon
maximum iterations of the ESMH algorithm to run for each frame
Definition: ESMH.h:26
RowVectorXd jacobian
1 x S Jacobian of the AM error norm w.r.t. SSM state vector
Definition: ESMH.h:106
Definition: AMParams.h:12
Definition: SearchMethod.h:10
JacType jac_type
maximum L1 norm of the state update vector at which to stop the iterations
Definition: ESMH.h:28
ESMHParams(int _max_iters, double _epsilon, JacType _jac_type, HessType _hess_type, bool _sec_ord_hess, bool _enable_spi, double _spi_thresh, bool _debug_mode)
decides whether logging data will be printed for debugging purposes;
Definition: ESMH.h:38