Blender V4.3
intern/track_region.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6#include "intern/image.h"
8#include "libmv/image/image.h"
11
12/* define this to generate PNG images with content of search areas
13 tracking between which failed */
14#undef DUMP_FAILURE
15
16/* define this to generate PNG images with content of search areas
17 on every iteration of tracking */
18#undef DUMP_ALWAYS
19
24
25namespace {
26
27TrackRegionOptions::Direction convertDirection(
29 switch (direction) {
32 }
33
34 LOG(FATAL) << "Unhandled tracking direction " << direction
35 << ", should never happen.";
36
38}
39
40TrackRegionOptions::Mode convertMotionModelToMode(int motion_model) {
41 switch (motion_model) {
42#define LIBMV_CONVERT(the_model) \
43 case TrackRegionOptions::the_model: return TrackRegionOptions::the_model;
44
45 LIBMV_CONVERT(TRANSLATION)
46 LIBMV_CONVERT(TRANSLATION_ROTATION)
47 LIBMV_CONVERT(TRANSLATION_SCALE)
48 LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE)
49 LIBMV_CONVERT(AFFINE)
50 LIBMV_CONVERT(HOMOGRAPHY)
51
52#undef LIBMV_CONVERT
53 }
54
55 LOG(FATAL) << "Unhandled motion model " << motion_model
56 << ", should never happen.";
57
59}
60
61} // namespace
62
65 TrackRegionOptions* track_region_options) {
66 track_region_options->direction = convertDirection(options.direction);
67 track_region_options->mode = convertMotionModelToMode(options.motion_model);
68 track_region_options->minimum_correlation = options.minimum_correlation;
69 track_region_options->max_iterations = options.num_iterations;
70 track_region_options->sigma = options.sigma;
71 track_region_options->num_extra_points = 1;
72 track_region_options->image1_mask = NULL;
73 track_region_options->use_brute_initialization = options.use_brute;
74 /* TODO(keir): This will make some cases better, but may be a regression until
75 * the motion model is in. Since this is on trunk, enable it for now.
76 *
77 * TODO(sergey): This gives much worse results on mango footage (see 04_2e)
78 * so disabling for now for until proper prediction model is landed.
79 *
80 * The thing is, currently blender sends input coordinates as the guess to
81 * region tracker and in case of fast motion such an early out ruins the
82 * track.
83 */
84 track_region_options->attempt_refine_before_brute = false;
85 track_region_options->use_normalized_intensities = options.use_normalization;
86}
87
88void libmv_regionTrackergetResult(const TrackRegionResult& track_region_result,
90 result->termination = (int)track_region_result.termination;
91 result->termination_reason = "";
92 result->correlation = track_region_result.correlation;
93}
94
96 const float* image1,
97 int image1_width,
98 int image1_height,
99 const float* image2,
100 int image2_width,
101 int image2_height,
102 const double* x1,
103 const double* y1,
104 libmv_TrackRegionResult* /*result*/,
105 double* x2,
106 double* y2) {
107 double xx1[5], yy1[5];
108 double xx2[5], yy2[5];
109 bool tracking_result = false;
110
111 // Convert to doubles for the libmv api. The four corners and the center.
112 for (int i = 0; i < 5; ++i) {
113 xx1[i] = x1[i];
114 yy1[i] = y1[i];
115 xx2[i] = x2[i];
116 yy2[i] = y2[i];
117 }
118
119 TrackRegionOptions track_region_options;
120 FloatImage image1_mask;
121
122 libmv_configureTrackRegionOptions(*options, &track_region_options);
123 if (options->image1_mask) {
125 options->image1_mask, image1_width, image1_height, 1, &image1_mask);
126
127 track_region_options.image1_mask = &image1_mask;
128 }
129
130 // Convert from raw float buffers to libmv's FloatImage.
131 FloatImage old_patch, new_patch;
133 image1, image1_width, image1_height, 1, &old_patch);
135 image2, image2_width, image2_height, 1, &new_patch);
136
137 TrackRegionResult track_region_result;
138 TrackRegion(old_patch,
139 new_patch,
140 xx1,
141 yy1,
142 track_region_options,
143 xx2,
144 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}
3D array (row, column, channel).
Definition array_nd.h:332
CCL_NAMESPACE_BEGIN struct Options options
#define NULL
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
bool libmv_saveImage(const FloatImage &image, const char *prefix, int x0, int y0)
void libmv_floatBufferToFloatImage(const float *buffer, int width, int height, int channels, FloatImage *image)
#define LIBMV_CONVERT(the_model)
void libmv_configureTrackRegionOptions(const libmv_TrackRegionOptions &options, TrackRegionOptions *track_region_options)
void libmv_regionTrackergetResult(const TrackRegionResult &track_region_result, libmv_TrackRegionResult *result)
int libmv_trackRegion(const libmv_TrackRegionOptions *options, const float *image1, int image1_width, int image1_height, const float *image2, int image2_width, int image2_height, const double *x1, const double *y1, libmv_TrackRegionResult *, double *x2, double *y2)
libmv_TrackRegionDirection
@ LIBMV_TRACK_REGION_FORWARD
@ LIBMV_TRACK_REGION_BACKWARD
#define LOG(severity)
Definition log.h:33
void TrackRegion(const FloatImage &image1, const FloatImage &image2, const double *x1, const double *y1, const TrackRegionOptions &options, double *x2, double *y2, TrackRegionResult *result)