Camera tracking: SAD tracker now supports patterns with any size
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 28 Nov 2011 21:48:49 +0000 (21:48 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 28 Nov 2011 21:48:49 +0000 (21:48 +0000)
(rectangle patterns are getting enlarged to square like it's happening for KLT)

extern/libmv/libmv-capi.cpp
extern/libmv/libmv-capi.h
extern/libmv/libmv/tracking/sad.cc
source/blender/blenkernel/intern/tracking.c

index f08aea9fbd1359c651359def49a920584e925963..aa05279d7312e344a1634b096c9b754d740a5a51 100644 (file)
@@ -297,16 +297,16 @@ void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker)
 /* ************ Tracks ************ */
 
 void libmv_SADSamplePattern(unsigned char *image, int stride,
-                       float warp[3][2], unsigned char *pattern)
+                       float warp[3][2], unsigned char *pattern, int pattern_size)
 {
        libmv::mat32 mat32;
 
        memcpy(mat32.data, warp, sizeof(float)*3*2);
 
-       libmv::SamplePattern(image, stride, mat32, pattern, 16);
+       libmv::SamplePattern(image, stride, mat32, pattern, pattern_size);
 }
 
-float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsigned char *image, int stride,
+float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, int pattern_size, unsigned char *image, int stride,
                        int width, int height, float warp[3][2])
 {
        float result;
@@ -314,7 +314,7 @@ float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsig
 
        memcpy(mat32.data, warp, sizeof(float)*3*2);
 
-       result = libmv::Track(pattern, warped, 16, image, stride, width, height, &mat32, 16, 16);
+       result = libmv::Track(pattern, warped, pattern_size, image, stride, width, height, &mat32, 16, 16);
 
        memcpy(warp, mat32.data, sizeof(float)*3*2);
 
index 536f8a5f14cf4edb5fa631cd965c14ef5733d6ed..321593520b53eeb0ada73b80f6ecc14d47480f26 100644 (file)
@@ -50,8 +50,8 @@ void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker);
 
 /* SAD Tracker */
 void libmv_SADSamplePattern(unsigned char *image, int stride,
-                       float warp[3][2], unsigned char *pattern);
-float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsigned char *image,
+                       float warp[3][2], unsigned char *pattern, int pattern_size);
+float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, int pattern_size, unsigned char *image,
                        int stride, int width, int height, float warp[3][2]);
 
 /* Tracks */
index 9b446bb4c35c0a61f5aed40248e97c136717622a..0876ef2fe731d52772f53b320612bf53905af3a3 100644 (file)
@@ -25,6 +25,7 @@
 #include "libmv/tracking/sad.h"
 #include <stdlib.h>
 #include <math.h>
+#include <stdio.h>
 
 namespace libmv {
 
@@ -78,15 +79,31 @@ void SamplePattern(ubyte* image, int stride, mat32 warp, ubyte* pattern, int siz
 
 #ifdef __SSE2__
 #include <emmintrin.h>
-static uint SAD(const ubyte* pattern, const ubyte* image, int stride, int size) {
+  static uint SAD(/*const*/ ubyte* pattern, /*const*/ ubyte* image, int stride, int size) {
+  uint sad = 0;
   __m128i a = _mm_setzero_si128();
+
   for(int i = 0; i < size; i++) {
-    for(int j = 0; j < size/16; j++) {
+    int j = 0;
+
+    for(j = 0; j < size/16; j++) {
+      if((i*size/16+j) % 32 == 0) {
+        sad += _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4);
+        a = _mm_setzero_si128();
+      }
+
       a = _mm_adds_epu16(a, _mm_sad_epu8( _mm_loadu_si128((__m128i*)(pattern+i*size+j*16)),
                                           _mm_loadu_si128((__m128i*)(image+i*stride+j*16))));
     }
+
+    for(j = j*16; j < size; j++) {
+      sad += abs((int)pattern[i*size+j] - image[i*stride+j]);
+    }
   }
-  return _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4);
+
+  sad += _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4);
+
+  return sad;
 }
 #else
 static uint SAD(const ubyte* pattern, const ubyte* image, int stride, int size) {
index cb94e3f3ec1c50cd1fd06e6e7a872a6134efbefc..2d906a9199b045246d5c7567dd709d58bb59be93 100644 (file)
@@ -718,7 +718,7 @@ typedef struct TrackContext {
        float *patch;                   /* keyframed patch */
 
        /* ** SAD tracker ** */
-       int patsize;                    /* size of pattern (currently only 16x16 due to libmv side) */
+       int pattern_size;               /* size of pattern */
        unsigned char *pattern; /* keyframed pattern */
        unsigned char *warped;  /* warped version of reference */
 #else
@@ -786,12 +786,16 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
 
 #ifdef WITH_LIBMV
                                        {
+                                               float patx, paty;
+                                               patx= (int)((track->pat_max[0]-track->pat_min[0])*width);
+                                               paty= (int)((track->pat_max[1]-track->pat_min[1])*height);
+
                                                if(track->tracker==TRACKER_KLT) {
                                                        float search_size_x= (track->search_max[0]-track->search_min[0])*width;
                                                        float search_size_y= (track->search_max[1]-track->search_min[1])*height;
                                                        float pattern_size_x= (track->pat_max[0]-track->pat_min[0])*width;
                                                        float pattern_size_y= (track->pat_max[1]-track->pat_min[1])*height;
-                                                       int wndx, wndy;
+                                                       int wndx= (int)patx/2, wndy= (int)paty/2;
 
                                                        /* compute the maximum pyramid size */
                                                        float search_to_pattern_ratio= MIN2(search_size_x,  search_size_y)
@@ -804,13 +808,10 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
                                                         * than the search size */
                                                        int level= MIN2(track->pyramid_levels, max_pyramid_levels);
 
-                                                       wndx= (int)((track->pat_max[0]-track->pat_min[0])*width)/2;
-                                                       wndy= (int)((track->pat_max[1]-track->pat_min[1])*height)/2;
-
                                                        track_context.region_tracker= libmv_regionTrackerNew(100, level, MAX2(wndx, wndy));
                                                }
                                                else if(track->tracker==TRACKER_SAD) {
-                                                       /* nothing to initialize */
+                                                       track_context.pattern_size= MAX2(patx, paty);
                                                }
                                        }
 #endif
@@ -1093,10 +1094,10 @@ static void get_warped(TrackContext *track_context, int x, int y, int width, uns
 {
        int i, j;
 
-       for(i=0; i<track_context->patsize; i++) {
-               for(j=0; j<track_context->patsize; j++) {
-                       track_context->warped[i*track_context->patsize+j]=
-                                       image[(y+i-track_context->patsize/2)*width+x+j-track_context->patsize/2];
+       for(i=0; i<track_context->pattern_size; i++) {
+               for(j=0; j<track_context->pattern_size; j++) {
+                       track_context->warped[i*track_context->pattern_size+j]=
+                                       image[(y+i-track_context->pattern_size/2)*width+x+j-track_context->pattern_size/2];
                }
        }
 }
@@ -1226,13 +1227,12 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                        warp[2][0]= pos[0];
                                        warp[2][1]= pos[1];
 
-                                       /* pattern size is hardcoded to 16x16px in libmv */
-                                       track_context->patsize= 16;
-
-                                       if(!track_context->pattern)
-                                               track_context->pattern= MEM_callocN(sizeof(unsigned char)*track_context->patsize*track_context->patsize, "trackking pattern");
+                                       if(!track_context->pattern) {
+                                               int square= track_context->pattern_size*track_context->pattern_size;
+                                               track_context->pattern= MEM_callocN(sizeof(unsigned char)*square, "trackking pattern");
+                                       }
 
-                                       libmv_SADSamplePattern(image, width, warp, track_context->pattern);
+                                       libmv_SADSamplePattern(image, width, warp, track_context->pattern, track_context->pattern_size);
 
                                        MEM_freeN(image);
                                        IMB_freeImBuf(ibuf);
@@ -1245,8 +1245,10 @@ int BKE_tracking_next(MovieTrackingContext *context)
 
                                        ibuf= get_frame_ibuf(context, curfra);
 
-                                       if(track_context->warped==NULL)
-                                               track_context->warped= MEM_callocN(sizeof(unsigned char)*track_context->patsize*track_context->patsize, "trackking warped");
+                                       if(track_context->warped==NULL) {
+                                               int square= track_context->pattern_size*track_context->pattern_size;
+                                               track_context->warped= MEM_callocN(sizeof(unsigned char)*square, "trackking warped");
+                                       }
 
                                        image_old= get_search_bytebuf(ibuf, track, marker, &width, &height, pos, origin);
                                        get_warped(track_context, pos[0], pos[1], width, image_old);
@@ -1260,7 +1262,8 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                warp[2][0]= pos[0];
                                warp[2][1]= pos[1];
 
-                               correlation= libmv_SADTrackerTrack(track_context->pattern, track_context->warped, image_new, width, width, height, warp);
+                               correlation= libmv_SADTrackerTrack(track_context->pattern, track_context->warped,
+                                                       track_context->pattern_size, image_new, width, width, height, warp);
 
                                x2= warp[2][0];
                                y2= warp[2][1];