rework findobject, add opecv_build
authorGood Guy <good1.2guy@gmail.com>
Mon, 18 Sep 2017 23:31:54 +0000 (17:31 -0600)
committerGood Guy <good1.2guy@gmail.com>
Mon, 18 Sep 2017 23:31:54 +0000 (17:31 -0600)
20 files changed:
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/configure.ac
cinelerra-5.1/guicast/bccmdl.py
cinelerra-5.1/guicast/bccmodels.C
cinelerra-5.1/guicast/bccmodels.h
cinelerra-5.1/info/plugins.txt
cinelerra-5.1/opencv_build [new file with mode: 0644]
cinelerra-5.1/plugin_config
cinelerra-5.1/plugin_defs
cinelerra-5.1/plugins/Makefile
cinelerra-5.1/plugins/findobject/Makefile
cinelerra-5.1/plugins/findobject/findobject.C
cinelerra-5.1/plugins/findobject/findobject.h
cinelerra-5.1/plugins/findobject/findobject.inc
cinelerra-5.1/plugins/findobject/findobjectwindow.C
cinelerra-5.1/plugins/findobject/findobjectwindow.h
cinelerra-5.1/plugins/findobject/findobjectwindow.inc
cinelerra-5.1/plugins/findobject/picon_cinfinity.png [new file with mode: 0644]
cinelerra-5.1/plugins/findobject/surfscan.C [deleted file]
cinelerra-5.1/plugins/findobject/surfscan.h [deleted file]

index dcbb49c63d4eeee18333df5bbacac178112e0d39..63a1196a2cd8b9bd0ee5c45127ff69b61d900eb1 100644 (file)
@@ -732,14 +732,13 @@ int FFAudioStream::load(int64_t pos, int len)
        }
        if( mbsz < len ) mbsz = len;
        int64_t end_pos = pos + len;
-       int ret = 0;
-       for( int i=0; ret>=0 && !flushed && curr_pos<end_pos && i<MAX_RETRY; ++i ) {
+       int ret = 0, i = len / frame_sz + MAX_RETRY;
+       while( ret>=0 && !flushed && curr_pos<end_pos && --i>=0 ) {
                ret = read_frame(frame);
-               if( ret > 0 ) {
+               if( ret > 0 && frame->nb_samples > 0 ) {
                        init_swr(frame->channels, frame->format, frame->sample_rate);
                        load_history(&frame->extended_data[0], frame->nb_samples);
                        curr_pos += frame->nb_samples;
-                       i = 0;
                }
        }
        if( end_pos > curr_pos ) {
@@ -867,9 +866,10 @@ int FFVideoStream::load(VFrame *vframe, int64_t pos)
                fprintf(stderr, "FFVideoStream::load: av_frame_alloc failed\n");
                return -1;
        }
-       for( int i=0; ret>=0 && !flushed && curr_pos<=pos && i<MAX_RETRY; ++i ) {
+       int i = MAX_RETRY + pos - curr_pos;
+       while( ret>=0 && !flushed && curr_pos<=pos && --i>=0 ) {
                ret = read_frame(frame);
-               if( ret > 0 ) { ++curr_pos;  i = 0; }
+               if( ret > 0 ) ++curr_pos;
        }
        if( frame->format == AV_PIX_FMT_NONE || frame->width <= 0 || frame->height <= 0 )
                ret = -1;
@@ -2124,6 +2124,8 @@ int FFMPEG::decode_activate()
                                if( aidx >= 0 && ffaudio[aidx]->nudge != AV_NOPTS_VALUE ) continue;
                                if( astart_time < st->start_time )
                                        astart_time = st->start_time;
+                               ffaudio[aidx]->frame_sz =
+                                       avpar->frame_size < 128 ? 128 : avpar->frame_size;
                                break; }
                        default: break;
                        }
index ab5c9430dcfd46d27dae9a4f7d1d150688710112..3ac9335930905e3858877245a547c1a24b8ecd24 100644 (file)
@@ -463,7 +463,7 @@ if test "x$WANT_$1" != "xno" ; then
  if test "x$RESULT" = "xno" -a "x$PKG_$1" = "x"; then
   echo "=== want $1 Failed."
   WANT_$1=no
- else
+ elif test "x$WANT_$1" = "xauto" ; then
   WANT_$1=yes
  fi
 fi
@@ -520,6 +520,9 @@ CHECK_WANT([DL], [auto], [system has libdl], [
  CHECK_LIB([DL], [dl], [dlopen])])
 
 CHECK_WANT([EXR], [auto], [use exr], [])
+CHECK_WANT([FINDOBJECT], [no], [findobject=sys/sta/dyn], [
+ WANT_FINDOBJECT="$withval"
+])
 
 CHECK_WANT([NUMA], [auto], [system has libnuma], [
  CHECK_LIB([NUMA], [numa], [numa_alloc])])
@@ -680,6 +683,7 @@ echo "  using: with-config-dir = $WANT_CONFIG_DIR"
 echo "  using: with-browser = $WANT_CIN_BROWSER"
 echo "  using: with-plugin-dir = $WANT_PLUGIN_DIR"
 echo "  using: with-ladspa-dir = $WANT_LADSPA_DIR"
+echo "  using: with-findobject = $WANT_FINDOBJECT"
 echo ""
 echo "  using: single-user  = $WANT_CINBIN_BUILD"
 echo "  using: static-build = $WANT_STATIC_BUILD"
index d4634e07e75613d63f4fd9f22d49245c80b80255..27c3a050fcbe162a1454459ac1ab934ea1511228 100755 (executable)
@@ -322,6 +322,28 @@ base = {
     },
   },
 
+  "grey8": {
+    "i8": {
+      "r": " int32_t iy = *inp++, y = iy * 0x010101u, u = 0x80, v = 0x80;",
+      "w": " *out++ = y; (void)u; (void)v;",
+    },
+    "i16": {
+      "r": " int32_t iy = *inp++, y = iy * 0x010101u, u = 0x8000, v = 0x8000;",
+      "w": " *out++ = y>>8; (void)u; (void)v;",
+    },
+  },
+
+  "grey16": {
+    "i8": {
+      "r": " int32_t iy = *inp++, y = (iy<<8) | (iy>>8), u = 0x80, v = 0x80;",
+      "w": " *out++ = y<<8; (void)u; (void)v;",
+    },
+    "i16": {
+      "r": " int32_t iy = *inp++, y = (iy<<8) | (iy>>8), u = 0x8000, v = 0x8000;",
+      "w": " *out++ = y; (void)u; (void)v;",
+    },
+  },
+
   # alpha component
   "a8": {
     "i8": {
@@ -461,6 +483,9 @@ add_cmodel(32, "bc_rgb_floatp", "fp", "rgbfltp")
 add_cmodel(33, "bc_rgba_floatp", "fp", "rgbfltp", "afpp")
 add_cmodel(34, "bc_yuv420pi", "i8", "yuv420pi")
 
+add_cmodel(36, "bc_grey8", "i8", "grey8")
+add_cmodel(37, "bc_grey16", "i16", "grey16")
+
 specialize("bc_rgba8888", "bc_transparency", "XFER_rgba8888_to_transparency")
 
 ctype = {
@@ -500,7 +525,7 @@ def is_yuv(nm):
   return nm in [ "bc_yuv888", "bc_yuva8888", "bc_yuv161616", \
     "bc_yuva16161616", "bc_ayuv16161616", "bc_yuv422", "bc_uvy422", "bc_yuv101010", \
     "bc_vyu888", "bc_uyva8888", "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", \
-    "bc_yuv444p", "bc_yuv411p", "bc_yuv410p", ]
+    "bc_yuv444p", "bc_yuv411p", "bc_yuv410p", "bc_grey8", "bc_grey16" ]
 
 def is_planar(nm):
   return nm in [ "bc_yuv420p", "bc_yuv420pi", "bc_yuv422p", "bc_yuv444p", \
index 6fe12cbbe5b1bdc66e1bfb70823ef5b9d49da80d..dc5c2af1e1d0c5feae4e796c6999cc2561b59eff 100644 (file)
@@ -57,6 +57,8 @@ int BC_CModels::components(int colormodel)
        case BC_RGBA_FLOAT:   return 4;
        case BC_RGB_FLOATP:   return 3;
        case BC_RGBA_FLOATP:  return 4;
+       case BC_GREY8:        return 1;
+       case BC_GREY16:       return 1;
        }
        return 0;
 }
@@ -91,6 +93,8 @@ int BC_CModels::calculate_pixelsize(int colormodel)
        case BC_UYVA8888:     return 4;
        case BC_RGB_FLOAT:    return 12;
        case BC_RGBA_FLOAT:   return 16;
+       case BC_GREY8:        return 1;
+       case BC_GREY16:       return 2;
 // Planar
        case BC_YUV420P:      return 1;
        case BC_YUV420PI:     return 1;
@@ -126,6 +130,8 @@ int BC_CModels::calculate_max(int colormodel)
        case BC_RGBA_FLOAT:   return 1;
        case BC_RGB_FLOATP:   return 1;
        case BC_RGBA_FLOATP:  return 1;
+       case BC_GREY8:        return 0xff;
+       case BC_GREY16:       return 0xffff;
        }
        return 0;
 }
@@ -245,6 +251,8 @@ int BC_CModels::is_yuv(int colormodel)
        case BC_YUV444P:
        case BC_YUV411P:
        case BC_YUV410P:
+       case BC_GREY8:
+       case BC_GREY16:
                return 1;
        }
        return 0;
index d079b290fe81e7da1182bbfb2121010544ec541b..57b595f4e30234ef9d44be201a007fe5dd218f85 100644 (file)
@@ -63,6 +63,8 @@ enum BC_CModel {
        BC_YUV420PI     = 34,
 // only used in intermediate ffmpeg xfers
        BC_AYUV16161616 = 35,
+       BC_GREY8        = 36,
+       BC_GREY16       = 37,
 };
 
 // Colormodels purely used by Quicktime are done in Quicktime.
index 00abacd124f1f961907e47366ea47f44a24d0099..79c54c7c5072584f8c8315dbee56e2cc26b204b7 100644 (file)
@@ -75,6 +75,8 @@ Downsample:   Reduce the sie of an image by throwing out data,
 Edge:          Display only the edges of the video throughout the image.
 Fields to frames: Reads frames at 2x the framerate, combining 2
                input frames into 1 interlaced output frame.
+Find Object:   Locate a specific object in a scene and replace with 
+               another object.  This uses OpenCV thirdparty package.
 Flip:          Flip a portion of a video track from left to right,
                up to down or vice versa.
 Frames to Fields: Extracts 2 interlaced fields stored in alternating
diff --git a/cinelerra-5.1/opencv_build b/cinelerra-5.1/opencv_build
new file mode 100644 (file)
index 0000000..86d96d1
--- /dev/null
@@ -0,0 +1,128 @@
+# builds opencv using want_var to create bld from src
+# want_var set as: "" (empty) or "bld=typ" or "bld=typ,src=typ"
+#   empty: defaults to bld=sys
+#   bld=typ   sta,dyn,sys: sta=static, dyn=shared, sys=system libraries
+#   src=typ   git,tar,git=url,tar=url: git (default git_url), tar (default: tar_url)
+# once thirdparty/opencv is built, it will be reused.
+# use target "mrclean" to remove thirdparty/opencv*
+#
+ifeq (no,$(shell [ -d $(THIRDPARTY) ] && echo yes || echo no))
+$(error THIRDPARTY is not a directory: '$(THIRDPARTY)')
+endif
+
+blddir:=$(shell cd $(THIRDPARTY) && pwd)
+srcdir:=$(blddir)/src
+opencv:=$(blddir)/opencv
+opencv_prefix:=$(opencv)/build/usr/local
+
+# if previous build stamped, use that bld
+ifneq (,$(wildcard $(opencv).sta))
+bld:=sta
+else ifneq (,$(wildcard $(opencv).dyn))
+bld:=dyn
+else ifneq (,$(wildcard $(opencv).sys))
+bld:=sys
+endif
+
+comma=,
+params:=$(subst $(comma), ,$(want_var))
+
+# code: src=tar/tar=tar_url;git/git=git_url, build: bld=sta/dyn/sys
+$(foreach p,$(params),\
+ $(if $(bld),,$(eval var:=$(filter sta dyn sys,$(p)))\
+  $(if $(var),$(eval bld:=$(var))))\
+ $(if $(src),,$(eval var:=$(filter git tar,$(p)))\
+  $(if $(var),$(eval src:=$(var)),\
+   $(if $(filter git=%,$(p)),$(eval src:=git)$(eval git_url=$(patsubst git=%,%,$(p))),\
+    $(if $(filter tar=%,$(p)),$(eval src:=tar)$(eval tar_url=$(patsubst tar=%,%,$(p))))))))
+
+# defaults: src=git, bld=sys
+src?=git
+bld?=sys
+git_url?=https://github.com/opencv
+tar_url?=https://cinelerra-cv.org/five/src/opencv-20170916.tgz
+opencv_tar:=$(notdir $(tar_url))
+
+cpus:=$(shell grep -c "^proc" /proc/cpuinfo)
+jobs:=-j$(shell echo $$(($(cpus) + $(cpus)/2 +2)))
+
+CFLAGS += -I$(opencv_prefix)/include
+
+ifeq ($(src),git)
+$(opencv).src:
+       cd $(blddir) && rm -rf opencv opencv_contrib opencv.*
+       git -C $(blddir) clone --depth 1 $(git_url)/opencv.git
+       git -C $(blddir) clone --depth 1 $(git_url)/opencv_contrib.git
+       touch $@
+else ifeq ($(src),tar)
+$(srcdir)/$(opencv_tar):
+       cd $(srcdir) && rm -f $(opencv_tar)
+       wget -P $(srcdir) "$(tar_url)"
+
+$(opencv).src: $(srcdir)/$(opencv_tar)
+       cd $(blddir) && rm -rf opencv opencv_contrib opencv.*
+       tar -C $(blddir) -xzf $(srcdir)/$(opencv_tar);
+       touch $@
+else
+$(error src not git/tar)
+endif
+
+ifeq ($(bld),sta)
+$(opencv)/build: $(opencv).src
+       mkdir -p $@
+       cd $@ && cmake \
+  -DCMAKE_BUILD_TYPE=RELEASE \
+  -DBUILD_SHARED_LIBS=OFF \
+  -DINSTALL_C_EXAMPLES=OFF \
+  -DINSTALL_PYTHON_EXAMPLES=OFF \
+  -DBUILD_EXAMPLES=OFF .. \
+  -DCMAKE_INSTALL_PREFIX=/usr/local \
+  -DOPENCV_EXTRA_MODULES_PATH="$(opencv)_contrib/modules/"
+
+LFLAGS += -Wl,--start-group
+LFLAGS += $(shell ls -1 $(opencv_prefix)/lib/libopencv_*.a 2> /dev/null)
+LFLAGS += $(shell ls -1 $(opencv_prefix)/share/OpenCV/3rdparty/lib/lib*.a 2> /dev/null)
+LFLAGS += -Wl,--end-group
+else ifeq ($(bld),dyn)
+$(opencv)/build: $(opencv).src
+       mkdir -p $@
+       cd $@ && cmake \
+  -DCMAKE_BUILD_TYPE=RELEASE \
+  -DBUILD_SHARED_LIBS=ON \
+  -DINSTALL_C_EXAMPLES=ON \
+  -DINSTALL_PYTHON_EXAMPLES=ON \
+  -DBUILD_EXAMPLES=ON .. \
+  -DCMAKE_INSTALL_PREFIX=/usr/local \
+  -DOPENCV_EXTRA_MODULES_PATH="$(opencv)_contrib/modules/"
+
+SYSLIB := $(lastword $(wildcard /usr/lib /usrlib32 /usr/lib64))
+CVLIBS := $(opencv_prefix)/lib
+LFLAGS += -L$(CVLIBS) $(patsubst $(CVLIBS)/lib%.so,-l%,$(wildcard $(CVLIBS)/libopencv_*.so))
+LFLAGS += $(patsubst $(SYSLIB)/lib%.so,-l%,$(wildcard $(SYSLIB)/lib{Half,Imath,Ilm,Iex}*.so))
+static_libs :=
+static_incs :=
+else ifeq ($(bld),sys)
+$(opencv)/build:
+
+SYSLIB := $(lastword $(wildcard /usr/lib /usrlib32 /usr/lib64))
+LFLAGS += $(patsubst $(SYSLIB)/lib%.so,-l%,$(wildcard $(SYSLIB)/libopencv_*.so))
+LFLAGS += $(patsubst $(SYSLIB)/lib%.so,-l%,$(wildcard $(SYSLIB)/lib{Half,Imath,Ilm,Iex}*.so))
+static_libs :=
+static_incs :=
+else
+$(error bld not sta/dyn/sys)
+endif
+
+$(opencv).sta $(opencv).dyn: $(opencv)/build
+       cd $(opencv)/build && make $(jobs) 2>&1 | tee log
+       cd $(opencv)/build && make install DESTDIR=`pwd`
+       touch $@
+
+$(opencv).sys:
+       touch $@
+
+mrclean:       clean
+       rm -rf $(blddir)/opencv* $(srcdir)/$(opencv_tar)
+
+opencv:        $(opencv).$(bld)
+
index e03d3c4d744bc007e64e6dfc1d98ee4e205122c1..5615a62efbd49413e26dc35f8f71e97a35927ea6 100644 (file)
@@ -45,8 +45,7 @@ $(PLUGIN_DIR)/%/$(PLUGIN).png:        %.png
        $(if $(wildcard $(dir $@)),,mkdir -p $(dir $@))
        cp -a $< $@
 
-clean:
-       find \( -name core -o -name '*.o' -o -name '*.a' \) -exec rm -f {} \;
+clean::
        rm -f $(OUTPUT)
        rm -rf $(OBJDIR)
 
index 428cda21f298b9ade6ce14441b0b67e09f2cc12b..9a663219292448862887789db3042a4f76636d23 100644 (file)
@@ -40,7 +40,7 @@ video_tools := blur decimate delayvideo denoisemjpeg denoisevideo downsample \
        motion2 motionblur motion motion-cv motion-hv motion51 \
        overlay radialblur reframe reframert reroute reversevideo \
        rumbler seltempavg sharpen svg titler timeavg timefront \
-       unsharp videoscope wave zoomblur
+       unsharp videoscope wave zoomblur findobject
 
 plugin_dirs += blending
 blending := crikey chromakeyhsv chromakey diffkey
index 5815bc199167817ca94491254bd723e686011e91..cf72e5ac70b95d9bdb3100189616cf2e86df3571 100644 (file)
@@ -4,6 +4,9 @@ include $(TOPDIR)/global_config
 ifeq ($(WANT_DVB), yes)
 LIVEDVB = liveaudio livevideo
 endif
+ifneq ($(WANT_FINDOBJECT), no)
+FINDOBJECT = findobject
+endif
 
 # burn must come before any other effecttv plugin
 # colors must come before any plugin
@@ -51,6 +54,7 @@ DIRS = \
        echo \
        echocancel \
        fieldframe \
+       $(FINDOBJECT) \
        flash \
        flip \
        framefield \
index d518f01a09b3629998c812642625c7e232bda432..7d37d82d6489fe6da4b7c58b821ab496db9c3aeb 100644 (file)
@@ -1,37 +1,21 @@
-include ../../plugin_defs
+default: all
 
-OPENCV_DIR := $(shell cd ../../thirdparty/OpenCV*; pwd)
+TOPDIR?=../..
+include $(TOPDIR)/plugin_defs
+
+PLUGIN = findobject
 
 OBJS := \
        $(OBJDIR)/findobject.o \
        $(OBJDIR)/findobjectwindow.o \
-       $(OBJDIR)/surfscan.o \
-
-ifeq ($(STATIC_LIBRARIES), y)
-LFLAGS += $(OPENCV_DIR)/libopencv.a
-else
-LFLAGS += -lopencv_video
-LFLAGS += -lopencv_legacy
-endif
-
-CFLAGS += -I$(OPENCV_DIR)/modules/core/include/ \
-       -I$(OPENCV_DIR)/modules/features2d/include/ \
-       -I$(OPENCV_DIR)/modules/calib3d/include/ \
-       -I$(OPENCV_DIR)/modules/flann/include/ \
-       -I$(OPENCV_DIR)/modules/imgproc/include/ \
-       -I$(OPENCV_DIR)/modules/legacy/include/ \
-       -I$(OPENCV_DIR)/modules/highgui/include/ \
-       -I$(OPENCV_DIR)/modules/objdetect/include/ \
-       -I$(OPENCV_DIR)/modules/video/include/
 
-PLUGIN = findobject
+want_var:=$(WANT_FINDOBJECT)
+include $(TOPDIR)/opencv_build
+include $(TOPDIR)/plugin_config
 
-include ../../plugin_config
+all:   opencv
+       +make $(OUTPUT)
 
 $(OBJDIR)/findobject.o: findobject.C findobject.h findobjectwindow.h
 $(OBJDIR)/findobjectwindow.o: findobjectwindow.C findobject.h findobjectwindow.h
-$(OBJDIR)/surfscan.o: surfscan.C
-
-
-
 
index fb9b9f6d0b88e421b0a651cd50726c40f99d6d26..c19226fed19fb247e647aed13dda4af98b8141e1 100644 (file)
  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
 
-
-// This is mainly a test for object tracking
-
 #include "affine.h"
 #include "cicolors.h"
 #include "clip.h"
 #include "filexml.h"
-#include "keyframe.h"
 #include "language.h"
 #include "findobject.h"
 #include "findobjectwindow.h"
 #include "mutex.h"
 #include "overlayframe.h"
-#include "surfscan.h"
-#include "transportque.h"
-
-// Needed with OpenCV version 2.4.8
-#include "opencv2/legacy/legacy.hpp"
-#include "opencv2/legacy/compat.hpp"
-
-#include "opencv2/video/tracking.hpp"
-#include "opencv2/video/background_segm.hpp"
-
 
 #include <errno.h>
+#include <exception>
 #include <unistd.h>
 
 REGISTER_PLUGIN(FindObjectMain)
 
-
-
 FindObjectConfig::FindObjectConfig()
 {
-       global_range_w = 5;
-       global_range_h = 5;
-       draw_keypoints = 1;
-       draw_border = 1;
-       replace_object = 0;
-       draw_object_border = 1;
-       global_block_w = MIN_BLOCK;
-       global_block_h = MIN_BLOCK;
-       block_x = 50;
-       block_y = 50;
-       object_layer = 0;
-       replace_layer = 1;
-       scene_layer = 2;
        algorithm = NO_ALGORITHM;
-       vmin = 10;
-       vmax = 256;
-       smin = 30;
+       use_flann = 1;
+       draw_keypoints = 0;
+       draw_border = 0;
+       replace_object = 0;
+       draw_object_border = 0;
+       object_x = 50;  object_y = 50;
+       object_w = 100; object_h = 100;
+       scene_x = 50;   scene_y = 50;
+       scene_w = 100;  scene_h = 100;
+       scene_layer = 0;
+       object_layer = 1;
+       replace_layer = 2;
        blend = 100;
 }
 
 void FindObjectConfig::boundaries()
 {
-       CLAMP(global_range_w, MIN_RADIUS, MAX_RADIUS);
-       CLAMP(global_range_h, MIN_RADIUS, MAX_RADIUS);
-       CLAMP(global_block_w, MIN_BLOCK, MAX_BLOCK);
-       CLAMP(global_block_h, MIN_BLOCK, MAX_BLOCK);
-       CLAMP(block_x, 0, 100);
-       CLAMP(block_y, 0, 100);
-       CLAMP(object_layer, MIN_LAYER, MAX_LAYER);
-       CLAMP(replace_layer, MIN_LAYER, MAX_LAYER);
-       CLAMP(scene_layer, MIN_LAYER, MAX_LAYER);
-       CLAMP(vmin, MIN_CAMSHIFT, MAX_CAMSHIFT);
-       CLAMP(vmax, MIN_CAMSHIFT, MAX_CAMSHIFT);
-       CLAMP(smin, MIN_CAMSHIFT, MAX_CAMSHIFT);
-       CLAMP(blend, MIN_BLEND, MAX_BLEND);
+       bclamp(object_x, 0, 100);  bclamp(object_y, 0, 100);
+       bclamp(object_w, 0, 100);  bclamp(object_h, 0, 100);
+       bclamp(scene_x, 0, 100);   bclamp(scene_y, 0, 100);
+       bclamp(scene_w, 0, 100);   bclamp(scene_h, 0, 100);
+       bclamp(object_layer, MIN_LAYER, MAX_LAYER);
+       bclamp(replace_layer, MIN_LAYER, MAX_LAYER);
+       bclamp(scene_layer, MIN_LAYER, MAX_LAYER);
+       bclamp(blend, MIN_BLEND, MAX_BLEND);
 }
 
 int FindObjectConfig::equivalent(FindObjectConfig &that)
 {
        int result =
-               global_range_w == that.global_range_w &&
-               global_range_h == that.global_range_h &&
+               algorithm == that.algorithm &&
+               use_flann == that.use_flann &&
                draw_keypoints == that.draw_keypoints &&
                draw_border == that.draw_border &&
                replace_object == that.replace_object &&
                draw_object_border == that.draw_object_border &&
-               global_block_w == that.global_block_w &&
-               global_block_h == that.global_block_h &&
-               block_x == that.block_x &&
-               block_y == that.block_y &&
+               object_x == that.object_x && object_y == that.object_y &&
+               object_w == that.object_w && object_h == that.object_h &&
+               scene_x == that.scene_x && scene_y == that.scene_y &&
+               scene_w == that.scene_w && scene_h == that.scene_h &&
                object_layer == that.object_layer &&
                replace_layer == that.replace_layer &&
                scene_layer == that.scene_layer &&
-               algorithm == that.algorithm &&
-               vmin == that.vmin &&
-               vmax == that.vmax &&
-               smin == that.smin &&
                blend == that.blend;
-       return result;
+        return result;
 }
 
 void FindObjectConfig::copy_from(FindObjectConfig &that)
 {
-       global_range_w = that.global_range_w;
-       global_range_h = that.global_range_h;
+       algorithm = that.algorithm;
+       use_flann = that.use_flann;
        draw_keypoints = that.draw_keypoints;
        draw_border = that.draw_border;
        replace_object = that.replace_object;
        draw_object_border = that.draw_object_border;
-       global_block_w = that.global_block_w;
-       global_block_h = that.global_block_h;
-       block_x = that.block_x;
-       block_y = that.block_y;
+       object_x = that.object_x;  object_y = that.object_y;
+       object_w = that.object_w;  object_h = that.object_h;
+       scene_x = that.scene_x;    scene_y = that.scene_y;
+       scene_w = that.scene_w;    scene_h = that.scene_h;
        object_layer = that.object_layer;
        replace_layer = that.replace_layer;
        scene_layer = that.scene_layer;
-       algorithm = that.algorithm;
-       vmin = that.vmin;
-       vmax = that.vmax;
-       smin = that.smin;
        blend = that.blend;
 }
 
-void FindObjectConfig::interpolate(FindObjectConfig &prev,
-       FindObjectConfig &next,
-       int64_t prev_frame,
-       int64_t next_frame,
-       int64_t current_frame)
+void FindObjectConfig::interpolate(FindObjectConfig &prev, FindObjectConfig &next,
+       int64_t prev_frame, int64_t next_frame, int64_t current_frame)
 {
        copy_from(prev);
 }
 
 
-
-
-
-
-
-
 FindObjectMain::FindObjectMain(PluginServer *server)
  : PluginVClient(server)
 {
-       bzero(&blob_param, sizeof(CvBlobTrackerAutoParam1));
-       blob_pTracker = 0;
+        affine = 0;
+        overlayer = 0;
+
+       cvmodel = BC_RGB888;
+       w = h = 0;
+        object = scene = replace = 0;
+       object_x = object_y = 0;
+       object_w = object_h = 0;
+       scene_x = scene_y = 0;
+       scene_w = scene_h = 0;
+       object_layer = 0;
+       scene_layer = 1;
+       replace_layer = 2;
 
+       border_x1 = 0;  border_y1 = 0;
+       border_x2 = 0;  border_y2 = 0;
+       border_x3 = 0;  border_y3 = 0;
+       border_x4 = 0;  border_y4 = 0;
 
-       object_image = 0;
-       prev_object = 0;
-       scene_image = 0;
-       object_image_w = 0;
-       object_image_h = 0;
-       scene_image_w = 0;
-       scene_image_h = 0;
-       storage = 0;
-       object_keypoints = 0;
-       object_descriptors = 0;
-       scene_keypoints = 0;
-       scene_descriptors = 0;
-       affine = 0;
-       temp = 0;
-       overlayer = 0;
-       init_border = 1;
+       obj_x1 = 0;     obj_y1 = 0;
+       obj_x2 = 0;     obj_y2 = 0;
+       obj_x3 = 0;     obj_y3 = 0;
+       obj_x4 = 0;     obj_y4 = 0;
+
+        init_border = 1;
 }
 
 FindObjectMain::~FindObjectMain()
 {
-// This releases all the arrays
-       if(storage) cvReleaseMemStorage(&storage);
-       if(object_image) cvReleaseImage(&object_image);
-       if(scene_image) cvReleaseImage(&scene_image);
-       if(prev_object) delete [] prev_object;
        delete affine;
-       delete temp;
        delete overlayer;
-
-    if(blob_param.pBT) cvReleaseBlobTracker(&blob_param.pBT);
-    if(blob_param.pBD) cvReleaseBlobDetector(&blob_param.pBD);
-    if(blob_param.pBTGen) cvReleaseBlobTrackGen(&blob_param.pBTGen);
-    if(blob_param.pBTA) cvReleaseBlobTrackAnalysis(&blob_param.pBTA);
-    if(blob_param.pFG) cvReleaseFGDetector(&blob_param.pFG);
-    if(blob_pTracker) cvReleaseBlobTrackerAuto(&blob_pTracker);
-
 }
 
 const char* FindObjectMain::plugin_title() { return _("Find Object"); }
 int FindObjectMain::is_realtime() { return 1; }
 int FindObjectMain::is_multichannel() { return 1; }
 
-
 NEW_WINDOW_MACRO(FindObjectMain, FindObjectWindow)
-
 LOAD_CONFIGURATION_MACRO(FindObjectMain, FindObjectConfig)
 
-
-
 void FindObjectMain::update_gui()
 {
-       if(thread)
-       {
-               if(load_configuration())
-               {
-                       thread->window->lock_window("FindObjectMain::update_gui");
-
-                       char string[BCTEXTLEN];
-
-                       ((FindObjectWindow*)thread->window)->global_range_w->update(config.global_range_w);
-                       ((FindObjectWindow*)thread->window)->global_range_h->update(config.global_range_h);
-                       ((FindObjectWindow*)thread->window)->global_block_w->update(config.global_block_w);
-                       ((FindObjectWindow*)thread->window)->global_block_h->update(config.global_block_h);
-                       ((FindObjectWindow*)thread->window)->block_x->update(config.block_x);
-                       ((FindObjectWindow*)thread->window)->block_y->update(config.block_y);
-                       ((FindObjectWindow*)thread->window)->block_x_text->update((float)config.block_x);
-                       ((FindObjectWindow*)thread->window)->block_y_text->update((float)config.block_y);
-
-                       ((FindObjectWindow*)thread->window)->draw_keypoints->update(config.draw_keypoints);
-                       ((FindObjectWindow*)thread->window)->draw_border->update(config.draw_border);
-                       ((FindObjectWindow*)thread->window)->replace_object->update(config.replace_object);
-                       ((FindObjectWindow*)thread->window)->draw_object_border->update(config.draw_object_border);
-
-
-                       ((FindObjectWindow*)thread->window)->object_layer->update(
-                               (int64_t)config.object_layer);
-                       ((FindObjectWindow*)thread->window)->replace_layer->update(
-                               (int64_t)config.replace_layer);
-                       ((FindObjectWindow*)thread->window)->scene_layer->update(
-                               (int64_t)config.scene_layer);
-                       ((FindObjectWindow*)thread->window)->algorithm->set_text(
-                               FindObjectAlgorithm::to_text(config.algorithm));
-
-                       ((FindObjectWindow*)thread->window)->vmin->update(
-                               (int64_t)config.vmin);
-                       ((FindObjectWindow*)thread->window)->vmax->update(
-                               (int64_t)config.vmax);
-                       ((FindObjectWindow*)thread->window)->smin->update(
-                               (int64_t)config.smin);
-                       ((FindObjectWindow*)thread->window)->blend->update(
-                               (int64_t)config.blend);
-
-                       ((FindObjectWindow*)thread->window)->flush();
-                       thread->window->unlock_window();
-               }
-// printf("FindObjectMain::update_gui %d %d %d %d\n",
-// __LINE__,
-// config.mode1,
-// config.mode2,
-// config.mode3);
-       }
+       if( !thread ) return;
+       if( !load_configuration() ) return;
+       FindObjectWindow *window = (FindObjectWindow*)thread->window;
+       window->lock_window("FindObjectMain::update_gui");
+       window->algorithm->set_text(FindObjectAlgorithm::to_text(config.algorithm));
+       window->use_flann->update(config.use_flann);
+       window->object_x->update(config.object_x);
+       window->object_x_text->update((float)config.object_x);
+       window->object_y->update(config.object_y);
+       window->object_y_text->update((float)config.object_y);
+       window->object_w->update(config.object_w);
+       window->object_w_text->update((float)config.object_w);
+       window->object_h->update(config.object_h);
+       window->object_h_text->update((float)config.object_h);
+       window->scene_x->update(config.scene_x);
+       window->scene_x_text->update((float)config.scene_x);
+       window->scene_y->update(config.scene_y);
+       window->scene_y_text->update((float)config.scene_y);
+       window->scene_w->update(config.scene_w);
+       window->scene_w_text->update((float)config.scene_w);
+       window->scene_h->update(config.scene_h);
+       window->scene_h_text->update((float)config.scene_h);
+       window->draw_keypoints->update(config.draw_keypoints);
+       window->draw_border->update(config.draw_border);
+       window->replace_object->update(config.replace_object);
+       window->draw_object_border->update(config.draw_object_border);
+       window->object_layer->update( (int64_t)config.object_layer);
+       window->replace_layer->update( (int64_t)config.replace_layer);
+       window->scene_layer->update( (int64_t)config.scene_layer);
+       window->blend->update( (int64_t)config.blend);
+       window->flush();
+       window->unlock_window();
 }
 
-
-
-
 void FindObjectMain::save_data(KeyFrame *keyframe)
 {
        FileXML output;
@@ -271,13 +195,16 @@ void FindObjectMain::save_data(KeyFrame *keyframe)
 // cause data to be stored directly in text
        output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
        output.tag.set_title("FINDOBJECT");
-
-       output.tag.set_property("GLOBAL_BLOCK_W", config.global_block_w);
-       output.tag.set_property("GLOBAL_BLOCK_H", config.global_block_h);
-       output.tag.set_property("BLOCK_X", config.block_x);
-       output.tag.set_property("BLOCK_Y", config.block_y);
-       output.tag.set_property("GLOBAL_RANGE_W", config.global_range_w);
-       output.tag.set_property("GLOBAL_RANGE_H", config.global_range_h);
+       output.tag.set_property("ALGORITHM", config.algorithm);
+       output.tag.set_property("USE_FLANN", config.use_flann);
+       output.tag.set_property("OBJECT_X", config.object_x);
+       output.tag.set_property("OBJECT_Y", config.object_y);
+       output.tag.set_property("OBJECT_W", config.object_w);
+       output.tag.set_property("OBJECT_H", config.object_h);
+       output.tag.set_property("SCENE_X", config.scene_x);
+       output.tag.set_property("SCENE_Y", config.scene_y);
+       output.tag.set_property("SCENE_W", config.scene_w);
+       output.tag.set_property("SCENE_H", config.scene_h);
        output.tag.set_property("DRAW_KEYPOINTS", config.draw_keypoints);
        output.tag.set_property("DRAW_BORDER", config.draw_border);
        output.tag.set_property("REPLACE_OBJECT", config.replace_object);
@@ -285,10 +212,6 @@ void FindObjectMain::save_data(KeyFrame *keyframe)
        output.tag.set_property("OBJECT_LAYER", config.object_layer);
        output.tag.set_property("REPLACE_LAYER", config.replace_layer);
        output.tag.set_property("SCENE_LAYER", config.scene_layer);
-       output.tag.set_property("ALGORITHM", config.algorithm);
-       output.tag.set_property("VMIN", config.vmin);
-       output.tag.set_property("VMAX", config.vmax);
-       output.tag.set_property("SMIN", config.smin);
        output.tag.set_property("BLEND", config.blend);
        output.append_tag();
        output.tag.set_title("/FINDOBJECT");
@@ -305,1115 +228,374 @@ void FindObjectMain::read_data(KeyFrame *keyframe)
 
        int result = 0;
 
-       while(!result)
-       {
-               result = input.read_tag();
-
-               if(!result)
-               {
-                       if(input.tag.title_is("FINDOBJECT"))
-                       {
-                               config.global_block_w = input.tag.get_property("GLOBAL_BLOCK_W", config.global_block_w);
-                               config.global_block_h = input.tag.get_property("GLOBAL_BLOCK_H", config.global_block_h);
-                               config.block_x = input.tag.get_property("BLOCK_X", config.block_x);
-                               config.block_y = input.tag.get_property("BLOCK_Y", config.block_y);
-                               config.global_range_w = input.tag.get_property("GLOBAL_RANGE_W", config.global_range_w);
-                               config.global_range_h = input.tag.get_property("GLOBAL_RANGE_H", config.global_range_h);
-                               config.draw_keypoints = input.tag.get_property("DRAW_KEYPOINTS", config.draw_keypoints);
-                               config.draw_border = input.tag.get_property("DRAW_BORDER", config.draw_border);
-                               config.replace_object = input.tag.get_property("REPLACE_OBJECT", config.replace_object);
-                               config.draw_object_border = input.tag.get_property("DRAW_OBJECT_BORDER", config.draw_object_border);
-                               config.object_layer = input.tag.get_property("OBJECT_LAYER", config.object_layer);
-                               config.replace_layer = input.tag.get_property("REPLACE_LAYER", config.replace_layer);
-                               config.scene_layer = input.tag.get_property("SCENE_LAYER", config.scene_layer);
-                               config.algorithm = input.tag.get_property("ALGORITHM", config.algorithm);
-                               config.vmin = input.tag.get_property("VMIN", config.vmin);
-                               config.vmax = input.tag.get_property("VMAX", config.vmax);
-                               config.smin = input.tag.get_property("SMIN", config.smin);
-                               config.blend = input.tag.get_property("BLEND", config.blend);
-                       }
+       while( !(result = input.read_tag()) ) {
+               if( input.tag.title_is("FINDOBJECT") ) {
+                       config.algorithm = input.tag.get_property("ALGORITHM", config.algorithm);
+                       config.use_flann = input.tag.get_property("USE_FLANN", config.use_flann);
+                       config.object_x = input.tag.get_property("OBJECT_X", config.object_x);
+                       config.object_y = input.tag.get_property("OBJECT_Y", config.object_y);
+                       config.object_w = input.tag.get_property("OBJECT_W", config.object_w);
+                       config.object_h = input.tag.get_property("OBJECT_H", config.object_h);
+                       config.scene_x = input.tag.get_property("SCENE_X", config.scene_x);
+                       config.scene_y = input.tag.get_property("SCENE_Y", config.scene_y);
+                       config.scene_w = input.tag.get_property("SCENE_W", config.scene_w);
+                       config.scene_h = input.tag.get_property("SCENE_H", config.scene_h);
+                       config.draw_keypoints = input.tag.get_property("DRAW_KEYPOINTS", config.draw_keypoints);
+                       config.draw_border = input.tag.get_property("DRAW_BORDER", config.draw_border);
+                       config.replace_object = input.tag.get_property("REPLACE_OBJECT", config.replace_object);
+                       config.draw_object_border = input.tag.get_property("DRAW_OBJECT_BORDER", config.draw_object_border);
+                       config.object_layer = input.tag.get_property("OBJECT_LAYER", config.object_layer);
+                       config.replace_layer = input.tag.get_property("REPLACE_LAYER", config.replace_layer);
+                       config.scene_layer = input.tag.get_property("SCENE_LAYER", config.scene_layer);
+                       config.blend = input.tag.get_property("BLEND", config.blend);
                }
        }
+
        config.boundaries();
 }
 
-
-
-
-
-void FindObjectMain::draw_pixel(VFrame *frame, int x, int y)
+void FindObjectMain::draw_line(VFrame *vframe, int x1, int y1, int x2, int y2)
 {
-       if(!(x >= 0 && y >= 0 && x < frame->get_w() && y < frame->get_h())) return;
+       vframe->draw_line(x1, y1, x2, y2);
+}
 
-#define DRAW_PIXEL(x, y, components, do_yuv, max, type) \
-{ \
-       type **rows = (type**)frame->get_rows(); \
-       rows[y][x * components] = max - rows[y][x * components]; \
-       if(!do_yuv) \
-       { \
-               rows[y][x * components + 1] = max - rows[y][x * components + 1]; \
-               rows[y][x * components + 2] = max - rows[y][x * components + 2]; \
-       } \
-       else \
-       { \
-               rows[y][x * components + 1] = (max / 2 + 1) - rows[y][x * components + 1]; \
-               rows[y][x * components + 2] = (max / 2 + 1) - rows[y][x * components + 2]; \
-       } \
-       if(components == 4) \
-               rows[y][x * components + 3] = max; \
+void FindObjectMain::draw_rect(VFrame *vframe, int x1, int y1, int x2, int y2)
+{
+       draw_line(vframe, x1, y1, x2, y1);
+       draw_line(vframe, x2, y1 + 1, x2, y2);
+       draw_line(vframe, x2 - 1, y2, x1, y2);
+       draw_line(vframe, x1, y2 - 1, x1, y1 + 1);
 }
 
+void FindObjectMain::draw_circle(VFrame *vframe, int x, int y, int r)
+{
+       int x1 = x-r, x2 = x+r;
+       int y1 = y-r, y2 = y+r;
+       vframe->draw_smooth(x1,y, x1,y1, x,y1);
+       vframe->draw_smooth(x,y1, x2,y1, x2,y);
+       vframe->draw_smooth(x2,y, x2,y2, x,y2);
+       vframe->draw_smooth(x,y2, x1,y2, x1,y);
+}
 
-       switch(frame->get_color_model())
-       {
-               case BC_RGB888:
-                       DRAW_PIXEL(x, y, 3, 0, 0xff, unsigned char);
-                       break;
-               case BC_RGBA8888:
-                       DRAW_PIXEL(x, y, 4, 0, 0xff, unsigned char);
-                       break;
-               case BC_RGB_FLOAT:
-                       DRAW_PIXEL(x, y, 3, 0, 1.0, float);
-                       break;
-               case BC_RGBA_FLOAT:
-                       DRAW_PIXEL(x, y, 4, 0, 1.0, float);
-                       break;
-               case BC_YUV888:
-                       DRAW_PIXEL(x, y, 3, 1, 0xff, unsigned char);
-                       break;
-               case BC_YUVA8888:
-                       DRAW_PIXEL(x, y, 4, 1, 0xff, unsigned char);
-                       break;
-               case BC_RGB161616:
-                       DRAW_PIXEL(x, y, 3, 0, 0xffff, uint16_t);
-                       break;
-               case BC_YUV161616:
-                       DRAW_PIXEL(x, y, 3, 1, 0xffff, uint16_t);
-                       break;
-               case BC_RGBA16161616:
-                       DRAW_PIXEL(x, y, 4, 0, 0xffff, uint16_t);
-                       break;
-               case BC_YUVA16161616:
-                       DRAW_PIXEL(x, y, 4, 1, 0xffff, uint16_t);
-                       break;
+void FindObjectMain::filter_matches(ptV &p1, ptV &p2, double ratio)
+{
+       DMatches::iterator it;
+       for( it=pairs.begin(); it!=pairs.end(); ++it ) { 
+               DMatchV &m = *it;
+               if( m.size() == 2 && m[0].distance < m[1].distance*ratio ) {
+                       p1.push_back(obj_keypts[m[0].queryIdx].pt);
+                       p2.push_back(scn_keypts[m[0].trainIdx].pt);
+               }
        }
 }
 
-
-void FindObjectMain::draw_line(VFrame *frame, int x1, int y1, int x2, int y2)
+void FindObjectMain::to_mat(Mat &mat, int mcols, int mrows,
+       VFrame *inp, int ix,int iy, BC_CModel mcolor_model)
 {
-       int w = labs(x2 - x1);
-       int h = labs(y2 - y1);
-//printf("FindObjectMain::draw_line 1 %d %d %d %d\n", x1, y1, x2, y2);
-
-       if(!w && !h)
-       {
-               draw_pixel(frame, x1, y1);
-       }
-       else
-       if(w > h)
-       {
-// Flip coordinates so x1 < x2
-               if(x2 < x1)
-               {
-                       y2 ^= y1;
-                       y1 ^= y2;
-                       y2 ^= y1;
-                       x1 ^= x2;
-                       x2 ^= x1;
-                       x1 ^= x2;
-               }
-               int numerator = y2 - y1;
-               int denominator = x2 - x1;
-               for(int i = x1; i <= x2; i++)
-               {
-                       int y = y1 + (int64_t)(i - x1) * (int64_t)numerator / (int64_t)denominator;
-                       draw_pixel(frame, i, y);
-               }
+       int mcomp = BC_CModels::components(mcolor_model);
+       int mbpp = BC_CModels::calculate_pixelsize(mcolor_model);
+       int psz = mbpp / mcomp;
+       int mdepth = psz < 2 ? CV_8U : CV_16U;
+       if( mat.dims != 2 || mat.depth() != mdepth || mat.channels() != mcomp ||
+           mat.cols != mcols || mat.rows != mrows ) {
+               mat.release();
        }
-       else
-       {
-// Flip coordinates so y1 < y2
-               if(y2 < y1)
-               {
-                       y2 ^= y1;
-                       y1 ^= y2;
-                       y2 ^= y1;
-                       x1 ^= x2;
-                       x2 ^= x1;
-                       x1 ^= x2;
-               }
-               int numerator = x2 - x1;
-               int denominator = y2 - y1;
-               for(int i = y1; i <= y2; i++)
-               {
-                       int x = x1 + (int64_t)(i - y1) * (int64_t)numerator / (int64_t)denominator;
-                       draw_pixel(frame, x, i);
-               }
+       if( mat.empty() ) {
+               int type = CV_MAKETYPE(mdepth, mcomp);
+               mat.create(mrows, mcols, type);
        }
-//printf("FindObjectMain::draw_line 2\n");
+       uint8_t *mat_rows[mrows];
+       for( int y=0; y<mrows; ++y ) mat_rows[y] = mat.ptr(y);
+       uint8_t **inp_rows = inp->get_rows();
+       int ibpl = inp->get_bytes_per_line(), obpl = mcols * mbpp;
+       int icolor_model = inp->get_color_model();
+       BC_CModels::transfer(mat_rows, mcolor_model, 0,0, mcols,mrows, obpl,
+               inp_rows, icolor_model, ix,iy, mcols,mrows, ibpl, 0);
+//     VFrame vfrm(mat_rows[0], -1, mcols,mrows, mcolor_model, mat_rows[1]-mat_rows[0]);
+//     static int vfrm_no = 0; char vfn[64]; sprintf(vfn,"/tmp/dat/%06d.png", vfrm_no++);
+//     vfrm.write_png(vfn);
 }
 
-void FindObjectMain::draw_rect(VFrame *frame, int x1, int y1, int x2, int y2)
+void FindObjectMain::detect(Mat &mat, KeyPointV &keypts,Mat &descrs)
 {
-       draw_line(frame, x1, y1, x2, y1);
-       draw_line(frame, x2, y1 + 1, x2, y2);
-       draw_line(frame, x2 - 1, y2, x1, y2);
-       draw_line(frame, x1, y2 - 1, x1, y1 + 1);
+       keypts.clear();
+       descrs.release();
+       try {
+               detector->detectAndCompute(mat, noArray(), keypts, descrs);
+       } catch(std::exception e) { printf(_("detector exception: %s\n"), e.what()); }
 }
 
-
-
-// Convert to greyscale & crop
-void FindObjectMain::grey_crop(unsigned char *dst,
-       VFrame *src,
-       int x1,
-       int y1,
-       int x2,
-       int y2,
-       int dst_w,
-       int dst_h)
+void FindObjectMain::match()
 {
-// Dimensions of dst frame
-       int w = x2 - x1;
-       int h = y2 - y1;
-
-       bzero(dst, dst_w * dst_h);
-
-//printf("FindObjectMain::grey_crop %d %d %d\n", __LINE__, w, h);
-       for(int i = 0; i < h; i++)
-       {
-
-#define RGB_TO_VALUE(r, g, b) \
-((r) * R_TO_Y + (g) * G_TO_Y + (b) * B_TO_Y)
-
-
-#define CONVERT(in_type, max, components, is_yuv) \
-{ \
-       in_type *input = ((in_type*)src->get_rows()[i + y1]) + x1 * components; \
-       unsigned char *output = dst + i * dst_w; \
- \
-       for(int j = 0; j < w; j++) \
-       { \
-/* Y channel only */ \
-               if(is_yuv) \
-               { \
-                       *output = *input; \
-               } \
-/* RGB */ \
-               else \
-               { \
-                       float r = (float)input[0] / max; \
-                       float g = (float)input[1] / max; \
-                       float b = (float)input[2] / max; \
-                       *output = RGB_TO_VALUE(r, g, b); \
-               } \
- \
-               input += components; \
-               output++; \
-       } \
+       pairs.clear();
+       try {
+               matcher->knnMatch(obj_descrs, scn_descrs, pairs, 2);
+       } catch(std::exception e) { printf(_("match execption: %s\n"), e.what()); }
 }
-               switch(src->get_color_model())
-               {
-                       case BC_RGB888:
-                       {
-                               CONVERT(unsigned char, 0xff, 3, 0)
-                               break;
-                       }
-
-                       case BC_RGBA8888:
-                       {
-                               CONVERT(unsigned char, 0xff, 4, 0)
-                               break;
-                       }
-
-                       case BC_RGB_FLOAT:
-                       {
-                               CONVERT(float, 1.0, 3, 0)
-                               break;
-                       }
-
-                       case BC_RGBA_FLOAT:
-                       {
-                               CONVERT(float, 1.0, 4, 0)
-                               break;
-                       }
 
-                       case BC_YUV888:
-                       {
-                               CONVERT(unsigned char, 0xff, 3, 1)
-                               break;
-                       }
-
-                       case BC_YUVA8888:
-                       {
-                               CONVERT(unsigned char, 0xff, 4, 1)
-                               break;
-                       }
-               }
-       }
+Ptr<DescriptorMatcher> FindObjectMain::flann_kdtree_matcher()
+{ // trees=5
+       const Ptr<flann::IndexParams>& indexParams =
+               makePtr<flann::KDTreeIndexParams>(5);
+       const Ptr<flann::SearchParams>& searchParams =
+               makePtr<flann::SearchParams>();
+       return makePtr<FlannBasedMatcher>(indexParams, searchParams);
 }
-
-
-void FindObjectMain::process_surf()
+Ptr<DescriptorMatcher> FindObjectMain::flann_lshidx_matcher()
+{ // table_number = 6#12, key_size = 12#20, multi_probe_level = 1#2
+       const Ptr<flann::IndexParams>& indexParams =
+               makePtr<flann::LshIndexParams>(6, 12, 1);
+       const Ptr<flann::SearchParams>& searchParams =
+               makePtr<flann::SearchParams>();
+       return makePtr<FlannBasedMatcher>(indexParams, searchParams);
+}
+Ptr<DescriptorMatcher> FindObjectMain::bf_matcher_norm_l2()
 {
-
-       if(!object_image)
-       {
-// Only does greyscale
-               object_image = cvCreateImage(
-                       cvSize(object_image_w, object_image_h),
-                       8,
-                       1);
-       }
-
-       if(!scene_image)
-       {
-// Only does greyscale
-               scene_image = cvCreateImage(
-                       cvSize(scene_image_w, scene_image_h),
-                       8,
-                       1);
-       }
-
-// Select only region with image size
-// Does this do anything?
-       cvSetImageROI( object_image, cvRect( 0, 0, object_w, object_h ) );
-       cvSetImageROI( scene_image, cvRect( 0, 0, scene_w, scene_h ) );
-
-       if(!prev_object) prev_object = new unsigned char[object_image_w * object_image_h];
-       memcpy(prev_object, object_image->imageData, object_image_w * object_image_h);
-       grey_crop((unsigned char*)scene_image->imageData,
-               get_input(scene_layer),
-               scene_x1,
-               scene_y1,
-               scene_x2,
-               scene_y2,
-               scene_image_w,
-               scene_image_h);
-
-
-       grey_crop((unsigned char*)object_image->imageData,
-               get_input(object_layer),
-               object_x1,
-               object_y1,
-               object_x2,
-               object_y2,
-               object_image_w,
-               object_image_h);
-
-
-       if(!storage) storage = cvCreateMemStorage(0);
-       CvSURFParams params = cvSURFParams(500, 1);
-
-
-//printf("FindObjectMain::process_surf %d\n", __LINE__);
-
-// Only compute keypoints if the image changed
-       if(memcmp(prev_object, object_image->imageData, object_image_w * object_image_h))
-       {
-               if(object_keypoints) cvClearSeq(object_keypoints);
-               if(object_descriptors) cvClearSeq(object_descriptors);
-               cvExtractSURF(object_image,
-                       0,
-                       &object_keypoints,
-                       &object_descriptors,
-                       storage,
-                       params,
-                       0);
-       }
-
-//printf("FindObjectMain::process_surf %d object keypoints=%d\n", __LINE__, object_keypoints->total);
-// Draw the keypoints
-//             for(int i = 0; i < object_keypoints->total; i++)
-//             {
-//             CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( object_keypoints, i );
-//                     int size = r1->size / 4;
-//                     draw_rect(frame[object_layer],
-//                             r1->pt.x + object_x1 - size,
-//                             r1->pt.y + object_y1 - size,
-//                             r1->pt.x + object_x1 + size,
-//                             r1->pt.y + object_y1 + size);
-//             }
-
-
-//printf("FindObjectMain::process_surf %d\n", __LINE__);
-
-// TODO: make the surf data persistent & check for image changes instead
-       if(scene_keypoints) cvClearSeq(scene_keypoints);
-       if(scene_descriptors) cvClearSeq(scene_descriptors);
-       cvExtractSURF(scene_image,
-               0,
-               &scene_keypoints,
-               &scene_descriptors,
-               storage,
-               params,
-               0);
-
-// Draw the keypoints
-//             for(int i = 0; i < scene_keypoints->total; i++)
-//             {
-//             CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( scene_keypoints, i );
-//                     int size = r1->size / 4;
-//                     draw_rect(frame[scene_layer],
-//                             r1->pt.x + scene_x1 - size,
-//                             r1->pt.y + scene_y1 - size,
-//                             r1->pt.x + scene_x1 + size,
-//                             r1->pt.y + scene_y1 + size);
-//             }
-
-// printf("FindObjectMain::process_surf %d %d %d scene keypoints=%d\n",
-// __LINE__,
-// scene_w,
-// scene_h,
-// scene_keypoints->total);
-
-       int *point_pairs = 0;
-       int total_pairs = 0;
-       CvPoint src_corners[4] =
-       {
-               { 0, 0 },
-               { object_w, 0 },
-               { object_w, object_h },
-               { 0, object_h }
-       };
-
-       CvPoint dst_corners[4] =
-       {
-               { 0, 0 },
-               { 0, 0 },
-               { 0, 0 },
-               { 0, 0 }
-       };
-
-//printf("FindObjectMain::process_surf %d\n", __LINE__);
-       if(scene_keypoints->total &&
-               object_keypoints->total &&
-                       locatePlanarObject(object_keypoints,
-                       object_descriptors,
-                       scene_keypoints,
-                       scene_descriptors,
-                       src_corners,
-                       dst_corners,
-                       &point_pairs,
-                       &total_pairs))
-       {
-
-
-
-
-
-// Draw keypoints in the scene & object layer
-               if(config.draw_keypoints)
-               {
-//printf("FindObjectMain::process_surf %d total pairs=%d\n", __LINE__, total_pairs);
-                       for(int i = 0; i < total_pairs; i++)
-                       {
-                       CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( object_keypoints, point_pairs[i * 2] );
-                       CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( scene_keypoints, point_pairs[i * 2 + 1] );
-
-
-                               int size = r2->size * 1.2 / 9 * 2;
-                               draw_rect(get_input(scene_layer),
-                                       r2->pt.x + scene_x1 - size,
-                                       r2->pt.y + scene_y1 - size,
-                                       r2->pt.x + scene_x1 + size,
-                                       r2->pt.y + scene_y1 + size);
-                               draw_rect(get_input(object_layer),
-                                       r1->pt.x + object_x1 - size,
-                                       r1->pt.y + object_y1 - size,
-                                       r1->pt.x + object_x1 + size,
-                                       r1->pt.y + object_y1 + size);
-                       }
-               }
-
-
-//printf("FindObjectMain::process_surf %d\n", __LINE__);
-// Get object outline in the scene layer
-               border_x1 = dst_corners[0].x + scene_x1;
-               border_y1 = dst_corners[0].y + scene_y1;
-               border_x2 = dst_corners[1].x + scene_x1;
-               border_y2 = dst_corners[1].y + scene_y1;
-               border_x3 = dst_corners[2].x + scene_x1;
-               border_y3 = dst_corners[2].y + scene_y1;
-               border_x4 = dst_corners[3].x + scene_x1;
-               border_y4 = dst_corners[3].y + scene_y1;
-//printf("FindObjectMain::process_surf %d\n", __LINE__);
-
-
-
-       }
-//printf("FindObjectMain::process_surf %d\n", __LINE__);
-
-
-
-// for(int i = 0; i < object_y2 - object_y1; i++)
-// {
-//     unsigned char *dst = get_input(object_layer)->get_rows()[i];
-//     unsigned char *src = (unsigned char*)object_image->imageData + i * (object_x2 - object_x1);
-//     for(int j = 0; j < object_x2 - object_x1; j++)
-//     {
-//             *dst++ = *src;
-//             *dst++ = 0x80;
-//             *dst++ = 0x80;
-//             src++;
-//     }
-// }
-
-
-// Frees the image structures
-       if(point_pairs) free(point_pairs);
+       return BFMatcher::create(NORM_L2);
 }
-
-
-
-void FindObjectMain::process_camshift()
+Ptr<DescriptorMatcher> FindObjectMain::bf_matcher_norm_hamming()
 {
-// Some user defined parameters
-       int vmin = config.vmin;
-       int vmax = config.vmax;
-       int smin = config.smin;
-       float hranges[] = { 0, 180 };
-       const float* phranges = hranges;
-
-
-// Create aligned, RGB images
-       if(!object_image)
-       {
-               object_image = cvCreateImage(
-                       cvSize(object_image_w, object_image_h),
-                       8,
-                       3);
-       }
-
-       if(!scene_image)
-       {
-               scene_image = cvCreateImage(
-                       cvSize(scene_image_w, scene_image_h),
-                       8,
-                       3);
-       }
-
-// Temporary row pointers
-       unsigned char **object_rows = new unsigned char*[object_image_h];
-       unsigned char **scene_rows = new unsigned char*[scene_image_h];
-       for(int i = 0; i < object_image_h; i++)
-       {
-               object_rows[i] = (unsigned char*)(object_image->imageData + i * object_image_w * 3);
-       }
-       for(int i = 0; i < scene_image_h; i++)
-       {
-               scene_rows[i] = (unsigned char*)(scene_image->imageData + i * scene_image_w * 3);
-       }
-
-// Transfer object & scene to RGB images for OpenCV
-       if(!prev_object) prev_object = new unsigned char[object_image_w * object_image_h * 3];
-// Back up old object image
-       memcpy(prev_object, object_image->imageData, object_image_w * object_image_h * 3);
-
-       BC_CModels::transfer(object_rows,
-               get_input(object_layer)->get_rows(),
-               0,
-               0,
-               0,
-               0,
-               0,
-               0,
-               object_x1,
-               object_y1,
-               object_w,
-               object_h,
-               0,
-               0,
-               object_w,
-               object_h,
-               get_input(object_layer)->get_color_model(),
-               BC_RGB888,
-               0,
-               0,
-               0);
-       BC_CModels::transfer(scene_rows,
-               get_input(scene_layer)->get_rows(),
-               0,
-               0,
-               0,
-               0,
-               0,
-               0,
-               scene_x1,
-               scene_y1,
-               scene_w,
-               scene_h,
-               0,
-               0,
-               scene_w,
-               scene_h,
-               get_input(scene_layer)->get_color_model(),
-               BC_RGB888,
-               0,
-               0,
-               0);
-
-       delete [] object_rows;
-       delete [] scene_rows;
-
-// from camshiftdemo.cpp
-// Compute new object
-       if(memcmp(prev_object,
-               object_image->imageData,
-               object_image_w * object_image_h * 3) ||
-               !hist.dims)
-       {
-               Mat image(object_image);
-               Mat hsv, hue, mask;
-               cvtColor(image, hsv, CV_RGB2HSV);
-       int _vmin = vmin, _vmax = vmax;
-//printf("FindObjectMain::process_camshift %d\n", __LINE__);
-
-       inRange(hsv,
-                       Scalar(0, smin, MIN(_vmin,_vmax)),
-               Scalar(180, 256, MAX(_vmin, _vmax)),
-                       mask);
-       int ch[] = { 0, 0 };
-       hue.create(hsv.size(), hsv.depth());
-       mixChannels(&hsv, 1, &hue, 1, ch, 1);
-
-               Rect selection = Rect(0, 0, object_w, object_h);
-               trackWindow = selection;
-               int hsize = 16;
-               Mat roi(hue, selection), maskroi(mask, selection);
-               calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
-               normalize(hist, hist, 0, 255, CV_MINMAX);
-       }
-
-
-// compute scene
-       Mat image(scene_image);
-       Mat hsv, hue, mask, backproj;
-       cvtColor(image, hsv, CV_RGB2HSV);
-    int _vmin = vmin, _vmax = vmax;
-
-    inRange(hsv,
-               Scalar(0, smin, MIN(_vmin,_vmax)),
-        Scalar(180, 256, MAX(_vmin, _vmax)),
-               mask);
-    int ch[] = {0, 0};
-    hue.create(hsv.size(), hsv.depth());
-    mixChannels(&hsv, 1, &hue, 1, ch, 1);
-
-//printf("FindObjectMain::process_camshift %d %d %d\n", __LINE__, hist.dims, hist.size[1]);
-       RotatedRect trackBox = RotatedRect(
-               Point2f((object_x1 + object_x2) / 2, (object_y1 + object_y2) / 2),
-               Size2f(object_w, object_h),
-               0);
-       trackWindow = Rect(0,
-               0,
-        scene_w,
-               scene_h);
-       if(hist.dims > 0)
-       {
-
-
-               calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
-               backproj &= mask;
-//printf("FindObjectMain::process_camshift %d\n", __LINE__);
-//             if(trackWindow.width <= 0 ||
-//                     trackWindow.height <= 0)
-//             {
-//                     trackWindow.width = object_w;
-//                     trackWindow.height = object_h;
-//             }
-
-               trackBox = CamShift(backproj,
-                       trackWindow,
-               TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ));
-//printf("FindObjectMain::process_camshift %d\n", __LINE__);
-
-
-//             if( trackWindow.area() <= 1 )
-//             {
-//             int cols = backproj.cols;
-//                     int rows = backproj.rows;
-//                     int r = (MIN(cols, rows) + 5) / 6;
-//             trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
-//                                trackWindow.x + r, trackWindow.y + r) &
-//                               Rect(0, 0, cols, rows);
-//             }
-       }
-// printf("FindObjectMain::process_camshift %d %d %d %d %d\n",
-// __LINE__,
-// trackWindow.x,
-// trackWindow.y,
-// trackWindow.width,
-// trackWindow.height);
-
-
-// Draw mask over scene
-       if(config.draw_keypoints)
-       {
-               for(int i = 0; i < scene_h; i++)
-               {
-                       switch(get_input(scene_layer)->get_color_model())
-                       {
-                               case BC_YUV888:
-                               {
-                                       unsigned char *input = backproj.data + i * scene_image_w;
-                                       unsigned char *output = get_input(scene_layer)->get_rows()[i + scene_y1] + scene_x1 * 3;
-                                       for(int j = 0; j < scene_w; j++)
-                                       {
-                                               output[0] = *input;
-                                               output[1] = 0x80;
-                                               output[2] = 0x80;
-                                               output += 3;
-                                               input++;
-                                       }
-                                       break;
-                               }
-                       }
-               }
-       }
-
-// Get object outline in the scene layer
-// printf("FindObjectMain::process_camshift %d %d %d %d %d %d\n",
-// __LINE__,
-// (int)trackBox.center.x,
-// (int)trackBox.center.y,
-// (int)trackBox.size.width,
-// (int)trackBox.size.height,
-// (int)trackBox.angle);
-       double angle = trackBox.angle * 2 * M_PI / 360;
-       double angle1 = atan2(-(double)trackBox.size.height / 2, -(double)trackBox.size.width / 2) + angle;
-       double angle2 = atan2(-(double)trackBox.size.height / 2, (double)trackBox.size.width / 2) + angle;
-       double angle3 = atan2((double)trackBox.size.height / 2, (double)trackBox.size.width / 2) + angle;
-       double angle4 = atan2((double)trackBox.size.height / 2, -(double)trackBox.size.width / 2) + angle;
-       double radius = sqrt(SQR(trackBox.size.height / 2) + SQR(trackBox.size.width / 2));
-       border_x1 = (int)(trackBox.center.x + cos(angle1) * radius) + scene_x1;
-       border_y1 = (int)(trackBox.center.y + sin(angle1) * radius) + scene_y1;
-       border_x2 = (int)(trackBox.center.x + cos(angle2) * radius) + scene_x1;
-       border_y2 = (int)(trackBox.center.y + sin(angle2) * radius) + scene_y1;
-       border_x3 = (int)(trackBox.center.x + cos(angle3) * radius) + scene_x1;
-       border_y3 = (int)(trackBox.center.y + sin(angle3) * radius) + scene_y1;
-       border_x4 = (int)(trackBox.center.x + cos(angle4) * radius) + scene_x1;
-       border_y4 = (int)(trackBox.center.y + sin(angle4) * radius) + scene_y1;
-
+       return BFMatcher::create(NORM_HAMMING);
 }
 
-
-#define APPLY_MASK(type, max, components, do_yuv) \
-{ \
-       type *output_row = (type*)get_input(scene_layer)->get_rows()[i]; \
-       unsigned char *mask_row = mask_rows[i]; \
-       int chroma_offset = (int)(max + 1) / 2; \
- \
-       for(int j  = 0; j < scene_w; j++) \
-       { \
-               if(components == 4) \
-               { \
-                       output_row[j * 4 + 3] = output_row[j * 4 + 3] * mask_row[j] / 255; \
-               } \
-               else \
-               { \
-                       output_row[j * 3] = output_row[j * 3] * mask_row[j] / 255; \
-                       output_row[j * 3 + 1] = output_row[j * 3 + 1] * mask_row[j] / 255; \
-                       output_row[j * 3 + 2] = output_row[j * 3 + 2] * mask_row[j] / 255; \
- \
-                       if(do_yuv) \
-                       { \
-                               output_row[j * 3 + 1] += chroma_offset * (255 - mask_row[j]) / 255; \
-                               output_row[j * 3 + 2] += chroma_offset * (255 - mask_row[j]) / 255; \
-                       } \
-               } \
-       } \
+#ifdef _SIFT
+void FindObjectMain::set_sift()
+{
+       cvmodel = BC_GREY8;
+       detector = SIFT::create();
+       matcher = config.use_flann ?
+               flann_kdtree_matcher() : bf_matcher_norm_l2();
 }
-
-
-
-// blobtrack_sample.cpp
-void FindObjectMain::process_blob()
+#endif
+#ifdef _SURF
+void FindObjectMain::set_surf()
 {
-       if(!blob_initialized)
-       {
-               blob_initialized = 1;
-
-               blob_param.FGTrainFrames = 5;
-
-
-/* Create FG Detection module: */
-               blob_param.pFG = cvCreateFGDetectorBase(CV_BG_MODEL_FGD, NULL);
-/* Create Blob Entrance Detection module: */
-        blob_param.pBD = cvCreateBlobDetectorCC();
-/* Create blob tracker module: */
-        blob_param.pBT = cvCreateBlobTrackerCCMSPF();
-/* Create whole pipline: */
-        blob_pTracker = cvCreateBlobTrackerAuto1(&blob_param);
-
-       }
-
-
-/* Process: */
-       IplImage*   pMask = NULL;
-
-// Create aligned, RGB images
-       if(!scene_image)
-       {
-               scene_image = cvCreateImage(
-                       cvSize(scene_image_w, scene_image_h),
-                       8,
-                       3);
-       }
-
-// Temporary row pointers
-       unsigned char **scene_rows = new unsigned char*[scene_image_h];
-       for(int i = 0; i < scene_image_h; i++)
-       {
-               scene_rows[i] = (unsigned char*)(scene_image->imageData + i * scene_image_w * 3);
-       }
-
-       BC_CModels::transfer(scene_rows,
-               get_input(scene_layer)->get_rows(),
-               0,
-               0,
-               0,
-               0,
-               0,
-               0,
-               scene_x1,
-               scene_y1,
-               scene_w,
-               scene_h,
-               0,
-               0,
-               scene_w,
-               scene_h,
-               get_input(scene_layer)->get_color_model(),
-               BC_RGB888,
-               0,
-               0,
-               0);
-
-       delete [] scene_rows;
-
-    blob_pTracker->Process(scene_image, pMask);
-printf("FindObjectMain::process_blob %d %jd %d\n", __LINE__, get_source_position(), blob_pTracker->GetBlobNum());
-
-
-#if 0
-       if(blob_pTracker->GetFGMask())
-       {
-               IplImage* pFG = blob_pTracker->GetFGMask();
-printf("FindObjectMain::process_blob %d %ld\n", __LINE__, get_source_position());
-
-// Temporary row pointers
-               unsigned char **mask_rows = new unsigned char*[scene_image_h];
-               for(int i = 0; i < scene_image_h; i++)
-               {
-                       mask_rows[i] = (unsigned char*)(pFG->imageData + i * scene_image_w);
-               }
+       cvmodel = BC_GREY8;
+       detector = SURF::create(800);
+       matcher = config.use_flann ?
+               flann_kdtree_matcher() : bf_matcher_norm_l2();
+}
+#endif
+#ifdef _ORB
+void FindObjectMain::set_orb()
+{
+       cvmodel = BC_GREY8;
+       detector = ORB::create();
+       matcher = config.use_flann ?
+               flann_lshidx_matcher() : bf_matcher_norm_hamming();
+}
+#endif
+#ifdef _AKAZE
+void FindObjectMain::set_akaze()
+{
+       cvmodel = BC_GREY8;
+       detector = AKAZE::create();
+       matcher = config.use_flann ?
+               flann_lshidx_matcher() : bf_matcher_norm_hamming();
+}
+#endif
+#ifdef _BRISK
+void FindObjectMain::set_brisk()
+{
+       cvmodel = BC_GREY8;
+       detector = BRISK::create();
+       matcher = config.use_flann ?
+               flann_lshidx_matcher() : bf_matcher_norm_hamming();
+}
+#endif
 
-               for(int i = 0; i < scene_image_h; i++)
-               {
-                       switch(get_input(scene_layer)->get_color_model())
-                       {
-                               case BC_RGB888:
-                                       APPLY_MASK(unsigned char, 0xff, 3, 0)
-                                       break;
-                               case BC_RGB_FLOAT:
-                                       APPLY_MASK(float, 1.0, 3, 0)
-                                       break;
-                               case BC_YUV888:
-                                       APPLY_MASK(unsigned char, 0xff, 3, 1)
-                                       break;
-                               case BC_RGBA8888:
-                                       APPLY_MASK(unsigned char, 0xff, 4, 0)
-                                       break;
-                               case BC_RGBA_FLOAT:
-                                       APPLY_MASK(float, 1.0, 4, 0)
-                                       break;
-                               case BC_YUVA8888:
-                                       APPLY_MASK(unsigned char, 0xff, 4, 1)
-                                       break;
-                       }
+void FindObjectMain::process_match()
+{
+       if( config.algorithm == NO_ALGORITHM ) return;
+       if( !config.replace_object &&
+           !config.draw_border &&
+           !config.draw_keypoints ) return;
+
+       if( detector.empty() ) {
+               switch( config.algorithm ) {
+#ifdef _SIFT
+               case ALGORITHM_SIFT:   set_sift();   break;
+#endif
+#ifdef _SURF
+               case ALGORITHM_SURF:   set_surf();   break;
+#endif
+#ifdef _ORB
+               case ALGORITHM_ORB:    set_orb();    break;
+#endif
+#ifdef _AKAZE
+               case ALGORITHM_AKAZE:  set_akaze();  break;
+#endif
+#ifdef _BRISK
+               case ALGORITHM_BRISK:  set_brisk();  break;
+#endif
                }
-
-               delete [] mask_rows;
-
-
+               obj_keypts.clear();  obj_descrs.release();
+               to_mat(object_mat, object_w,object_h, object, object_x,object_y, cvmodel);
+               detect(object_mat, obj_keypts, obj_descrs);
+//printf("detect obj %d features\n", (int)obj_keypts.size());
        }
-#endif
 
+       to_mat(scene_mat, scene_w,scene_h, scene, scene_x,scene_y, cvmodel);
+       detect(scene_mat, scn_keypts, scn_descrs);
+//printf("detect scn %d features\n", (int)scn_keypts.size());
+       match();
+       ptV p1, p2;
+       filter_matches(p1, p2);
+       if( p1.size() < 4 ) return;
+       Mat H = findHomography(p1, p2, RANSAC, 5.0);
+       if( !H.dims || !H.rows || !H.cols ) {
+//printf("fail, size p1=%d,p2=%d\n",(int)p1.size(),(int)p2.size());
+               return;
+       }
 
+       ptV src, dst;
+       float obj_x1 = 0, obj_x2 = object_w;
+       float obj_y1 = 0, obj_y2 = object_h;
+       src.push_back(Point2f(obj_x1,obj_y1));
+       src.push_back(Point2f(obj_x2,obj_y1));
+       src.push_back(Point2f(obj_x2,obj_y2));
+       src.push_back(Point2f(obj_x1,obj_y2));
+       perspectiveTransform(src, dst, H);
+
+       border_x1 = dst[0].x + scene_x;  border_y1 = dst[0].y + scene_y;
+       border_x2 = dst[1].x + scene_x;  border_y2 = dst[1].y + scene_y;
+       border_x3 = dst[2].x + scene_x;  border_y3 = dst[2].y + scene_y;
+       border_x4 = dst[3].x + scene_x;  border_y4 = dst[3].y + scene_y;
+//printf("src %f,%f  %f,%f  %f,%f  %f,%f\n",
+// src[0].x,src[0].y, src[1].x,src[1].y, src[2].x,src[2].y, src[3].x,src[3].y);
+//printf("dst %f,%f  %f,%f  %f,%f  %f,%f\n",
+// dst[0].x,dst[0].y, dst[1].x,dst[1].y, dst[2].x,dst[2].y, dst[3].x,dst[3].y);
 }
 
-
-
-
-
-
-
-int FindObjectMain::process_buffer(VFrame **frame,
-       int64_t start_position,
-       double frame_rate)
+int FindObjectMain::process_buffer(VFrame **frame, int64_t start_position, double frame_rate)
 {
        int prev_algorithm = config.algorithm;
-       if(load_configuration())
-       {
+       int prev_use_flann = config.use_flann;
+
+       if( load_configuration() )
                init_border = 1;
+
+       if( prev_algorithm != config.algorithm ||
+           prev_use_flann != config.use_flann ) {
+               detector.release();
+               matcher.release();
        }
 
        w = frame[0]->get_w();
        h = frame[0]->get_h();
-//printf("FindObjectMain::process_buffer %d\n", __LINE__);
 
-
-// Get the layer containing the object.
        object_layer = config.object_layer;
-// Get the layer to search in.
        scene_layer = config.scene_layer;
-// Get the layer with the replacement object
        replace_layer = config.replace_layer;
 
-       object_layer = MIN(object_layer, PluginClient::get_total_buffers() - 1);
-       scene_layer = MIN(scene_layer, PluginClient::get_total_buffers() - 1);
-       replace_layer = MIN(replace_layer, PluginClient::get_total_buffers() - 1);
-
-// printf("FindObjectMain::process_buffer %d %d %d %d %d %d\n",
-// __LINE__,
-// PluginClient::get_total_buffers(),
-// config.object_layer,
-// config.scene_layer,
-// object_layer,
-// scene_layer);
-//
-// Create cropped images
-// TODO: use oblique corners & affine transform
-       object_w = (int)(config.global_block_w * w / 100);
-       object_h = (int)(config.global_block_h * h / 100);
-
-       object_x1 = (int)(config.block_x * w / 100 - object_w / 2);
-       object_y1 = (int)(config.block_y * h / 100 - object_h / 2);
-       object_x2 = object_x1 + object_w;
-       object_y2 = object_y1 + object_h;
-       CLAMP(object_x1, 0, frame[0]->get_w() - 1);
-       CLAMP(object_x2, 0, frame[0]->get_w() - 1);
-       CLAMP(object_y1, 0, frame[0]->get_h() - 1);
-       CLAMP(object_y2, 0, frame[0]->get_h() - 1);
-       object_w = object_x2 - object_x1;
-       object_h = object_y2 - object_y1;
-
-
-       scene_w = (int)(config.global_range_w * w / 100);
-       scene_h = (int)(config.global_range_h * h / 100);
-       scene_x1 = (int)(config.block_x * w / 100 - scene_w / 2);
-       scene_y1 = (int)(config.block_y * h / 100 - scene_h / 2);
-       scene_x2 = scene_x1 + scene_w;
-       scene_y2 = scene_y1 + scene_h;
-       CLAMP(scene_x1, 0, frame[0]->get_w() - 1);
-       CLAMP(scene_x2, 0, frame[0]->get_w() - 1);
-       CLAMP(scene_y1, 0, frame[0]->get_h() - 1);
-       CLAMP(scene_y2, 0, frame[0]->get_h() - 1);
-       scene_w = scene_x2 - scene_x1;
-       scene_h = scene_y2 - scene_y1;
-
-// Get quantized sizes
-       int object_image_w = object_w;
-       int object_image_h = object_h;
-       int scene_image_w = scene_w;
-       int scene_image_h = scene_h;
-       if(object_w % QUANTIZE) object_image_w += QUANTIZE - (object_w % QUANTIZE);
-       if(object_h % QUANTIZE) object_image_h += QUANTIZE - (object_h % QUANTIZE);
-       if(scene_w % QUANTIZE) scene_image_w += QUANTIZE - (scene_w % QUANTIZE);
-       if(scene_h % QUANTIZE) scene_image_h += QUANTIZE - (scene_h % QUANTIZE);
-
-       if(object_image &&
-               (object_image_w != this->object_image_w ||
-               object_image_h != this->object_image_h ||
-               prev_algorithm != config.algorithm))
-       {
-               cvReleaseImage(&object_image);
-               object_image = 0;
-               delete [] prev_object;
-               prev_object = 0;
-       }
-       this->object_image_w = object_image_w;
-       this->object_image_h = object_image_h;
-
-       if(scene_image &&
-               (scene_image_w != this->scene_image_w ||
-               scene_image_h != this->scene_image_h ||
-               prev_algorithm != config.algorithm))
-       {
-               cvReleaseImage(&scene_image);
-               scene_image = 0;
-       }
-       this->scene_image_w = scene_image_w;
-       this->scene_image_h = scene_image_h;
-
-
-
-
-//printf("FindObjectMain::process_buffer %d object_w=%d object_h=%d object_image_w=%d object_image_h=%d\n", __LINE__, object_w, object_h, object_image_w, object_image_h);
-//printf("FindObjectMain::process_buffer %d scene_w=%d scene_h=%d scene_image_w=%d scene_image_h=%d\n", __LINE__, scene_w, scene_h, scene_image_w, scene_image_h);
-//printf("FindObjectMain::process_buffer %d total_layers=%d\n", __LINE__, get_total_buffers());
+       int max_layer = PluginClient::get_total_buffers() - 1;
+       object_layer = bclip(config.object_layer, 0, max_layer);
+       scene_layer = bclip(config.scene_layer, 0, max_layer);
+       replace_layer = bclip(config.replace_layer, 0, max_layer);
+
+       int cfg_w, cfg_h, cfg_x1, cfg_y1, cfg_x2, cfg_y2;
+       cfg_w = (int)(config.object_w * w / 100);
+       cfg_h = (int)(config.object_h * h / 100);
+       cfg_x1 = (int)(config.object_x * w / 100 - cfg_w / 2);
+       cfg_y1 = (int)(config.object_y * h / 100 - cfg_h / 2);
+       cfg_x2 = cfg_x1 + cfg_w;
+       cfg_y2 = cfg_y1 + cfg_h;
+       bclamp(cfg_x1, 0, w);  object_x = cfg_x1;
+       bclamp(cfg_y1, 0, h);  object_y = cfg_y1;
+       bclamp(cfg_x2, 0, w);  object_w = cfg_x2 - cfg_x1;
+       bclamp(cfg_y2, 0, h);  object_h = cfg_y2 - cfg_y1;
+
+       cfg_w = (int)(config.scene_w * w / 100);
+       cfg_h = (int)(config.scene_h * h / 100);
+       cfg_x1 = (int)(config.scene_x * w / 100 - cfg_w / 2);
+       cfg_y1 = (int)(config.scene_y * h / 100 - cfg_h / 2);
+       cfg_x2 = cfg_x1 + cfg_w;
+       cfg_y2 = cfg_y1 + cfg_h;
+       bclamp(cfg_x1, 0, w);  scene_x = cfg_x1;
+       bclamp(cfg_y1, 0, h);  scene_y = cfg_y1;
+       bclamp(cfg_x2, 0, w);  scene_w = cfg_x2 - cfg_x1;
+       bclamp(cfg_y2, 0, h);  scene_h = cfg_y2 - cfg_y1;
 
 // Read in the input frames
-       for(int i = 0; i < PluginClient::get_total_buffers(); i++)
-       {
-               read_frame(frame[i],
-                       i,
-                       start_position,
-                       frame_rate);
+       for( int i = 0; i < PluginClient::get_total_buffers(); i++ ) {
+               read_frame(frame[i], i, start_position, frame_rate, 0);
        }
 
+       object = frame[object_layer];
+       scene = frame[scene_layer];
+       replace = frame[replace_layer];
 
-// Search for object
-       if(config.algorithm != NO_ALGORITHM &&
-               (config.replace_object ||
-               config.draw_border ||
-               config.draw_keypoints))
-       {
-
-
-               switch(config.algorithm)
-               {
-#if HAVE_OPENCV_SURF
-                       case ALGORITHM_SURF:
-                               process_surf();
-                               break;
-#endif
-
-                       case ALGORITHM_CAMSHIFT:
-                               process_camshift();
-                               break;
-
-                       case ALGORITHM_BLOB:
-                               process_blob();
-                               break;
-               }
+       border_x1 = obj_x1;  border_y1 = obj_y1;
+       border_x2 = obj_x2;  border_y2 = obj_y2;
+       border_x3 = obj_x3;  border_y3 = obj_y3;
+       border_x4 = obj_x4;  border_y4 = obj_y4;
 
+       if( scene_w > 0 && scene_h > 0 && object_w > 0 && object_h > 0 ) {
+               process_match();
+       }
 
-               if(init_border)
-               {
-                       border_x1_accum = border_x1;
-                       border_y1_accum = border_y1;
-                       border_x2_accum = border_x2;
-                       border_y2_accum = border_y2;
-                       border_x3_accum = border_x3;
-                       border_y3_accum = border_y3;
-                       border_x4_accum = border_x4;
-                       border_y4_accum = border_y4;
-                       init_border = 0;
-               }
-               else
-               {
-                       border_x1_accum = (float)border_x1 * config.blend / 100 +
-                               border_x1_accum * (100 - config.blend) / 100;
-                       border_y1_accum = (float)border_y1 * config.blend / 100 +
-                               border_y1_accum * (100 - config.blend) / 100;
-                       border_x2_accum = (float)border_x2 * config.blend / 100 +
-                               border_x2_accum * (100 - config.blend) / 100;
-                       border_y2_accum = (float)border_y2 * config.blend / 100 +
-                               border_y2_accum * (100 - config.blend) / 100;
-                       border_x3_accum = (float)border_x3 * config.blend / 100 +
-                               border_x3_accum * (100 - config.blend) / 100;
-                       border_y3_accum = (float)border_y3 * config.blend / 100 +
-                               border_y3_accum * (100 - config.blend) / 100;
-                       border_x4_accum = (float)border_x4 * config.blend / 100 +
-                               border_x4_accum * (100 - config.blend) / 100;
-                       border_y4_accum = (float)border_y4 * config.blend / 100 +
-                               border_y4_accum * (100 - config.blend) / 100;
-               }
+       double w0 = init_border ? 1. : config.blend/100., w1 = 1. - w0;
+       obj_x1 = border_x1*w0 + obj_x1*w1;  obj_y1 = border_y1*w0 + obj_y1*w1;
+       obj_x2 = border_x2*w0 + obj_x2*w1;  obj_y2 = border_y2*w0 + obj_y2*w1;
+       obj_x3 = border_x3*w0 + obj_x3*w1;  obj_y3 = border_y3*w0 + obj_y3*w1;
+       obj_x4 = border_x4*w0 + obj_x4*w1;  obj_y4 = border_y4*w0 + obj_y4*w1;
 
 // Replace object in the scene layer
-               if(config.replace_object)
-               {
-
-// Some trickery to get the affine transform to alpha blend into the output
-                       if(!affine) affine = new AffineEngine(get_project_smp() + 1,
-                               get_project_smp() + 1);
+       if( config.replace_object ) {
+               int cpus1 = get_project_smp() + 1;
+               if( !affine )
+                       affine = new AffineEngine(cpus1, cpus1);
+               if( !overlayer )
+                       overlayer = new OverlayFrame(cpus1);
+
+               VFrame *temp = new_temp(scene->get_w(), scene->get_h(), scene->get_color_model());
+               temp->clear_frame();
+               float sx = 100./w, sy = 100./h;
+               float x1 = sx * obj_x1, y1 = sy * obj_y1;
+               float x2 = sx * obj_x2, y2 = sy * obj_y2;
+               float x3 = sx * obj_x3, y3 = sy * obj_y3;
+               float x4 = sx * obj_x4, y4 = sy * obj_y4;
+               affine->process(temp, replace, 0, AffineEngine::PERSPECTIVE,
+                       x1,y1, x2,y2, x3,y3, x4,y4, 1);
+               overlayer->overlay(scene, temp,  0,0, w,h,  0,0, w,h,
+                       1, TRANSFER_NORMAL, NEAREST_NEIGHBOR);
 
-//printf("FindObjectMain::process_surf %d replace_layer=%d\n", __LINE__, replace_layer);
-                       if(!temp)
-                               temp = new VFrame(w,
-                                       h,
-                                       get_input(scene_layer)->get_color_model());
-                       if(!overlayer)
-                               overlayer = new OverlayFrame(get_project_smp() + 1);
-
-                       temp->clear_frame();
-                       affine->process(temp,
-                               get_input(replace_layer),
-                               0,
-                               AffineEngine::PERSPECTIVE,
-                               border_x1_accum * 100 / w,
-                               border_y1_accum * 100 / h,
-                               border_x2_accum * 100 / w,
-                               border_y2_accum * 100 / h,
-                               border_x3_accum * 100 / w,
-                               border_y3_accum * 100 / h,
-                               border_x4_accum * 100 / w,
-                               border_y4_accum * 100 / h,
-                               1);
-
-                       overlayer->overlay(get_input(scene_layer),
-                               temp,
-                               0,
-                               0,
-                               w,
-                               h,
-                               0,
-                               0,
-                               w,
-                               h,
-                               1,        // 0 - 1
-                               TRANSFER_NORMAL,
-                               NEAREST_NEIGHBOR);
-               }
+       }
 
+       if( config.draw_border ) {
+               int wh = (w+h)>>8, ss = 1; while( wh>>=1 ) ss<<=1;
+               scene->set_pixel_color(WHITE);  scene->set_stiple(ss*2);
+               draw_line(scene, obj_x1, obj_y1, obj_x2, obj_y2);
+               draw_line(scene, obj_x2, obj_y2, obj_x3, obj_y3);
+               draw_line(scene, obj_x3, obj_y3, obj_x4, obj_y4);
+               draw_line(scene, obj_x4, obj_y4, obj_x1, obj_y1);
+       }
 
-               if(config.draw_border)
-               {
-                       draw_line(get_input(scene_layer),
-                               border_x1_accum,
-                               border_y1_accum,
-                               border_x2_accum,
-                               border_y2_accum);
-                       draw_line(get_input(scene_layer),
-                               border_x2_accum,
-                               border_y2_accum,
-                               border_x3_accum,
-                               border_y3_accum);
-                       draw_line(get_input(scene_layer),
-                               border_x3_accum,
-                               border_y3_accum,
-                               border_x4_accum,
-                               border_y4_accum);
-                       draw_line(get_input(scene_layer),
-                               border_x4_accum,
-                               border_y4_accum,
-                               border_x1_accum,
-                               border_y1_accum);
+       if( config.draw_keypoints ) {
+               scene->set_pixel_color(RED);  scene->set_stiple(0);
+               for( int i=0,n=scn_keypts.size(); i<n; ++i ) {
+                       Point2f &pt = scn_keypts[i].pt;
+                       int r = scn_keypts[i].size * 1.2/9 * 2;
+                       int x = pt.x + scene_x, y = pt.y + scene_y;
+                       draw_circle(scene, x, y, r);
                }
-
        }
 
 // Draw object outline in the object layer
-       if(config.draw_object_border)
-       {
-               draw_line(frame[object_layer], object_x1, object_y1, object_x2, object_y1);
-               draw_line(frame[object_layer], object_x2, object_y1, object_x2, object_y2);
-               draw_line(frame[object_layer], object_x2, object_y2, object_x1, object_y2);
-               draw_line(frame[object_layer], object_x1, object_y2, object_x1, object_y1);
-
-               draw_line(frame[object_layer], scene_x1, scene_y1, scene_x2, scene_y1);
-               draw_line(frame[object_layer], scene_x2, scene_y1, scene_x2, scene_y2);
-               draw_line(frame[object_layer], scene_x2, scene_y2, scene_x1, scene_y2);
-               draw_line(frame[object_layer], scene_x1, scene_y2, scene_x1, scene_y1);
+       if( config.draw_object_border ) {
+               int wh = (w+h)>>8, ss = 1; while( wh>>=1 ) ss<<=1;
+               scene->set_pixel_color(YELLOW);  scene->set_stiple(ss*3);
+               int x1 = object_x, x2 = x1 + object_w - 1;
+               int y1 = object_y, y2 = y1 + object_h - 1;
+               draw_rect(scene, x1, y1, x2, y2);
+               scene->set_pixel_color(GREEN);  scene->set_stiple(0);
+               x1 = scene_x, x2 = x1 + scene_w - 1;
+               y1 = scene_y, y2 = y1 + scene_h - 1;
+               draw_rect(scene, x1, y1, x2, y2);
        }
 
-
-
-
+       scene->set_pixel_color(BLACK);
+       scene->set_stiple(0);
        return 0;
 }
 
-
index b8a0a434ce3b983427a1c72d9a89b22420901665..7825d25f9dd69acf0d3aed4450ad40cd82252530 100644 (file)
 #include <string.h>
 
 #include "affine.inc"
+#include "bccmodels.h"
 #include "bchash.inc"
 #include "filexml.inc"
 #include "keyframe.inc"
-#include "findobjectwindow.inc"
+#include "findobject.inc"
 #include "overlayframe.inc"
 #include "pluginvclient.h"
 #include "vframe.inc"
 
-#include "opencv2/core/core_c.h"
-#include "opencv2/objdetect/objdetect.hpp"
+#include "opencv2/core/types.hpp"
 #include "opencv2/core/mat.hpp"
-#include "opencv2/imgproc/types_c.h"
 #include "opencv2/imgproc/imgproc.hpp"
-#include "opencv2/legacy/blobtrack.hpp"
+#include "opencv2/xfeatures2d.hpp"
+#include "opencv2/calib3d.hpp"
+#include "opencv2/flann/defines.h"
+#include "opencv2/flann/params.h"
 
-class FindObjectMain;
-class FindObjectWindow;
+#include <vector>
 
+using namespace std;
 using namespace cv;
+using namespace cv::xfeatures2d;
+using namespace cvflann;
 
-
-
+// enabled detectors
+#define _SIFT
+#define _SURF
+#define _ORB
+#define _AKAZE
+#define _BRISK
 
 // Limits of global range in percent
 #define MIN_RADIUS 1
@@ -73,22 +81,12 @@ using namespace cv;
 #define MIN_BLEND 1
 #define MAX_BLEND 100
 
-// Sizes must be quantized a certain amount for OpenCV
-#define QUANTIZE 8
-
-// Storage for results
-#define FINDOBJECT_FILE "/tmp/findobject"
-
-#define MIN_CAMSHIFT 0
-#define MAX_CAMSHIFT 256
-
-
 #define NO_ALGORITHM 0
-#if HAVE_OPENCV_SURF
-#define ALGORITHM_SURF 1
-#endif
-#define ALGORITHM_CAMSHIFT 2
-#define ALGORITHM_BLOB 3
+#define ALGORITHM_SIFT  1
+#define ALGORITHM_SURF  2
+#define ALGORITHM_ORB   3
+#define ALGORITHM_AKAZE 4
+#define ALGORITHM_BRISK 5
 
 class FindObjectConfig
 {
@@ -97,182 +95,110 @@ public:
 
        int equivalent(FindObjectConfig &that);
        void copy_from(FindObjectConfig &that);
-       void interpolate(FindObjectConfig &prev,
-               FindObjectConfig &next,
-               int64_t prev_frame,
-               int64_t next_frame,
-               int64_t current_frame);
+       void interpolate(FindObjectConfig &prev, FindObjectConfig &next,
+               int64_t prev_frame, int64_t next_frame, int64_t current_frame);
        void boundaries();
 
-       int global_range_w;
-       int global_range_h;
-// Block size as percent of image size
-// Object must be a rectangle for the algorithm to work,
-// so no oblique edges unless we also do an affine transform.
-       float global_block_w;
-       float global_block_h;
-// Block position in percentage 0 - 100
-       float block_x;
-       float block_y;
-// Draw key points
+       int algorithm, use_flann;
+       float object_x, object_y, object_w, object_h;
+       float scene_x, scene_y,   scene_w, scene_h;
+
        int draw_keypoints;
-// Draw border over object in scene layer
        int draw_border;
-// Draw transparency over object in object layer
        int replace_object;
-// Draw border over object
        int draw_object_border;
 
-// Which layer is the object 0 or 1
        int object_layer;
-// Which layer replaces the object
        int replace_layer;
-// Which layer is the object searched for in
        int scene_layer;
-
-       int algorithm;
-// Camshift parameters
-       int vmin, vmax, smin;
-// Amount to blend new object position in
        int blend;
 };
 
-
-
-
 class FindObjectMain : public PluginVClient
 {
 public:
        FindObjectMain(PluginServer *server);
        ~FindObjectMain();
 
-       int process_buffer(VFrame **frame,
-               int64_t start_position,
-               double frame_rate);
+       int process_buffer(VFrame **frame, int64_t start_position, double frame_rate);
+#ifdef _SIFT
+       void set_sift();
+#endif
+#ifdef _SURF
+       void set_surf();
+#endif
+#ifdef _ORB
+       void set_orb();
+#endif
+#ifdef _AKAZE
+       void set_akaze();
+#endif
+#ifdef _BRISK
+       void set_brisk();
+#endif
+       void process_match();
+
        void draw_vectors(VFrame *frame);
        int is_multichannel();
        int is_realtime();
        void save_data(KeyFrame *keyframe);
        void read_data(KeyFrame *keyframe);
        void update_gui();
-// Calculate frame to copy from and frame to move
-       void calculate_pointers(VFrame **frame, VFrame **src, VFrame **dst);
-       void allocate_temp(int w, int h, int color_model);
 
        PLUGIN_CLASS_MEMBERS2(FindObjectConfig)
 
-
        AffineEngine *affine;
-// Temporary for affine overlay
-       VFrame *temp;
        OverlayFrame *overlayer;
+       VFrame *object, *scene, *replace;
+
+       static void draw_line(VFrame *vframe, int x1, int y1, int x2, int y2);
+       static void draw_rect(VFrame *vframe, int x1, int y1, int x2, int y2);
+       static void draw_circle(VFrame *vframe, int x, int y, int r);
+
+       int object_x, object_y, object_w, object_h;
+       int scene_x, scene_y, scene_w, scene_h;
 
-       static void draw_pixel(VFrame *frame, int x, int y);
-       static void draw_line(VFrame *frame, int x1, int y1, int x2, int y2);
-       static void draw_rect(VFrame *frame, int x1, int y1, int x2, int y2);
-
-       void grey_crop(unsigned char *dst,
-               VFrame *src,
-               int x1,
-               int y1,
-               int x2,
-               int y2,
-               int dst_w,
-               int dst_h);
-
-
-
-       void process_surf();
-       void process_camshift();
-       void process_blob();
-
-
-
-// clamped coordinates
-       int object_w;
-       int object_h;
-       int object_x1;
-       int object_y1;
-       int object_x2;
-       int object_y2;
-       int scene_w;
-       int scene_h;
-       int scene_x1;
-       int scene_y1;
-       int scene_x2;
-       int scene_y2;
-// input frame size
        int w, h;
-// clamped layers
        int object_layer;
        int scene_layer;
        int replace_layer;
 
 // Latest coordinates of object in scene
-       int border_x1;
-       int border_y1;
-       int border_x2;
-       int border_y2;
-       int border_x3;
-       int border_y3;
-       int border_x4;
-       int border_y4;
+       int border_x1, border_y1;
+       int border_x2, border_y2;
+       int border_x3, border_y3;
+       int border_x4, border_y4;
 // Coordinates of object in scene with blending
-       float border_x1_accum;
-       float border_y1_accum;
-       float border_x2_accum;
-       float border_y2_accum;
-       float border_x3_accum;
-       float border_y3_accum;
-       float border_x4_accum;
-       float border_y4_accum;
+       float obj_x1, obj_y1;
+       float obj_x2, obj_y2;
+       float obj_x3, obj_y3;
+       float obj_x4, obj_y4;
        int init_border;
 
-
-       IplImage *object_image;
-       IplImage *scene_image;
-
-
-// Comparison with current object_image
-       unsigned char *prev_object;
-// Quantized sizes
-       int object_image_w;
-       int object_image_h;
-       int scene_image_w;
-       int scene_image_h;
-       CvSeq *object_keypoints;
-       CvSeq *object_descriptors;
-       CvSeq *scene_keypoints;
-       CvSeq *scene_descriptors;
-       CvMemStorage *storage;
-
-// camshift
-// object histogram
-       Mat hist;
-       Rect trackWindow;
-
-
-// Blob
-       int blob_initialized;
-       CvBlobTrackerAutoParam1 blob_param;
-       CvBlobTrackerAuto* blob_pTracker;
-
-
+//opencv
+       typedef vector<DMatch> DMatchV;
+       typedef vector<DMatchV> DMatches;
+       typedef vector<KeyPoint> KeyPointV;
+       typedef vector<Point2f> ptV;
+
+       BC_CModel cvmodel;
+       Mat object_mat, scene_mat;
+       Mat obj_descrs;  KeyPointV obj_keypts;
+       Mat scn_descrs;  KeyPointV scn_keypts;
+       DMatches pairs;
+
+       static void to_mat(Mat &mat, int mcols, int mrows,
+               VFrame *inp, int ix,int iy, BC_CModel mcolor_model);
+       void detect(Mat &mat, KeyPointV &keypts, Mat &descrs);
+       void match();
+       void filter_matches(ptV &p1, ptV &p2, double ratio=0.75);
+
+       Ptr<Feature2D> detector;
+       Ptr<DescriptorMatcher> matcher;
+       Ptr<DescriptorMatcher> flann_kdtree_matcher();
+       Ptr<DescriptorMatcher> flann_lshidx_matcher();
+       Ptr<DescriptorMatcher> bf_matcher_norm_l2();
+       Ptr<DescriptorMatcher> bf_matcher_norm_hamming();
 };
 
-
-
-
-
-
-
-
-
-
 #endif
-
-
-
-
-
-
index be2711162172cda5341ee2d3b0179914cb3549ce..0a1262e4c027897550886c5e3761482cfe845e7b 100644 (file)
@@ -22,9 +22,7 @@
 #ifndef FINDOBJECT_INC
 #define FINDOBJECT_INC
 
-
 class FindObjectConfig;
 class FindObjectMain;
 
-
 #endif
index 0e0116424d63e0250c3799e9a885fe12feb299db..4cde53752493603ea6700c398efcccd05b8ac914 100644 (file)
 
 
 FindObjectWindow::FindObjectWindow(FindObjectMain *plugin)
- : PluginClientWindow(plugin,
-       300,
-       550,
-       300,
-       550,
-       0)
+ : PluginClientWindow(plugin, 340, 660, 340, 660, 0)
 {
        this->plugin = plugin;
 }
@@ -44,246 +39,155 @@ FindObjectWindow::~FindObjectWindow()
 
 void FindObjectWindow::create_objects()
 {
-       int x1 = 10, x = 10, y = 10;
-       int x2 = 310;
-       BC_Title *title;
-
+       int x = 10, y = 10, x1 = x, x2 = get_w()/2;
+       plugin->load_configuration();
 
-       add_subwindow(title = new BC_Title(x1,
-               y,
-               _("Algorithm:")));
-       add_subwindow(algorithm = new FindObjectAlgorithm(plugin,
-               this,
-               x1 + title->get_w() + 10,
-               y));
+       BC_Title *title;
+       add_subwindow(title = new BC_Title(x1, y, _("Algorithm:")));
+       add_subwindow(algorithm = new FindObjectAlgorithm(plugin, this,
+               x1 + title->get_w() + 10, y));
        algorithm->create_objects();
        y += algorithm->get_h() + plugin->get_theme()->widget_border;
 
+       add_subwindow(use_flann = new FindObjectUseFlann(plugin, this, x, y));
+       y += use_flann->get_h() + plugin->get_theme()->widget_border + 20;
 
-       add_subwindow(title = new BC_Title(x1,
-               y,
-               _("Search radius:\n(W/H Percent of image)")));
-       add_subwindow(global_range_w = new FindObjectGlobalRange(plugin,
-               x1 + title->get_w() + 10,
-               y,
-               &plugin->config.global_range_w));
-       add_subwindow(global_range_h = new FindObjectGlobalRange(plugin,
-               x1 + title->get_w() + 10 + global_range_w->get_w(),
-               y,
-               &plugin->config.global_range_h));
-
-       y += 50;
-       add_subwindow(title = new BC_Title(x1,
-               y,
-               _("Object size:\n(W/H Percent of image)")));
-       add_subwindow(global_block_w = new FindObjectBlockSize(plugin,
-               x1 + title->get_w() + 10,
-               y,
-               &plugin->config.global_block_w));
-       add_subwindow(global_block_h = new FindObjectBlockSize(plugin,
-               x1 + title->get_w() + 10 + global_block_w->get_w(),
-               y,
-               &plugin->config.global_block_h));
-
-       y += 40;
-       add_subwindow(title = new BC_Title(x, y + 10, _("Block X:")));
-       add_subwindow(block_x = new FindObjectBlockCenter(plugin,
-               this,
-               x + title->get_w() + 10,
-               y,
-               &plugin->config.block_x));
-       add_subwindow(block_x_text = new FindObjectBlockCenterText(plugin,
-               this,
-               x + title->get_w() + 10 + block_x->get_w() + 10,
-               y + 10,
-               &plugin->config.block_x));
-       block_x->center_text = block_x_text;
-       block_x_text->center = block_x;
-
-       y += 40;
-       add_subwindow(title = new BC_Title(x, y + 10, _("Block Y:")));
-       add_subwindow(block_y = new FindObjectBlockCenter(plugin,
-               this,
-               x + title->get_w() + 10,
-               y,
-               &plugin->config.block_y));
-       add_subwindow(block_y_text = new FindObjectBlockCenterText(plugin,
-               this,
-               x + title->get_w() + 10 + block_y->get_w() + 10,
-               y + 10,
-               &plugin->config.block_y));
-       block_y->center_text = block_y_text;
-       block_y_text->center = block_y;
-
-
-       y += 40;
-       add_subwindow(draw_keypoints = new FindObjectDrawKeypoints(plugin,
-               this,
-               x,
-               y));
-
-       y += draw_keypoints->get_h() + plugin->get_theme()->widget_border;
-       add_subwindow(draw_border = new FindObjectDrawBorder(plugin,
-               this,
-               x,
-               y));
-
-       y += draw_keypoints->get_h() + plugin->get_theme()->widget_border;
-       add_subwindow(replace_object = new FindObjectReplace(plugin,
-               this,
-               x,
-               y));
-
-       y += draw_keypoints->get_h() + plugin->get_theme()->widget_border;
-       add_subwindow(draw_object_border = new FindObjectDrawObjectBorder(plugin,
-               this,
-               x,
-               y));
-
+       int x0 = x + 200;
+       add_subwindow(title = new BC_Title(x, y, _("Output/scene layer:")));
+       scene_layer = new FindObjectLayer(plugin, this, x0, y,
+               &plugin->config.scene_layer);
+       scene_layer->create_objects();
+       y += scene_layer->get_h() + plugin->get_theme()->widget_border;
 
-       y += draw_keypoints->get_h() + plugin->get_theme()->widget_border;
        add_subwindow(title = new BC_Title(x, y, _("Object layer:")));
-       object_layer = new FindObjectLayer(plugin,
-               this,
-               x + title->get_w() + 10,
-               y,
+       object_layer = new FindObjectLayer(plugin, this, x0, y,
                &plugin->config.object_layer);
        object_layer->create_objects();
        y += object_layer->get_h() + plugin->get_theme()->widget_border;
 
        add_subwindow(title = new BC_Title(x, y, _("Replacement object layer:")));
-       replace_layer = new FindObjectLayer(plugin,
-               this,
-               x + title->get_w() + 10,
-               y,
+       replace_layer = new FindObjectLayer(plugin, this, x0, y,
                &plugin->config.replace_layer);
        replace_layer->create_objects();
-       y += replace_layer->get_h() + plugin->get_theme()->widget_border;
+       y += replace_layer->get_h() + plugin->get_theme()->widget_border + 10;
 
-       add_subwindow(title = new BC_Title(x, y, _("Output/scene layer:")));
-       scene_layer = new FindObjectLayer(plugin,
-               this,
-               x + title->get_w() + 10,
-               y,
-               &plugin->config.scene_layer);
-       scene_layer->create_objects();
-       y += scene_layer->get_h() + plugin->get_theme()->widget_border;
+       add_subwindow(title = new BC_Title(x+15, y, _("Units: 0 to 100 percent")));
+       y += title->get_h();
 
+       int y1 = y;
+       add_subwindow(new BC_Title(x1, y + 10, _("Scene X:")));
+       y += title->get_h() + 15;
+       add_subwindow(scene_x = new FindObjectScanFloat(plugin, this,
+               x1, y, &plugin->config.scene_x));
+       add_subwindow(scene_x_text = new FindObjectScanFloatText(plugin, this,
+               x1 + scene_x->get_w() + 10, y + 10, &plugin->config.scene_x));
+       scene_x->center_text = scene_x_text;
+       scene_x_text->center = scene_x;
 
-       add_subwindow(title = new BC_Title(x, y + 10, _("Object blend amount:")));
-       add_subwindow(blend = new FindObjectBlend(plugin,
-               x + title->get_w() + plugin->get_theme()->widget_border,
-               y,
-               &plugin->config.blend));
-       y += blend->get_h();
+       y += 40;
+       add_subwindow(title = new BC_Title(x1, y + 10, _("Scene Y:")));
+       y += title->get_h() + 15;
+       add_subwindow(scene_y = new FindObjectScanFloat(plugin, this,
+               x1, y, &plugin->config.scene_y));
+       add_subwindow(scene_y_text = new FindObjectScanFloatText(plugin, this,
+               x1 + scene_y->get_w() + 10, y + 10, &plugin->config.scene_y));
+       scene_y->center_text = scene_y_text;
+       scene_y_text->center = scene_y;
 
+       y += 40;
+       add_subwindow(new BC_Title(x1, y + 10, _("Scene W:")));
+       y += title->get_h() + 15;
+       add_subwindow(scene_w = new FindObjectScanFloat(plugin, this,
+               x1, y, &plugin->config.scene_w));
+       add_subwindow(scene_w_text = new FindObjectScanFloatText(plugin, this,
+               x1 + scene_w->get_w() + 10, y + 10, &plugin->config.scene_w));
+       scene_w->center_text = scene_w_text;
+       scene_w_text->center = scene_w;
 
-       add_subwindow(title = new BC_Title(x, y + 10, _("Camshift VMIN:")));
-       add_subwindow(vmin = new FindObjectCamParam(plugin,
-               x + title->get_w() + plugin->get_theme()->widget_border,
-               y,
-               &plugin->config.vmin));
-       y += vmin->get_h() * 2 / 3;
+       y += 40;
+       add_subwindow(title = new BC_Title(x1, y + 10, _("Scene H:")));
+       y += title->get_h() + 15;
+       add_subwindow(scene_h = new FindObjectScanFloat(plugin, this,
+               x1, y, &plugin->config.scene_h));
+       add_subwindow(scene_h_text = new FindObjectScanFloatText(plugin, this,
+               x1 + scene_h->get_w() + 10, y + 10,
+               &plugin->config.scene_h));
+       scene_h->center_text = scene_h_text;
+       scene_h_text->center = scene_h;
+
+       y = y1;
+       add_subwindow(new BC_Title(x2, y + 10, _("Object X:")));
+       y += title->get_h() + 15;
+       add_subwindow(object_x = new FindObjectScanFloat(plugin, this,
+               x2, y, &plugin->config.object_x));
+       add_subwindow(object_x_text = new FindObjectScanFloatText(plugin, this,
+               x2 + object_x->get_w() + 10, y + 10, &plugin->config.object_x));
+       object_x->center_text = object_x_text;
+       object_x_text->center = object_x;
 
-       add_subwindow(title = new BC_Title(x, y + 10, _("Camshift VMAX:")));
-       add_subwindow(vmax = new FindObjectCamParam(plugin,
-               x + title->get_w() + vmin->get_w() + plugin->get_theme()->widget_border,
-               y,
-               &plugin->config.vmax));
-       y += vmin->get_h() * 2 / 3;
+       y += 40;
+       add_subwindow(title = new BC_Title(x2, y + 10, _("Object Y:")));
+       y += title->get_h() + 15;
+       add_subwindow(object_y = new FindObjectScanFloat(plugin, this,
+               x2, y, &plugin->config.object_y));
+       add_subwindow(object_y_text = new FindObjectScanFloatText(plugin, this,
+               x2 + object_y->get_w() + 10, y + 10, &plugin->config.object_y));
+       object_y->center_text = object_y_text;
+       object_y_text->center = object_y;
 
-       add_subwindow(title = new BC_Title(x, y + 10, _("Camshift SMIN:")));
-       add_subwindow(smin = new FindObjectCamParam(plugin,
-               x + title->get_w() + plugin->get_theme()->widget_border,
-               y,
-               &plugin->config.smin));
-       y += vmin->get_h();
+       y += 40;
+       add_subwindow(new BC_Title(x2, y + 10, _("Object W:")));
+       y += title->get_h() + 15;
+       add_subwindow(object_w = new FindObjectScanFloat(plugin, this,
+               x2, y, &plugin->config.object_w));
+       add_subwindow(object_w_text = new FindObjectScanFloatText(plugin, this,
+               x2 + object_w->get_w() + 10, y + 10, &plugin->config.object_w));
+       object_w->center_text = object_w_text;
+       object_w_text->center = object_w;
 
+       y += 40;
+       add_subwindow(title = new BC_Title(x2, y + 10, _("Object H:")));
+       y += title->get_h() + 15;
+       add_subwindow(object_h = new FindObjectScanFloat(plugin, this,
+               x2, y, &plugin->config.object_h));
+       add_subwindow(object_h_text = new FindObjectScanFloatText(plugin, this,
+               x2 + object_h->get_w() + 10, y + 10,
+               &plugin->config.object_h));
+       object_h->center_text = object_h_text;
+       object_h_text->center = object_h;
+
+       y += 40 + 15;
+       add_subwindow(draw_keypoints = new FindObjectDrawKeypoints(plugin, this, x, y));
+       y += draw_keypoints->get_h() + plugin->get_theme()->widget_border;
+       add_subwindow(draw_border = new FindObjectDrawBorder(plugin, this, x, y));
+       y += draw_border->get_h() + plugin->get_theme()->widget_border;
+       add_subwindow(replace_object = new FindObjectReplace(plugin, this, x, y));
+       y += replace_object->get_h() + plugin->get_theme()->widget_border;
+       add_subwindow(draw_object_border = new FindObjectDrawObjectBorder(plugin, this, x, y));
+       y += draw_object_border->get_h() + plugin->get_theme()->widget_border;
 
+       add_subwindow(title = new BC_Title(x, y + 10, _("Object blend amount:")));
+       add_subwindow(blend = new FindObjectBlend(plugin,
+               x + title->get_w() + plugin->get_theme()->widget_border, y,
+               &plugin->config.blend));
+       y += blend->get_h();
 
        show_window(1);
 }
 
 
-
-
-
-
-
-FindObjectGlobalRange::FindObjectGlobalRange(FindObjectMain *plugin,
-       int x,
-       int y,
-       int *value)
- : BC_IPot(x,
-               y,
-               (int64_t)*value,
-               (int64_t)MIN_RADIUS,
-               (int64_t)MAX_RADIUS)
-{
-       this->plugin = plugin;
-       this->value = value;
-}
-
-
-int FindObjectGlobalRange::handle_event()
-{
-       *value = (int)get_value();
-       plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-
-FindObjectBlockSize::FindObjectBlockSize(FindObjectMain *plugin,
-       int x,
-       int y,
-       float *value)
- : BC_FPot(x,
-               y,
-               (float)*value,
-               (float)MIN_BLOCK,
-               (float)MAX_BLOCK)
-{
-       this->plugin = plugin;
-       this->value = value;
-       set_precision(0.1);
-}
-
-
-
-int FindObjectBlockSize::handle_event()
-{
-       *value = get_value();
-       plugin->send_configure_change();
-       return 1;
-}
-
-
-
-
-
-
-
-FindObjectBlockCenter::FindObjectBlockCenter(FindObjectMain *plugin,
-       FindObjectWindow *gui,
-       int x,
-       int y,
-       float *value)
- : BC_FPot(x,
-       y,
-       *value,
-       (float)0,
-       (float)100)
+FindObjectScanFloat::FindObjectScanFloat(FindObjectMain *plugin, FindObjectWindow *gui,
+       int x, int y, float *value)
+ : BC_FPot(x, y, *value, (float)0, (float)100)
 {
        this->plugin = plugin;
        this->gui = gui;
        this->value = value;
+       this->center_text = 0;
        set_precision(0.1);
 }
 
-int FindObjectBlockCenter::handle_event()
+int FindObjectScanFloat::handle_event()
 {
        *value = get_value();
        center_text->update(*value);
@@ -292,28 +196,18 @@ int FindObjectBlockCenter::handle_event()
 }
 
 
-
-
-
-
-FindObjectBlockCenterText::FindObjectBlockCenterText(FindObjectMain *plugin,
-       FindObjectWindow *gui,
-       int x,
-       int y,
-       float *value)
- : BC_TextBox(x,
-       y,
-       75,
-       1,
-       *value)
+FindObjectScanFloatText::FindObjectScanFloatText(FindObjectMain *plugin, FindObjectWindow *gui,
+       int x, int y, float *value)
+ : BC_TextBox(x, y, 75, 1, *value)
 {
        this->plugin = plugin;
        this->gui = gui;
        this->value = value;
+       this->center = 0;
        set_precision(1);
 }
 
-int FindObjectBlockCenterText::handle_event()
+int FindObjectScanFloatText::handle_event()
 {
        *value = atof(get_text());
        center->update(*value);
@@ -322,19 +216,9 @@ int FindObjectBlockCenterText::handle_event()
 }
 
 
-
-
-
-
-
-FindObjectDrawBorder::FindObjectDrawBorder(FindObjectMain *plugin,
-       FindObjectWindow *gui,
-       int x,
-       int y)
- : BC_CheckBox(x,
-       y,
-       plugin->config.draw_border,
-       _("Draw border"))
+FindObjectDrawBorder::FindObjectDrawBorder(FindObjectMain *plugin, FindObjectWindow *gui,
+       int x, int y)
+ : BC_CheckBox(x, y, plugin->config.draw_border, _("Draw border"))
 {
        this->gui = gui;
        this->plugin = plugin;
@@ -348,18 +232,9 @@ int FindObjectDrawBorder::handle_event()
 }
 
 
-
-
-
-
-FindObjectDrawKeypoints::FindObjectDrawKeypoints(FindObjectMain *plugin,
-       FindObjectWindow *gui,
-       int x,
-       int y)
- : BC_CheckBox(x,
-       y,
-       plugin->config.draw_keypoints,
-       _("Draw keypoints"))
+FindObjectDrawKeypoints::FindObjectDrawKeypoints(FindObjectMain *plugin, FindObjectWindow *gui,
+       int x, int y)
+ : BC_CheckBox(x, y, plugin->config.draw_keypoints, _("Draw keypoints"))
 {
        this->gui = gui;
        this->plugin = plugin;
@@ -373,16 +248,9 @@ int FindObjectDrawKeypoints::handle_event()
 }
 
 
-
-
-FindObjectReplace::FindObjectReplace(FindObjectMain *plugin,
-       FindObjectWindow *gui,
-       int x,
-       int y)
- : BC_CheckBox(x,
-       y,
-       plugin->config.replace_object,
-       _("Replace object"))
+FindObjectReplace::FindObjectReplace(FindObjectMain *plugin, FindObjectWindow *gui,
+       int x, int y)
+ : BC_CheckBox(x, y, plugin->config.replace_object, _("Replace object"))
 {
        this->gui = gui;
        this->plugin = plugin;
@@ -396,18 +264,9 @@ int FindObjectReplace::handle_event()
 }
 
 
-
-
-
-
-FindObjectDrawObjectBorder::FindObjectDrawObjectBorder(FindObjectMain *plugin,
-       FindObjectWindow *gui,
-       int x,
-       int y)
- : BC_CheckBox(x,
-       y,
-       plugin->config.draw_object_border,
-       _("Draw object border"))
+FindObjectDrawObjectBorder::FindObjectDrawObjectBorder(FindObjectMain *plugin, FindObjectWindow *gui,
+       int x, int y)
+ : BC_CheckBox(x, y, plugin->config.draw_object_border, _("Draw object border"))
 {
        this->gui = gui;
        this->plugin = plugin;
@@ -421,54 +280,8 @@ int FindObjectDrawObjectBorder::handle_event()
 }
 
 
-
-
-
-
-FindObjectLayer::FindObjectLayer(FindObjectMain *plugin,
-       FindObjectWindow *gui,
-       int x,
-       int y,
-       int *value)
- : BC_TumbleTextBox(gui,
-       *value,
-       MIN_LAYER,
-       MAX_LAYER,
-       x,
-       y,
-       calculate_w(gui))
-{
-       this->plugin = plugin;
-       this->gui = gui;
-       this->value = value;
-}
-
-int FindObjectLayer::handle_event()
-{
-       *value = atoi(get_text());
-       plugin->send_configure_change();
-       return 1;
-}
-
-int FindObjectLayer::calculate_w(FindObjectWindow *gui)
-{
-       int result = 0;
-       result = gui->get_text_width(MEDIUMFONT, "000");
-       return result + 50;
-}
-
-
-
-
-
-
-
-
 FindObjectAlgorithm::FindObjectAlgorithm(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y)
- : BC_PopupMenu(x,
-       y,
-       calculate_w(gui),
-       to_text(plugin->config.algorithm))
+ : BC_PopupMenu(x, y, calculate_w(gui), to_text(plugin->config.algorithm))
 {
        this->plugin = plugin;
        this->gui = gui;
@@ -484,88 +297,126 @@ int FindObjectAlgorithm::handle_event()
 void FindObjectAlgorithm::create_objects()
 {
        add_item(new BC_MenuItem(to_text(NO_ALGORITHM)));
-#if HAVE_OPENCV_SURF
+#ifdef _SIFT
+       add_item(new BC_MenuItem(to_text(ALGORITHM_SIFT)));
+#endif
+#ifdef _SURF
        add_item(new BC_MenuItem(to_text(ALGORITHM_SURF)));
 #endif
-       add_item(new BC_MenuItem(to_text(ALGORITHM_CAMSHIFT)));
-       add_item(new BC_MenuItem(to_text(ALGORITHM_BLOB)));
+#ifdef _ORB
+       add_item(new BC_MenuItem(to_text(ALGORITHM_ORB)));
+#endif
+#ifdef _AKAZE
+       add_item(new BC_MenuItem(to_text(ALGORITHM_AKAZE)));
+#endif
+#ifdef _BRISK
+       add_item(new BC_MenuItem(to_text(ALGORITHM_BRISK)));
+#endif
 }
 
 int FindObjectAlgorithm::from_text(char *text)
 {
-       if(!strcmp(text, _("Don't Calculate"))) return NO_ALGORITHM;
-#if HAVE_OPENCV_SURF
+#ifdef _SIFT
+       if(!strcmp(text, _("SIFT"))) return ALGORITHM_SIFT;
+#endif
+#ifdef _SURF
        if(!strcmp(text, _("SURF"))) return ALGORITHM_SURF;
 #endif
-       if(!strcmp(text, _("CAMSHIFT"))) return ALGORITHM_CAMSHIFT;
-       if(!strcmp(text, _("Blob"))) return ALGORITHM_BLOB;
-       return ALGORITHM_CAMSHIFT;
+#ifdef _ORB
+       if(!strcmp(text, _("ORB"))) return ALGORITHM_ORB;
+#endif
+#ifdef _AKAZE
+       if(!strcmp(text, _("AKAZE"))) return ALGORITHM_AKAZE;
+#endif
+#ifdef _BRISK
+       if(!strcmp(text, _("BRISK"))) return ALGORITHM_BRISK;
+#endif
+       return NO_ALGORITHM;
 }
 
 char* FindObjectAlgorithm::to_text(int mode)
 {
-       switch(mode)
-       {
-               case NO_ALGORITHM:
-                       return _("Don't Calculate");
-#if HAVE_OPENCV_SURF
-               case ALGORITHM_SURF:
-                       return _("SURF");
+       switch( mode ) {
+#ifdef _SIFT
+       case ALGORITHM_SIFT:    return _("SIFT");
+#endif
+#ifdef _SURF
+       case ALGORITHM_SURF:    return _("SURF");
+#endif
+#ifdef _ORB
+       case ALGORITHM_ORB:     return _("ORB");
+#endif
+#ifdef _AKAZE
+       case ALGORITHM_AKAZE:   return _("AKAZE");
+#endif
+#ifdef _BRISK
+       case ALGORITHM_BRISK:   return _("BRISK");
 #endif
-               case ALGORITHM_BLOB:
-                       return _("Blob");
-               case ALGORITHM_CAMSHIFT:
-                       break;
        }
-       return _("CAMSHIFT");
+       return _("Don't Calculate");
 }
 
 int FindObjectAlgorithm::calculate_w(FindObjectWindow *gui)
 {
        int result = 0;
        result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(NO_ALGORITHM)));
-#if HAVE_OPENCV_SURF
+#ifdef _SIFT
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(ALGORITHM_SIFT)));
+#endif
+#ifdef _SURF
        result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(ALGORITHM_SURF)));
 #endif
-       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(ALGORITHM_CAMSHIFT)));
-       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(ALGORITHM_BLOB)));
+#ifdef _ORB
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(ALGORITHM_ORB)));
+#endif
+#ifdef _AKAZE
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(ALGORITHM_AKAZE)));
+#endif
+#ifdef _BRISK
+       result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(ALGORITHM_BRISK)));
+#endif
        return result + 50;
 }
 
 
+FindObjectUseFlann::FindObjectUseFlann(FindObjectMain *plugin, FindObjectWindow *gui,
+       int x, int y)
+ : BC_CheckBox(x, y, plugin->config.use_flann, _("Use FLANN"))
+{
+       this->gui = gui;
+       this->plugin = plugin;
+}
 
+int FindObjectUseFlann::handle_event()
+{
+       plugin->config.use_flann = get_value();
+       plugin->send_configure_change();
+       return 1;
+}
 
 
-
-
-
-FindObjectCamParam::FindObjectCamParam(FindObjectMain *plugin,
-       int x,
-       int y,
-       int *value)
- : BC_IPot(x,
-               y,
-               (int64_t)*value,
-               (int64_t)MIN_CAMSHIFT,
-               (int64_t)MAX_CAMSHIFT)
+FindObjectLayer::FindObjectLayer(FindObjectMain *plugin, FindObjectWindow *gui,
+       int x, int y, int *value)
+ : BC_TumbleTextBox(gui, *value, MIN_LAYER, MAX_LAYER, x, y, calculate_w(gui))
 {
        this->plugin = plugin;
+       this->gui = gui;
        this->value = value;
 }
 
-
-int FindObjectCamParam::handle_event()
+int FindObjectLayer::handle_event()
 {
-       *value = (int)get_value();
+       *value = atoi(get_text());
        plugin->send_configure_change();
        return 1;
 }
 
-
-
-
-
-
+int FindObjectLayer::calculate_w(FindObjectWindow *gui)
+{
+       int result = 0;
+       result = gui->get_text_width(MEDIUMFONT, "000");
+       return result + 50;
+}
 
 
 FindObjectBlend::FindObjectBlend(FindObjectMain *plugin,
@@ -582,7 +433,6 @@ FindObjectBlend::FindObjectBlend(FindObjectMain *plugin,
        this->value = value;
 }
 
-
 int FindObjectBlend::handle_event()
 {
        *value = (int)get_value();
@@ -590,15 +440,3 @@ int FindObjectBlend::handle_event()
        return 1;
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
index 883ebaa7fa86c5fce21a0d59ccc1aaa4d725295c..ef2bc52ccde93a6da7396bc8bd6284812d6ce441 100644 (file)
  */
 
 
-#ifndef FINDOBJECTWINDOW_H
-#define FINDOBJECTWINDOW_H
+#ifndef __FINDOBJECTWINDOW_H__
+#define __FINDOBJECTWINDOW_H__
 
 #include "guicast.h"
 #include "findobject.inc"
 
+class FindObjectLayer;
+class FindObjectScanFloat;
+class FindObjectScanFloatText;
+class FindObjectDrawBorder;
+class FindObjectDrawKeypoints;
+class FindObjectReplace;
+class FindObjectDrawObjectBorder;
+class FindObjectAlgorithm;
+class FindObjectBlend;
+class FindObjectWindow;
+
 class FindObjectLayer : public BC_TumbleTextBox
 {
 public:
-       FindObjectLayer(FindObjectMain *plugin,
-               FindObjectWindow *gui,
-               int x,
-               int y,
-               int *value);
+       FindObjectLayer(FindObjectMain *plugin, FindObjectWindow *gui,
+               int x, int y, int *value);
        int handle_event();
        static int calculate_w(FindObjectWindow *gui);
        FindObjectMain *plugin;
@@ -41,71 +49,33 @@ public:
        int *value;
 };
 
-class FindObjectGlobalRange : public BC_IPot
-{
-public:
-       FindObjectGlobalRange(FindObjectMain *plugin,
-               int x,
-               int y,
-               int *value);
-       int handle_event();
-       FindObjectMain *plugin;
-       int *value;
-};
-
-class FindObjectBlockSize : public BC_FPot
+class FindObjectScanFloat : public BC_FPot
 {
 public:
-       FindObjectBlockSize(FindObjectMain *plugin,
-               int x,
-               int y,
-               float *value);
+       FindObjectScanFloat(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y, float *value);
        int handle_event();
        FindObjectMain *plugin;
-       float *value;
-};
-
-class FindObjectBlockCenterText;
-
-class FindObjectBlockCenter : public BC_FPot
-{
-public:
-       FindObjectBlockCenter(FindObjectMain *plugin,
-               FindObjectWindow *gui,
-               int x,
-               int y,
-               float *value);
-       int handle_event();
        FindObjectWindow *gui;
-       FindObjectMain *plugin;
-       FindObjectBlockCenterText *center_text;
+       FindObjectScanFloatText *center_text;
        float *value;
 };
 
-class FindObjectBlockCenterText : public BC_TextBox
+class FindObjectScanFloatText : public BC_TextBox
 {
 public:
-       FindObjectBlockCenterText(FindObjectMain *plugin,
-               FindObjectWindow *gui,
-               int x,
-               int y,
-               float *value);
+       FindObjectScanFloatText(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y, float *value);
        int handle_event();
        FindObjectWindow *gui;
        FindObjectMain *plugin;
-       FindObjectBlockCenter *center;
+       FindObjectScanFloat *center;
        float *value;
 };
 
 
-
 class FindObjectDrawBorder : public BC_CheckBox
 {
 public:
-       FindObjectDrawBorder(FindObjectMain *plugin,
-               FindObjectWindow *gui,
-               int x,
-               int y);
+       FindObjectDrawBorder(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
        int handle_event();
        FindObjectMain *plugin;
        FindObjectWindow *gui;
@@ -114,10 +84,7 @@ public:
 class FindObjectDrawKeypoints : public BC_CheckBox
 {
 public:
-       FindObjectDrawKeypoints(FindObjectMain *plugin,
-               FindObjectWindow *gui,
-               int x,
-               int y);
+       FindObjectDrawKeypoints(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
        int handle_event();
        FindObjectMain *plugin;
        FindObjectWindow *gui;
@@ -126,38 +93,25 @@ public:
 class FindObjectReplace : public BC_CheckBox
 {
 public:
-       FindObjectReplace(FindObjectMain *plugin,
-               FindObjectWindow *gui,
-               int x,
-               int y);
+       FindObjectReplace(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
        int handle_event();
        FindObjectMain *plugin;
        FindObjectWindow *gui;
 };
 
-
 class FindObjectDrawObjectBorder : public BC_CheckBox
 {
 public:
-       FindObjectDrawObjectBorder(FindObjectMain *plugin,
-               FindObjectWindow *gui,
-               int x,
-               int y);
+       FindObjectDrawObjectBorder(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
        int handle_event();
        FindObjectMain *plugin;
        FindObjectWindow *gui;
 };
 
-
-
-
 class FindObjectAlgorithm : public BC_PopupMenu
 {
 public:
-       FindObjectAlgorithm(FindObjectMain *plugin,
-               FindObjectWindow *gui,
-               int x,
-               int y);
+       FindObjectAlgorithm(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
        int handle_event();
        void create_objects();
        static int calculate_w(FindObjectWindow *gui);
@@ -167,50 +121,37 @@ public:
        FindObjectWindow *gui;
 };
 
-
-class FindObjectCamParam : public BC_IPot
+class FindObjectUseFlann : public BC_CheckBox
 {
 public:
-       FindObjectCamParam(FindObjectMain *plugin,
-               int x,
-               int y,
-               int *value);
+       FindObjectUseFlann(FindObjectMain *plugin, FindObjectWindow *gui, int x, int y);
        int handle_event();
        FindObjectMain *plugin;
-       int *value;
+       FindObjectWindow *gui;
 };
 
-
 class FindObjectBlend : public BC_IPot
 {
 public:
-       FindObjectBlend(FindObjectMain *plugin,
-               int x,
-               int y,
-               int *value);
+       FindObjectBlend(FindObjectMain *plugin, int x, int y, int *value);
        int handle_event();
        FindObjectMain *plugin;
        int *value;
 };
 
-
 class FindObjectWindow : public PluginClientWindow
 {
 public:
        FindObjectWindow(FindObjectMain *plugin);
        ~FindObjectWindow();
-
        void create_objects();
-       char* get_radius_title();
-
-       FindObjectGlobalRange *global_range_w;
-       FindObjectGlobalRange *global_range_h;
-       FindObjectBlockSize *global_block_w;
-       FindObjectBlockSize *global_block_h;
-       FindObjectBlockCenter *block_x;
-       FindObjectBlockCenter *block_y;
-       FindObjectBlockCenterText *block_x_text;
-       FindObjectBlockCenterText *block_y_text;
+
+       FindObjectAlgorithm *algorithm;
+       FindObjectUseFlann *use_flann;
+       FindObjectScanFloat *object_x, *object_y, *object_w, *object_h;
+       FindObjectScanFloatText *object_x_text, *object_y_text, *object_w_text, *object_h_text;
+       FindObjectScanFloat *scene_x, *scene_y, *scene_w, *scene_h;
+       FindObjectScanFloatText *scene_x_text, *scene_y_text, *scene_w_text, *scene_h_text;
        FindObjectDrawKeypoints *draw_keypoints;
        FindObjectDrawBorder *draw_border;
        FindObjectReplace *replace_object;
@@ -218,19 +159,8 @@ public:
        FindObjectLayer *object_layer;
        FindObjectLayer *scene_layer;
        FindObjectLayer *replace_layer;
-       FindObjectAlgorithm *algorithm;
-       FindObjectCamParam *vmin;
-       FindObjectCamParam *vmax;
-       FindObjectCamParam *smin;
        FindObjectBlend *blend;
        FindObjectMain *plugin;
 };
 
-
-
-
-
-#endif // FINDOBJECTWINDOW_H
-
-
-
+#endif
index 667700e3c85ff64dd359433212b905e7df3640d5..8a8632fe21018745d3d5d21cfeafec568e8b1f73 100644 (file)
 #ifndef FINDOBJECTWINDOW_INC
 #define FINDOBJECTWINDOW_INC
 
+class FindObjectLayer;
+class FindObjectScanFloat;
+class FindObjectScanFloatText;
+class FindObjectDrawBorder;
+class FindObjectDrawKeypoints;
+class FindObjectReplace;
+class FindObjectDrawObjectBorder;
+class FindObjectAlgorithm;
+class FindObjectUseFlann;
+class FindObjectBlend;
 class FindObjectWindow;
-class FindObjectThread;
 
 #endif
diff --git a/cinelerra-5.1/plugins/findobject/picon_cinfinity.png b/cinelerra-5.1/plugins/findobject/picon_cinfinity.png
new file mode 100644 (file)
index 0000000..aa54323
Binary files /dev/null and b/cinelerra-5.1/plugins/findobject/picon_cinfinity.png differ
diff --git a/cinelerra-5.1/plugins/findobject/surfscan.C b/cinelerra-5.1/plugins/findobject/surfscan.C
deleted file mode 100644 (file)
index fa90a61..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-#include "surfscan.h"
-#include "opencv2/calib3d/calib3d.hpp"
-#include "opencv2/objdetect/objdetect.hpp"
-#include "opencv2/features2d/features2d.hpp"
-
-
-#include <iostream>
-#include <vector>
-#include <stdio.h>
-#include <stdlib.h>
-
-
-
-
-using namespace std;
-
-
-// define whether to use approximate nearest-neighbor search
-#define USE_FLANN
-
-
-double
-compareSURFDescriptors( const float* d1, const float* d2, double best, int length )
-{
-    double total_cost = 0;
-    assert( length % 4 == 0 );
-    for( int i = 0; i < length; i += 4 )
-    {
-        double t0 = d1[i  ] - d2[i  ];
-        double t1 = d1[i+1] - d2[i+1];
-        double t2 = d1[i+2] - d2[i+2];
-        double t3 = d1[i+3] - d2[i+3];
-        total_cost += t0*t0 + t1*t1 + t2*t2 + t3*t3;
-        if( total_cost > best )
-            break;
-    }
-    return total_cost;
-}
-
-
-int
-naiveNearestNeighbor( const float* vec, int laplacian,
-                      const CvSeq* model_keypoints,
-                      const CvSeq* model_descriptors )
-{
-    int length = (int)(model_descriptors->elem_size/sizeof(float));
-    int i, neighbor = -1;
-    double d, dist1 = 1e6, dist2 = 1e6;
-    CvSeqReader reader, kreader;
-    cvStartReadSeq( model_keypoints, &kreader, 0 );
-    cvStartReadSeq( model_descriptors, &reader, 0 );
-
-    for( i = 0; i < model_descriptors->total; i++ )
-    {
-        const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr;
-        const float* mvec = (const float*)reader.ptr;
-       CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
-        CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
-        if( laplacian != kp->laplacian )
-            continue;
-        d = compareSURFDescriptors( vec, mvec, dist2, length );
-        if( d < dist1 )
-        {
-            dist2 = dist1;
-            dist1 = d;
-            neighbor = i;
-        }
-        else if ( d < dist2 )
-            dist2 = d;
-    }
-    if ( dist1 < 0.6*dist2 )
-        return neighbor;
-    return -1;
-}
-
-void
-findPairs( const CvSeq* objectKeypoints, const CvSeq* objectDescriptors,
-           const CvSeq* imageKeypoints, const CvSeq* imageDescriptors, vector<int>& ptpairs )
-{
-    int i;
-    CvSeqReader reader, kreader;
-    cvStartReadSeq( objectKeypoints, &kreader );
-    cvStartReadSeq( objectDescriptors, &reader );
-    ptpairs.clear();
-
-    for( i = 0; i < objectDescriptors->total; i++ )
-    {
-        const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr;
-        const float* descriptor = (const float*)reader.ptr;
-        CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
-        CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
-        int nearest_neighbor = naiveNearestNeighbor( descriptor, kp->laplacian, imageKeypoints, imageDescriptors );
-        if( nearest_neighbor >= 0 )
-        {
-            ptpairs.push_back(i);
-            ptpairs.push_back(nearest_neighbor);
-        }
-    }
-}
-
-
-void
-flannFindPairs( const CvSeq*,
-       const CvSeq* objectDescriptors,
-    const CvSeq*,
-       const CvSeq* imageDescriptors,
-       vector<int>& ptpairs )
-{
-       int length = (int)(objectDescriptors->elem_size/sizeof(float));
-
-    cv::Mat m_object(objectDescriptors->total, length, CV_32F);
-       cv::Mat m_image(imageDescriptors->total, length, CV_32F);
-
-
-       // copy descriptors
-    CvSeqReader obj_reader;
-       float* obj_ptr = m_object.ptr<float>(0);
-    cvStartReadSeq( objectDescriptors, &obj_reader );
-    for(int i = 0; i < objectDescriptors->total; i++ )
-    {
-        const float* descriptor = (const float*)obj_reader.ptr;
-        CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );
-        memcpy(obj_ptr, descriptor, length*sizeof(float));
-        obj_ptr += length;
-    }
-    CvSeqReader img_reader;
-       float* img_ptr = m_image.ptr<float>(0);
-    cvStartReadSeq( imageDescriptors, &img_reader );
-    for(int i = 0; i < imageDescriptors->total; i++ )
-    {
-        const float* descriptor = (const float*)img_reader.ptr;
-        CV_NEXT_SEQ_ELEM( img_reader.seq->elem_size, img_reader );
-        memcpy(img_ptr, descriptor, length*sizeof(float));
-        img_ptr += length;
-    }
-
-    // find nearest neighbors using FLANN
-    cv::Mat m_indices(objectDescriptors->total, 2, CV_32S);
-    cv::Mat m_dists(objectDescriptors->total, 2, CV_32F);
-    cv::flann::Index flann_index(m_image, cv::flann::KDTreeIndexParams(4));  // using 4 randomized kdtrees
-    flann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked
-
-    int* indices_ptr = m_indices.ptr<int>(0);
-    float* dists_ptr = m_dists.ptr<float>(0);
-//printf("flannFindPairs %d m_indices.rows=%d\n", __LINE__, m_indices.rows);
-    for (int i = 0; i < m_indices.rows; ++i)
-       {
-//printf("flannFindPairs %d dists=%f %f\n", __LINE__, dists_ptr[2 * i], 0.6 * dists_ptr[2 * i + 1]);
-       if (dists_ptr[2 * i] < 0.6 * dists_ptr[2 * i + 1])
-               {
-//printf("flannFindPairs %d pairs=%d\n", __LINE__, ptpairs.size());
-               ptpairs.push_back(i);
-               ptpairs.push_back(indices_ptr[2*i]);
-       }
-    }
-}
-
-
-/* a rough implementation for object location */
-int
-locatePlanarObject(const CvSeq* objectKeypoints,
-       const CvSeq* objectDescriptors,
-    const CvSeq* imageKeypoints,
-       const CvSeq* imageDescriptors,
-    const CvPoint src_corners[4],
-       CvPoint dst_corners[4],
-       int *(*point_pairs),
-       int (*total_pairs))
-{
-    double h[9];
-    CvMat _h = cvMat(3, 3, CV_64F, h);
-    vector<int> ptpairs;
-    vector<CvPoint2D32f> pt1, pt2;
-    CvMat _pt1, _pt2;
-    int i, n;
-
-       (*point_pairs) = 0;
-       (*total_pairs) = 0;
-
-#ifdef USE_FLANN
-    flannFindPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
-#else
-    findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
-#endif
-
-
-// Store keypoints
-       (*point_pairs) = (int*)calloc(ptpairs.size(), sizeof(int));
-       (*total_pairs) = ptpairs.size() / 2;
-
-
-    for(int i = 0; i < (int)ptpairs.size(); i++)
-    {
-               (*point_pairs)[i] = ptpairs[i];
-    }
-
-
-
-    n = (int)(ptpairs.size()/2);
-    if( n < 4 )
-        return 0;
-
-    pt1.resize(n);
-    pt2.resize(n);
-    for( i = 0; i < n; i++ )
-    {
-        pt1[i] = ((CvSURFPoint*)cvGetSeqElem(objectKeypoints,ptpairs[i*2]))->pt;
-        pt2[i] = ((CvSURFPoint*)cvGetSeqElem(imageKeypoints,ptpairs[i*2+1]))->pt;
-    }
-
-    _pt1 = cvMat(1, n, CV_32FC2, &pt1[0] );
-    _pt2 = cvMat(1, n, CV_32FC2, &pt2[0] );
-    if( !cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 ))
-        return 0;
-
-    for( i = 0; i < 4; i++ )
-    {
-        double x = src_corners[i].x, y = src_corners[i].y;
-        double Z = 1./(h[6]*x + h[7]*y + h[8]);
-        double X = (h[0]*x + h[1]*y + h[2])*Z;
-        double Y = (h[3]*x + h[4]*y + h[5])*Z;
-        dst_corners[i] = cvPoint(cvRound(X), cvRound(Y));
-    }
-
-    return 1;
-}
-
-
-void locate_points(const CvSeq* objectKeypoints,
-       const CvSeq* objectDescriptors,
-    const CvSeq* imageKeypoints,
-       const CvSeq* imageDescriptors,
-       int *(*points),
-       int *(*sizes),
-       int (*total_points))
-{
-       vector<int> ptpairs;
-
-#ifdef USE_FLANN
-    flannFindPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
-#else
-    findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
-#endif
-
-       (*points) = (int*)calloc(ptpairs.size(), sizeof(int) * 2);
-       (*sizes) = (int*)calloc(ptpairs.size(), sizeof(int));
-       (*total_points) = ptpairs.size();
-
-
-    for(int i = 0; i < (int)ptpairs.size(); i += 2 )
-    {
-        CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, ptpairs[i] );
-        CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( imageKeypoints, ptpairs[i+1] );
-
-
-               (*points)[i * 2] = r2->pt.x;
-               (*points)[i * 2 + 1] = r2->pt.y;
-               (*sizes)[i] = r2->size;
-    }
-}
-
-
-
-
diff --git a/cinelerra-5.1/plugins/findobject/surfscan.h b/cinelerra-5.1/plugins/findobject/surfscan.h
deleted file mode 100644 (file)
index 835e161..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef SURFSCAN_H
-#define SURFSCAN_H
-
-
-// Wrapper & extra functions for object tracking
-
-
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include "opencv2/core/core_c.h"
-
-
-int locatePlanarObject(const CvSeq* objectKeypoints,
-       const CvSeq* objectDescriptors,
-    const CvSeq* imageKeypoints,
-       const CvSeq* imageDescriptors,
-    const CvPoint src_corners[4],
-       CvPoint dst_corners[4],
-       int *(*point_pairs),
-       int (*total_pairs));
-
-void locate_points(const CvSeq* objectKeypoints,
-       const CvSeq* objectDescriptors,
-    const CvSeq* imageKeypoints,
-       const CvSeq* imageDescriptors,
-       int *(*points),
-       int *(*sizes),
-       int *total_points);
-
-
-#ifdef __cplusplus
-
-}
-#endif
-
-
-
-
-#endif
-
-