Implement per-frame track reprojection error visualization
It is now possible to display per-frame track reprojection error in curve view of clip editor. Simply enable corresponding option in filter buttons. Currently displayed using blue color which might confuse with average reprojection error, further color tweaks are possible and easy. Also changed icon track x/y curves. Better icons here are really appreciated.
This commit is contained in:
parent
122e2b4bfa
commit
28b671d98f
|
@ -98,7 +98,8 @@ class CLIP_HT_header(Header):
|
|||
sub.active = clip.tracking.reconstruction.is_valid
|
||||
sub.prop(sc, "show_graph_frames", icon='SEQUENCE', text="")
|
||||
|
||||
row.prop(sc, "show_graph_tracks", icon='ANIM', text="")
|
||||
row.prop(sc, "show_graph_tracks_motion", icon='IPO', text="")
|
||||
row.prop(sc, "show_graph_tracks_error", icon='ANIM', text="")
|
||||
else:
|
||||
row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT',
|
||||
text="Filters")
|
||||
|
|
|
@ -116,7 +116,7 @@ static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track,
|
|||
glBegin(GL_LINE_STRIP);
|
||||
}
|
||||
|
||||
static void tracking_segment_end_cb(void *UNUSED(userdata))
|
||||
static void tracking_segment_end_cb(void *UNUSED(userdata), int UNUSED(coord))
|
||||
{
|
||||
glEnd();
|
||||
|
||||
|
@ -151,7 +151,7 @@ static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track,
|
|||
}
|
||||
}
|
||||
|
||||
static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
|
||||
static void draw_tracks_motion_curves(View2D *v2d, SpaceClip *sc)
|
||||
{
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
MovieTracking *tracking = &clip->tracking;
|
||||
|
@ -191,6 +191,108 @@ static void draw_tracks_curves(View2D *v2d, SpaceClip *sc)
|
|||
&userdata, tracking_segment_knot_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
typedef struct TrackErrorCurveUserData {
|
||||
MovieTracking *tracking;
|
||||
MovieTrackingObject *tracking_object;
|
||||
MovieTrackingTrack *active_track;
|
||||
bool matrix_initialized;
|
||||
int matrix_frame;
|
||||
float projection_matrix[4][4];
|
||||
int width, height;
|
||||
float aspy;
|
||||
} TrackErrorCurveUserData;
|
||||
|
||||
static void tracking_error_segment_point_cb(void *userdata,
|
||||
MovieTrackingTrack *track, MovieTrackingMarker *marker,
|
||||
int coord, int scene_framenr, float UNUSED(value))
|
||||
{
|
||||
if (coord == 1) {
|
||||
TrackErrorCurveUserData *data = (TrackErrorCurveUserData *) userdata;
|
||||
float reprojected_position[4], bundle_position[4], marker_position[2], delta[2];
|
||||
float reprojection_error;
|
||||
|
||||
if (!data->matrix_initialized || data->matrix_frame != scene_framenr) {
|
||||
BKE_tracking_get_projection_matrix(data->tracking, data->tracking_object,
|
||||
scene_framenr, data->width, data->height,
|
||||
data->projection_matrix);
|
||||
}
|
||||
|
||||
copy_v3_v3(bundle_position, track->bundle_pos);
|
||||
bundle_position[3] = 1;
|
||||
|
||||
mul_v4_m4v4(reprojected_position, data->projection_matrix, bundle_position);
|
||||
reprojected_position[0] = (reprojected_position[0] /
|
||||
(reprojected_position[3] * 2.0f) + 0.5f) * data->width;
|
||||
reprojected_position[1] = (reprojected_position[1] /
|
||||
(reprojected_position[3] * 2.0f) + 0.5f) * data->height * data->aspy;
|
||||
|
||||
BKE_tracking_distort_v2(data->tracking, reprojected_position, reprojected_position);
|
||||
|
||||
marker_position[0] = (marker->pos[0] + track->offset[0]) * data->width;
|
||||
marker_position[1] = (marker->pos[1] + track->offset[1]) * data->height * data->aspy;
|
||||
|
||||
sub_v2_v2v2(delta, reprojected_position, marker_position);
|
||||
reprojection_error = len_v2(delta);
|
||||
|
||||
glVertex2f(scene_framenr, reprojection_error);
|
||||
}
|
||||
}
|
||||
|
||||
static void tracking_error_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord)
|
||||
{
|
||||
if (coord == 1) {
|
||||
TrackErrorCurveUserData *data = (TrackErrorCurveUserData *) userdata;
|
||||
float col[4] = {0.0f, 0.0f, 1.0f, 1.0f};
|
||||
|
||||
if (track == data->active_track) {
|
||||
col[3] = 1.0f;
|
||||
glLineWidth(2.0f);
|
||||
}
|
||||
else {
|
||||
col[3] = 0.5f;
|
||||
glLineWidth(1.0f);
|
||||
}
|
||||
|
||||
glColor4fv(col);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
}
|
||||
}
|
||||
|
||||
static void tracking_error_segment_end_cb(void *UNUSED(userdata), int coord)
|
||||
{
|
||||
if (coord == 1) {
|
||||
glEnd();
|
||||
glLineWidth(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_tracks_error_curves(SpaceClip *sc)
|
||||
{
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
MovieTracking *tracking = &clip->tracking;
|
||||
TrackErrorCurveUserData data;
|
||||
|
||||
data.tracking = tracking;
|
||||
data.tracking_object = BKE_tracking_object_get_active(tracking);
|
||||
data.active_track = BKE_tracking_track_get_active(tracking);
|
||||
data.matrix_initialized = false;
|
||||
BKE_movieclip_get_size(clip, &sc->user, &data.width, &data.height);
|
||||
data.aspy = 1.0f / tracking->camera.pixel_aspect;
|
||||
|
||||
if (!data.width || !data.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
clip_graph_tracking_values_iterate(sc,
|
||||
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
|
||||
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
|
||||
&data,
|
||||
tracking_error_segment_point_cb,
|
||||
tracking_error_segment_start_cb,
|
||||
tracking_error_segment_end_cb);
|
||||
}
|
||||
|
||||
static void draw_frame_curves(SpaceClip *sc)
|
||||
{
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
|
@ -237,8 +339,11 @@ void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene)
|
|||
UI_view2d_grid_free(grid);
|
||||
|
||||
if (clip) {
|
||||
if (sc->flag & SC_SHOW_GRAPH_TRACKS)
|
||||
draw_tracks_curves(v2d, sc);
|
||||
if (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION)
|
||||
draw_tracks_motion_curves(v2d, sc);
|
||||
|
||||
if (sc->flag & SC_SHOW_GRAPH_TRACKS_ERROR)
|
||||
draw_tracks_error_curves(sc);
|
||||
|
||||
if (sc->flag & SC_SHOW_GRAPH_FRAMES)
|
||||
draw_frame_curves(sc);
|
||||
|
|
|
@ -130,7 +130,7 @@ static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack
|
|||
copy_v2_v2(data->prev_co, co);
|
||||
}
|
||||
|
||||
static void find_nearest_tracking_segment_end_cb(void *userdata)
|
||||
static void find_nearest_tracking_segment_end_cb(void *userdata, int UNUSED(coord))
|
||||
{
|
||||
MouseSelectUserData *data = userdata;
|
||||
|
||||
|
|
|
@ -125,12 +125,12 @@ void ED_clip_tool_props_register(struct ARegionType *art);
|
|||
void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata,
|
||||
void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val),
|
||||
void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord),
|
||||
void (*segment_end)(void *userdata));
|
||||
void (*segment_end)(void *userdata, int coord));
|
||||
|
||||
void clip_graph_tracking_values_iterate(struct SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata,
|
||||
void (*func)(void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val),
|
||||
void (*segment_start)(void *userdata, struct MovieTrackingTrack *track, int coord),
|
||||
void (*segment_end)(void *userdata));
|
||||
void (*segment_end)(void *userdata, int coord));
|
||||
|
||||
void clip_graph_tracking_iterate(struct SpaceClip *sc, bool selected_only, bool include_hidden, void *userdata,
|
||||
void (*func)(void *userdata, struct MovieTrackingMarker *marker));
|
||||
|
|
|
@ -70,7 +70,7 @@ void clip_graph_tracking_values_iterate_track(
|
|||
void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord,
|
||||
int scene_framenr, float val),
|
||||
void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord),
|
||||
void (*segment_end)(void *userdata))
|
||||
void (*segment_end)(void *userdata, int coord))
|
||||
{
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
int width, height, coord;
|
||||
|
@ -89,7 +89,7 @@ void clip_graph_tracking_values_iterate_track(
|
|||
if (marker->flag & MARKER_DISABLED) {
|
||||
if (open) {
|
||||
if (segment_end)
|
||||
segment_end(userdata);
|
||||
segment_end(userdata, coord);
|
||||
|
||||
open = false;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ void clip_graph_tracking_values_iterate_track(
|
|||
|
||||
if (open) {
|
||||
if (segment_end)
|
||||
segment_end(userdata);
|
||||
segment_end(userdata, coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ void clip_graph_tracking_values_iterate(
|
|||
void (*func)(void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker,
|
||||
int coord, int scene_framenr, float val),
|
||||
void (*segment_start)(void *userdata, MovieTrackingTrack *track, int coord),
|
||||
void (*segment_end)(void *userdata))
|
||||
void (*segment_end)(void *userdata, int coord))
|
||||
{
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
MovieTracking *tracking = &clip->tracking;
|
||||
|
|
|
@ -247,7 +247,7 @@ static SpaceLink *clip_new(const bContext *C)
|
|||
sc = MEM_callocN(sizeof(SpaceClip), "initclip");
|
||||
sc->spacetype = SPACE_CLIP;
|
||||
sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH | SC_MANUAL_CALIBRATION |
|
||||
SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL;
|
||||
SC_SHOW_GRAPH_TRACKS_MOTION | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL;
|
||||
sc->zoom = 1.0f;
|
||||
sc->path_length = 20;
|
||||
sc->scopes.track_preview_height = 120;
|
||||
|
|
|
@ -1107,27 +1107,28 @@ typedef struct SpaceClip {
|
|||
|
||||
/* SpaceClip->flag */
|
||||
typedef enum eSpaceClip_Flag {
|
||||
SC_SHOW_MARKER_PATTERN = (1 << 0),
|
||||
SC_SHOW_MARKER_SEARCH = (1 << 1),
|
||||
SC_LOCK_SELECTION = (1 << 2),
|
||||
SC_SHOW_TINY_MARKER = (1 << 3),
|
||||
SC_SHOW_TRACK_PATH = (1 << 4),
|
||||
SC_SHOW_BUNDLES = (1 << 5),
|
||||
SC_MUTE_FOOTAGE = (1 << 6),
|
||||
SC_HIDE_DISABLED = (1 << 7),
|
||||
SC_SHOW_NAMES = (1 << 8),
|
||||
SC_SHOW_GRID = (1 << 9),
|
||||
SC_SHOW_STABLE = (1 << 10),
|
||||
SC_MANUAL_CALIBRATION = (1 << 11),
|
||||
SC_SHOW_GPENCIL = (1 << 12),
|
||||
SC_SHOW_FILTERS = (1 << 13),
|
||||
SC_SHOW_GRAPH_FRAMES = (1 << 14),
|
||||
SC_SHOW_GRAPH_TRACKS = (1 << 15),
|
||||
/* SC_SHOW_PYRAMID_LEVELS = (1 << 16), */ /* UNUSED */
|
||||
SC_LOCK_TIMECURSOR = (1 << 17),
|
||||
SC_SHOW_SECONDS = (1 << 18),
|
||||
SC_SHOW_GRAPH_SEL_ONLY = (1 << 19),
|
||||
SC_SHOW_GRAPH_HIDDEN = (1 << 20),
|
||||
SC_SHOW_MARKER_PATTERN = (1 << 0),
|
||||
SC_SHOW_MARKER_SEARCH = (1 << 1),
|
||||
SC_LOCK_SELECTION = (1 << 2),
|
||||
SC_SHOW_TINY_MARKER = (1 << 3),
|
||||
SC_SHOW_TRACK_PATH = (1 << 4),
|
||||
SC_SHOW_BUNDLES = (1 << 5),
|
||||
SC_MUTE_FOOTAGE = (1 << 6),
|
||||
SC_HIDE_DISABLED = (1 << 7),
|
||||
SC_SHOW_NAMES = (1 << 8),
|
||||
SC_SHOW_GRID = (1 << 9),
|
||||
SC_SHOW_STABLE = (1 << 10),
|
||||
SC_MANUAL_CALIBRATION = (1 << 11),
|
||||
SC_SHOW_GPENCIL = (1 << 12),
|
||||
SC_SHOW_FILTERS = (1 << 13),
|
||||
SC_SHOW_GRAPH_FRAMES = (1 << 14),
|
||||
SC_SHOW_GRAPH_TRACKS_MOTION = (1 << 15),
|
||||
/* SC_SHOW_PYRAMID_LEVELS = (1 << 16), */ /* UNUSED */
|
||||
SC_LOCK_TIMECURSOR = (1 << 17),
|
||||
SC_SHOW_SECONDS = (1 << 18),
|
||||
SC_SHOW_GRAPH_SEL_ONLY = (1 << 19),
|
||||
SC_SHOW_GRAPH_HIDDEN = (1 << 20),
|
||||
SC_SHOW_GRAPH_TRACKS_ERROR = (1 << 21),
|
||||
} eSpaceClip_Flag;
|
||||
|
||||
/* SpaceClip->mode */
|
||||
|
|
|
@ -3745,14 +3745,21 @@ static void rna_def_space_clip(BlenderRNA *brna)
|
|||
"Show curve for per-frame average error (camera motion should be solved first)");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
|
||||
|
||||
/* show graph_tracks */
|
||||
prop = RNA_def_property(srna, "show_graph_tracks", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS);
|
||||
RNA_def_property_ui_text(prop, "Show Tracks",
|
||||
/* show graph tracks motion */
|
||||
prop = RNA_def_property(srna, "show_graph_tracks_motion", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS_MOTION);
|
||||
RNA_def_property_ui_text(prop, "Show Tracks Motion",
|
||||
"Display the speed curves (in \"x\" direction red, in \"y\" direction green) "
|
||||
"for the selected tracks");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
|
||||
|
||||
/* show graph tracks motion */
|
||||
prop = RNA_def_property(srna, "show_graph_tracks_error", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_TRACKS_ERROR);
|
||||
RNA_def_property_ui_text(prop, "Show Tracks Error",
|
||||
"Display the reprojection error curve for selected tracks");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL);
|
||||
|
||||
/* show_only_selected */
|
||||
prop = RNA_def_property(srna, "show_graph_only_selected", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GRAPH_SEL_ONLY);
|
||||
|
|
Loading…
Reference in New Issue