bool SkinMeme::compute_delt() { static bool debug = ::debug || Config::get_var_bool("DEBUG_SKIN_MEMES",false); _delt = Wvec::null(); if (is_frozen()) return false; if (!is_tracking()) { err_msg("SkinMeme::compute_delt: not tracking, can't proceed"); return false; } if (!is_boss()) { err_adv(debug, "SkinMeme::compute_delt: non-boss; bailing..."); track_to_target(loc()); return false; } Wpt cur = loc(); Wpt centroid = vert()->qr_centroid(); static const double bw = Config::get_var_dbl("SKIN_SMOOTH_CENTROID_WEIGHT",0.5); Wpt target = interp(cur, centroid, bw); // Target is where we want to be, but we'll settle for // somewhere on the skeleton surface that is as close as // possible. Wpt tp; if (track_to_target(target, tp)) { // double d = target.dist(tp); // Wpt new_loc = target + norm() * (fabs(_h) - d); // Wpt new_loc = tp + ((target - tp).normalized() * fabs(_h)); // XXX - hack // can we figure this out, one day, soon?? Wpt new_loc; if (is_border(track_simplex())) { new_loc = tp + track_norm()*_h; } else { new_loc = tp + ((target - tp).normalized() * fabs(_h)); } _delt = new_loc - cur; return true; } err_adv(debug, "SkinMeme::compute_delt: track to target failed"); return false; }
void SkinMeme::set_track_simplex(Bsimplex* s) { assert(_track_filter); if (!s) { _trackers.clear(); } else if (!_track_filter->accept(s)) { err_adv(debug, "SkinMeme::set_track_simplex: error: filter rejects simplex"); } else if (is_tracking()) { _trackers[0] = s; } else { add_track_simplex(s); } }
CWpt& SkinMeme::compute_update() { static bool debug = ::debug || Config::get_var_bool("DEBUG_SKIN_UPDATE",false); // compute 3D vertex location WRT track simplex if (_is_sticky) { // this meme is supposed to follow the skeleton surface if (is_tracking()) { // it actually is following it return _update = skin_loc(track_simplex(), _bc, _h); } // supposed to follow, but has no track point: do nothing return _update = loc(); } // this meme is not following the skeleton surface; // it computes its location via smooth subdivision. // but it may still track the closest point on the skeleton // surface to avoid penetrating inside the skeleton surface. if (vert()->parent() == 0) _update = loc(); else _update = vert()->detail_loc_from_parent(); track_to_target(_update); if (_non_penetrate && is_tracking()) { Wvec d = penetration_correction(_update, track_simplex(), _bc, _stay_out); if (debug && !d.is_null()) err_msg("SkinMeme::compute_update: correcting penetration, level %d", bbase()->subdiv_level()); _update += d; } return _update; }
void OpenCVTracker::update(Image& image) { if (!is_tracking()) return; const cv::Mat gray = image.get_gray(); DEBUGMSG("Updating tracker \n"); active = tracker->update(gray, rectangle); if (!active) DEBUGMSG("Update failed \n"); }
bool SkinMeme::track_to_target(CWpt& target, Wpt& near_pt) { // Do a local search to find the closest point to 'target' on the // tracked surface. Do the search starting from our own track // simplex, and then repeat the search starting from each track // simplex that can be borrowed from our SkinMeme neighbors. In the // end take the one that yielded the closest result, and store the // corresponding track simplex. if (is_frozen()) return is_tracking(); Wvec near_bc; Bsimplex* track_sim = update_tracker( target, get_local_trackers(), near_pt, near_bc ); // Record the result, even if unsuccessful: set(track_sim, near_bc); return (track_simplex() != 0); }
Wvec SkinMeme::track_norm() const { return is_tracking() ? bc2norm(track_simplex(), _bc) : norm(); }
Wpt SkinMeme::track_pt() const { return is_tracking() ? track_simplex()->bc2pos(_bc) : loc(); }