Blender  V2.93
tracking_plane_tracker.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2011 Blender Foundation.
17  * All rights reserved.
18  */
19 
26 #include "MEM_guardedalloc.h"
27 
28 #include "DNA_movieclip_types.h"
29 
30 #include "BLI_math.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BKE_tracking.h"
34 
35 #include "libmv-capi.h"
36 
37 typedef double Vec2[2];
38 
40  MovieTrackingPlaneTrack *plane_track, int frame1, int frame2, Vec2 **x1_r, Vec2 **x2_r)
41 {
42  Vec2 *x1, *x2;
43 
44  *x1_r = x1 = MEM_mallocN(sizeof(*x1) * plane_track->point_tracksnr, "point correspondences x1");
45  *x2_r = x2 = MEM_mallocN(sizeof(*x1) * plane_track->point_tracksnr, "point correspondences x2");
46 
47  int correspondence_index = 0;
48  for (int i = 0; i < plane_track->point_tracksnr; i++) {
49  MovieTrackingTrack *point_track = plane_track->point_tracks[i];
50  MovieTrackingMarker *point_marker1, *point_marker2;
51 
52  point_marker1 = BKE_tracking_marker_get_exact(point_track, frame1);
53  point_marker2 = BKE_tracking_marker_get_exact(point_track, frame2);
54 
55  if (point_marker1 != NULL && point_marker2 != NULL) {
56  /* Here conversion from float to double happens. */
57  x1[correspondence_index][0] = point_marker1->pos[0];
58  x1[correspondence_index][1] = point_marker1->pos[1];
59 
60  x2[correspondence_index][0] = point_marker2->pos[0];
61  x2[correspondence_index][1] = point_marker2->pos[1];
62 
63  correspondence_index++;
64  }
65  }
66 
67  return correspondence_index;
68 }
69 
70 /* NOTE: frame number should be in clip space, not scene space */
72  int start_frame,
73  int direction,
74  bool retrack)
75 {
76  MovieTrackingPlaneMarker *start_plane_marker = BKE_tracking_plane_marker_get(plane_track,
77  start_frame);
78  MovieTrackingPlaneMarker *keyframe_plane_marker = NULL;
79  MovieTrackingPlaneMarker new_plane_marker;
80  int frame_delta = direction > 0 ? 1 : -1;
81 
82  if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
83  /* Find a keyframe in given direction. */
84  for (int current_frame = start_frame;; current_frame += frame_delta) {
86  plane_track, current_frame + frame_delta);
87 
88  if (next_plane_marker == NULL) {
89  break;
90  }
91 
92  if ((next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
93  keyframe_plane_marker = next_plane_marker;
94  break;
95  }
96  }
97  }
98  else {
99  start_plane_marker->flag |= PLANE_MARKER_TRACKED;
100  }
101 
102  new_plane_marker = *start_plane_marker;
103  new_plane_marker.flag |= PLANE_MARKER_TRACKED;
104 
105  for (int current_frame = start_frame;; current_frame += frame_delta) {
107  plane_track, current_frame + frame_delta);
108  Vec2 *x1, *x2;
109  double H_double[3][3];
110  float H[3][3];
111 
112  /* As soon as we meet keyframed plane, we stop updating the sequence. */
113  if (next_plane_marker && (next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
114  /* Don't override keyframes if track is in auto-keyframe mode */
115  if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
116  break;
117  }
118  }
119 
120  const int num_correspondences = point_markers_correspondences_on_both_image(
121  plane_track, current_frame, current_frame + frame_delta, &x1, &x2);
122  if (num_correspondences < 4) {
123  MEM_freeN(x1);
124  MEM_freeN(x2);
125  break;
126  }
127 
128  libmv_homography2DFromCorrespondencesEuc(x1, x2, num_correspondences, H_double);
129 
130  copy_m3_m3d(H, H_double);
131 
132  for (int i = 0; i < 4; i++) {
133  float vec[3] = {0.0f, 0.0f, 1.0f}, vec2[3];
134  copy_v2_v2(vec, new_plane_marker.corners[i]);
135 
136  /* Apply homography */
137  mul_v3_m3v3(vec2, H, vec);
138 
139  /* Normalize. */
140  vec2[0] /= vec2[2];
141  vec2[1] /= vec2[2];
142 
143  copy_v2_v2(new_plane_marker.corners[i], vec2);
144  }
145 
146  new_plane_marker.framenr = current_frame + frame_delta;
147 
148  if (!retrack && keyframe_plane_marker && next_plane_marker &&
149  (plane_track->flag & PLANE_TRACK_AUTOKEY)) {
150  float fac = ((float)next_plane_marker->framenr - start_plane_marker->framenr) /
151  ((float)keyframe_plane_marker->framenr - start_plane_marker->framenr);
152 
153  fac = 3 * fac * fac - 2 * fac * fac * fac;
154 
155  for (int i = 0; i < 4; i++) {
156  interp_v2_v2v2(new_plane_marker.corners[i],
157  new_plane_marker.corners[i],
158  next_plane_marker->corners[i],
159  fac);
160  }
161  }
162 
163  BKE_tracking_plane_marker_insert(plane_track, &new_plane_marker);
164 
165  MEM_freeN(x1);
166  MEM_freeN(x2);
167  }
168 }
169 
170 /* NOTE: frame number should be in clip space, not scene space */
172  int start_frame)
173 {
174  track_plane_from_existing_motion(plane_track, start_frame, 1, false);
175  track_plane_from_existing_motion(plane_track, start_frame, -1, false);
176 }
177 
179  int start_frame,
180  int direction)
181 {
182  MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
183  int index = plane_marker - plane_track->markers;
184  int frame_delta = direction > 0 ? 1 : -1;
185 
186  while (index >= 0 && index < plane_track->markersnr) {
187  if ((plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
188  return plane_marker;
189  }
190  plane_marker += frame_delta;
191  }
192 
193  return NULL;
194 }
195 
197  MovieTrackingPlaneTrack *plane_track, int start_frame)
198 {
199  MovieTrackingPlaneMarker *prev_plane_keyframe, *next_plane_keyframe;
200 
201  prev_plane_keyframe = find_plane_keyframe(plane_track, start_frame, -1);
202  next_plane_keyframe = find_plane_keyframe(plane_track, start_frame, 1);
203 
204  if (prev_plane_keyframe != NULL && next_plane_keyframe != NULL) {
205  /* First we track from left keyframe to the right one without any blending. */
206  track_plane_from_existing_motion(plane_track, prev_plane_keyframe->framenr, 1, true);
207 
208  /* And then we track from the right keyframe to the left one, so shape blends in nicely */
209  track_plane_from_existing_motion(plane_track, next_plane_keyframe->framenr, -1, false);
210  }
211  else if (prev_plane_keyframe != NULL) {
212  track_plane_from_existing_motion(plane_track, prev_plane_keyframe->framenr, 1, true);
213  }
214  else if (next_plane_keyframe != NULL) {
215  track_plane_from_existing_motion(plane_track, next_plane_keyframe->framenr, -1, true);
216  }
217 }
218 
219 BLI_INLINE void float_corners_to_double(/*const*/ float corners[4][2], double double_corners[4][2])
220 {
221  copy_v2db_v2fl(double_corners[0], corners[0]);
222  copy_v2db_v2fl(double_corners[1], corners[1]);
223  copy_v2db_v2fl(double_corners[2], corners[2]);
224  copy_v2db_v2fl(double_corners[3], corners[3]);
225 }
226 
227 void BKE_tracking_homography_between_two_quads(/*const*/ float reference_corners[4][2],
228  /*const*/ float corners[4][2],
229  float H[3][3])
230 {
231  Vec2 x1[4], x2[4];
232  double H_double[3][3];
233 
234  float_corners_to_double(reference_corners, x1);
235  float_corners_to_double(corners, x2);
236 
238 
239  copy_m3_m3d(H, H_double);
240 }
typedef float(TangentPoint)[2]
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_insert(struct MovieTrackingPlaneTrack *plane_track, struct MovieTrackingPlaneMarker *plane_marker)
Definition: tracking.c:1919
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition: tracking.c:1994
struct MovieTrackingMarker * BKE_tracking_marker_get_exact(struct MovieTrackingTrack *track, int framenr)
Definition: tracking.c:1556
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get_exact(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition: tracking.c:2045
#define BLI_INLINE
void copy_m3_m3d(float m1[3][3], const double m2[3][3])
Definition: math_matrix.c:206
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
Definition: math_matrix.c:901
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t)
Definition: math_vector.c:32
MINLINE void copy_v2db_v2fl(double r[2], const float a[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
@ PLANE_MARKER_TRACKED
@ PLANE_TRACK_AUTOKEY
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
Read Guarded memory(de)allocation.
void libmv_homography2DFromCorrespondencesEuc(double(*x1)[2], double(*x2)[2], int num_points, double H[3][3])
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
MovieTrackingTrack ** point_tracks
MovieTrackingPlaneMarker * markers
static MovieTrackingPlaneMarker * find_plane_keyframe(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction)
double Vec2[2]
static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction, bool retrack)
BLI_INLINE void float_corners_to_double(float corners[4][2], double double_corners[4][2])
void BKE_tracking_retrack_plane_from_existing_motion_at_segment(MovieTrackingPlaneTrack *plane_track, int start_frame)
void BKE_tracking_track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame)
static int point_markers_correspondences_on_both_image(MovieTrackingPlaneTrack *plane_track, int frame1, int frame2, Vec2 **x1_r, Vec2 **x2_r)
void BKE_tracking_homography_between_two_quads(float reference_corners[4][2], float corners[4][2], float H[3][3])
#define H(x, y, z)