Blender V4.3
pyramid_region_tracker.cc
Go to the documentation of this file.
1// Copyright (c) 2007, 2008, 2009, 2011 libmv authors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to
5// deal in the Software without restriction, including without limitation the
6// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7// sell copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19// IN THE SOFTWARE.
20
22
23#include <vector>
24
26#include "libmv/image/image.h"
27#include "libmv/image/sample.h"
29
30namespace libmv {
31
32static void MakePyramid(const FloatImage& image,
33 int num_levels,
34 std::vector<FloatImage>* pyramid) {
35 pyramid->resize(num_levels);
36 (*pyramid)[0] = image;
37 for (int i = 1; i < num_levels; ++i) {
38 DownsampleChannelsBy2((*pyramid)[i - 1], &(*pyramid)[i]);
39 }
40}
41
43 const FloatImage& image2,
44 double x1,
45 double y1,
46 double* x2,
47 double* y2) const {
48 // Shrink the guessed x and y location to match the coarsest level + 1 (which
49 // when gets corrected in the loop).
50 *x2 /= pow(2., num_levels_);
51 *y2 /= pow(2., num_levels_);
52
53 // Create all the levels of the pyramid, since tracking has to happen from
54 // the coarsest to finest levels, which means holding on to all levels of the
55 // pyraid at once.
56 std::vector<FloatImage> pyramid1(num_levels_);
57 std::vector<FloatImage> pyramid2(num_levels_);
58 MakePyramid(image1, num_levels_, &pyramid1);
59 MakePyramid(image2, num_levels_, &pyramid2);
60
61 for (int i = num_levels_ - 1; i >= 0; --i) {
62 // Position in the first image at pyramid level i.
63 double xx = x1 / pow(2., i);
64 double yy = y1 / pow(2., i);
65
66 // Guess the new tracked position is where the last level tracked to.
67 *x2 *= 2;
68 *y2 *= 2;
69
70 // Save the previous best guess for this level, since tracking within this
71 // level might fail.
72 double x2_new = *x2;
73 double y2_new = *y2;
74
75 // Track the point on this level with the base tracker.
76 LG << "Tracking on level " << i;
77 bool succeeded =
78 tracker_->Track(pyramid1[i], pyramid2[i], xx, yy, &x2_new, &y2_new);
79
80 if (!succeeded) {
81 if (i == 0) {
82 // Only fail on the highest-resolution level, because a failure on a
83 // coarse level does not mean failure at a lower level (consider
84 // out-of-bounds conditions).
85 LG << "Finest level of pyramid tracking failed; failing.";
86 return false;
87 }
88
89 LG << "Failed to track at level " << i << "; restoring guess.";
90 } else {
91 // Only save the update if the track for this level succeeded. This is a
92 // bit of a hack; the jury remains out on whether this is better than
93 // re-using the previous failed-attempt.
94 *x2 = x2_new;
95 *y2 = y2_new;
96 }
97 }
98 return true;
99}
100
101} // namespace libmv
3D array (row, column, channel).
Definition array_nd.h:332
virtual bool Track(const FloatImage &image1, const FloatImage &image2, double x1, double y1, double *x2, double *y2) const
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
#define LG
static void MakePyramid(const FloatImage &image, int num_levels, std::vector< FloatImage > *pyramid)
void DownsampleChannelsBy2(const Array3Df &in, Array3Df *out)