From b0015686e2e48a384a0b2a03a75f6daaad7271c0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 26 May 2017 15:21:15 +0200 Subject: Fix T50908: Motion Tracker ignored grease pencil mask This feature got lost with new auto-track API, Added it back by extending frame accessor class. This isn't really a frame thing, but we don't have other type of accessor here. Surely, we can use old-style API here and pass mask via region tracker options for this particular case, but then it becomes much less obvious how real auto-tracker will access this mask with old style API. So seems we do need an accessor for such data, just matter of finding better place than frame accessor. --- intern/libmv/intern/frame_accessor.cc | 53 +++++++++++++++++++++++++-- intern/libmv/intern/frame_accessor.h | 15 +++++++- intern/libmv/intern/stub.cc | 4 +- intern/libmv/intern/track_region.cc | 2 +- intern/libmv/libmv/autotrack/autotrack.cc | 23 +++++++++++- intern/libmv/libmv/autotrack/frame_accessor.h | 19 ++++++++++ 6 files changed, 108 insertions(+), 8 deletions(-) (limited to 'intern/libmv') diff --git a/intern/libmv/intern/frame_accessor.cc b/intern/libmv/intern/frame_accessor.cc index 5d274d7ccca..e7fc0ab4883 100644 --- a/intern/libmv/intern/frame_accessor.cc +++ b/intern/libmv/intern/frame_accessor.cc @@ -40,10 +40,14 @@ using mv::Region; struct LibmvFrameAccessor : public FrameAccessor { LibmvFrameAccessor(libmv_FrameAccessorUserData* user_data, libmv_GetImageCallback get_image_callback, - libmv_ReleaseImageCallback release_image_callback) + libmv_ReleaseImageCallback release_image_callback, + libmv_GetMaskForTrackCallback get_mask_for_track_callback, + libmv_ReleaseMaskCallback release_mask_callback) : user_data_(user_data), get_image_callback_(get_image_callback), - release_image_callback_(release_image_callback) { } + release_image_callback_(release_image_callback), + get_mask_for_track_callback_(get_mask_for_track_callback), + release_mask_callback_(release_mask_callback) { } virtual ~LibmvFrameAccessor() { } @@ -109,6 +113,41 @@ struct LibmvFrameAccessor : public FrameAccessor { release_image_callback_(cache_key); } + Key GetMaskForTrack(int clip, + int frame, + int track, + const Region* region, + FloatImage* destination) { + float *float_buffer; + int width, height; + libmv_Region libmv_region; + if (region) { + get_libmv_region(*region, &libmv_region); + } + Key cache_key = get_mask_for_track_callback_( + user_data_, + clip, + frame, + track, + region != NULL ? &libmv_region : NULL, + &float_buffer, + &width, + &height); + + // TODO(sergey): Dumb code for until we can set data directly. + FloatImage temp_image(float_buffer, + height, + width, + 1); + destination->CopyFrom(temp_image); + + return cache_key; + } + + void ReleaseMask(Key key) { + release_mask_callback_(key); + } + bool GetClipDimensions(int /*clip*/, int * /*width*/, int * /*height*/) { return false; } @@ -124,6 +163,8 @@ struct LibmvFrameAccessor : public FrameAccessor { libmv_FrameAccessorUserData* user_data_; libmv_GetImageCallback get_image_callback_; libmv_ReleaseImageCallback release_image_callback_; + libmv_GetMaskForTrackCallback get_mask_for_track_callback_; + libmv_ReleaseMaskCallback release_mask_callback_; }; } // namespace @@ -131,11 +172,15 @@ struct LibmvFrameAccessor : public FrameAccessor { libmv_FrameAccessor* libmv_FrameAccessorNew( libmv_FrameAccessorUserData* user_data, libmv_GetImageCallback get_image_callback, - libmv_ReleaseImageCallback release_image_callback) { + libmv_ReleaseImageCallback release_image_callback, + libmv_GetMaskForTrackCallback get_mask_for_track_callback, + libmv_ReleaseMaskCallback release_mask_callback) { return (libmv_FrameAccessor*) LIBMV_OBJECT_NEW(LibmvFrameAccessor, user_data, get_image_callback, - release_image_callback); + release_image_callback, + get_mask_for_track_callback, + release_mask_callback); } void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor) { diff --git a/intern/libmv/intern/frame_accessor.h b/intern/libmv/intern/frame_accessor.h index 3e813fe7581..c041d67f56f 100644 --- a/intern/libmv/intern/frame_accessor.h +++ b/intern/libmv/intern/frame_accessor.h @@ -61,10 +61,23 @@ typedef libmv_CacheKey (*libmv_GetImageCallback) ( typedef void (*libmv_ReleaseImageCallback) (libmv_CacheKey cache_key); +typedef libmv_CacheKey (*libmv_GetMaskForTrackCallback) ( + libmv_FrameAccessorUserData* user_data, + int clip, + int frame, + int track, + const libmv_Region* region, + float** destination, + int* width, + int* height); +typedef void (*libmv_ReleaseMaskCallback) (libmv_CacheKey cache_key); + libmv_FrameAccessor* libmv_FrameAccessorNew( libmv_FrameAccessorUserData* user_data, libmv_GetImageCallback get_image_callback, - libmv_ReleaseImageCallback release_image_callback); + libmv_ReleaseImageCallback release_image_callback, + libmv_GetMaskForTrackCallback get_mask_for_track_callback, + libmv_ReleaseMaskCallback release_mask_callback); void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor); int64_t libmv_frameAccessorgetTransformKey(const libmv_FrameTransform *transform); diff --git a/intern/libmv/intern/stub.cc b/intern/libmv/intern/stub.cc index 47e1915e072..8603cc03153 100644 --- a/intern/libmv/intern/stub.cc +++ b/intern/libmv/intern/stub.cc @@ -375,7 +375,9 @@ int libmv_autoTrackGetMarker(libmv_AutoTrack* /*libmv_autotrack*/, libmv_FrameAccessor* libmv_FrameAccessorNew( libmv_FrameAccessorUserData* /*user_data**/, libmv_GetImageCallback /*get_image_callback*/, - libmv_ReleaseImageCallback /*release_image_callback*/) + libmv_ReleaseImageCallback /*release_image_callback*/, + libmv_GetMaskForTrackCallback /*get_mask_for_track_callback*/, + libmv_ReleaseMaskCallback /*release_mask_callback*/) { return NULL; } diff --git a/intern/libmv/intern/track_region.cc b/intern/libmv/intern/track_region.cc index 8989897e09f..d395b6457d7 100644 --- a/intern/libmv/intern/track_region.cc +++ b/intern/libmv/intern/track_region.cc @@ -36,7 +36,7 @@ /* define this to generate PNG images with content of search areas on every itteration of tracking */ -#undef DUMP_ALWAYS +#define DUMP_ALWAYS using libmv::FloatImage; using libmv::TrackRegionOptions; diff --git a/intern/libmv/libmv/autotrack/autotrack.cc b/intern/libmv/libmv/autotrack/autotrack.cc index 4c7bdf1fde8..00366e0f661 100644 --- a/intern/libmv/libmv/autotrack/autotrack.cc +++ b/intern/libmv/libmv/autotrack/autotrack.cc @@ -111,6 +111,17 @@ FrameAccessor::Key GetImageForMarker(const Marker& marker, image); } +FrameAccessor::Key GetMaskForMarker(const Marker& marker, + FrameAccessor* frame_accessor, + FloatImage* mask) { + Region region = marker.search_region.Rounded(); + return frame_accessor->GetMaskForTrack(marker.clip, + marker.frame, + marker.track, + ®ion, + mask); +} + } // namespace bool AutoTrack::TrackMarker(Marker* tracked_marker, @@ -149,6 +160,11 @@ bool AutoTrack::TrackMarker(Marker* tracked_marker, return false; } + FloatImage reference_mask; + FrameAccessor::Key reference_mask_key = GetMaskForMarker(reference_marker, + frame_accessor_, + &reference_mask); + FloatImage tracked_image; FrameAccessor::Key tracked_key = GetImageForMarker(*tracked_marker, frame_accessor_, @@ -167,6 +183,10 @@ bool AutoTrack::TrackMarker(Marker* tracked_marker, if (track_options) { local_track_region_options = *track_options; } + if (reference_mask_key != NULL) { + LG << "Using mask for reference marker: " << reference_marker; + local_track_region_options.image1_mask = &reference_mask; + } local_track_region_options.num_extra_points = 1; // For center point. local_track_region_options.attempt_refine_before_brute = predicted_position; TrackRegion(reference_image, @@ -191,9 +211,10 @@ bool AutoTrack::TrackMarker(Marker* tracked_marker, tracked_marker->reference_clip = reference_marker.clip; tracked_marker->reference_frame = reference_marker.frame; - // Release the images from the accessor cache. + // Release the images and masks from the accessor cache. frame_accessor_->ReleaseImage(reference_key); frame_accessor_->ReleaseImage(tracked_key); + frame_accessor_->ReleaseMask(reference_mask_key); // TODO(keir): Possibly the return here should get removed since the results // are part of TrackResult. However, eventually the autotrack stuff will have diff --git a/intern/libmv/libmv/autotrack/frame_accessor.h b/intern/libmv/libmv/autotrack/frame_accessor.h index 8de5d865cd7..32f6349963c 100644 --- a/intern/libmv/libmv/autotrack/frame_accessor.h +++ b/intern/libmv/libmv/autotrack/frame_accessor.h @@ -76,6 +76,25 @@ struct FrameAccessor { // free the image immediately; others may hold onto the image. virtual void ReleaseImage(Key) = 0; + // Get mask image for the given track. + // + // Implementation of this method should sample mask associated with the track + // within given region to the given destination. + // + // Result is supposed to be a single channel image. + // + // If region is NULL, it it assumed to be full-frame. + virtual Key GetMaskForTrack(int clip, + int frame, + int track, + const Region* region, + FloatImage* destination) = 0; + + // Release a specified mask. + // + // Non-caching implementation may free used memory immediately. + virtual void ReleaseMask(Key key) = 0; + virtual bool GetClipDimensions(int clip, int* width, int* height) = 0; virtual int NumClips() = 0; virtual int NumFrames(int clip) = 0; -- cgit v1.2.3