Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extern/libmv/CMakeLists.txt3
-rw-r--r--extern/libmv/libmv-capi.cpp42
-rw-r--r--extern/libmv/libmv-capi.h7
-rw-r--r--extern/libmv/libmv/image/correlation.h51
-rw-r--r--extern/libmv/libmv/image/sample.h18
-rw-r--r--extern/libmv/libmv/tracking/brute_region_tracker.cc24
-rw-r--r--extern/libmv/libmv/tracking/brute_region_tracker.h5
-rw-r--r--extern/libmv/libmv/tracking/esm_region_tracker.cc38
-rw-r--r--extern/libmv/libmv/tracking/lmicklt_region_tracker.cc18
-rw-r--r--extern/libmv/libmv/tracking/sad.cc191
-rw-r--r--extern/libmv/libmv/tracking/sad.h109
-rw-r--r--source/blender/blenkernel/intern/tracking.c171
12 files changed, 144 insertions, 533 deletions
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
index 5239c7ff7ca..005bcdf0a3b 100644
--- a/extern/libmv/CMakeLists.txt
+++ b/extern/libmv/CMakeLists.txt
@@ -80,7 +80,6 @@ set(SRC
libmv/tracking/lmicklt_region_tracker.cc
libmv/tracking/pyramid_region_tracker.cc
libmv/tracking/retrack_region_tracker.cc
- libmv/tracking/sad.cc
libmv/tracking/trklt_region_tracker.cc
third_party/fast/fast_10.c
@@ -104,6 +103,7 @@ set(SRC
libmv/image/array_nd.h
libmv/image/convolve.h
libmv/image/image.h
+ libmv/image/correlation.h
libmv/image/sample.h
libmv/image/tuple.h
libmv/logging/logging.h
@@ -137,7 +137,6 @@ set(SRC
libmv/tracking/pyramid_region_tracker.h
libmv/tracking/region_tracker.h
libmv/tracking/retrack_region_tracker.h
- libmv/tracking/sad.h
libmv/tracking/trklt_region_tracker.h
third_party/fast/fast.h
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
index 465bf519dbd..7fd4bfdd9d1 100644
--- a/extern/libmv/libmv-capi.cpp
+++ b/extern/libmv/libmv-capi.cpp
@@ -44,8 +44,6 @@
#include "libmv/tracking/lmicklt_region_tracker.h"
#include "libmv/tracking/pyramid_region_tracker.h"
-#include "libmv/tracking/sad.h"
-
#include "libmv/simple_pipeline/callbacks.h"
#include "libmv/simple_pipeline/tracks.h"
#include "libmv/simple_pipeline/initialize_reconstruction.h"
@@ -137,12 +135,25 @@ libmv_RegionTracker *libmv_hybridRegionTrackerNew(int max_iterations, int half_w
libmv::BruteRegionTracker *brute_region_tracker = new libmv::BruteRegionTracker;
brute_region_tracker->half_window_size = half_window_size;
+ /* do not use correlation check for brute checker itself,
+ * this check will happen in esm tracker */
+ brute_region_tracker->minimum_correlation = 0.0;
+
libmv::HybridRegionTracker *hybrid_region_tracker =
new libmv::HybridRegionTracker(brute_region_tracker, esm_region_tracker);
return (libmv_RegionTracker *)hybrid_region_tracker;
}
+libmv_RegionTracker *libmv_bruteRegionTrackerNew(int half_window_size, double minimum_correlation)
+{
+ libmv::BruteRegionTracker *brute_region_tracker = new libmv::BruteRegionTracker;
+ brute_region_tracker->half_window_size = half_window_size;
+ brute_region_tracker->minimum_correlation = minimum_correlation;
+
+ return (libmv_RegionTracker *)brute_region_tracker;
+}
+
static void floatBufToImage(const float *buf, int width, int height, libmv::FloatImage *image)
{
int x, y, a = 0;
@@ -316,33 +327,6 @@ void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker)
/* ************ Tracks ************ */
-void libmv_SADSamplePattern(unsigned char *image, int stride,
- 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, 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])
-{
- float result;
- libmv::mat32 mat32;
-
- memcpy(mat32.data, warp, sizeof(float)*3*2);
-
- result = libmv::Track(pattern, warped, pattern_size, image, stride, width, height, &mat32, 16, 16);
-
- memcpy(warp, mat32.data, sizeof(float)*3*2);
-
- return result;
-}
-
-/* ************ Tracks ************ */
-
libmv_Tracks *libmv_tracksNew(void)
{
libmv::Tracks *libmv_tracks = new libmv::Tracks();
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index e10d4ef842a..e5728188afb 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -45,16 +45,11 @@ void libmv_setLoggingVerbosity(int verbosity);
/* RegionTracker */
struct libmv_RegionTracker *libmv_pyramidRegionTrackerNew(int max_iterations, int pyramid_level, int half_window_size, double minimum_correlation);
struct libmv_RegionTracker *libmv_hybridRegionTrackerNew(int max_iterations, int half_window_size, double minimum_correlation);
+struct libmv_RegionTracker *libmv_bruteRegionTrackerNew(int half_window_size, double minimum_correlation);
int libmv_regionTrackerTrack(struct libmv_RegionTracker *libmv_tracker, const float *ima1, const float *ima2,
int width, int height, double x1, double y1, double *x2, double *y2);
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, 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 */
struct libmv_Tracks *libmv_tracksNew(void);
void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y);
diff --git a/extern/libmv/libmv/image/correlation.h b/extern/libmv/libmv/image/correlation.h
new file mode 100644
index 00000000000..9d6aceecceb
--- /dev/null
+++ b/extern/libmv/libmv/image/correlation.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2012 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_IMAGE_CORRELATION_H
+#define LIBMV_IMAGE_CORRELATION_H
+
+#include "libmv/image/image.h"
+
+namespace libmv {
+
+inline double PearsonProductMomentCorrelation(Array3Df image_and_gradient1_sampled,
+ Array3Df image_and_gradient2_sampled,
+ int width) {
+ double sX=0,sY=0,sXX=0,sYY=0,sXY=0;
+ for (int r = 0; r < width; ++r) {
+ for (int c = 0; c < width; ++c) {
+ double x = image_and_gradient1_sampled(r, c, 0);
+ double y = image_and_gradient2_sampled(r, c, 0);
+ sX += x;
+ sY += y;
+ sXX += x*x;
+ sYY += y*y;
+ sXY += x*y;
+ }
+ }
+ double N = width*width;
+ sX /= N, sY /= N, sXX /= N, sYY /= N, sXY /= N;
+ double correlation = (sXY-sX*sY)/sqrt(double((sXX-sX*sX)*(sYY-sY*sY)));
+ return correlation;
+}
+
+} // namespace libmv
+
+#endif // LIBMV_IMAGE_IMAGE_CORRELATION_H
diff --git a/extern/libmv/libmv/image/sample.h b/extern/libmv/libmv/image/sample.h
index cd361231b58..ea86edf117d 100644
--- a/extern/libmv/libmv/image/sample.h
+++ b/extern/libmv/libmv/image/sample.h
@@ -98,6 +98,24 @@ inline void DownsampleChannelsBy2(const Array3Df &in, Array3Df *out) {
}
+// Sample a region centered at x,y in image with size extending by half_width
+// from x,y. Channels specifies the number of channels to sample from.
+inline void SamplePattern(const FloatImage &image,
+ double x, double y,
+ int half_width,
+ int channels,
+ FloatImage *sampled) {
+ sampled->Resize(2 * half_width + 1, 2 * half_width + 1, channels);
+ for (int r = -half_width; r <= half_width; ++r) {
+ for (int c = -half_width; c <= half_width; ++c) {
+ for (int i = 0; i < channels; ++i) {
+ (*sampled)(r + half_width, c + half_width, i) =
+ SampleLinear(image, y + r, x + c, i);
+ }
+ }
+ }
+}
+
} // namespace libmv
#endif // LIBMV_IMAGE_SAMPLE_H_
diff --git a/extern/libmv/libmv/tracking/brute_region_tracker.cc b/extern/libmv/libmv/tracking/brute_region_tracker.cc
index a416710ad2b..af7f673472e 100644
--- a/extern/libmv/libmv/tracking/brute_region_tracker.cc
+++ b/extern/libmv/libmv/tracking/brute_region_tracker.cc
@@ -44,6 +44,7 @@
#include "libmv/image/image.h"
#include "libmv/image/convolve.h"
+#include "libmv/image/correlation.h"
#include "libmv/image/sample.h"
#include "libmv/logging/logging.h"
@@ -332,6 +333,29 @@ bool BruteRegionTracker::Track(const FloatImage &image1,
if (best_sad != INT_MAX) {
*x2 = best_j + half_window_size;
*y2 = best_i + half_window_size;
+
+ if (minimum_correlation > 0) {
+ Array3Df image_and_gradient1_sampled, image_and_gradient2_sampled;
+
+ SamplePattern(image_and_gradient1, x1, y1, half_window_size, 3,
+ &image_and_gradient1_sampled);
+ SamplePattern(image_and_gradient2, *x2, *y2, half_window_size, 3,
+ &image_and_gradient2_sampled);
+
+ // Compute the Pearson product-moment correlation coefficient to check
+ // for sanity.
+ double correlation = PearsonProductMomentCorrelation(image_and_gradient1_sampled,
+ image_and_gradient2_sampled,
+ pattern_width);
+ LG << "Final correlation: " << correlation;
+
+ if (correlation < minimum_correlation) {
+ LG << "Correlation " << correlation << " greater than "
+ << minimum_correlation << "; bailing.";
+ return false;
+ }
+ }
+
return true;
}
return false;
diff --git a/extern/libmv/libmv/tracking/brute_region_tracker.h b/extern/libmv/libmv/tracking/brute_region_tracker.h
index 7a9b06d8a31..8ff0c1b7965 100644
--- a/extern/libmv/libmv/tracking/brute_region_tracker.h
+++ b/extern/libmv/libmv/tracking/brute_region_tracker.h
@@ -27,7 +27,9 @@
namespace libmv {
struct BruteRegionTracker : public RegionTracker {
- BruteRegionTracker() : half_window_size(4) {}
+ BruteRegionTracker()
+ : half_window_size(4),
+ minimum_correlation(0.78) {}
virtual ~BruteRegionTracker() {}
@@ -39,6 +41,7 @@ struct BruteRegionTracker : public RegionTracker {
// No point in creating getters or setters.
int half_window_size;
+ double minimum_correlation;
};
} // namespace libmv
diff --git a/extern/libmv/libmv/tracking/esm_region_tracker.cc b/extern/libmv/libmv/tracking/esm_region_tracker.cc
index df9c89a46d4..e0b85f19943 100644
--- a/extern/libmv/libmv/tracking/esm_region_tracker.cc
+++ b/extern/libmv/libmv/tracking/esm_region_tracker.cc
@@ -26,6 +26,7 @@
#include "libmv/logging/logging.h"
#include "libmv/image/image.h"
#include "libmv/image/convolve.h"
+#include "libmv/image/correlation.h"
#include "libmv/image/sample.h"
#include "libmv/numeric/numeric.h"
@@ -55,24 +56,6 @@ static bool RegionIsInBounds(const FloatImage &image1,
return true;
}
-// Sample a region centered at x,y in image with size extending by half_width
-// from x,y. Channels specifies the number of channels to sample from.
-static void SamplePattern(const FloatImage &image,
- double x, double y,
- int half_width,
- int channels,
- FloatImage *sampled) {
- sampled->Resize(2 * half_width + 1, 2 * half_width + 1, channels);
- for (int r = -half_width; r <= half_width; ++r) {
- for (int c = -half_width; c <= half_width; ++c) {
- for (int i = 0; i < channels; ++i) {
- (*sampled)(r + half_width, c + half_width, i) =
- SampleLinear(image, y + r, x + c, i);
- }
- }
- }
-}
-
// Estimate "reasonable" error by computing autocorrelation for a small shift.
// TODO(keir): Add a facility for
static double EstimateReasonableError(const FloatImage &image,
@@ -276,22 +259,9 @@ bool EsmRegionTracker::Track(const FloatImage &image1,
if (d.squaredNorm() < min_update_squared_distance) {
// Compute the Pearson product-moment correlation coefficient to check
// for sanity.
- // TODO(keir): Put this somewhere smarter.
- double sX=0,sY=0,sXX=0,sYY=0,sXY=0;
- for (int r = 0; r < width; ++r) {
- for (int c = 0; c < width; ++c) {
- double x = image_and_gradient1_sampled(r, c, 0);
- double y = image_and_gradient2_sampled[new_image](r, c, 0);
- sX += x;
- sY += y;
- sXX += x*x;
- sYY += y*y;
- sXY += x*y;
- }
- }
- double N = width*width;
- sX /= N, sY /= N, sXX /= N, sYY /= N, sXY /= N;
- double correlation = (sXY-sX*sY)/sqrt(double((sXX-sX*sX)*(sYY-sY*sY)));
+ double correlation = PearsonProductMomentCorrelation(image_and_gradient1_sampled,
+ image_and_gradient2_sampled[new_image],
+ width);
LG << "Final correlation: " << correlation;
if (correlation < minimum_correlation) {
diff --git a/extern/libmv/libmv/tracking/lmicklt_region_tracker.cc b/extern/libmv/libmv/tracking/lmicklt_region_tracker.cc
index c06a1d3302c..581e984b569 100644
--- a/extern/libmv/libmv/tracking/lmicklt_region_tracker.cc
+++ b/extern/libmv/libmv/tracking/lmicklt_region_tracker.cc
@@ -52,24 +52,6 @@ static bool RegionIsInBounds(const FloatImage &image1,
return true;
}
-// Sample a region centered at x,y in image with size extending by half_width
-// from x,y. Channels specifies the number of channels to sample from.
-static void SamplePattern(const FloatImage &image,
- double x, double y,
- int half_width,
- int channels,
- FloatImage *sampled) {
- sampled->Resize(2 * half_width + 1, 2 * half_width + 1, channels);
- for (int r = -half_width; r <= half_width; ++r) {
- for (int c = -half_width; c <= half_width; ++c) {
- for (int i = 0; i < channels; ++i) {
- (*sampled)(r + half_width, c + half_width, i) =
- SampleLinear(image, y + r, x + c, i);
- }
- }
- }
-}
-
// Estimate "reasonable" error by computing autocorrelation for a small shift.
static double EstimateReasonableError(const FloatImage &image,
double x, double y,
diff --git a/extern/libmv/libmv/tracking/sad.cc b/extern/libmv/libmv/tracking/sad.cc
deleted file mode 100644
index 0876ef2fe73..00000000000
--- a/extern/libmv/libmv/tracking/sad.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2011 libmv authors.
-**
-** Permission is hereby granted, free of charge, to any person obtaining a copy
-** of this software and associated documentation files (the "Software"), to
-** deal in the Software without restriction, including without limitation the
-** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-** sell copies of the Software, and to permit persons to whom the Software is
-** furnished to do so, subject to the following conditions:
-**
-** The above copyright notice and this permission notice shall be included in
-** all copies or substantial portions of the Software.
-**
-** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-** IN THE SOFTWARE.
-**
-****************************************************************************/
-
-#include "libmv/tracking/sad.h"
-#include <stdlib.h>
-#include <math.h>
-#include <stdio.h>
-
-namespace libmv {
-
-void LaplaceFilter(ubyte* src, ubyte* dst, int width, int height, int strength) {
- for(int y=1; y<height-1; y++) for(int x=1; x<width-1; x++) {
- const ubyte* s = &src[y*width+x];
- int l = 128 +
- s[-width-1] + s[-width] + s[-width+1] +
- s[1] - 8*s[0] + s[1] +
- s[ width-1] + s[ width] + s[ width+1] ;
- int d = ((256-strength)*s[0] + strength*l) / 256;
- if(d < 0) d=0;
- if(d > 255) d=255;
- dst[y*width+x] = d;
- }
-}
-
-struct vec2 {
- float x,y;
- inline vec2(float x, float y):x(x),y(y){}
-};
-inline vec2 operator*(mat32 m, vec2 v) {
- return vec2(v.x*m(0,0)+v.y*m(0,1)+m(0,2),v.x*m(1,0)+v.y*m(1,1)+m(1,2));
-}
-
-//! fixed point bilinear sample with precision k
-template <int k> inline int sample(const ubyte* image,int stride, int x, int y, int u, int v) {
- const ubyte* s = &image[y*stride+x];
- return ((s[ 0] * (k-u) + s[ 1] * u) * (k-v)
- + (s[stride] * (k-u) + s[stride+1] * u) * ( v) ) / (k*k);
-}
-
-#ifdef __SSE__
-#include <xmmintrin.h>
-int lround(float x) { return _mm_cvtss_si32(_mm_set_ss(x)); }
-#elif defined(_MSC_VER)
-int lround(float x) { return x+0.5; }
-#endif
-
-//TODO(MatthiasF): SSE optimization
-void SamplePattern(ubyte* image, int stride, mat32 warp, ubyte* pattern, int size) {
- const int k = 256;
- for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) {
- vec2 p = warp*vec2(j-size/2,i-size/2);
- int fx = lround(p.x*k), fy = lround(p.y*k);
- int ix = fx/k, iy = fy/k;
- int u = fx%k, v = fy%k;
- pattern[i*size+j] = sample<k>(image,stride,ix,iy,u,v);
- }
-}
-
-#ifdef __SSE2__
-#include <emmintrin.h>
- 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++) {
- 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]);
- }
- }
-
- 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) {
- uint sad=0;
- for(int i = 0; i < size; i++) {
- for(int j = 0; j < size; j++) {
- sad += abs((int)pattern[i*size+j] - image[i*stride+j]);
- }
- }
- return sad;
-}
-#endif
-
-float sq(float x) { return x*x; }
-float Track(ubyte* reference, ubyte* warped, int size, ubyte* image, int stride, int w, int h, mat32* warp, float areaPenalty, float conditionPenalty) {
- mat32 m=*warp;
- uint min=-1;
-
- // exhaustive search integer pixel translation
- int ix = m(0,2), iy = m(1,2);
- for(int y = size/2; y < h-size/2; y++) {
- for(int x = size/2; x < w-size/2; x++) {
- m(0,2) = x, m(1,2) = y;
- uint sad = SAD(warped,&image[(y-size/2)*stride+(x-size/2)],stride,size);
- // TODO: using chroma could help disambiguate some cases
- if(sad < min) {
- min = sad;
- ix = x, iy = y;
- }
- }
- }
- m(0,2) = ix, m(1,2) = iy;
- min=-1; //reset score since direct warped search match too well (but the wrong pattern).
-
- // 6D coordinate descent to find affine transform
- ubyte* match = new ubyte[size*size];
- float step = 0.5;
- for(int p = 0; p < 8; p++) { //foreach precision level
- for(int i = 0; i < 2; i++) { // iterate twice per precision level
- //TODO: other sweep pattern might converge better
- for(int d=0; d < 6; d++) { // iterate dimension sequentially (cyclic descent)
- for(float e = -step; e <= step; e+=step) { //solve subproblem (evaluate only along one coordinate)
- mat32 t = m;
- t.data[d] += e;
- //TODO: better performance would also allow a more exhaustive search
- SamplePattern(image,stride,t,match,size);
- uint sad = SAD(reference,match,size,size);
- // regularization: keep constant area and good condition
- float area = t(0,0)*t(1,1)-t(0,1)*t(1,0);
- float x = sq(t(0,0))+sq(t(0,1)), y = sq(t(1,0))+sq(t(1,1));
- float condition = x>y ? x/y : y/x;
- sad += size*size*( areaPenalty*sq(area-1) + conditionPenalty*sq(condition-1) );
- if(sad < min) {
- min = sad;
- m = t;
- }
- }
- }
- }
- step /= 2;
- }
- *warp = m;
-
- // Compute Pearson product-moment correlation coefficient
- uint sX=0,sY=0,sXX=0,sYY=0,sXY=0;
- SamplePattern(image,stride,m,match,size);
- SAD(reference,match,size,size);
- for(int i = 0; i < size; i++) {
- for(int j = 0; j < size; j++) {
- int x = reference[i*size+j];
- int y = match[i*size+j];
- sX += x;
- sY += y;
- sXX += x*x;
- sYY += y*y;
- sXY += x*y;
- }
- }
- delete[] match;
- const int N = size*size;
- sX /= N, sY /= N, sXX /= N, sYY /= N, sXY /= N;
- return (sXY-sX*sY)/sqrt(double((sXX-sX*sX)*(sYY-sY*sY)));
-}
-
-} // namespace libmv
diff --git a/extern/libmv/libmv/tracking/sad.h b/extern/libmv/libmv/tracking/sad.h
deleted file mode 100644
index 9fe323b74c4..00000000000
--- a/extern/libmv/libmv/tracking/sad.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/****************************************************************************
-**
-** Copyright (c) 2011 libmv authors.
-**
-** Permission is hereby granted, free of charge, to any person obtaining a copy
-** of this software and associated documentation files (the "Software"), to
-** deal in the Software without restriction, including without limitation the
-** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-** sell copies of the Software, and to permit persons to whom the Software is
-** furnished to do so, subject to the following conditions:
-**
-** The above copyright notice and this permission notice shall be included in
-** all copies or substantial portions of the Software.
-**
-** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-** IN THE SOFTWARE.
-**
-****************************************************************************/
-
-#ifndef LIBMV_TRACKING_SAD_H_
-#define LIBMV_TRACKING_SAD_H_
-
-#ifdef __cplusplus
-namespace libmv {
-#endif
-
-typedef unsigned char ubyte;
-typedef unsigned int uint;
-
-/*!
- Convolve \a src into \a dst with the discrete laplacian operator.
-
- \a src and \a dst should be \a width x \a height images.
- \a strength is an interpolation coefficient (0-256) between original image and the laplacian.
-
- \note Make sure the search region is filtered with the same strength as the pattern.
-*/
-void LaplaceFilter(ubyte* src, ubyte* dst, int width, int height, int strength);
-
-/// Affine transformation matrix in column major order.
-struct mat32 {
- float data[3*2];
-#ifdef __cplusplus
- inline mat32(int d=1) { for(int i=0;i<3*2;i++) data[i]=0; if(d!=0) for(int i=0;i<2;i++) m(i,i)=d; }
- inline float m(int i, int j) const { return data[j*2+i]; }
- inline float& m(int i, int j) { return data[j*2+i]; }
- inline float operator()(int i, int j) const { return m(i,j); }
- inline float& operator()(int i, int j) { return m(i,j); }
- inline operator bool() const { for (int i=0; i<3*2; i++) if(data[i]!=0) return true; return false; }
-#endif
-};
-
-/*!
- Sample \a pattern from \a image.
-
- \a warp is the transformation to apply to \a image when sampling the \a pattern.
-*/
-void SamplePattern(ubyte* image, int stride, mat32 warp, ubyte* pattern, int size);
-
-/*!
- Track \a pattern in \a image.
-
- This template matcher computes the
- \link http://en.wikipedia.org/wiki/Sum_of_absolute_differences Sum of Absolute Differences (SAD) \endlink
- for each integer pixel position in the search region and then iteratively
- refine subpixel position using a square search.
- A similar method is used for motion estimation in video encoders.
-
- \a reference is the pattern to track.
- \a warped is a warped version of reference for fast unsampled integer search.
- Best is to directly extract an already warped pattern from previous frame.
- The \a size of the patterns should be aligned to 16.
- \a image is a reference to the region to search.
- \a stride is size of \a image lines.
-
- On input, \a warp is the predicted affine transformation (e.g from previous frame)
- On return, \a warp is the affine transformation which best match the reference \a pattern
-
- \a areaPenalty and conditionPenalty control the regularization and need to be tweaked depending on the motion.
- Setting them to 0 will allow any transformation (including unrealistic distortions and scaling).
- Good values are between 0-32. 16 can be used as a realistic default.
- areaPenalty control scaling (decrease to allow pull/zoom, increase to allow only 2D rotation).
- a large conditionPenalty avoid a large ratio between the largest and smallest axices.
- It need to be decreased for non-2D rotation (when pattern appears to scale along an axis).
-
- \return Pearson product-moment correlation coefficient between reference and matched pattern.
- This measure of the linear dependence between the patterns
- ranges from −1 (negative correlation) to 1 (positive correlation).
- A value of 0 implies that there is no linear correlation between the variables.
-
- \note To track affine features:
- - Sample reference pattern using estimated (e.g previous frame) warp.
- -
- \note \a stride allow you to reference your search region instead of copying.
- \note For a 16x speedup, compile this tracker with SSE2 support.
-*/
-float Track(ubyte* reference, ubyte* warped, int size, ubyte* image, int stride, int width, int height, mat32* warp,
- float areaPenalty, float conditionPenalty);
-
-#ifdef __cplusplus
-} // namespace libmv
-#endif
-
-#endif // LIBMV_TRACKING_SAD_H_
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 350b30b34d3..0af8f2cf625 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -906,14 +906,8 @@ typedef struct TrackContext {
#ifdef WITH_LIBMV
float keyframed_pos[2];
- /* ** KLT tracker ** */
struct libmv_RegionTracker *region_tracker;
float *patch; /* keyframed patch */
-
- /* ** SAD tracker ** */
- int pattern_size; /* size of pattern */
- unsigned char *pattern; /* keyframed pattern */
- unsigned char *warped; /* warped version of reference */
#else
int pad;
#endif
@@ -983,40 +977,37 @@ 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 (ELEM(track->tracker, TRACKER_KLT, TRACKER_HYBRID)) {
- 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 = (int)patx / 2, wndy = (int)paty / 2;
- int half_wnd = MAX2(wndx, wndy);
+ float patx = (int)((track->pat_max[0]-track->pat_min[0])*width),
+ paty = (int)((track->pat_max[1]-track->pat_min[1])*height);
+
+ 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 = (int)patx / 2, wndy = (int)paty / 2;
+ int half_wnd = MAX2(wndx, wndy);
/* compute the maximum pyramid size */
- float search_to_pattern_ratio = MIN2(search_size_x, search_size_y)
- / MAX2(pattern_size_x, pattern_size_y);
- float log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2;
- int max_pyramid_levels = floor(log2_search_to_pattern_ratio + 1);
-
- /* try to accommodate the user's choice of pyramid level in a way
- * that doesn't cause the coarsest pyramid pattern to be larger
- * than the search size */
- int level = MIN2(track->pyramid_levels, max_pyramid_levels);
-
- if (track->tracker==TRACKER_KLT) {
- track_context.region_tracker =
- libmv_pyramidRegionTrackerNew(100, level, half_wnd, track->minimum_correlation);
- }
- else {
- track_context.region_tracker =
- libmv_hybridRegionTrackerNew(100, half_wnd, track->minimum_correlation);
- }
+ float search_to_pattern_ratio = MIN2(search_size_x, search_size_y)
+ / MAX2(pattern_size_x, pattern_size_y);
+ float log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2;
+ int max_pyramid_levels = floor(log2_search_to_pattern_ratio + 1);
+
+ /* try to accommodate the user's choice of pyramid level in a way
+ * that doesn't cause the coarsest pyramid pattern to be larger
+ * than the search size */
+ int level = MIN2(track->pyramid_levels, max_pyramid_levels);
+
+ if (track->tracker==TRACKER_KLT) {
+ track_context.region_tracker =
+ libmv_pyramidRegionTrackerNew(100, level, half_wnd, track->minimum_correlation);
+ }
+ else if (track->tracker == TRACKER_HYBRID) {
+ track_context.region_tracker =
+ libmv_hybridRegionTrackerNew(100, half_wnd, track->minimum_correlation);
}
else if (track->tracker == TRACKER_SAD) {
- track_context.pattern_size = MAX2(patx, paty);
+ track_context.region_tracker= libmv_bruteRegionTrackerNew(MAX2(wndx, wndy), track->minimum_correlation);
}
}
#endif
@@ -1062,11 +1053,6 @@ static void track_context_free(void *customdata)
if (track_context->patch)
MEM_freeN(track_context->patch);
- if (track_context->pattern)
- MEM_freeN(track_context->pattern);
-
- if (track_context->warped)
- MEM_freeN(track_context->warped);
#else
(void) track_context;
#endif
@@ -1282,25 +1268,6 @@ static unsigned char *get_ucharbuf(ImBuf *ibuf)
return pixels;
}
-static unsigned char *get_search_bytebuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
- int *width_r, int *height_r, float pos[2], int origin[2])
-{
- ImBuf *tmpibuf;
- unsigned char *pixels;
-
- tmpibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin);
- disable_imbuf_channels(tmpibuf, track, FALSE /* don't grayscale */);
-
- *width_r = tmpibuf->x;
- *height_r = tmpibuf->y;
-
- pixels = get_ucharbuf(tmpibuf);
-
- IMB_freeImBuf(tmpibuf);
-
- return pixels;
-}
-
static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr)
{
ImBuf *ibuf;
@@ -1367,18 +1334,6 @@ static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack
return ibuf;
}
-static void get_warped(TrackContext *track_context, int x, int y, int width, unsigned char *image)
-{
- int i, j;
-
- 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];
- }
- }
-}
-
#endif
void BKE_tracking_sync(MovieTrackingContext *context)
@@ -1464,7 +1419,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
{
onbound = TRUE;
}
- else if (ELEM(track->tracker, TRACKER_KLT, TRACKER_HYBRID)) {
+ else {
float *patch_new;
if (need_readjust) {
@@ -1493,76 +1448,6 @@ int BKE_tracking_next(MovieTrackingContext *context)
MEM_freeN(patch_new);
}
- else if (track->tracker == TRACKER_SAD) {
- unsigned char *image_new;
- float correlation;
- float warp[3][2] = {{0}};
-
- if (need_readjust) {
- unsigned char *image;
-
- /* calculate pattern for keyframed position */
- ibuf = get_adjust_ibuf(context, track, marker, curfra, &marker_keyed);
-
- image = get_search_bytebuf(ibuf, track, marker_keyed, &width, &height, pos, origin);
-
- memset(warp, 0, sizeof(warp));
- warp[0][0] = 1;
- warp[1][1] = 1;
- warp[2][0] = pos[0];
- warp[2][1] = pos[1];
-
- 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, track_context->pattern_size);
-
- MEM_freeN(image);
- IMB_freeImBuf(ibuf);
- }
-
- image_new = get_search_bytebuf(ibuf_new, track, marker, &width, &height, pos, origin);
-
- if (track_context->warped == NULL) {
- unsigned char *image_old;
-
- ibuf = get_frame_ibuf(context, curfra);
-
- 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);
- IMB_freeImBuf(ibuf);
- MEM_freeN(image_old);
- }
-
- memset(warp, 0, sizeof(warp));
- warp[0][0] = 1;
- warp[1][1] = 1;
- warp[2][0] = pos[0];
- warp[2][1] = pos[1];
-
- 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];
-
- tracked = track->minimum_correlation < correlation;
-
- if (tracked)
- get_warped(track_context, x2, y2, width, image_new);
-
- MEM_freeN(image_new);
- }
if (tracked && !onbound && finite(x2) && finite(y2)) {
if (context->first_time) {