MT::MT(const unsigned char *gray, int width, int height, rect_t rect, ostream *os) : image_width(width), image_height(height), window_width(rect.width), window_height(rect.height), warp(width, height), feature(width, height), log(os) { //build the fine template on uniform grid warp.sett(locate(rect)); float fine_stride = sqrt(window_width * window_height / fine_n); int W = int(floor(window_width / (2.0f * fine_stride))); int H = int(floor(window_height / (2.0f * fine_stride))); for (int y = 0; y <= 2 * H; ++y) for (int x = 0; x <= 2 * W; ++x) fine_samples.push_back(Vector3f((x - W) * fine_stride, (y - H) * fine_stride, 0.0f)); //initialization feature.process(gray, 0.0f); N = 0; fine_train(warp); fast_train(warp); fine_errors.push_back(0.0f); error = 0.0f; roll = yaw = pitch = 0.0f; number_coarse = number_MLK = number_iteration = 0; }
Rect2f MT::track(Mat img, const vector<Rect2f> &detections) { if (log != NULL) { (*log) << "roll = " << roll * 90.0f / PI_2 << endl; (*log) << "yaw = " << yaw * 90.0f / PI_2 << endl; (*log) << "pitch = " << pitch * 90.0f / PI_2 << endl; } if (!detections.empty()) roll = 0.0f; feature.process(img, roll); vector<Point3f> candidates; candidates.push_back(warp.t); candidates.push_back(fast_test(warp)); for (auto d : detections) candidates.push_back(locate(d)); Warp best_warp(image_size); float best_error = 1.0f; for (auto& t : candidates) { if (log != NULL) (*log) << "candidate " << t << " " << window(t) << endl; Warp w(image_size); if (detections.empty()) w.set(warp.r); w.set(t); w = fine_test(w); float e = evaluate(w); if (log != NULL) { (*log) << "final translation = " << w.t << " " << window(w.t) << endl; (*log) << "final rotation = " << w.r << endl; (*log) << "final error = " << e << endl; } if (e < best_error) { best_warp = w; best_error = e; } } candidates.clear(); error = best_error; if (error < threshold_error) { count = 0; warp = best_warp; warp.euler(roll, yaw, pitch); fine_train(warp); } else { ++count; warp.t = best_warp.t * (warp.t.z / best_warp.t.z); } fast_train(warp); return window(best_warp.t); }
void MT::update(Warp w, float e) { if (log != NULL) { (*log) << "final translation = " << w.t.transpose() << " " << window(w.t) << endl; (*log) << "final rotation = " << w.r.transpose() << endl; (*log) << "final error = " << e << endl; } //if the error is lower than threshold, we update the fine model error = e; if (e < fine_threshold) { warp = w; warp.euler(roll, yaw, pitch); fine_train(warp); } else warp.t = w.t * (warp.t.z() / w.t.z()); fast_train(warp); fine_errors.push_back(e); while (fine_errors.size() > detect_interval) fine_errors.pop_front(); }
MT::MT(Mat img, Rect2f rect, ostream *os) : log(os), image_size(img.size()), window_size(rect.size()), feature(image_size), warp(image_size) { warp.set(locate(rect)); float fine_stride = sqrt(window_size.area() / fine_n); int W = int(floor(window_size.width / (2.0f * fine_stride))); int H = int(floor(window_size.height / (2.0f * fine_stride))); for (int y = 0; y <= 2 * H; ++y) for (int x = 0; x <= 2 * W; ++x) fine_samples.push_back(Point3f((x - W) * fine_stride, (y - H) * fine_stride, 0.0f)); feature.process(img, 0.0f); fine_train(warp); fast_train(warp); error = 0.0f; roll = yaw = pitch = 0.0f; count = N = 0; }