[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58823] branches/soc-2011-tomato: Compute homographies when creating new plane tracker

Sergey Sharybin sergey.vfx at gmail.com
Fri Aug 2 10:50:31 CEST 2013


Revision: 58823
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58823
Author:   nazgul
Date:     2013-08-02 08:50:30 +0000 (Fri, 02 Aug 2013)
Log Message:
-----------
Compute homographies when creating new plane tracker

When new plane tracker is creating, blender will go
over tracked sequence of point tracks, compute homography
between neighbor frames and deform plane rectangle using
this homography.

This makes rectangle plane follow tracked plane quite
nicely. But as an additional homographies will be
updated after corners were slided with a mouse.

Additional changes:

- Display keyframed/tracked information in the cache line
  for plane tracks (the same way as it's done for point tracks).
- Fix couple of buys in homography C-API.

Modified Paths:
--------------
    branches/soc-2011-tomato/extern/libmv/libmv-capi.cc
    branches/soc-2011-tomato/source/blender/blenkernel/BKE_tracking.h
    branches/soc-2011-tomato/source/blender/blenkernel/intern/tracking.c
    branches/soc-2011-tomato/source/blender/editors/space_clip/clip_draw.c
    branches/soc-2011-tomato/source/blender/editors/space_clip/clip_utils.c
    branches/soc-2011-tomato/source/blender/editors/space_clip/tracking_ops.c
    branches/soc-2011-tomato/source/blender/makesdna/DNA_tracking_types.h

Modified: branches/soc-2011-tomato/extern/libmv/libmv-capi.cc
===================================================================
--- branches/soc-2011-tomato/extern/libmv/libmv-capi.cc	2013-08-02 07:59:26 UTC (rev 58822)
+++ branches/soc-2011-tomato/extern/libmv/libmv-capi.cc	2013-08-02 08:50:30 UTC (rev 58823)
@@ -1103,11 +1103,17 @@
 
 	for (int i = 0; i < num_points; i++) {
 		x1_mat.col(i) = libmv::Vec2(x1[i][0], x1[i][1]);
+		x2_mat.col(i) = libmv::Vec2(x2[i][0], x2[i][1]);
 	}
 
+	LG << "x1: " << x1_mat;
+	LG << "x2: " << x2_mat;
+
 	libmv::Homography2DFromCorrespondencesLinear(x1_mat, x2_mat, &H_mat, expected_precision);
 
-	memcpy(H, H_mat.data(), 9 * sizeof(float));
+	LG << "H: " << H_mat;
+
+	memcpy(H, H_mat.data(), 9 * sizeof(double));
 }
 
 #endif

Modified: branches/soc-2011-tomato/source/blender/blenkernel/BKE_tracking.h
===================================================================
--- branches/soc-2011-tomato/source/blender/blenkernel/BKE_tracking.h	2013-08-02 07:59:26 UTC (rev 58822)
+++ branches/soc-2011-tomato/source/blender/blenkernel/BKE_tracking.h	2013-08-02 08:50:30 UTC (rev 58823)
@@ -232,6 +232,10 @@
                                            float *warped_position_x,
                                            float *warped_position_y);
 
+/* **** Plane tracking **** */
+
+void BKE_tracking_track_plane_from_existing_motion(struct MovieTrackingPlaneTrack *plane_track, int start_frame);
+
 /* **** Camera solving **** */
 int BKE_tracking_reconstruction_check(struct MovieTracking *tracking, struct MovieTrackingObject *object,
                                       char *error_msg, int error_size);

Modified: branches/soc-2011-tomato/source/blender/blenkernel/intern/tracking.c
===================================================================
--- branches/soc-2011-tomato/source/blender/blenkernel/intern/tracking.c	2013-08-02 07:59:26 UTC (rev 58822)
+++ branches/soc-2011-tomato/source/blender/blenkernel/intern/tracking.c	2013-08-02 08:50:30 UTC (rev 58823)
@@ -1348,7 +1348,7 @@
 		}
 	}
 
-	if (num_selected_tracks < 3) {
+	if (num_selected_tracks < 4) {
 		return NULL;
 	}
 
@@ -1369,6 +1369,7 @@
 
 	/* Setup new plane marker and add it to the track. */
 	plane_marker.framenr = framenr;
+	plane_marker.flag = 0;
 
 	copy_v2_v2(plane_marker.corners[0], tracks_min);
 	copy_v2_v2(plane_marker.corners[2], tracks_max);
@@ -3294,6 +3295,126 @@
 	*warped_position_y = warped_position_y_double;
 }
 
+/*********************** Plane tracking *************************/
+
+typedef double Vec2[2];
+
+static int point_markers_correspondences_on_both_image(MovieTrackingPlaneTrack *plane_track, int frame1, int frame2,
+                                                       Vec2 **x1_r, Vec2 **x2_r)
+{
+	int i, correspondence_index;
+	Vec2 *x1, *x2;
+
+	*x1_r = x1 = MEM_mallocN(sizeof(*x1) * plane_track->point_tracksnr, "point correspondences x1");
+	*x2_r = x2 = MEM_mallocN(sizeof(*x1) * plane_track->point_tracksnr, "point correspondences x2");
+
+	for (i = 0, correspondence_index = 0; i < plane_track->point_tracksnr; i++) {
+		MovieTrackingTrack *point_track = plane_track->point_tracks[i];
+		MovieTrackingMarker *point_marker1, *point_marker2;
+
+		point_marker1 = BKE_tracking_marker_get_exact(point_track, frame1);
+		point_marker2 = BKE_tracking_marker_get_exact(point_track, frame2);
+
+		if (point_marker1 != NULL && point_marker2 != NULL) {
+			/* Here conversion from float to double happens. */
+			x1[correspondence_index][0] = point_marker1->pos[0];
+			x1[correspondence_index][1] = point_marker1->pos[1];
+
+			x2[correspondence_index][0] = point_marker2->pos[0];
+			x2[correspondence_index][1] = point_marker2->pos[1];
+
+			correspondence_index++;
+		}
+	}
+
+	return correspondence_index;
+}
+
+/* TODO(sergey): Make it generic function available for everyone. */
+BLI_INLINE void mat3f_from_mat3d(float mat_float[3][3], double mat_double[3][3])
+{
+	/* Keep it stupid simple for better data flow in CPU. */
+	mat_float[0][0] = mat_double[0][0];
+	mat_float[0][1] = mat_double[0][1];
+	mat_float[0][2] = mat_double[0][2];
+
+	mat_float[1][0] = mat_double[1][0];
+	mat_float[1][1] = mat_double[1][1];
+	mat_float[1][2] = mat_double[1][2];
+
+	mat_float[2][0] = mat_double[2][0];
+	mat_float[2][1] = mat_double[2][1];
+	mat_float[2][2] = mat_double[2][2];
+}
+
+/* NOTE: frame number should be in clip space, not scene space */
+static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame, int direction)
+{
+	MovieTrackingPlaneMarker *start_plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
+	MovieTrackingPlaneMarker new_plane_marker;
+	int current_frame, frame_delta = direction > 0 ? 1 : -1;
+
+	new_plane_marker = *start_plane_marker;
+	new_plane_marker.flag |= PLANE_MARKER_TRACKED;
+
+	for (current_frame = start_frame; ; current_frame += frame_delta) {
+		MovieTrackingPlaneMarker *next_plane_marker =
+			BKE_tracking_plane_marker_get_exact(plane_track, current_frame + frame_delta);
+		Vec2 *x1, *x2;
+		int i, num_correspondences;
+		double H_double[3][3];
+		float H[3][3];
+
+		/* As soon as we meet keyframed plane, we stop updating the sequence. */
+		if (next_plane_marker && (next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
+			break;
+		}
+
+		num_correspondences =
+			point_markers_correspondences_on_both_image(plane_track, current_frame, current_frame + frame_delta,
+			                                            &x1, &x2);
+
+		if (num_correspondences == 0) {
+			MEM_freeN(x1);
+			MEM_freeN(x2);
+
+			break;
+		}
+
+		libmv_homography2DFromCorrespondencesLinear(x1, x2, num_correspondences, H_double, 1e-8);
+
+		mat3f_from_mat3d(H, H_double);
+
+		for (i = 0; i < 4; i++) {
+			float vec[3] = {0.0f, 0.0f, 1.0f};
+			copy_v2_v2(vec, new_plane_marker.corners[i]);
+
+			/* Apply homography */
+			mul_v3_m3v3(vec, H, vec);
+
+			/* Normalize. */
+			vec[0] /= vec[2];
+			vec[1] /= vec[2];
+
+			copy_v2_v2(new_plane_marker.corners[i], vec);
+		}
+
+		new_plane_marker.framenr = current_frame + frame_delta;
+
+		BKE_tracking_plane_marker_insert(plane_track, &new_plane_marker);
+
+		MEM_freeN(x1);
+		MEM_freeN(x2);
+	}
+}
+
+/* NOTE: frame number should be in clip space, not scene space */
+void BKE_tracking_track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame)
+{
+	track_plane_from_existing_motion(plane_track, start_frame, 1);
+	track_plane_from_existing_motion(plane_track, start_frame, -1);
+}
+
 /*********************** Camera solving *************************/
 
 typedef struct MovieReconstructContext {

Modified: branches/soc-2011-tomato/source/blender/editors/space_clip/clip_draw.c
===================================================================
--- branches/soc-2011-tomato/source/blender/editors/space_clip/clip_draw.c	2013-08-02 07:59:26 UTC (rev 58822)
+++ branches/soc-2011-tomato/source/blender/editors/space_clip/clip_draw.c	2013-08-02 08:50:30 UTC (rev 58823)
@@ -111,6 +111,57 @@
 	}
 }
 
+static int generic_track_get_markersnr(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track)
+{
+	if (track) {
+		return track->markersnr;
+	}
+	else if (plane_track) {
+		return plane_track->markersnr;
+	}
+
+	return 0;
+}
+
+static int generic_track_get_marker_framenr(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
+                                            int marker_index)
+{
+	if (track) {
+		return track->markers[marker_index].framenr;
+	}
+	else if (plane_track) {
+		return plane_track->markers[marker_index].framenr;
+	}
+
+	return 0;
+}
+
+static bool generic_track_is_marker_enabled(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
+                                            int marker_index)
+{
+	if (track) {
+		return (track->markers[marker_index].flag & MARKER_DISABLED) == 0;
+	}
+	else if (plane_track) {
+		return true;
+	}
+
+	return false;
+}
+
+static bool generic_track_is_marker_keyframed(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
+                                              int marker_index)
+{
+	if (track) {
+		return (track->markers[marker_index].flag & MARKER_TRACKED) == 0;
+	}
+	else if (plane_track) {
+		return (plane_track->markers[marker_index].flag & PLANE_MARKER_TRACKED) == 0;
+	}
+
+	return false;
+}
+
 static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
 {
 	float x;
@@ -119,6 +170,7 @@
 	MovieTracking *tracking = &clip->tracking;
 	MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking);
 	MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
+	MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking);
 	MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
 
 	glEnable(GL_BLEND);
@@ -143,34 +195,29 @@
 	}
 
 	/* track */
-	if (act_track) {
-		MovieTrackingTrack *track = act_track;
-
+	if (act_track || act_plane_track) {
 		for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) {
 			int framenr;
-			MovieTrackingMarker *marker;
+			int markersnr = generic_track_get_markersnr(act_track, act_plane_track);
 
-			while (a < track->markersnr) {
-				if (track->markers[a].framenr >= i)
+			while (a < markersnr) {
+				int marker_framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
+
+				if (marker_framenr >= i)
 					break;
 
-				if (a < track->markersnr - 1 && track->markers[a + 1].framenr > i)
+				if (a < markersnr - 1 && generic_track_get_marker_framenr(act_track, act_plane_track, a + 1) > i)
 					break;
 
 				a++;
 			}
 
-			if (a < track->markersnr)
-				marker = &track->markers[a];
-			else
-				marker = &track->markers[track->markersnr - 1];
+			if (generic_track_is_marker_enabled(act_track, act_plane_track, a)) {
+				framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
 
-			if ((marker->flag & MARKER_DISABLED) == 0) {
-				framenr = marker->framenr;
-
 				if (framenr != i)
 					glColor4ub(128, 128, 0, 96);
-				else if ((marker->flag & MARKER_TRACKED) == 0)
+				else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a))
 					glColor4ub(255, 255, 0, 196);
 				else
 					glColor4ub(255, 255, 0, 96);

Modified: branches/soc-2011-tomato/source/blender/editors/space_clip/clip_utils.c
===================================================================

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list