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:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-12-30 15:03:59 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-01-01 20:32:48 +0400
commit2785e8e73d3473cf481ba65a6b50a50c194e63d8 (patch)
tree179263a95aa25ccf8ecd383786dd535419aeabe4 /source/blender/blenkernel/intern/tracking_detect.c
parent5933b2455c409963580ea616047f2f2ee332ff71 (diff)
Split tracking.c into several files
File tracking.c became rather huge and annoying to maintain and it really contains several independent areas of motrack pipeline. Now we've got: * tracking.c: general-purpose functions which are used by blender, clip editor, RNA and so. * tracking_detect.c: feature detection functions (blender-side, logic is still in libmv). * tracking_plane_tracker.c: blender-side 2D tracking logic. * tracking_plane_tracker.c: plane track tracker. * tracking_solver.c: functions for camera solving. * tracking_stabilize.c: 2D stabilization functions. * tracking_util.c: utility functions for all those files and which shouldn't be public.
Diffstat (limited to 'source/blender/blenkernel/intern/tracking_detect.c')
-rw-r--r--source/blender/blenkernel/intern/tracking_detect.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/tracking_detect.c b/source/blender/blenkernel/intern/tracking_detect.c
new file mode 100644
index 00000000000..b262844d40f
--- /dev/null
+++ b/source/blender/blenkernel/intern/tracking_detect.c
@@ -0,0 +1,181 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ * Keir Mierle
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/tracking_detect.c
+ * \ingroup bke
+ *
+ * This file contains blender-side implementation of feature detection.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_object_types.h" /* SELECT */
+
+#include "BLI_utildefines.h"
+
+#include "BKE_tracking.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "libmv-capi.h"
+
+/* Check whether point is inside grease pencil stroke. */
+static bool check_point_in_stroke(bGPDstroke *stroke, float x, float y)
+{
+ int i, prev;
+ int count = 0;
+ bGPDspoint *points = stroke->points;
+
+ /* Count intersections of horizontal ray coming from the point.
+ * Point will be inside layer if and only if number of intersection
+ * is uneven.
+ *
+ * Well, if layer has got self-intersections, this logic wouldn't
+ * work, but such situation is crappy anyway.
+ */
+
+ prev = stroke->totpoints - 1;
+
+ for (i = 0; i < stroke->totpoints; i++) {
+ if ((points[i].y < y && points[prev].y >= y) || (points[prev].y < y && points[i].y >= y)) {
+ float fac = (y - points[i].y) / (points[prev].y - points[i].y);
+
+ if (points[i].x + fac * (points[prev].x - points[i].x) < x)
+ count++;
+ }
+
+ prev = i;
+ }
+
+ return (count % 2) ? true : false;
+}
+
+/* Check whether point is inside any stroke of grease pencil layer. */
+static bool check_point_in_layer(bGPDlayer *layer, float x, float y)
+{
+ bGPDframe *frame = layer->frames.first;
+
+ while (frame) {
+ bGPDstroke *stroke = frame->strokes.first;
+
+ while (stroke) {
+ if (check_point_in_stroke(stroke, x, y))
+ return true;
+
+ stroke = stroke->next;
+ }
+ frame = frame->next;
+ }
+
+ return false;
+}
+
+/* Get features detected by libmv and create tracks on the clip for them. */
+static void detect_retrieve_libmv_features(MovieTracking *tracking, ListBase *tracksbase,
+ struct libmv_Features *features, int framenr, int width, int height,
+ bGPDlayer *layer, bool place_outside_layer)
+{
+ int a;
+
+ a = libmv_countFeatures(features);
+ while (a--) {
+ MovieTrackingTrack *track;
+ double x, y, size, score;
+ bool ok = true;
+ float xu, yu;
+
+ libmv_getFeature(features, a, &x, &y, &score, &size);
+
+ xu = x / width;
+ yu = y / height;
+
+ if (layer)
+ ok = check_point_in_layer(layer, xu, yu) != place_outside_layer;
+
+ if (ok) {
+ track = BKE_tracking_track_add(tracking, tracksbase, xu, yu, framenr, width, height);
+ track->flag |= SELECT;
+ track->pat_flag |= SELECT;
+ track->search_flag |= SELECT;
+ }
+ }
+}
+
+/* Get a gray-scale unsigned char buffer from given image buffer
+ * wich will be used for feature detection.
+ */
+static unsigned char *detect_get_frame_ucharbuf(ImBuf *ibuf)
+{
+ int x, y;
+ unsigned char *pixels, *cp;
+
+ cp = pixels = MEM_callocN(ibuf->x * ibuf->y * sizeof(unsigned char), "tracking ucharBuf");
+ for (y = 0; y < ibuf->y; y++) {
+ for (x = 0; x < ibuf->x; x++) {
+ int pixel = ibuf->x * y + x;
+
+ if (ibuf->rect_float) {
+ const float *rrgbf = ibuf->rect_float + pixel * 4;
+ const float gray_f = 0.2126f * rrgbf[0] + 0.7152f * rrgbf[1] + 0.0722f * rrgbf[2];
+
+ *cp = FTOCHAR(gray_f);
+ }
+ else {
+ const unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
+
+ *cp = 0.2126f * rrgb[0] + 0.7152f * rrgb[1] + 0.0722f * rrgb[2];
+ }
+
+ cp++;
+ }
+ }
+
+ return pixels;
+}
+
+/* Detect features using FAST detector */
+void BKE_tracking_detect_fast(MovieTracking *tracking, ListBase *tracksbase, ImBuf *ibuf,
+ int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer,
+ bool place_outside_layer)
+{
+ struct libmv_Features *features;
+ unsigned char *pixels = detect_get_frame_ucharbuf(ibuf);
+
+ features = libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x,
+ margin, min_trackness, min_distance);
+
+ MEM_freeN(pixels);
+
+ detect_retrieve_libmv_features(tracking, tracksbase, features,
+ framenr, ibuf->x, ibuf->y, layer,
+ place_outside_layer);
+
+ libmv_featuresDestroy(features);
+}