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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs