From c9bbecdcb49b2dc8fdefd017104fd4d052edb8a3 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Mon, 18 Sep 2017 17:31:54 -0600 Subject: [PATCH] rework findobject, add opecv_build --- cinelerra-5.1/cinelerra/ffmpeg.C | 14 +- cinelerra-5.1/configure.ac | 6 +- cinelerra-5.1/guicast/bccmdl.py | 27 +- cinelerra-5.1/guicast/bccmodels.C | 8 + cinelerra-5.1/guicast/bccmodels.h | 2 + cinelerra-5.1/info/plugins.txt | 2 + cinelerra-5.1/opencv_build | 128 ++ cinelerra-5.1/plugin_config | 3 +- cinelerra-5.1/plugin_defs | 2 +- cinelerra-5.1/plugins/Makefile | 4 + cinelerra-5.1/plugins/findobject/Makefile | 36 +- cinelerra-5.1/plugins/findobject/findobject.C | 1618 ++++------------- cinelerra-5.1/plugins/findobject/findobject.h | 246 +-- .../plugins/findobject/findobject.inc | 2 - .../plugins/findobject/findobjectwindow.C | 590 +++--- .../plugins/findobject/findobjectwindow.h | 146 +- .../plugins/findobject/findobjectwindow.inc | 11 +- .../plugins/findobject/picon_cinfinity.png | Bin 0 -> 6480 bytes cinelerra-5.1/plugins/findobject/surfscan.C | 264 --- cinelerra-5.1/plugins/findobject/surfscan.h | 46 - 20 files changed, 943 insertions(+), 2212 deletions(-) create mode 100644 cinelerra-5.1/opencv_build create mode 100644 cinelerra-5.1/plugins/findobject/picon_cinfinity.png delete mode 100644 cinelerra-5.1/plugins/findobject/surfscan.C delete mode 100644 cinelerra-5.1/plugins/findobject/surfscan.h diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index dcbb49c6..63a1196a 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -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=0 && !flushed && curr_pos=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=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; } diff --git a/cinelerra-5.1/configure.ac b/cinelerra-5.1/configure.ac index ab5c9430..3ac93359 100644 --- a/cinelerra-5.1/configure.ac +++ b/cinelerra-5.1/configure.ac @@ -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" diff --git a/cinelerra-5.1/guicast/bccmdl.py b/cinelerra-5.1/guicast/bccmdl.py index d4634e07..27c3a050 100755 --- a/cinelerra-5.1/guicast/bccmdl.py +++ b/cinelerra-5.1/guicast/bccmdl.py @@ -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", \ diff --git a/cinelerra-5.1/guicast/bccmodels.C b/cinelerra-5.1/guicast/bccmodels.C index 6fe12cbb..dc5c2af1 100644 --- a/cinelerra-5.1/guicast/bccmodels.C +++ b/cinelerra-5.1/guicast/bccmodels.C @@ -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; diff --git a/cinelerra-5.1/guicast/bccmodels.h b/cinelerra-5.1/guicast/bccmodels.h index d079b290..57b595f4 100644 --- a/cinelerra-5.1/guicast/bccmodels.h +++ b/cinelerra-5.1/guicast/bccmodels.h @@ -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. diff --git a/cinelerra-5.1/info/plugins.txt b/cinelerra-5.1/info/plugins.txt index 00abacd1..79c54c7c 100644 --- a/cinelerra-5.1/info/plugins.txt +++ b/cinelerra-5.1/info/plugins.txt @@ -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 index 00000000..86d96d1c --- /dev/null +++ b/cinelerra-5.1/opencv_build @@ -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) + diff --git a/cinelerra-5.1/plugin_config b/cinelerra-5.1/plugin_config index e03d3c4d..5615a62e 100644 --- a/cinelerra-5.1/plugin_config +++ b/cinelerra-5.1/plugin_config @@ -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) diff --git a/cinelerra-5.1/plugin_defs b/cinelerra-5.1/plugin_defs index 428cda21..9a663219 100644 --- a/cinelerra-5.1/plugin_defs +++ b/cinelerra-5.1/plugin_defs @@ -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 diff --git a/cinelerra-5.1/plugins/Makefile b/cinelerra-5.1/plugins/Makefile index 5815bc19..cf72e5ac 100644 --- a/cinelerra-5.1/plugins/Makefile +++ b/cinelerra-5.1/plugins/Makefile @@ -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 \ diff --git a/cinelerra-5.1/plugins/findobject/Makefile b/cinelerra-5.1/plugins/findobject/Makefile index d518f01a..7d37d82d 100644 --- a/cinelerra-5.1/plugins/findobject/Makefile +++ b/cinelerra-5.1/plugins/findobject/Makefile @@ -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 - - - diff --git a/cinelerra-5.1/plugins/findobject/findobject.C b/cinelerra-5.1/plugins/findobject/findobject.C index fb9b9f6d..c19226fe 100644 --- a/cinelerra-5.1/plugins/findobject/findobject.C +++ b/cinelerra-5.1/plugins/findobject/findobject.C @@ -16,254 +16,178 @@ * 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 +#include #include 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; yget_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 FindObjectMain::flann_kdtree_matcher() +{ // trees=5 + const Ptr& indexParams = + makePtr(5); + const Ptr& searchParams = + makePtr(); + return makePtr(indexParams, searchParams); } - - -void FindObjectMain::process_surf() +Ptr FindObjectMain::flann_lshidx_matcher() +{ // table_number = 6#12, key_size = 12#20, multi_probe_level = 1#2 + const Ptr& indexParams = + makePtr(6, 12, 1); + const Ptr& searchParams = + makePtr(); + return makePtr(indexParams, searchParams); +} +Ptr 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 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>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; } - diff --git a/cinelerra-5.1/plugins/findobject/findobject.h b/cinelerra-5.1/plugins/findobject/findobject.h index b8a0a434..7825d25f 100644 --- a/cinelerra-5.1/plugins/findobject/findobject.h +++ b/cinelerra-5.1/plugins/findobject/findobject.h @@ -36,28 +36,36 @@ #include #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 +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 DMatchV; + typedef vector DMatches; + typedef vector KeyPointV; + typedef vector 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 detector; + Ptr matcher; + Ptr flann_kdtree_matcher(); + Ptr flann_lshidx_matcher(); + Ptr bf_matcher_norm_l2(); + Ptr bf_matcher_norm_hamming(); }; - - - - - - - - - #endif - - - - - - diff --git a/cinelerra-5.1/plugins/findobject/findobject.inc b/cinelerra-5.1/plugins/findobject/findobject.inc index be271116..0a1262e4 100644 --- a/cinelerra-5.1/plugins/findobject/findobject.inc +++ b/cinelerra-5.1/plugins/findobject/findobject.inc @@ -22,9 +22,7 @@ #ifndef FINDOBJECT_INC #define FINDOBJECT_INC - class FindObjectConfig; class FindObjectMain; - #endif diff --git a/cinelerra-5.1/plugins/findobject/findobjectwindow.C b/cinelerra-5.1/plugins/findobject/findobjectwindow.C index 0e011642..4cde5375 100644 --- a/cinelerra-5.1/plugins/findobject/findobjectwindow.C +++ b/cinelerra-5.1/plugins/findobject/findobjectwindow.C @@ -28,12 +28,7 @@ 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; } - - - - - - - - - - - - diff --git a/cinelerra-5.1/plugins/findobject/findobjectwindow.h b/cinelerra-5.1/plugins/findobject/findobjectwindow.h index 883ebaa7..ef2bc52c 100644 --- a/cinelerra-5.1/plugins/findobject/findobjectwindow.h +++ b/cinelerra-5.1/plugins/findobject/findobjectwindow.h @@ -20,20 +20,28 @@ */ -#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 diff --git a/cinelerra-5.1/plugins/findobject/findobjectwindow.inc b/cinelerra-5.1/plugins/findobject/findobjectwindow.inc index 667700e3..8a8632fe 100644 --- a/cinelerra-5.1/plugins/findobject/findobjectwindow.inc +++ b/cinelerra-5.1/plugins/findobject/findobjectwindow.inc @@ -22,7 +22,16 @@ #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 index 0000000000000000000000000000000000000000..aa543231bd1b3a98fd307ad17f9794a1e20ab92a GIT binary patch literal 6480 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 -#include -#include -#include - - - - -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& 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& 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(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(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(0); - float* dists_ptr = m_dists.ptr(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 ptpairs; - vector 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 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 index 835e1611..00000000 --- a/cinelerra-5.1/plugins/findobject/surfscan.h +++ /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 - - -- 2.26.2