Libmv: Solve some strict compiler warnings
[blender.git] / intern / libmv / intern / track_region.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2011 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation,
22  *                 Sergey Sharybin
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 #include "intern/track_region.h"
28 #include "intern/image.h"
29 #include "intern/utildefines.h"
30 #include "libmv/image/image.h"
31 #include "libmv/tracking/track_region.h"
32
33 /* define this to generate PNG images with content of search areas
34    tracking between which failed */
35 #undef DUMP_FAILURE
36
37 /* define this to generate PNG images with content of search areas
38    on every itteration of tracking */
39 #undef DUMP_ALWAYS
40
41 using libmv::FloatImage;
42 using libmv::TrackRegionOptions;
43 using libmv::TrackRegionResult;
44 using libmv::TrackRegion;
45
46 void libmv_configureTrackRegionOptions(
47     const libmv_TrackRegionOptions& options,
48     TrackRegionOptions* track_region_options) {
49   switch (options.motion_model) {
50 #define LIBMV_CONVERT(the_model) \
51   case TrackRegionOptions::the_model: \
52     track_region_options->mode = TrackRegionOptions::the_model; \
53     break;
54     LIBMV_CONVERT(TRANSLATION)
55     LIBMV_CONVERT(TRANSLATION_ROTATION)
56     LIBMV_CONVERT(TRANSLATION_SCALE)
57     LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE)
58     LIBMV_CONVERT(AFFINE)
59     LIBMV_CONVERT(HOMOGRAPHY)
60 #undef LIBMV_CONVERT
61   }
62
63   track_region_options->minimum_correlation = options.minimum_correlation;
64   track_region_options->max_iterations = options.num_iterations;
65   track_region_options->sigma = options.sigma;
66   track_region_options->num_extra_points = 1;
67   track_region_options->image1_mask = NULL;
68   track_region_options->use_brute_initialization = options.use_brute;
69   /* TODO(keir): This will make some cases better, but may be a regression until
70    * the motion model is in. Since this is on trunk, enable it for now.
71    *
72    * TODO(sergey): This gives much worse results on mango footage (see 04_2e)
73    * so disabling for now for until proper prediction model is landed.
74    *
75    * The thing is, currently blender sends input coordinates as the guess to
76    * region tracker and in case of fast motion such an early out ruins the track.
77    */
78   track_region_options->attempt_refine_before_brute = false;
79   track_region_options->use_normalized_intensities = options.use_normalization;
80 }
81
82 void libmv_regionTrackergetResult(const TrackRegionResult& track_region_result,
83                                   libmv_TrackRegionResult* result) {
84   result->termination = (int) track_region_result.termination;
85   result->termination_reason = "";
86   result->correlation = track_region_result.correlation;
87 }
88
89 int libmv_trackRegion(const libmv_TrackRegionOptions* options,
90                       const float* image1,
91                       int image1_width,
92                       int image1_height,
93                       const float* image2,
94                       int image2_width,
95                       int image2_height,
96                       const double* x1,
97                       const double* y1,
98                       libmv_TrackRegionResult* /*result*/,
99                       double* x2,
100                       double* y2) {
101   double xx1[5], yy1[5];
102   double xx2[5], yy2[5];
103   bool tracking_result = false;
104
105   // Convert to doubles for the libmv api. The four corners and the center.
106   for (int i = 0; i < 5; ++i) {
107     xx1[i] = x1[i];
108     yy1[i] = y1[i];
109     xx2[i] = x2[i];
110     yy2[i] = y2[i];
111   }
112
113   TrackRegionOptions track_region_options;
114   FloatImage image1_mask;
115
116   libmv_configureTrackRegionOptions(*options, &track_region_options);
117   if (options->image1_mask) {
118     libmv_floatBufferToFloatImage(options->image1_mask,
119                                   image1_width,
120                                   image1_height,
121                                   1,
122                                   &image1_mask);
123
124     track_region_options.image1_mask = &image1_mask;
125   }
126
127   // Convert from raw float buffers to libmv's FloatImage.
128   FloatImage old_patch, new_patch;
129   libmv_floatBufferToFloatImage(image1,
130                                 image1_width,
131                                 image1_height,
132                                 1,
133                                 &old_patch);
134   libmv_floatBufferToFloatImage(image2,
135                                 image2_width,
136                                 image2_height,
137                                 1,
138                                 &new_patch);
139
140   TrackRegionResult track_region_result;
141   TrackRegion(old_patch, new_patch,
142               xx1, yy1,
143               track_region_options,
144               xx2, yy2,
145               &track_region_result);
146
147   // Convert to floats for the blender api.
148   for (int i = 0; i < 5; ++i) {
149     x2[i] = xx2[i];
150     y2[i] = yy2[i];
151   }
152
153   // TODO(keir): Update the termination string with failure details.
154   if (track_region_result.termination == TrackRegionResult::CONVERGENCE ||
155       track_region_result.termination == TrackRegionResult::NO_CONVERGENCE) {
156     tracking_result = true;
157   }
158
159   // Debug dump of patches.
160 #if defined(DUMP_FAILURE) || defined(DUMP_ALWAYS)
161   bool need_dump = !tracking_result;
162
163 #  ifdef DUMP_ALWAYS
164   need_dump = true;
165 #  endif
166
167   if (need_dump) {
168     libmv_saveImage(old_patch, "old_patch", x1[4], y1[4]);
169     libmv_saveImage(new_patch, "new_patch", x2[4], y2[4]);
170     if (options->image1_mask) {
171       libmv_saveImage(image1_mask, "mask", x2[4], y2[4]);
172     }
173   }
174 #endif
175
176   return tracking_result;
177 }