From 18f5322f7c2145b772ab4d47a9d4cf890222b080 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 17 Aug 2011 17:12:10 +0000 Subject: Camera tracking integration =========================== - Bundling new libmv, issues with undefined uint and C99 functions should gone. - Changes to Detect operator to match new API. --- extern/libmv/ChangeLog | 46 ++++++++++ extern/libmv/libmv-capi.cpp | 51 +++++++---- extern/libmv/libmv-capi.h | 12 +-- extern/libmv/libmv/numeric/function_derivative.h | 3 +- extern/libmv/libmv/numeric/levenberg_marquardt.h | 51 ++++------- extern/libmv/libmv/simple_pipeline/detect.cc | 109 +++++++++++++++-------- extern/libmv/libmv/simple_pipeline/detect.h | 49 +++++----- extern/libmv/libmv/tracking/sad.cc | 19 +++- extern/libmv/libmv/tracking/sad.h | 6 +- source/blender/blenkernel/BKE_tracking.h | 2 +- source/blender/blenkernel/intern/tracking.c | 12 +-- source/blender/editors/space_clip/tracking_ops.c | 6 +- 12 files changed, 226 insertions(+), 140 deletions(-) diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog index 5db3c420ea5..936ec9d5d8d 100644 --- a/extern/libmv/ChangeLog +++ b/extern/libmv/ChangeLog @@ -1,3 +1,49 @@ +commit d22720e618456329388d2c107422c3b371657cba +Author: Matthias Fauconneau +Date: Wed Aug 17 14:14:45 2011 +0200 + + Improve Detect and SAD Tracker API and documentation. + +commit 5d6cd4ad365b061901bad40695b51d568487a0cf +Author: Matthias Fauconneau +Date: Wed Aug 17 11:57:29 2011 +0200 + + MSVC support fixes. + +commit 50f0323173c6deebd6aaf9c126f0b51b2a79c3c1 +Author: Matthias Fauconneau +Date: Tue Aug 16 23:21:37 2011 +0200 + + Detector can detect features similar to a given pattern. + +commit 5734cc27bbf84c2b6edcfcc1ea736798e12d5820 +Author: Matthias Fauconneau +Date: Tue Aug 16 22:53:54 2011 +0200 + + Ensure SAD Tracker is C compatible. + Update Detect API documentation. + +commit 701c42842574064fea992f8822e3899cb9066108 +Author: Matthias Fauconneau +Date: Tue Aug 16 21:56:42 2011 +0200 + + Remove FAST detector. + Add Moravec detector. + This detector is more suited to tracking since it try to choose patterns which are unlikely to drift by computing SAD with neighbouring patches. + It could be improved to better avoid edges. + +commit 9bdf93e13fc880c78b6f34397da673388c16040e +Author: Matthias Fauconneau +Date: Tue Aug 16 21:55:08 2011 +0200 + + Fix Qt Tracker GL to work with AMD drivers. + +commit 81613ee0cc94b315f333c9632b18b95d426aad05 +Author: Matthias Fauconneau +Date: Tue Aug 16 21:54:12 2011 +0200 + + Make CameraIntrinsics (and thus Qt tracker) compilable without linking libmv. + commit a1d9a8fa8b01ef7cf2a79b3b891633fc333fc9cf Author: Matthias Fauconneau Date: Tue Aug 16 21:24:51 2011 +0200 diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp index 70985f545b9..c3a0d717d12 100644 --- a/extern/libmv/libmv-capi.cpp +++ b/extern/libmv/libmv-capi.cpp @@ -77,6 +77,11 @@ typedef struct libmv_Reconstruction { double error; } libmv_Reconstruction; +typedef struct libmv_Features { + int count, margin; + libmv::Feature *features; +} libmv_Features; + /* ************ Logging ************ */ void libmv_initLogging(const char *argv0) @@ -324,12 +329,12 @@ int libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *image, int stri { float x2, y2; - int result = libmv::Track(pattern, image, stride, width, height, &x2, &y2); + libmv::Track(pattern, image, stride, width, height, &x2, &y2); *x= x2; *y= y2; - return result; + return 1; } /* ************ Tracks ************ */ @@ -495,37 +500,45 @@ void libmv_destroyReconstruction(libmv_Reconstruction *libmv_reconstruction) /* ************ feature detector ************ */ -struct libmv_Corners *libmv_detectCorners(unsigned char *data, int width, int height, int stride, - int margin, int min_trackness, int min_distance) +struct libmv_Features *libmv_detectFeatures(unsigned char *data, int width, int height, int stride, + int margin, int count, int min_distance) { - std::vector detect; - std::vector *libmv_corners= new std::vector(); + libmv::Feature *features = new libmv::Feature[count]; + libmv_Features *libmv_features = new libmv_Features; + + if(margin) { + data += margin*stride+margin; + width -= 2*margin; + height -= 2*margin; + } - detect= libmv::Detect(data, width, height, stride, margin, min_trackness, min_distance); + libmv::Detect(data, stride, width, height, features, &count, min_distance, NULL); - libmv_corners->insert(libmv_corners->begin(), detect.begin(), detect.end()); + libmv_features->count= count; + libmv_features->margin= margin; + libmv_features->features= features; - return (libmv_Corners *)libmv_corners; + return libmv_features ; } -int libmv_countCorners(struct libmv_Corners *libmv_corners) +int libmv_countFeatures(struct libmv_Features *libmv_features) { - return ((std::vector *)libmv_corners)->size(); + return libmv_features->count; } -void libmv_getCorner(struct libmv_Corners *libmv_corners, int number, double *x, double *y, double *score, double *size) +void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size) { - libmv::Corner corner = ((std::vector *)libmv_corners)->at(number); + libmv::Feature feature = libmv_features->features[number]; - *x = corner.x; - *y = corner.y; - *score = corner.score; - *size = corner.size; + *x = feature.x + libmv_features->margin; + *y = feature.y + libmv_features->margin; + *score = feature.score; + *size = feature.size; } -void libmv_destroyCorners(struct libmv_Corners *libmv_corners) +void libmv_destroyFeatures(struct libmv_Features *libmv_features) { - delete (std::vector *)libmv_corners; + delete (libmv::Feature *)libmv_features; } /* ************ distortion ************ */ diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h index 0a7dd0beadf..d50632f3d4f 100644 --- a/extern/libmv/libmv-capi.h +++ b/extern/libmv/libmv-capi.h @@ -36,7 +36,7 @@ extern "C" { struct libmv_RegionTracker; struct libmv_Tracks; struct libmv_Reconstruction; -struct libmv_Corners; +struct libmv_Features; /* Logging */ void libmv_initLogging(const char *argv0); @@ -71,11 +71,11 @@ double libmv_reprojectionError(struct libmv_Reconstruction *libmv_reconstruction void libmv_destroyReconstruction(struct libmv_Reconstruction *libmv_reconstruction); /* feature detector */ -struct libmv_Corners *libmv_detectCorners(unsigned char *data, int width, int height, int stride, - int margin, int min_trackness, int min_distance); -int libmv_countCorners(struct libmv_Corners *libmv_corners); -void libmv_getCorner(struct libmv_Corners *libmv_corners, int number, double *x, double *y, double *score, double *size); -void libmv_destroyCorners(struct libmv_Corners *libmv_corners); +struct libmv_Features *libmv_detectFeatures(unsigned char *data, int width, int height, int stride, + int margin, int count, int min_distance); +int libmv_countFeatures(struct libmv_Features *libmv_features); +void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size); +void libmv_destroyFeatures(struct libmv_Features *libmv_features); /* dsitortion */ void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, diff --git a/extern/libmv/libmv/numeric/function_derivative.h b/extern/libmv/libmv/numeric/function_derivative.h index d7bc437b2e0..0075d23ac56 100644 --- a/extern/libmv/libmv/numeric/function_derivative.h +++ b/extern/libmv/libmv/numeric/function_derivative.h @@ -24,7 +24,6 @@ #include #include "libmv/numeric/numeric.h" -#include "libmv/logging/logging.h" namespace libmv { @@ -98,7 +97,7 @@ bool CheckJacobian(const Function &f, const typename Function::XMatrixType &x) { typename NumericJacobian::JMatrixType J_numeric = j_numeric(x); typename NumericJacobian::JMatrixType J_analytic = j_analytic(x); - LG << J_numeric - J_analytic; + //LG << J_numeric - J_analytic; return true; } diff --git a/extern/libmv/libmv/numeric/levenberg_marquardt.h b/extern/libmv/libmv/numeric/levenberg_marquardt.h index 4473b72f156..6a54f660d31 100644 --- a/extern/libmv/libmv/numeric/levenberg_marquardt.h +++ b/extern/libmv/libmv/numeric/levenberg_marquardt.h @@ -33,7 +33,6 @@ #include "libmv/numeric/numeric.h" #include "libmv/numeric/function_derivative.h" -#include "libmv/logging/logging.h" namespace libmv { @@ -124,40 +123,26 @@ class LevenbergMarquardt { Parameters dx, x_new; int i; for (i = 0; results.status == RUNNING && i < params.max_iterations; ++i) { - VLOG(1) << "iteration: " << i; - VLOG(1) << "||f(x)||: " << f_(x).norm(); - VLOG(1) << "max(g): " << g.array().abs().maxCoeff(); - VLOG(1) << "u: " << u; - VLOG(1) << "v: " << v; - - AMatrixType A_augmented = A + u*AMatrixType::Identity(J.cols(), J.cols()); - Solver solver(A_augmented); - dx = solver.solve(g); - bool solved = (A_augmented * dx).isApprox(g); - if (!solved) { - LOG(ERROR) << "Failed to solve"; - } - if (solved && dx.norm() <= params.relative_step_threshold * x.norm()) { + if (dx.norm() <= params.relative_step_threshold * x.norm()) { results.status = RELATIVE_STEP_SIZE_TOO_SMALL; break; - } - if (solved) { - x_new = x + dx; - // Rho is the ratio of the actual reduction in error to the reduction - // in error that would be obtained if the problem was linear. - // See [1] for details. - Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm()) - / dx.dot(u*dx + g)); - if (rho > 0) { - // Accept the Gauss-Newton step because the linear model fits well. - x = x_new; - results.status = Update(x, params, &J, &A, &error, &g); - Scalar tmp = Scalar(2*rho-1); - u = u*std::max(1/3., 1 - (tmp*tmp*tmp)); - v = 2; - continue; - } - } + } + x_new = x + dx; + // Rho is the ratio of the actual reduction in error to the reduction + // in error that would be obtained if the problem was linear. + // See [1] for details. + Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm()) + / dx.dot(u*dx + g)); + if (rho > 0) { + // Accept the Gauss-Newton step because the linear model fits well. + x = x_new; + results.status = Update(x, params, &J, &A, &error, &g); + Scalar tmp = Scalar(2*rho-1); + u = u*std::max(1/3., 1 - (tmp*tmp*tmp)); + v = 2; + continue; + } + // Reject the update because either the normal equations failed to solve // or the local linear model was not good (rho < 0). Instead, increase u // to move closer to gradient descent. diff --git a/extern/libmv/libmv/simple_pipeline/detect.cc b/extern/libmv/libmv/simple_pipeline/detect.cc index c3f54fffa18..28cd01fa73f 100644 --- a/extern/libmv/libmv/simple_pipeline/detect.cc +++ b/extern/libmv/libmv/simple_pipeline/detect.cc @@ -23,49 +23,84 @@ ****************************************************************************/ #include "libmv/simple_pipeline/detect.h" -#include -#include +#include namespace libmv { -std::vector Detect(const unsigned char* data, int width, int height, int stride, - int margin, int min_trackness, int min_distance) { - std::vector corners; - data += margin*width + margin; - // TODO(MatthiasF): Support targetting a feature count (binary search trackness) - int num_corners; - xy* all = fast9_detect(data, width-2*margin, height-2*margin, - stride, min_trackness, &num_corners); - if(num_corners == 0) { - free(all); - return corners; +#ifdef __SSE2__ +#include +static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) { + __m128i a = _mm_setzero_si128(); + for(int i = 0; i < 16; i++) { + a = _mm_adds_epu16(a, _mm_sad_epu8( _mm_loadu_si128((__m128i*)(imageA+i*strideA)), + _mm_loadu_si128((__m128i*)(imageB+i*strideB)))); } - int* scores = fast9_score(data, stride, all, num_corners, min_trackness); - // TODO: merge with close feature suppression - xy* nonmax = nonmax_suppression(all, scores, num_corners, &num_corners); - free(all); - // Remove too close features - // TODO(MatthiasF): A resolution independent parameter would be better than distance - // e.g. a coefficient going from 0 (no minimal distance) to 1 (optimal circle packing) - // FIXME(MatthiasF): this method will not necessarily give all maximum markers - if(num_corners) corners.reserve(num_corners); - for(int i = 0; i < num_corners; ++i) { - xy xy = nonmax[i]; - Corner a = { xy.x+margin, xy.y+margin, scores[i], 7 }; - // compare each feature against filtered set - for(int j = 0; j < corners.size(); j++) { - Corner& b = corners[j]; - if ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) < min_distance*min_distance ) { - // already a nearby feature - goto skip; + return _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4); +} +#else +static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) { + uint sad=0; + for(int i = 0; i < 16; i++) { + for(int j = 0; j < 16; j++) { + sad += abs((int)imageA[i*strideA+j] - imageB[i*strideB+j]); + } + } + return sad; +} +#endif + +void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) { + unsigned short histogram[256]; + memset(histogram,0,sizeof(histogram)); + ubyte scores[width*height]; + memset(scores,0,sizeof(scores)); + const int r = 1; //radius for self similarity comparison + for(int y=distance; y255) score=255; // clip + ubyte* c = &scores[y*width+x]; + for(int i=-distance; i<0; i++) { + for(int j=-distance; j= score) goto nonmax; + c[i*width+j]=0, histogram[s]--; + } } + for(int i=0, j=-distance; j<0; j++) { + int s = c[i*width+j]; + if(s == 0) continue; + if(s >= score) goto nonmax; + c[i*width+j]=0, histogram[s]--; + } + c[0] = score, histogram[score]++; + nonmax:; } - // otherwise add the new feature - corners.push_back(a); - skip: ; } - free(scores); - free(nonmax); - return corners; + int min=255, total=0; + for(; min>0; min--) { + int h = histogram[min]; + if(total+h > *count) break; + total += h; + } + int i=0; + for(int y=16; ymin) detected[i++] = f; + } + } + *count = i; } + } diff --git a/extern/libmv/libmv/simple_pipeline/detect.h b/extern/libmv/libmv/simple_pipeline/detect.h index 5e947fe8f5b..23b239b81d6 100644 --- a/extern/libmv/libmv/simple_pipeline/detect.h +++ b/extern/libmv/libmv/simple_pipeline/detect.h @@ -25,53 +25,48 @@ #ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_ #define LIBMV_SIMPLE_PIPELINE_DETECT_H_ -#include - +#ifdef __cplusplus namespace libmv { +#endif + +typedef unsigned char ubyte; /*! - A Corner is the 2D location of a detected feature in an image. + \a Feature is the 2D location of a detected feature in an image. - \a x, \a y is the position of the corner in pixels from the top left corner. - \a score is an estimate of how well the feature will be tracked. - \a size can be used as an initial pattern size to track the feature. + \a x, \a y is the position of the center in pixels (from image top-left). + \a score is an estimate of how well the pattern will be tracked. + \a size can be used as an initial size to track the pattern. \sa Detect */ -struct Corner { - /// Position in pixels (from top-left corner) - /// \note libmv might eventually support subpixel precision. +struct Feature { float x, y; - /// Trackness of the feature float score; - /// Size of the feature in pixels float size; }; - + //radius for non maximal suppression /*! Detect features in an image. - You need to input a single channel 8-bit image using pointer to image \a data, - \a width, \a height and \a stride (i.e bytes per line). - - To avoid detecting tracks which will quickly go out of frame, only corners - further than \a margin pixels from the image edges are considered. + \a image is a single channel 8-bit image of size \a width x \a height - You can tweak the count of detected corners using \a min_trackness, which is - the minimum score to add a corner, and \a min_distance which is the minimal - distance accepted between two corners. + \a detected is an array with space to hold \a *count features. + \a *count is the maximum count to detect on input and the actual + detected count on output. - \note You can binary search over \a min_trackness to get a given corner count. + \a distance is the minimal distance between detected features. - \note a way to get an uniform distribution of a given corner count is: - \a min_distance = \a width * \a height / desired_corner_count ^ 2 + if \a pattern is null all good features will be found. + if \a pattern is not null only features similar to \a pattern will be found. - \return All detected corners matching given parameters + \note \a You can crop the image (to avoid detecting markers near the borders) without copying: + image += marginY*stride+marginX, width -= 2*marginX, height -= 2*marginY; */ -std::vector Detect(const unsigned char* data, int width, int height, - int stride, int margin = 16, int min_trackness = 16, - int min_distance = 120); +void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/); +#ifdef __cplusplus } +#endif #endif diff --git a/extern/libmv/libmv/tracking/sad.cc b/extern/libmv/libmv/tracking/sad.cc index 0bcf3cbec3f..4f17bc9e39c 100644 --- a/extern/libmv/libmv/tracking/sad.cc +++ b/extern/libmv/libmv/tracking/sad.cc @@ -28,6 +28,8 @@ namespace libmv { +typedef unsigned int uint; + struct vec2 { float x,y; inline vec2(float x, float y):x(x),y(y){} @@ -44,11 +46,20 @@ template inline int sample(const ubyte* image,int stride, int x, int y, + (s[stride] * (k-u) + s[stride+1] * u) * ( v) ) / (k*k); } -void SamplePattern(const ubyte* image, int stride, mat3 warp, ubyte* pattern) { +#ifdef __SSE__ +#include +#endif +void SamplePattern(ubyte* image, int stride, mat3 warp, ubyte* pattern) { const int k = 256; for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++) { vec2 p = warp*vec2(j-8,i-8); +#ifdef __SSE__ + //MSVC apparently doesn't support any float rounding. + int fx = _mm_cvtss_si32(_mm_set_ss(p.x*k)); + int fy = _mm_cvtss_si32(_mm_set_ss(p.y*k)); +#else int fx = lround(p.x*k), fy = lround(p.y*k); +#endif int ix = fx/k, iy = fy/k; int u = fx%k, v = fy%k; pattern[i*16+j] = sample(image,stride,ix,iy,u,v); @@ -78,14 +89,14 @@ static uint SAD(const ubyte* pattern, const ubyte* image, int stride) { #endif //float sq( float x ) { return x*x; } -bool Track(const ubyte* pattern, const ubyte* image, int stride, int w, int h, float* px, float* py) { +int Track(ubyte* pattern, ubyte* image, int stride, int w, int h, float* px, float* py) { int ix = *px-8, iy = *py-8; uint min=-1; // integer pixel for(int y = 0; y < h-16; y++) { for(int x = 0; x < w-16; x++) { uint d = SAD(pattern,&image[y*stride+x],stride); //image L1 distance - //d += sq(x-w/2-8)+sq(y-h/2-8); //spatial L2 distance + //d += sq(x-w/2-8)+sq(y-h/2-8); //spatial L2 distance (need feature prediction first) if(d < min) { min = d; ix = x, iy = y; @@ -123,7 +134,7 @@ bool Track(const ubyte* pattern, const ubyte* image, int stride, int w, int h, f *px = float((ix*kScale)+fx)/kScale+8; *py = float((iy*kScale)+fy)/kScale+8; - return true; + return min; } } // namespace libmv diff --git a/extern/libmv/libmv/tracking/sad.h b/extern/libmv/libmv/tracking/sad.h index 4b82d6cb646..92307c9580f 100644 --- a/extern/libmv/libmv/tracking/sad.h +++ b/extern/libmv/libmv/tracking/sad.h @@ -40,7 +40,7 @@ typedef float mat3[9]; \note \a warp might be used by higher level tracking methods (e.g planar) */ -void SamplePattern(const ubyte* image, int stride, mat3 warp, ubyte* pattern); +void SamplePattern(ubyte* image, int stride, mat3 warp, ubyte* pattern); /*! Track \a pattern in \a image. @@ -59,8 +59,10 @@ void SamplePattern(const ubyte* image, int stride, mat3 warp, ubyte* pattern); \note For a 16x speedup, compile this tracker with SSE2 support. \note \a stride allow you to reference your search region instead of copying. + + \return Sum of absolute difference between reference and matched pattern. */ -bool Track(const ubyte* pattern, const ubyte* image, int stride, int width, int height, float* x, float* y); +int Track(ubyte* pattern, ubyte* image, int stride, int width, int height, float* x, float* y); #ifdef __cplusplus } // namespace libmv diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 3681cb5f0e4..efb55c1c803 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -84,7 +84,7 @@ void BKE_tracking_projection_matrix(struct MovieTracking *tracking, int framenr, void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]); void BKE_tracking_invert_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]); -void BKE_tracking_detect(struct MovieTracking *tracking, struct ImBuf *imbuf, int framenr, int margin, int min_trackness, int min_distance); +void BKE_tracking_detect(struct MovieTracking *tracking, struct ImBuf *imbuf, int framenr, int margin, int count, int min_distance); struct MovieTrackingTrack *BKE_tracking_indexed_bundle(struct MovieTracking *tracking, int bundlenr); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index a1db0eb8dd0..b111909a3bd 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1363,22 +1363,22 @@ static unsigned char *acquire_ucharbuf(ImBuf *ibuf) } #endif -void BKE_tracking_detect(MovieTracking *tracking, ImBuf *ibuf, int framenr, int margin, int min_trackness, int min_distance) +void BKE_tracking_detect(MovieTracking *tracking, ImBuf *ibuf, int framenr, int margin, int count, int min_distance) { #ifdef WITH_LIBMV - struct libmv_Corners *corners; + struct libmv_Features *features; unsigned char *pixels= acquire_ucharbuf(ibuf); int a; - corners= libmv_detectCorners(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance); + features= libmv_detectFeatures(pixels, ibuf->x, ibuf->y, ibuf->x, margin, count, min_distance); MEM_freeN(pixels); - a= libmv_countCorners(corners); + a= libmv_countFeatures(features); while(a--) { MovieTrackingTrack *track; double x, y, size, score; - libmv_getCorner(corners, a, &x, &y, &score, &size); + libmv_getFeature(features, a, &x, &y, &score, &size); track= BKE_tracking_add_track(tracking, x/ibuf->x, 1.0f-(y/ibuf->y), framenr, ibuf->x, ibuf->y); track->flag|= SELECT; @@ -1386,7 +1386,7 @@ void BKE_tracking_detect(MovieTracking *tracking, ImBuf *ibuf, int framenr, int track->search_flag|= SELECT; } - libmv_destroyCorners(corners); + libmv_destroyFeatures(features); #endif } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index b6229894378..64b7a8ffeff 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2175,7 +2175,7 @@ static int detect_features_exec(bContext *C, wmOperator *op) ImBuf *ibuf= BKE_movieclip_acquire_ibuf_flag(clip, &sc->user, 0); MovieTrackingTrack *track= clip->tracking.tracks.first; int margin= RNA_int_get(op->ptr, "margin"); - int min_trackness= RNA_int_get(op->ptr, "min_trackness"); + int count= RNA_int_get(op->ptr, "count"); int min_distance= RNA_int_get(op->ptr, "min_distance"); /* deselect existing tracks */ @@ -2187,7 +2187,7 @@ static int detect_features_exec(bContext *C, wmOperator *op) track= track->next; } - BKE_tracking_detect(&clip->tracking, ibuf, sc->user.framenr, margin, min_trackness, min_distance); + BKE_tracking_detect(&clip->tracking, ibuf, sc->user.framenr, margin, count, min_distance); IMB_freeImBuf(ibuf); @@ -2212,7 +2212,7 @@ void CLIP_OT_detect_features(wmOperatorType *ot) /* properties */ RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin", "Only corners further than margin pixels from the image edges are considered", 0, 300); - RNA_def_int(ot->srna, "min_trackness", 16, 0, INT_MAX, "Trackness", "Minimum score to add a corner", 0, 300); + RNA_def_int(ot->srna, "count", 50, 1, INT_MAX, "Count", "Count of corners to detect", 0, 300); RNA_def_int(ot->srna, "min_distance", 120, 0, INT_MAX, "Distance", "Minimal distance accepted between two corners", 0, 300); } -- cgit v1.2.3