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/libmv-capi.cpp61
-rw-r--r--extern/libmv/libmv-capi.h4
-rw-r--r--extern/libmv/libmv/simple_pipeline/detect.cc50
-rw-r--r--extern/libmv/libmv/simple_pipeline/detect.h43
-rw-r--r--extern/libmv/patches/detect.patch151
-rw-r--r--extern/libmv/patches/series1
-rw-r--r--source/blender/blenkernel/BKE_tracking.h2
-rw-r--r--source/blender/blenkernel/intern/tracking.c8
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c39
9 files changed, 330 insertions, 29 deletions
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
index 8bf27ac0656..863e16515df 100644
--- a/extern/libmv/libmv-capi.cpp
+++ b/extern/libmv/libmv-capi.cpp
@@ -502,11 +502,13 @@ void libmv_destroyReconstruction(libmv_Reconstruction *libmv_reconstruction)
/* ************ feature detector ************ */
-struct libmv_Features *libmv_detectFeatures(unsigned char *data, int width, int height, int stride,
- int margin, int count, int min_distance)
+struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride,
+ int margin, int min_trackness, int min_distance)
{
- libmv::Feature *features = new libmv::Feature[count];
- libmv_Features *libmv_features = new libmv_Features;
+ libmv::Feature *features = NULL;
+ std::vector<libmv::Feature> v;
+ libmv_Features *libmv_features = new libmv_Features();
+ int i= 0, count;
if(margin) {
data += margin*stride+margin;
@@ -514,13 +516,47 @@ struct libmv_Features *libmv_detectFeatures(unsigned char *data, int width, int
height -= 2*margin;
}
- libmv::Detect(data, stride, width, height, features, &count, min_distance, NULL);
+ v = libmv::DetectFAST(data, width, height, stride, min_trackness, min_distance);
+
+ count = v.size();
+
+ if(count) {
+ features= new libmv::Feature[count];
+
+ for(std::vector<libmv::Feature>::iterator it = v.begin(); it != v.end(); it++) {
+ features[i++]= *it;
+ }
+ }
- libmv_features->count= count;
- libmv_features->margin= margin;
- libmv_features->features= features;
+ libmv_features->features = features;
+ libmv_features->count = count;
+ libmv_features->margin = margin;
- return libmv_features ;
+ return (libmv_Features *)libmv_features;
+}
+
+struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride,
+ int margin, int count, int min_distance)
+{
+ libmv::Feature *features = NULL;
+ libmv_Features *libmv_features = new libmv_Features;
+
+ if(count) {
+ if(margin) {
+ data += margin*stride+margin;
+ width -= 2*margin;
+ height -= 2*margin;
+ }
+
+ features = new libmv::Feature[count];
+ libmv::DetectMORAVEC(data, stride, width, height, features, &count, min_distance, NULL);
+ }
+
+ libmv_features->count = count;
+ libmv_features->margin = margin;
+ libmv_features->features = features;
+
+ return libmv_features;
}
int libmv_countFeatures(struct libmv_Features *libmv_features)
@@ -530,7 +566,7 @@ 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)
{
- libmv::Feature feature = libmv_features->features[number];
+ libmv::Feature feature= libmv_features->features[number];
*x = feature.x + libmv_features->margin;
*y = feature.y + libmv_features->margin;
@@ -540,7 +576,10 @@ void libmv_getFeature(struct libmv_Features *libmv_features, int number, double
void libmv_destroyFeatures(struct libmv_Features *libmv_features)
{
- delete (libmv::Feature *)libmv_features;
+ if(libmv_features->features)
+ delete [] libmv_features->features;
+
+ delete libmv_features;
}
/* ************ camera intrinsics ************ */
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index 8f2a57748b2..d77e9ac62fa 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -72,7 +72,9 @@ double libmv_reprojectionError(struct libmv_Reconstruction *libmv_reconstruction
void libmv_destroyReconstruction(struct libmv_Reconstruction *libmv_reconstruction);
/* feature detector */
-struct libmv_Features *libmv_detectFeatures(unsigned char *data, int width, int height, int stride,
+struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride,
+ int margin, int min_trackness, int min_distance);
+struct libmv_Features *libmv_detectFeaturesMORAVEC(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);
diff --git a/extern/libmv/libmv/simple_pipeline/detect.cc b/extern/libmv/libmv/simple_pipeline/detect.cc
index 6fc0cdd120a..b316f427649 100644
--- a/extern/libmv/libmv/simple_pipeline/detect.cc
+++ b/extern/libmv/libmv/simple_pipeline/detect.cc
@@ -23,15 +23,59 @@
****************************************************************************/
#include "libmv/simple_pipeline/detect.h"
+#include <third_party/fast/fast.h>
#include <stdlib.h>
-#include <string.h>
+#include <memory.h>
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
namespace libmv {
typedef unsigned int uint;
+std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height, int stride,
+ int min_trackness, int min_distance) {
+ std::vector<Feature> features;
+ // TODO(MatthiasF): Support targetting a feature count (binary search trackness)
+ int num_features;
+ xy* all = fast9_detect(data, width, height,
+ stride, min_trackness, &num_features);
+ if(num_features == 0) {
+ free(all);
+ return features;
+ }
+ int* scores = fast9_score(data, stride, all, num_features, min_trackness);
+ // TODO: merge with close feature suppression
+ xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features);
+ 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_features) features.reserve(num_features);
+ for(int i = 0; i < num_features; ++i) {
+ xy xy = nonmax[i];
+ Feature a = { xy.x, xy.y, scores[i], 7 };
+ // compare each feature against filtered set
+ for(int j = 0; j < features.size(); j++) {
+ Feature& b = features[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;
+ }
+ }
+ // otherwise add the new feature
+ features.push_back(a);
+ skip: ;
+ }
+ free(scores);
+ free(nonmax);
+ return features;
+}
+
#ifdef __SSE2__
-#include <emmintrin.h>
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++) {
@@ -52,7 +96,7 @@ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strid
}
#endif
-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
+void DetectMORAVEC(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 = new ubyte[width*height];
diff --git a/extern/libmv/libmv/simple_pipeline/detect.h b/extern/libmv/libmv/simple_pipeline/detect.h
index 23b239b81d6..bbe7aed784c 100644
--- a/extern/libmv/libmv/simple_pipeline/detect.h
+++ b/extern/libmv/libmv/simple_pipeline/detect.h
@@ -25,27 +25,52 @@
#ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_
#define LIBMV_SIMPLE_PIPELINE_DETECT_H_
-#ifdef __cplusplus
+#include <vector>
+
namespace libmv {
-#endif
typedef unsigned char ubyte;
/*!
- \a Feature 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 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.
+ \a x, \a y is the position of the feature 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.
\sa Detect
*/
struct Feature {
+ /// Position in pixels (from top-left corner)
+ /// \note libmv might eventually support subpixel precision.
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).
+
+ You can tweak the count of detected features using \a min_trackness, which is
+ the minimum score to add a feature, and \a min_distance which is the minimal
+ distance accepted between two featuress.
+
+ \note You can binary search over \a min_trackness to get a given feature count.
+
+ \note a way to get an uniform distribution of a given feature count is:
+ \a min_distance = \a width * \a height / desired_feature_count ^ 2
+
+ \return All detected feartures matching given parameters
+*/
+std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height,
+ int stride, int min_trackness = 128,
+ int min_distance = 120);
+
/*!
Detect features in an image.
@@ -63,10 +88,8 @@ struct Feature {
\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;
*/
-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
+void DetectMORAVEC(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/patches/detect.patch b/extern/libmv/patches/detect.patch
new file mode 100644
index 00000000000..0d9b88faa96
--- /dev/null
+++ b/extern/libmv/patches/detect.patch
@@ -0,0 +1,151 @@
+diff --git a/src/libmv/simple_pipeline/detect.cc b/src/libmv/simple_pipeline/detect.cc
+index 6fc0cdd..b316f42 100644
+--- a/src/libmv/simple_pipeline/detect.cc
++++ b/src/libmv/simple_pipeline/detect.cc
+@@ -23,15 +23,59 @@
+ ****************************************************************************/
+
+ #include "libmv/simple_pipeline/detect.h"
++#include <third_party/fast/fast.h>
+ #include <stdlib.h>
+-#include <string.h>
++#include <memory.h>
++
++#ifdef __SSE2__
++#include <emmintrin.h>
++#endif
+
+ namespace libmv {
+
+ typedef unsigned int uint;
+
++std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height, int stride,
++ int min_trackness, int min_distance) {
++ std::vector<Feature> features;
++ // TODO(MatthiasF): Support targetting a feature count (binary search trackness)
++ int num_features;
++ xy* all = fast9_detect(data, width, height,
++ stride, min_trackness, &num_features);
++ if(num_features == 0) {
++ free(all);
++ return features;
++ }
++ int* scores = fast9_score(data, stride, all, num_features, min_trackness);
++ // TODO: merge with close feature suppression
++ xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features);
++ 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_features) features.reserve(num_features);
++ for(int i = 0; i < num_features; ++i) {
++ xy xy = nonmax[i];
++ Feature a = { xy.x, xy.y, scores[i], 7 };
++ // compare each feature against filtered set
++ for(int j = 0; j < features.size(); j++) {
++ Feature& b = features[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;
++ }
++ }
++ // otherwise add the new feature
++ features.push_back(a);
++ skip: ;
++ }
++ free(scores);
++ free(nonmax);
++ return features;
++}
++
+ #ifdef __SSE2__
+-#include <emmintrin.h>
+ 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++) {
+@@ -52,7 +96,7 @@ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strid
+ }
+ #endif
+
+-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) {
++void DetectMORAVEC(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 = new ubyte[width*height];
+diff --git a/src/libmv/simple_pipeline/detect.h b/src/libmv/simple_pipeline/detect.h
+index 23b239b..bbe7aed 100644
+--- a/src/libmv/simple_pipeline/detect.h
++++ b/src/libmv/simple_pipeline/detect.h
+@@ -25,27 +25,52 @@
+ #ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_
+ #define LIBMV_SIMPLE_PIPELINE_DETECT_H_
+
+-#ifdef __cplusplus
++#include <vector>
++
+ namespace libmv {
+-#endif
+
+ typedef unsigned char ubyte;
+
+ /*!
+- \a Feature 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 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.
++ \a x, \a y is the position of the feature 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.
+
+ \sa Detect
+ */
+ struct Feature {
++ /// Position in pixels (from top-left corner)
++ /// \note libmv might eventually support subpixel precision.
+ 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).
++
++ You can tweak the count of detected features using \a min_trackness, which is
++ the minimum score to add a feature, and \a min_distance which is the minimal
++ distance accepted between two featuress.
++
++ \note You can binary search over \a min_trackness to get a given feature count.
++
++ \note a way to get an uniform distribution of a given feature count is:
++ \a min_distance = \a width * \a height / desired_feature_count ^ 2
++
++ \return All detected feartures matching given parameters
++*/
++std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height,
++ int stride, int min_trackness = 128,
++ int min_distance = 120);
++
+ /*!
+ Detect features in an image.
+
+@@ -63,10 +88,8 @@ struct Feature {
+ \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;
+ */
+-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/);
++void DetectMORAVEC(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/patches/series b/extern/libmv/patches/series
index 410a14ca135..00a52c1cfaa 100644
--- a/extern/libmv/patches/series
+++ b/extern/libmv/patches/series
@@ -10,3 +10,4 @@ mingw.patch
msvc2010.patch
scaled_distortion.patch
overscan.patch
+detect.patch
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 84e2acfb147..0e29bb44181 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -87,7 +87,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 count, int min_distance);
+void BKE_tracking_detect(struct MovieTracking *tracking, struct ImBuf *imbuf, int framenr, int margin, int min_trackness, int count, int min_distance, int fast);
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 9ad7b963447..9f5478df0b1 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -1526,14 +1526,18 @@ static unsigned char *acquire_ucharbuf(ImBuf *ibuf)
}
#endif
-void BKE_tracking_detect(MovieTracking *tracking, ImBuf *ibuf, int framenr, int margin, int count, int min_distance)
+void BKE_tracking_detect(MovieTracking *tracking, ImBuf *ibuf, int framenr, int margin, int min_trackness, int count, int min_distance, int fast)
{
#ifdef WITH_LIBMV
struct libmv_Features *features;
unsigned char *pixels= acquire_ucharbuf(ibuf);
int a;
- features= libmv_detectFeatures(pixels, ibuf->x, ibuf->y, ibuf->x, margin, count, min_distance);
+ if(fast)
+ features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance);
+ else
+ features= libmv_detectFeaturesMORAVEC(pixels, ibuf->x, ibuf->y, ibuf->x, margin, count, min_distance);
+
MEM_freeN(pixels);
a= libmv_countFeatures(features);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 1651d4cea7e..3a559bbf935 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -2214,7 +2214,9 @@ static int detect_features_exec(bContext *C, wmOperator *op)
MovieClip *clip= ED_space_clip(sc);
ImBuf *ibuf= BKE_movieclip_acquire_ibuf_flag(clip, &sc->user, 0);
MovieTrackingTrack *track= clip->tracking.tracks.first;
+ int detector= RNA_enum_get(op->ptr, "detector");
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");
@@ -2227,7 +2229,7 @@ static int detect_features_exec(bContext *C, wmOperator *op)
track= track->next;
}
- BKE_tracking_detect(&clip->tracking, ibuf, sc->user.framenr, margin, count, min_distance);
+ BKE_tracking_detect(&clip->tracking, ibuf, sc->user.framenr, margin, min_trackness, count, min_distance, detector==0);
IMB_freeImBuf(ibuf);
@@ -2236,8 +2238,40 @@ static int detect_features_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static void detect_features_draw(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ wmWindowManager *wm= CTX_wm_manager(C);
+ PointerRNA ptr;
+ int detector= RNA_enum_get(op->ptr, "detector");
+ PropertyRNA *prop_min_trackness;
+ PropertyRNA *prop_count;
+
+ prop_min_trackness= RNA_struct_find_property(op->ptr, "min_trackness");
+ prop_count= RNA_struct_find_property(op->ptr, "count");
+
+ if(detector==0) {
+ RNA_def_property_clear_flag(prop_min_trackness, PROP_HIDDEN);
+ RNA_def_property_flag(prop_count, PROP_HIDDEN);
+ } else {
+ RNA_def_property_flag(prop_min_trackness, PROP_HIDDEN);
+ RNA_def_property_clear_flag(prop_count, PROP_HIDDEN);
+ }
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ /* main draw call */
+ uiDefAutoButsRNA(layout, &ptr, NULL, 'V');
+}
+
void CLIP_OT_detect_features(wmOperatorType *ot)
{
+ static EnumPropertyItem detector_items[] = {
+ {0, "FAST", 0, "FAST", "FAST corner detector"},
+ {1, "MORAVEC", 0, "Moravec", "Moravec corner detector"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
/* identifiers */
ot->name= "Detect Features";
ot->description= "Automatically detect features to track";
@@ -2246,12 +2280,15 @@ void CLIP_OT_detect_features(wmOperatorType *ot)
/* api callbacks */
ot->exec= detect_features_exec;
ot->poll= space_clip_frame_poll;
+ ot->ui= detect_features_draw;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
+ RNA_def_enum(ot->srna, "detector", detector_items, 0, "Detector", "Detector using for detecting features");
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);
}