完善目录结构

完善了目录结构,添加了以前的web段com组件调用的代码(在/测试目录下)(部署没有使用到)
This commit is contained in:
yanshui177
2017-05-17 20:43:16 +08:00
parent ad754709a5
commit 6dcd378738
1246 changed files with 671388 additions and 517 deletions

View File

@@ -0,0 +1,538 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = cvaux
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/autotools/aclocal/az_python.m4 \
$(top_srcdir)/autotools/aclocal/pkg.m4 \
$(top_srcdir)/autotools/aclocal/swig_complete.m4 \
$(top_srcdir)/autotools/aclocal/version_at_least.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/cvconfig.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_APPS_FALSE = @BUILD_APPS_FALSE@
BUILD_APPS_TRUE = @BUILD_APPS_TRUE@
BUILD_CARBON_FALSE = @BUILD_CARBON_FALSE@
BUILD_CARBON_TRUE = @BUILD_CARBON_TRUE@
BUILD_DC1394_FALSE = @BUILD_DC1394_FALSE@
BUILD_DC1394_TRUE = @BUILD_DC1394_TRUE@
BUILD_FFMPEG_FALSE = @BUILD_FFMPEG_FALSE@
BUILD_FFMPEG_TRUE = @BUILD_FFMPEG_TRUE@
BUILD_GTK_FALSE = @BUILD_GTK_FALSE@
BUILD_GTK_TRUE = @BUILD_GTK_TRUE@
BUILD_PYTHON_WRAPPERS_FALSE = @BUILD_PYTHON_WRAPPERS_FALSE@
BUILD_PYTHON_WRAPPERS_TRUE = @BUILD_PYTHON_WRAPPERS_TRUE@
BUILD_QUICKTIME_FALSE = @BUILD_QUICKTIME_FALSE@
BUILD_QUICKTIME_TRUE = @BUILD_QUICKTIME_TRUE@
BUILD_V4L_FALSE = @BUILD_V4L_FALSE@
BUILD_V4L_TRUE = @BUILD_V4L_TRUE@
BUILD_XINE_FALSE = @BUILD_XINE_FALSE@
BUILD_XINE_TRUE = @BUILD_XINE_TRUE@
CARBON_CFLAGS = @CARBON_CFLAGS@
CARBON_LIBS = @CARBON_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUG = @DEBUG@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
FFMPEGLIBS = @FFMPEGLIBS@
GREP = @GREP@
GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
GTHREAD_LIBS = @GTHREAD_LIBS@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
IEEE1394LIBS = @IEEE1394LIBS@
IMAGELIBS = @IMAGELIBS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_VERSION = @LT_VERSION@
MAKEINFO = @MAKEINFO@
MMAJOR = @MMAJOR@
MMINOR = @MMINOR@
MSUBMINOR = @MSUBMINOR@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CSPEC = @PYTHON_CSPEC@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_LSPEC = @PYTHON_LSPEC@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
QUICKTIME_CFLAGS = @QUICKTIME_CFLAGS@
QUICKTIME_LIBS = @QUICKTIME_LIBS@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_PYTHON_LIBS = @SWIG_PYTHON_LIBS@
SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
SWIG_RUNTIME_LIBS_DIR = @SWIG_RUNTIME_LIBS_DIR@
SWIG_VERSION = @SWIG_VERSION@
UPDATE_SWIG_WRAPPERS_FALSE = @UPDATE_SWIG_WRAPPERS_FALSE@
UPDATE_SWIG_WRAPPERS_TRUE = @UPDATE_SWIG_WRAPPERS_TRUE@
VERSION = @VERSION@
XINE_LIBS = @XINE_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
SUBDIRS = src include
all: all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cvaux/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu cvaux/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(mkdir_p) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool \
distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
clean clean-generic clean-libtool clean-recursive ctags \
ctags-recursive distclean distclean-generic distclean-libtool \
distclean-recursive distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic maintainer-clean-recursive \
mostlyclean mostlyclean-generic mostlyclean-libtool \
mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,5 @@
# The directory where the include files will be installed
libcvauxincludedir = $(includedir)/opencv
# Which header files to install
libcvauxinclude_HEADERS = cvaux.h cvmat.hpp cvaux.hpp cvvidsurv.hpp

View File

@@ -0,0 +1,464 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = cvaux/include
DIST_COMMON = $(libcvauxinclude_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/autotools/aclocal/az_python.m4 \
$(top_srcdir)/autotools/aclocal/pkg.m4 \
$(top_srcdir)/autotools/aclocal/swig_complete.m4 \
$(top_srcdir)/autotools/aclocal/version_at_least.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/cvconfig.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libcvauxincludedir)"
libcvauxincludeHEADERS_INSTALL = $(INSTALL_HEADER)
HEADERS = $(libcvauxinclude_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_APPS_FALSE = @BUILD_APPS_FALSE@
BUILD_APPS_TRUE = @BUILD_APPS_TRUE@
BUILD_CARBON_FALSE = @BUILD_CARBON_FALSE@
BUILD_CARBON_TRUE = @BUILD_CARBON_TRUE@
BUILD_DC1394_FALSE = @BUILD_DC1394_FALSE@
BUILD_DC1394_TRUE = @BUILD_DC1394_TRUE@
BUILD_FFMPEG_FALSE = @BUILD_FFMPEG_FALSE@
BUILD_FFMPEG_TRUE = @BUILD_FFMPEG_TRUE@
BUILD_GTK_FALSE = @BUILD_GTK_FALSE@
BUILD_GTK_TRUE = @BUILD_GTK_TRUE@
BUILD_PYTHON_WRAPPERS_FALSE = @BUILD_PYTHON_WRAPPERS_FALSE@
BUILD_PYTHON_WRAPPERS_TRUE = @BUILD_PYTHON_WRAPPERS_TRUE@
BUILD_QUICKTIME_FALSE = @BUILD_QUICKTIME_FALSE@
BUILD_QUICKTIME_TRUE = @BUILD_QUICKTIME_TRUE@
BUILD_V4L_FALSE = @BUILD_V4L_FALSE@
BUILD_V4L_TRUE = @BUILD_V4L_TRUE@
BUILD_XINE_FALSE = @BUILD_XINE_FALSE@
BUILD_XINE_TRUE = @BUILD_XINE_TRUE@
CARBON_CFLAGS = @CARBON_CFLAGS@
CARBON_LIBS = @CARBON_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUG = @DEBUG@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
FFMPEGLIBS = @FFMPEGLIBS@
GREP = @GREP@
GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
GTHREAD_LIBS = @GTHREAD_LIBS@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
IEEE1394LIBS = @IEEE1394LIBS@
IMAGELIBS = @IMAGELIBS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_VERSION = @LT_VERSION@
MAKEINFO = @MAKEINFO@
MMAJOR = @MMAJOR@
MMINOR = @MMINOR@
MSUBMINOR = @MSUBMINOR@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CSPEC = @PYTHON_CSPEC@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_LSPEC = @PYTHON_LSPEC@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
QUICKTIME_CFLAGS = @QUICKTIME_CFLAGS@
QUICKTIME_LIBS = @QUICKTIME_LIBS@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_PYTHON_LIBS = @SWIG_PYTHON_LIBS@
SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
SWIG_RUNTIME_LIBS_DIR = @SWIG_RUNTIME_LIBS_DIR@
SWIG_VERSION = @SWIG_VERSION@
UPDATE_SWIG_WRAPPERS_FALSE = @UPDATE_SWIG_WRAPPERS_FALSE@
UPDATE_SWIG_WRAPPERS_TRUE = @UPDATE_SWIG_WRAPPERS_TRUE@
VERSION = @VERSION@
XINE_LIBS = @XINE_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
# The directory where the include files will be installed
libcvauxincludedir = $(includedir)/opencv
# Which header files to install
libcvauxinclude_HEADERS = cvaux.h cvmat.hpp cvaux.hpp cvvidsurv.hpp
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cvaux/include/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu cvaux/include/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
install-libcvauxincludeHEADERS: $(libcvauxinclude_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(libcvauxincludedir)" || $(mkdir_p) "$(DESTDIR)$(libcvauxincludedir)"
@list='$(libcvauxinclude_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(libcvauxincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libcvauxincludedir)/$$f'"; \
$(libcvauxincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libcvauxincludedir)/$$f"; \
done
uninstall-libcvauxincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libcvauxinclude_HEADERS)'; for p in $$list; do \
f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(libcvauxincludedir)/$$f'"; \
rm -f "$(DESTDIR)$(libcvauxincludedir)/$$f"; \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libcvauxincludedir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-libcvauxincludeHEADERS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-libcvauxincludeHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool ctags distclean distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-libcvauxincludeHEADERS install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-libcvauxincludeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,144 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __CVAUX_HPP__
#define __CVAUX_HPP__
#ifdef __cplusplus
/****************************************************************************************\
* Image class *
\****************************************************************************************/
class CV_EXPORTS CvCamShiftTracker
{
public:
CvCamShiftTracker();
virtual ~CvCamShiftTracker();
/**** Characteristics of the object that are calculated by track_object method *****/
float get_orientation() const // orientation of the object in degrees
{ return m_box.angle; }
float get_length() const // the larger linear size of the object
{ return m_box.size.height; }
float get_width() const // the smaller linear size of the object
{ return m_box.size.width; }
CvPoint2D32f get_center() const // center of the object
{ return m_box.center; }
CvRect get_window() const // bounding rectangle for the object
{ return m_comp.rect; }
/*********************** Tracking parameters ************************/
int get_threshold() const // thresholding value that applied to back project
{ return m_threshold; }
int get_hist_dims( int* dims = 0 ) const // returns number of histogram dimensions and sets
{ return m_hist ? cvGetDims( m_hist->bins, dims ) : 0; }
int get_min_ch_val( int channel ) const // get the minimum allowed value of the specified channel
{ return m_min_ch_val[channel]; }
int get_max_ch_val( int channel ) const // get the maximum allowed value of the specified channel
{ return m_max_ch_val[channel]; }
// set initial object rectangle (must be called before initial calculation of the histogram)
bool set_window( CvRect window)
{ m_comp.rect = window; return true; }
bool set_threshold( int threshold ) // threshold applied to the histogram bins
{ m_threshold = threshold; return true; }
bool set_hist_bin_range( int dim, int min_val, int max_val );
bool set_hist_dims( int c_dims, int* dims );// set the histogram parameters
bool set_min_ch_val( int channel, int val ) // set the minimum allowed value of the specified channel
{ m_min_ch_val[channel] = val; return true; }
bool set_max_ch_val( int channel, int val ) // set the maximum allowed value of the specified channel
{ m_max_ch_val[channel] = val; return true; }
/************************ The processing methods *********************************/
// update object position
virtual bool track_object( const IplImage* cur_frame );
// update object histogram
virtual bool update_histogram( const IplImage* cur_frame );
// reset histogram
virtual void reset_histogram();
/************************ Retrieving internal data *******************************/
// get back project image
virtual IplImage* get_back_project()
{ return m_back_project; }
float query( int* bin ) const
{ return m_hist ? cvQueryHistValue_nD( m_hist, bin ) : 0.f; }
protected:
// internal method for color conversion: fills m_color_planes group
virtual void color_transform( const IplImage* img );
CvHistogram* m_hist;
CvBox2D m_box;
CvConnectedComp m_comp;
float m_hist_ranges_data[CV_MAX_DIM][2];
float* m_hist_ranges[CV_MAX_DIM];
int m_min_ch_val[CV_MAX_DIM];
int m_max_ch_val[CV_MAX_DIM];
int m_threshold;
IplImage* m_color_planes[CV_MAX_DIM];
IplImage* m_back_project;
IplImage* m_temp;
IplImage* m_mask;
};
#endif /* __cplusplus */
#endif /* __CVAUX_HPP__ */
/* End of file. */

View File

@@ -0,0 +1,54 @@
EXTRA_DIST = cvaux.dsp cvaux.vcproj cvaux.rc resource.h
INCLUDES = -I. -I$(top_srcdir)/cvaux/include -I$(top_srcdir)/cxcore/include -I$(top_srcdir)/cv/include -I$(top_srcdir)/cv/src -I$(top_srcdir)
noinst_HEADERS = _cvaux.h _cvfacedetection.h _cvvectrack.h _cvvm.h
noinst_LTLIBRARIES = lib_cvaux.la
lib_LTLIBRARIES = libcvaux.la
# convenience library
lib_cvaux_la_SOURCES = \
camshift.cpp cv3dtracker.cpp cvaux.cpp cvauxutils.cpp \
cvbgfg_acmmm2003.cpp cvbgfg_common.cpp cvbgfg_gaussmix.cpp \
cvcalibfilter.cpp cvclique.cpp cvcorrespond.cpp cvcorrimages.cpp \
cvcreatehandmask.cpp cvdpstereo.cpp cveigenobjects.cpp \
cvepilines.cpp cvface.cpp cvfacedetection.cpp cvfacetemplate.cpp \
cvfindface.cpp cvfindhandregion.cpp cvhmm1d.cpp cvhmm.cpp \
cvhmmobs.cpp cvlcm.cpp cvlee.cpp cvlevmar.cpp cvlevmarprojbandle.cpp \
cvlevmartrif.cpp cvlines.cpp cvlmeds.cpp cvmat.cpp cvmorphcontours.cpp \
cvmorphing.cpp cvprewarp.cpp cvscanlines.cpp cvsegment.cpp \
cvsubdiv2.cpp cvtexture.cpp cvtrifocal.cpp cvvecfacetracking.cpp \
cvvideo.cpp decomppoly.cpp enmin.cpp extendededges.cpp \
precomp.cpp \
\
vs/bgfg_estimation.cpp \
vs/blobtrackanalysis.cpp \
vs/blobtrackanalysishist.cpp \
vs/blobtrackanalysisior.cpp \
vs/blobtrackanalysistrackdist.cpp \
vs/blobtrackgen1.cpp \
vs/blobtrackgenyml.cpp \
vs/blobtrackingauto.cpp \
vs/blobtrackingcc.cpp \
vs/blobtrackingccwithcr.cpp \
vs/blobtrackingkalman.cpp \
vs/blobtrackinglist.cpp \
vs/blobtrackingmsfg.cpp \
vs/blobtrackingmsfgs.cpp \
vs/blobtrackpostprockalman.cpp \
vs/blobtrackpostproclinear.cpp \
vs/blobtrackpostproclist.cpp \
vs/enteringblobdetection.cpp \
vs/enteringblobdetectionreal.cpp \
vs/testseq.cpp
lib_cvaux_la_LDFLAGS = -no-undefined @LDFLAGS@
# real library
libcvaux_la_SOURCES = dummy.cpp
libcvaux_la_LDFLAGS = -no-undefined -version-info @LT_VERSION@ @LDFLAGS@
libcvaux_la_LIBADD = \
lib_cvaux.la \
$(top_builddir)/cxcore/src/libcxcore.la \
$(top_builddir)/cv/src/libcv.la \
@LTLIBOBJS@

View File

@@ -0,0 +1,844 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = cvaux/src
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/autotools/aclocal/az_python.m4 \
$(top_srcdir)/autotools/aclocal/pkg.m4 \
$(top_srcdir)/autotools/aclocal/swig_complete.m4 \
$(top_srcdir)/autotools/aclocal/version_at_least.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/autotools/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/cvconfig.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
lib_cvaux_la_LIBADD =
am_lib_cvaux_la_OBJECTS = camshift.lo cv3dtracker.lo cvaux.lo \
cvauxutils.lo cvbgfg_acmmm2003.lo cvbgfg_common.lo \
cvbgfg_gaussmix.lo cvcalibfilter.lo cvclique.lo \
cvcorrespond.lo cvcorrimages.lo cvcreatehandmask.lo \
cvdpstereo.lo cveigenobjects.lo cvepilines.lo cvface.lo \
cvfacedetection.lo cvfacetemplate.lo cvfindface.lo \
cvfindhandregion.lo cvhmm1d.lo cvhmm.lo cvhmmobs.lo cvlcm.lo \
cvlee.lo cvlevmar.lo cvlevmarprojbandle.lo cvlevmartrif.lo \
cvlines.lo cvlmeds.lo cvmat.lo cvmorphcontours.lo \
cvmorphing.lo cvprewarp.lo cvscanlines.lo cvsegment.lo \
cvsubdiv2.lo cvtexture.lo cvtrifocal.lo cvvecfacetracking.lo \
cvvideo.lo decomppoly.lo enmin.lo extendededges.lo precomp.lo \
bgfg_estimation.lo blobtrackanalysis.lo \
blobtrackanalysishist.lo blobtrackanalysisior.lo \
blobtrackanalysistrackdist.lo blobtrackgen1.lo \
blobtrackgenyml.lo blobtrackingauto.lo blobtrackingcc.lo \
blobtrackingccwithcr.lo blobtrackingkalman.lo \
blobtrackinglist.lo blobtrackingmsfg.lo blobtrackingmsfgs.lo \
blobtrackpostprockalman.lo blobtrackpostproclinear.lo \
blobtrackpostproclist.lo enteringblobdetection.lo \
enteringblobdetectionreal.lo testseq.lo
lib_cvaux_la_OBJECTS = $(am_lib_cvaux_la_OBJECTS)
libcvaux_la_DEPENDENCIES = lib_cvaux.la \
$(top_builddir)/cxcore/src/libcxcore.la \
$(top_builddir)/cv/src/libcv.la @LTLIBOBJS@
am_libcvaux_la_OBJECTS = dummy.lo
libcvaux_la_OBJECTS = $(am_libcvaux_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/autotools/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(lib_cvaux_la_SOURCES) $(libcvaux_la_SOURCES)
DIST_SOURCES = $(lib_cvaux_la_SOURCES) $(libcvaux_la_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_APPS_FALSE = @BUILD_APPS_FALSE@
BUILD_APPS_TRUE = @BUILD_APPS_TRUE@
BUILD_CARBON_FALSE = @BUILD_CARBON_FALSE@
BUILD_CARBON_TRUE = @BUILD_CARBON_TRUE@
BUILD_DC1394_FALSE = @BUILD_DC1394_FALSE@
BUILD_DC1394_TRUE = @BUILD_DC1394_TRUE@
BUILD_FFMPEG_FALSE = @BUILD_FFMPEG_FALSE@
BUILD_FFMPEG_TRUE = @BUILD_FFMPEG_TRUE@
BUILD_GTK_FALSE = @BUILD_GTK_FALSE@
BUILD_GTK_TRUE = @BUILD_GTK_TRUE@
BUILD_PYTHON_WRAPPERS_FALSE = @BUILD_PYTHON_WRAPPERS_FALSE@
BUILD_PYTHON_WRAPPERS_TRUE = @BUILD_PYTHON_WRAPPERS_TRUE@
BUILD_QUICKTIME_FALSE = @BUILD_QUICKTIME_FALSE@
BUILD_QUICKTIME_TRUE = @BUILD_QUICKTIME_TRUE@
BUILD_V4L_FALSE = @BUILD_V4L_FALSE@
BUILD_V4L_TRUE = @BUILD_V4L_TRUE@
BUILD_XINE_FALSE = @BUILD_XINE_FALSE@
BUILD_XINE_TRUE = @BUILD_XINE_TRUE@
CARBON_CFLAGS = @CARBON_CFLAGS@
CARBON_LIBS = @CARBON_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEBUG = @DEBUG@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
FFMPEGLIBS = @FFMPEGLIBS@
GREP = @GREP@
GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
GTHREAD_LIBS = @GTHREAD_LIBS@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_LIBS = @GTK_LIBS@
IEEE1394LIBS = @IEEE1394LIBS@
IMAGELIBS = @IMAGELIBS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_VERSION = @LT_VERSION@
MAKEINFO = @MAKEINFO@
MMAJOR = @MMAJOR@
MMINOR = @MMINOR@
MSUBMINOR = @MSUBMINOR@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PYTHON = @PYTHON@
PYTHON_CSPEC = @PYTHON_CSPEC@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_LSPEC = @PYTHON_LSPEC@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
QUICKTIME_CFLAGS = @QUICKTIME_CFLAGS@
QUICKTIME_LIBS = @QUICKTIME_LIBS@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SWIG = @SWIG@
SWIG_PYTHON_LIBS = @SWIG_PYTHON_LIBS@
SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@
SWIG_RUNTIME_LIBS_DIR = @SWIG_RUNTIME_LIBS_DIR@
SWIG_VERSION = @SWIG_VERSION@
UPDATE_SWIG_WRAPPERS_FALSE = @UPDATE_SWIG_WRAPPERS_FALSE@
UPDATE_SWIG_WRAPPERS_TRUE = @UPDATE_SWIG_WRAPPERS_TRUE@
VERSION = @VERSION@
XINE_LIBS = @XINE_LIBS@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
EXTRA_DIST = cvaux.dsp cvaux.vcproj cvaux.rc resource.h
INCLUDES = -I. -I$(top_srcdir)/cvaux/include -I$(top_srcdir)/cxcore/include -I$(top_srcdir)/cv/include -I$(top_srcdir)/cv/src -I$(top_srcdir)
noinst_HEADERS = _cvaux.h _cvfacedetection.h _cvvectrack.h _cvvm.h
noinst_LTLIBRARIES = lib_cvaux.la
lib_LTLIBRARIES = libcvaux.la
# convenience library
lib_cvaux_la_SOURCES = \
camshift.cpp cv3dtracker.cpp cvaux.cpp cvauxutils.cpp \
cvbgfg_acmmm2003.cpp cvbgfg_common.cpp cvbgfg_gaussmix.cpp \
cvcalibfilter.cpp cvclique.cpp cvcorrespond.cpp cvcorrimages.cpp \
cvcreatehandmask.cpp cvdpstereo.cpp cveigenobjects.cpp \
cvepilines.cpp cvface.cpp cvfacedetection.cpp cvfacetemplate.cpp \
cvfindface.cpp cvfindhandregion.cpp cvhmm1d.cpp cvhmm.cpp \
cvhmmobs.cpp cvlcm.cpp cvlee.cpp cvlevmar.cpp cvlevmarprojbandle.cpp \
cvlevmartrif.cpp cvlines.cpp cvlmeds.cpp cvmat.cpp cvmorphcontours.cpp \
cvmorphing.cpp cvprewarp.cpp cvscanlines.cpp cvsegment.cpp \
cvsubdiv2.cpp cvtexture.cpp cvtrifocal.cpp cvvecfacetracking.cpp \
cvvideo.cpp decomppoly.cpp enmin.cpp extendededges.cpp \
precomp.cpp \
\
vs/bgfg_estimation.cpp \
vs/blobtrackanalysis.cpp \
vs/blobtrackanalysishist.cpp \
vs/blobtrackanalysisior.cpp \
vs/blobtrackanalysistrackdist.cpp \
vs/blobtrackgen1.cpp \
vs/blobtrackgenyml.cpp \
vs/blobtrackingauto.cpp \
vs/blobtrackingcc.cpp \
vs/blobtrackingccwithcr.cpp \
vs/blobtrackingkalman.cpp \
vs/blobtrackinglist.cpp \
vs/blobtrackingmsfg.cpp \
vs/blobtrackingmsfgs.cpp \
vs/blobtrackpostprockalman.cpp \
vs/blobtrackpostproclinear.cpp \
vs/blobtrackpostproclist.cpp \
vs/enteringblobdetection.cpp \
vs/enteringblobdetectionreal.cpp \
vs/testseq.cpp
lib_cvaux_la_LDFLAGS = -no-undefined @LDFLAGS@
# real library
libcvaux_la_SOURCES = dummy.cpp
libcvaux_la_LDFLAGS = -no-undefined -version-info @LT_VERSION@ @LDFLAGS@
libcvaux_la_LIBADD = \
lib_cvaux.la \
$(top_builddir)/cxcore/src/libcxcore.la \
$(top_builddir)/cv/src/libcv.la \
@LTLIBOBJS@
all: all-am
.SUFFIXES:
.SUFFIXES: .c .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cvaux/src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu cvaux/src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
lib_cvaux.la: $(lib_cvaux_la_OBJECTS) $(lib_cvaux_la_DEPENDENCIES)
$(CXXLINK) $(lib_cvaux_la_LDFLAGS) $(lib_cvaux_la_OBJECTS) $(lib_cvaux_la_LIBADD) $(LIBS)
libcvaux.la: $(libcvaux_la_OBJECTS) $(libcvaux_la_DEPENDENCIES)
$(CXXLINK) -rpath $(libdir) $(libcvaux_la_LDFLAGS) $(libcvaux_la_OBJECTS) $(libcvaux_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bgfg_estimation.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackanalysis.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackanalysishist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackanalysisior.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackanalysistrackdist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackgen1.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackgenyml.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackingauto.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackingcc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackingccwithcr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackingkalman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackinglist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackingmsfg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackingmsfgs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackpostprockalman.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackpostproclinear.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobtrackpostproclist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camshift.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cv3dtracker.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvaux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvauxutils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvbgfg_acmmm2003.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvbgfg_common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvbgfg_gaussmix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvcalibfilter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvclique.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvcorrespond.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvcorrimages.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvcreatehandmask.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvdpstereo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cveigenobjects.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvepilines.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvfacedetection.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvfacetemplate.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvfindface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvfindhandregion.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvhmm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvhmm1d.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvhmmobs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvlcm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvlee.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvlevmar.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvlevmarprojbandle.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvlevmartrif.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvlines.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvlmeds.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvmat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvmorphcontours.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvmorphing.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvprewarp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvscanlines.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvsegment.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvsubdiv2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvtexture.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvtrifocal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvvecfacetracking.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvvideo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decomppoly.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enmin.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enteringblobdetection.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enteringblobdetectionreal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extendededges.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/precomp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testseq.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
bgfg_estimation.lo: vs/bgfg_estimation.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bgfg_estimation.lo -MD -MP -MF "$(DEPDIR)/bgfg_estimation.Tpo" -c -o bgfg_estimation.lo `test -f 'vs/bgfg_estimation.cpp' || echo '$(srcdir)/'`vs/bgfg_estimation.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/bgfg_estimation.Tpo" "$(DEPDIR)/bgfg_estimation.Plo"; else rm -f "$(DEPDIR)/bgfg_estimation.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/bgfg_estimation.cpp' object='bgfg_estimation.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bgfg_estimation.lo `test -f 'vs/bgfg_estimation.cpp' || echo '$(srcdir)/'`vs/bgfg_estimation.cpp
blobtrackanalysis.lo: vs/blobtrackanalysis.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackanalysis.lo -MD -MP -MF "$(DEPDIR)/blobtrackanalysis.Tpo" -c -o blobtrackanalysis.lo `test -f 'vs/blobtrackanalysis.cpp' || echo '$(srcdir)/'`vs/blobtrackanalysis.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackanalysis.Tpo" "$(DEPDIR)/blobtrackanalysis.Plo"; else rm -f "$(DEPDIR)/blobtrackanalysis.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackanalysis.cpp' object='blobtrackanalysis.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackanalysis.lo `test -f 'vs/blobtrackanalysis.cpp' || echo '$(srcdir)/'`vs/blobtrackanalysis.cpp
blobtrackanalysishist.lo: vs/blobtrackanalysishist.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackanalysishist.lo -MD -MP -MF "$(DEPDIR)/blobtrackanalysishist.Tpo" -c -o blobtrackanalysishist.lo `test -f 'vs/blobtrackanalysishist.cpp' || echo '$(srcdir)/'`vs/blobtrackanalysishist.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackanalysishist.Tpo" "$(DEPDIR)/blobtrackanalysishist.Plo"; else rm -f "$(DEPDIR)/blobtrackanalysishist.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackanalysishist.cpp' object='blobtrackanalysishist.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackanalysishist.lo `test -f 'vs/blobtrackanalysishist.cpp' || echo '$(srcdir)/'`vs/blobtrackanalysishist.cpp
blobtrackanalysisior.lo: vs/blobtrackanalysisior.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackanalysisior.lo -MD -MP -MF "$(DEPDIR)/blobtrackanalysisior.Tpo" -c -o blobtrackanalysisior.lo `test -f 'vs/blobtrackanalysisior.cpp' || echo '$(srcdir)/'`vs/blobtrackanalysisior.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackanalysisior.Tpo" "$(DEPDIR)/blobtrackanalysisior.Plo"; else rm -f "$(DEPDIR)/blobtrackanalysisior.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackanalysisior.cpp' object='blobtrackanalysisior.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackanalysisior.lo `test -f 'vs/blobtrackanalysisior.cpp' || echo '$(srcdir)/'`vs/blobtrackanalysisior.cpp
blobtrackanalysistrackdist.lo: vs/blobtrackanalysistrackdist.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackanalysistrackdist.lo -MD -MP -MF "$(DEPDIR)/blobtrackanalysistrackdist.Tpo" -c -o blobtrackanalysistrackdist.lo `test -f 'vs/blobtrackanalysistrackdist.cpp' || echo '$(srcdir)/'`vs/blobtrackanalysistrackdist.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackanalysistrackdist.Tpo" "$(DEPDIR)/blobtrackanalysistrackdist.Plo"; else rm -f "$(DEPDIR)/blobtrackanalysistrackdist.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackanalysistrackdist.cpp' object='blobtrackanalysistrackdist.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackanalysistrackdist.lo `test -f 'vs/blobtrackanalysistrackdist.cpp' || echo '$(srcdir)/'`vs/blobtrackanalysistrackdist.cpp
blobtrackgen1.lo: vs/blobtrackgen1.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackgen1.lo -MD -MP -MF "$(DEPDIR)/blobtrackgen1.Tpo" -c -o blobtrackgen1.lo `test -f 'vs/blobtrackgen1.cpp' || echo '$(srcdir)/'`vs/blobtrackgen1.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackgen1.Tpo" "$(DEPDIR)/blobtrackgen1.Plo"; else rm -f "$(DEPDIR)/blobtrackgen1.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackgen1.cpp' object='blobtrackgen1.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackgen1.lo `test -f 'vs/blobtrackgen1.cpp' || echo '$(srcdir)/'`vs/blobtrackgen1.cpp
blobtrackgenyml.lo: vs/blobtrackgenyml.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackgenyml.lo -MD -MP -MF "$(DEPDIR)/blobtrackgenyml.Tpo" -c -o blobtrackgenyml.lo `test -f 'vs/blobtrackgenyml.cpp' || echo '$(srcdir)/'`vs/blobtrackgenyml.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackgenyml.Tpo" "$(DEPDIR)/blobtrackgenyml.Plo"; else rm -f "$(DEPDIR)/blobtrackgenyml.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackgenyml.cpp' object='blobtrackgenyml.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackgenyml.lo `test -f 'vs/blobtrackgenyml.cpp' || echo '$(srcdir)/'`vs/blobtrackgenyml.cpp
blobtrackingauto.lo: vs/blobtrackingauto.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackingauto.lo -MD -MP -MF "$(DEPDIR)/blobtrackingauto.Tpo" -c -o blobtrackingauto.lo `test -f 'vs/blobtrackingauto.cpp' || echo '$(srcdir)/'`vs/blobtrackingauto.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackingauto.Tpo" "$(DEPDIR)/blobtrackingauto.Plo"; else rm -f "$(DEPDIR)/blobtrackingauto.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackingauto.cpp' object='blobtrackingauto.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackingauto.lo `test -f 'vs/blobtrackingauto.cpp' || echo '$(srcdir)/'`vs/blobtrackingauto.cpp
blobtrackingcc.lo: vs/blobtrackingcc.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackingcc.lo -MD -MP -MF "$(DEPDIR)/blobtrackingcc.Tpo" -c -o blobtrackingcc.lo `test -f 'vs/blobtrackingcc.cpp' || echo '$(srcdir)/'`vs/blobtrackingcc.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackingcc.Tpo" "$(DEPDIR)/blobtrackingcc.Plo"; else rm -f "$(DEPDIR)/blobtrackingcc.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackingcc.cpp' object='blobtrackingcc.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackingcc.lo `test -f 'vs/blobtrackingcc.cpp' || echo '$(srcdir)/'`vs/blobtrackingcc.cpp
blobtrackingccwithcr.lo: vs/blobtrackingccwithcr.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackingccwithcr.lo -MD -MP -MF "$(DEPDIR)/blobtrackingccwithcr.Tpo" -c -o blobtrackingccwithcr.lo `test -f 'vs/blobtrackingccwithcr.cpp' || echo '$(srcdir)/'`vs/blobtrackingccwithcr.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackingccwithcr.Tpo" "$(DEPDIR)/blobtrackingccwithcr.Plo"; else rm -f "$(DEPDIR)/blobtrackingccwithcr.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackingccwithcr.cpp' object='blobtrackingccwithcr.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackingccwithcr.lo `test -f 'vs/blobtrackingccwithcr.cpp' || echo '$(srcdir)/'`vs/blobtrackingccwithcr.cpp
blobtrackingkalman.lo: vs/blobtrackingkalman.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackingkalman.lo -MD -MP -MF "$(DEPDIR)/blobtrackingkalman.Tpo" -c -o blobtrackingkalman.lo `test -f 'vs/blobtrackingkalman.cpp' || echo '$(srcdir)/'`vs/blobtrackingkalman.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackingkalman.Tpo" "$(DEPDIR)/blobtrackingkalman.Plo"; else rm -f "$(DEPDIR)/blobtrackingkalman.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackingkalman.cpp' object='blobtrackingkalman.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackingkalman.lo `test -f 'vs/blobtrackingkalman.cpp' || echo '$(srcdir)/'`vs/blobtrackingkalman.cpp
blobtrackinglist.lo: vs/blobtrackinglist.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackinglist.lo -MD -MP -MF "$(DEPDIR)/blobtrackinglist.Tpo" -c -o blobtrackinglist.lo `test -f 'vs/blobtrackinglist.cpp' || echo '$(srcdir)/'`vs/blobtrackinglist.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackinglist.Tpo" "$(DEPDIR)/blobtrackinglist.Plo"; else rm -f "$(DEPDIR)/blobtrackinglist.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackinglist.cpp' object='blobtrackinglist.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackinglist.lo `test -f 'vs/blobtrackinglist.cpp' || echo '$(srcdir)/'`vs/blobtrackinglist.cpp
blobtrackingmsfg.lo: vs/blobtrackingmsfg.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackingmsfg.lo -MD -MP -MF "$(DEPDIR)/blobtrackingmsfg.Tpo" -c -o blobtrackingmsfg.lo `test -f 'vs/blobtrackingmsfg.cpp' || echo '$(srcdir)/'`vs/blobtrackingmsfg.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackingmsfg.Tpo" "$(DEPDIR)/blobtrackingmsfg.Plo"; else rm -f "$(DEPDIR)/blobtrackingmsfg.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackingmsfg.cpp' object='blobtrackingmsfg.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackingmsfg.lo `test -f 'vs/blobtrackingmsfg.cpp' || echo '$(srcdir)/'`vs/blobtrackingmsfg.cpp
blobtrackingmsfgs.lo: vs/blobtrackingmsfgs.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackingmsfgs.lo -MD -MP -MF "$(DEPDIR)/blobtrackingmsfgs.Tpo" -c -o blobtrackingmsfgs.lo `test -f 'vs/blobtrackingmsfgs.cpp' || echo '$(srcdir)/'`vs/blobtrackingmsfgs.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackingmsfgs.Tpo" "$(DEPDIR)/blobtrackingmsfgs.Plo"; else rm -f "$(DEPDIR)/blobtrackingmsfgs.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackingmsfgs.cpp' object='blobtrackingmsfgs.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackingmsfgs.lo `test -f 'vs/blobtrackingmsfgs.cpp' || echo '$(srcdir)/'`vs/blobtrackingmsfgs.cpp
blobtrackpostprockalman.lo: vs/blobtrackpostprockalman.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackpostprockalman.lo -MD -MP -MF "$(DEPDIR)/blobtrackpostprockalman.Tpo" -c -o blobtrackpostprockalman.lo `test -f 'vs/blobtrackpostprockalman.cpp' || echo '$(srcdir)/'`vs/blobtrackpostprockalman.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackpostprockalman.Tpo" "$(DEPDIR)/blobtrackpostprockalman.Plo"; else rm -f "$(DEPDIR)/blobtrackpostprockalman.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackpostprockalman.cpp' object='blobtrackpostprockalman.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackpostprockalman.lo `test -f 'vs/blobtrackpostprockalman.cpp' || echo '$(srcdir)/'`vs/blobtrackpostprockalman.cpp
blobtrackpostproclinear.lo: vs/blobtrackpostproclinear.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackpostproclinear.lo -MD -MP -MF "$(DEPDIR)/blobtrackpostproclinear.Tpo" -c -o blobtrackpostproclinear.lo `test -f 'vs/blobtrackpostproclinear.cpp' || echo '$(srcdir)/'`vs/blobtrackpostproclinear.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackpostproclinear.Tpo" "$(DEPDIR)/blobtrackpostproclinear.Plo"; else rm -f "$(DEPDIR)/blobtrackpostproclinear.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackpostproclinear.cpp' object='blobtrackpostproclinear.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackpostproclinear.lo `test -f 'vs/blobtrackpostproclinear.cpp' || echo '$(srcdir)/'`vs/blobtrackpostproclinear.cpp
blobtrackpostproclist.lo: vs/blobtrackpostproclist.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT blobtrackpostproclist.lo -MD -MP -MF "$(DEPDIR)/blobtrackpostproclist.Tpo" -c -o blobtrackpostproclist.lo `test -f 'vs/blobtrackpostproclist.cpp' || echo '$(srcdir)/'`vs/blobtrackpostproclist.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/blobtrackpostproclist.Tpo" "$(DEPDIR)/blobtrackpostproclist.Plo"; else rm -f "$(DEPDIR)/blobtrackpostproclist.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/blobtrackpostproclist.cpp' object='blobtrackpostproclist.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o blobtrackpostproclist.lo `test -f 'vs/blobtrackpostproclist.cpp' || echo '$(srcdir)/'`vs/blobtrackpostproclist.cpp
enteringblobdetection.lo: vs/enteringblobdetection.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT enteringblobdetection.lo -MD -MP -MF "$(DEPDIR)/enteringblobdetection.Tpo" -c -o enteringblobdetection.lo `test -f 'vs/enteringblobdetection.cpp' || echo '$(srcdir)/'`vs/enteringblobdetection.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/enteringblobdetection.Tpo" "$(DEPDIR)/enteringblobdetection.Plo"; else rm -f "$(DEPDIR)/enteringblobdetection.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/enteringblobdetection.cpp' object='enteringblobdetection.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o enteringblobdetection.lo `test -f 'vs/enteringblobdetection.cpp' || echo '$(srcdir)/'`vs/enteringblobdetection.cpp
enteringblobdetectionreal.lo: vs/enteringblobdetectionreal.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT enteringblobdetectionreal.lo -MD -MP -MF "$(DEPDIR)/enteringblobdetectionreal.Tpo" -c -o enteringblobdetectionreal.lo `test -f 'vs/enteringblobdetectionreal.cpp' || echo '$(srcdir)/'`vs/enteringblobdetectionreal.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/enteringblobdetectionreal.Tpo" "$(DEPDIR)/enteringblobdetectionreal.Plo"; else rm -f "$(DEPDIR)/enteringblobdetectionreal.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/enteringblobdetectionreal.cpp' object='enteringblobdetectionreal.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o enteringblobdetectionreal.lo `test -f 'vs/enteringblobdetectionreal.cpp' || echo '$(srcdir)/'`vs/enteringblobdetectionreal.cpp
testseq.lo: vs/testseq.cpp
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT testseq.lo -MD -MP -MF "$(DEPDIR)/testseq.Tpo" -c -o testseq.lo `test -f 'vs/testseq.cpp' || echo '$(srcdir)/'`vs/testseq.cpp; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/testseq.Tpo" "$(DEPDIR)/testseq.Plo"; else rm -f "$(DEPDIR)/testseq.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='vs/testseq.cpp' object='testseq.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o testseq.lo `test -f 'vs/testseq.cpp' || echo '$(srcdir)/'`vs/testseq.cpp
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
clean-noinstLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am: install-libLTLIBRARIES
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
ctags distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-libLTLIBRARIES install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-info-am uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,73 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __CVAUX_H__
#define __CVAUX_H__
#if _MSC_VER >= 1200
#pragma warning( disable: 4710 4711 4514 4996 ) /* function AAA selected for automatic inline expansion */
#endif
#include "cvaux.h"
#include "cxmisc.h"
#include "_cvmatrix.h"
typedef unsigned short ushort;
CV_INLINE bool operator == (CvSize size1, CvSize size2 );
CV_INLINE bool operator == (CvSize size1, CvSize size2 )
{
return size1.width == size2.width && size1.height == size2.height;
}
CV_INLINE bool operator != (CvSize size1, CvSize size2 );
CV_INLINE bool operator != (CvSize size1, CvSize size2 )
{
return size1.width != size2.width || size1.height != size2.height;
}
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#endif /* __CVAUX_H__ */

View File

@@ -0,0 +1,412 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
///////////////////////////////////////////////
//// Created by Khudyakov V.A. bober@gorodok.net
// FaceDetection.h: interface for the FaceDetection class.
//
//////////////////////////////////////////////////////////////////////
#ifndef _CVFACEDETECTION_H_
#define _CVFACEDETECTION_H_
#define MAX_LAYERS 64
class FaceFeature
{
public:
FaceFeature(double dWeight,void * lpContour,bool bIsFeature);
FaceFeature();
virtual ~FaceFeature();
inline bool isFaceFeature();
inline void * GetContour();
inline double GetWeight();
inline void SetContour(void * lpContour);
inline void SetWeight(double dWeight);
inline void SetFeature(bool bIsFeature);
private:
double m_dWeight;
void * m_lpContour;
bool m_bIsFaceFeature;
};//class FaceFeature
inline void FaceFeature::SetFeature(bool bIsFeature)
{
m_bIsFaceFeature = bIsFeature;
}
inline bool FaceFeature::isFaceFeature()
{
return m_bIsFaceFeature;
}//inline bool FaceFeature::isFaceFeature()
inline void * FaceFeature::GetContour()
{
return m_lpContour;
}//inline void * FaceFeature::GetContour()
inline double FaceFeature::GetWeight()
{
return m_dWeight;
}//inline long FaceFeature::GetWeight()
inline void FaceFeature::SetContour(void * lpContour)
{
m_lpContour = lpContour;
}//inline void FaceFeature::SetContour(void * lpContour)
inline void FaceFeature::SetWeight(double dWeight)
{
m_dWeight = dWeight;
}//inline void FaceFeature::SetWeight(double * dWeight)
class FaceTemplate
{
public:
FaceTemplate(long lFeatureCount) {m_lFeturesCount = lFeatureCount; m_lpFeaturesList = new FaceFeature[lFeatureCount];};
virtual ~FaceTemplate();
inline long GetCount();
inline FaceFeature * GetFeatures();
protected:
FaceFeature * m_lpFeaturesList;
private:
long m_lFeturesCount;
};//class FaceTemplate
inline long FaceTemplate::GetCount()
{
return m_lFeturesCount;
}//inline long FaceTemplate::GetCount()
inline FaceFeature * FaceTemplate::GetFeatures()
{
return m_lpFeaturesList;
}//inline FaceFeature * FaceTemplate::GetFeatures()
////////////
//class RFaceTemplate
///////////
class MouthFaceTemplate:public FaceTemplate
{
public:
inline MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth);
~MouthFaceTemplate();
};//class MouthFaceTemplate:public FaceTemplate
inline MouthFaceTemplate::MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight,
double dDistanceBetweenEye,double dDistanceEyeAboveMouth):FaceTemplate(lNumber)
{
CvRect MouthRect = rect;
CvRect LeftEyeRect = cvRect(cvRound(rect.x - (dEyeWidth + dDistanceBetweenEye/(double)2 - (double)rect.width/(double)2)),
cvRound(rect.y - dDistanceEyeAboveMouth - dEyeHeight),
cvRound(dEyeWidth),
cvRound(dEyeHeight) );
CvRect RightEyeRect = cvRect(cvRound(rect.x + (double)rect.width/(double)2 + dDistanceBetweenEye/(double)2),
cvRound(rect.y - dDistanceEyeAboveMouth - dEyeHeight),
cvRound(dEyeWidth),
cvRound(dEyeHeight) );
// CvRect NoseRect = cvRect(cvRound(rect.x + (double)rect.width/(double)4),
// cvRound(rect.y - (double)rect.width/(double)2 - (double)rect.height/(double)4),
// cvRound((double)rect.width/(double)2),
// cvRound((double)rect.width/(double)2) );
/*
CvRect CheenRect = cvRect(rect.x,rect.y + 3*rect.height/2,rect.width,rect.height);
*/
CvRect * lpMouthRect = new CvRect();
*lpMouthRect = MouthRect;
m_lpFeaturesList[0].SetContour(lpMouthRect);
m_lpFeaturesList[0].SetWeight(1);
m_lpFeaturesList[0].SetFeature(false);
CvRect * lpLeftEyeRect = new CvRect();
*lpLeftEyeRect = LeftEyeRect;
m_lpFeaturesList[1].SetContour(lpLeftEyeRect);
m_lpFeaturesList[1].SetWeight(1);
m_lpFeaturesList[1].SetFeature(true);
CvRect * lpRightEyeRect = new CvRect();
*lpRightEyeRect = RightEyeRect;
m_lpFeaturesList[2].SetContour(lpRightEyeRect);
m_lpFeaturesList[2].SetWeight(1);
m_lpFeaturesList[2].SetFeature(true);
// CvRect * lpNoseRect = new CvRect();
// *lpNoseRect = NoseRect;
// m_lpFeaturesList[3].SetContour(lpNoseRect);
// m_lpFeaturesList[3].SetWeight(0);
// m_lpFeaturesList[3].SetFeature(true);
/* CvRect * lpCheenRect = new CvRect();
*lpCheenRect = CheenRect;
m_lpFeaturesList[4].SetContour(lpCheenRect);
m_lpFeaturesList[4].SetWeight(1);
m_lpFeaturesList[4].SetFeature(false);
*/
}//constructor MouthFaceTemplate(long lNumFeatures,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth);
typedef struct CvContourRect
{
int iNumber;
int iType;
int iFlags;
CvSeq *seqContour;
int iContourLength;
CvRect r;
CvPoint pCenter;
int iColor;
} CvContourRect;
class Face
{
public:
Face(FaceTemplate * lpFaceTemplate);
virtual ~Face();
inline bool isFeature(void * lpElem);
virtual void Show(IplImage * /*Image*/){};
virtual void ShowIdeal(IplImage* /*Image*/){};
virtual void CreateFace(void * lpData) = 0;
virtual bool CheckElem(void * lpCandidat,void * lpIdeal) = 0;
virtual double GetWeight() = 0;
protected:
FaceFeature * m_lpIdealFace;//ideal face definition
long m_lFaceFeaturesNumber; //total number of diferent face fetures
long * m_lplFaceFeaturesCount;//number of each fetures fouded for this face
FaceFeature ** m_lppFoundedFaceFeatures;//founded features of curen face
double m_dWeight;
};
inline bool Face::isFeature(void * lpElem)
{
for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
{
void * lpIdeal = m_lpIdealFace[i].GetContour();
if ( CheckElem( lpElem,lpIdeal) )
{
if (m_lplFaceFeaturesCount[i] < 3*MAX_LAYERS)
{
double dWeight = m_lpIdealFace[i].GetWeight();
bool bIsFeature = m_lpIdealFace[i].isFaceFeature();
if (bIsFeature)
{
m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetWeight(dWeight);
m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetContour(lpElem);
m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetFeature(bIsFeature);
m_lplFaceFeaturesCount[i] ++;
}
m_dWeight += dWeight;
if (bIsFeature)
return true;
}
}
}
return false;
}//inline bool RFace::isFeature(void * lpElem);
struct FaceData
{
CvRect LeftEyeRect;
CvRect RightEyeRect;
CvRect MouthRect;
double Error;
};//struct FaceData
class RFace:public Face
{
public:
RFace(FaceTemplate * lpFaceTemplate);
virtual ~RFace();
virtual bool CheckElem(void * lpCandidat,void * lpIdeal);
virtual void CreateFace(void * lpData);
virtual void Show(IplImage* Image);
virtual void ShowIdeal(IplImage* Image);
virtual double GetWeight();
private:
bool isPointInRect(CvPoint p,CvRect rect);
bool m_bIsGenerated;
void ResizeRect(CvRect Rect,CvRect * lpRect,long lDir,long lD);
void CalculateError(FaceData * lpFaceData);
};
class ListElem
{
public:
ListElem();
ListElem(Face * pFace,ListElem * pHead);
virtual ~ListElem();
ListElem * m_pNext;
ListElem * m_pPrev;
Face * m_pFace;
};//class ListElem
class List
{
public:
List();
int AddElem(Face * pFace);
virtual ~List();
Face* GetData();
long m_FacesCount;
private:
ListElem * m_pHead;
ListElem * m_pCurElem;
};//class List
class FaceDetection
{
public:
void FindFace(IplImage* img);
void CreateResults(CvSeq * lpSeq);
FaceDetection();
virtual ~FaceDetection();
void SetBoosting(bool bBoosting) {m_bBoosting = bBoosting;}
bool isPostBoosting() {return m_bBoosting;}
protected:
IplImage* m_imgGray;
IplImage* m_imgThresh;
int m_iNumLayers;
CvMemStorage* m_mstgContours;
CvSeq* m_seqContours[MAX_LAYERS];
CvMemStorage* m_mstgRects;
CvSeq* m_seqRects;
bool m_bBoosting;
List * m_pFaceList;
protected:
void ResetImage();
void FindContours(IplImage* imgGray);
void AddContours2Rect(CvSeq* seq, int color, int iLayer);
void ThresholdingParam(IplImage* imgGray, int iNumLayers, int& iMinLevel, int& iMaxLevel, int& iStep);
void FindCandidats();
void PostBoostingFindCandidats(IplImage * FaceImage);
};
inline void ReallocImage(IplImage** ppImage, CvSize sz, long lChNum)
{
IplImage* pImage;
if( ppImage == NULL )
return;
pImage = *ppImage;
if( pImage != NULL )
{
if (pImage->width != sz.width || pImage->height != sz.height || pImage->nChannels != lChNum)
cvReleaseImage( &pImage );
}
if( pImage == NULL )
pImage = cvCreateImage( sz, IPL_DEPTH_8U, lChNum);
*ppImage = pImage;
}
////////////
//class RFaceTemplate
///////////
class BoostingFaceTemplate:public FaceTemplate
{
public:
inline BoostingFaceTemplate(long lNumber,CvRect rect);
~BoostingFaceTemplate() {};
};//class RFaceTemplate:public FaceTemplate
inline BoostingFaceTemplate::BoostingFaceTemplate(long lNumber,CvRect rect):FaceTemplate(lNumber)
{
long EyeWidth = rect.width/5;
long EyeHeight = EyeWidth;
CvRect LeftEyeRect = cvRect(rect.x + EyeWidth,rect.y + rect.height/2 - EyeHeight,EyeWidth,EyeHeight);
CvRect RightEyeRect = cvRect(rect.x + 3*EyeWidth,rect.y + rect.height/2 - EyeHeight,EyeWidth,EyeHeight);
CvRect MouthRect = cvRect(rect.x + 3*EyeWidth/2,rect.y + 3*rect.height/4 - EyeHeight/2,2*EyeWidth,EyeHeight);
CvRect * lpMouthRect = new CvRect();
*lpMouthRect = MouthRect;
m_lpFeaturesList[0].SetContour(lpMouthRect);
m_lpFeaturesList[0].SetWeight(1);
m_lpFeaturesList[0].SetFeature(true);
CvRect * lpLeftEyeRect = new CvRect();
*lpLeftEyeRect = LeftEyeRect;
m_lpFeaturesList[1].SetContour(lpLeftEyeRect);
m_lpFeaturesList[1].SetWeight(1);
m_lpFeaturesList[1].SetFeature(true);
CvRect * lpRightEyeRect = new CvRect();
*lpRightEyeRect = RightEyeRect;
m_lpFeaturesList[2].SetContour(lpRightEyeRect);
m_lpFeaturesList[2].SetWeight(1);
m_lpFeaturesList[2].SetFeature(true);
}//inline BoostingFaceTemplate::BoostingFaceTemplate(long lNumber,CvRect rect):FaceTemplate(lNumber)
#endif // !defined(AFX_FACEDETECTION_H__55865033_D8E5_4DD5_8925_34C2285BB1BE__INCLUDED_)

View File

@@ -0,0 +1,163 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __CVVECTRACK_H__
#define __CVVECTRACK_H__
#include <string.h>
#include <math.h>
#include <time.h>
#include <stdio.h>
#undef max
#undef min
#define max(a,b) ((a)<(b) ? (b) : (a))
#define min(a,b) ((a)>(b) ? (a) : (b))
inline int pow2(int v)
{
return (v*v);
}
inline int operator == (const CvRect& r1, const CvRect& r2)
{
return (r1.x == r2.x) && (r1.y == r2.y) &&
(r1.width == r2.width) && (r1.height == r2.height);
}
inline int operator != (const CvRect& r1, const CvRect& r2)
{
return !(r1 == r2);
}
inline
int CmpPoints(const CvPoint& p1, const CvPoint& p2, int err)
{
/* Simakov: modify __max to max */
return (max(abs(p1.x - p2.x), abs(p1.y - p2.y)) < err);
}
inline
int PointInRect(const CvPoint& p, const CvRect& r)
{
return ((p.x > r.x) && (p.x < (r.x + r.width)) &&
(p.y > r.y) && (p.y < (r.y + r.height)));
}
inline
int RectInRect(const CvRect& r1, const CvRect& r2)
{
CvPoint plt = {r1.x, r1.y};
CvPoint prb = {r1.x + r1.width, r1.y + r1.height};
return (PointInRect(plt, r2) && PointInRect(prb, r2));
}
inline
CvRect Increase(const CvRect& r, int decr)
{
CvRect rect;
rect.x = r.x * decr;
rect.y = r.y * decr;
rect.width = r.width * decr;
rect.height = r.height * decr;
return rect;
}
inline
CvPoint Increase(const CvPoint& p, int decr)
{
CvPoint point;
point.x = p.x * decr;
point.y = p.y * decr;
return point;
}
inline
void Move(CvRect& r, int dx, int dy)
{
r.x += dx;
r.y += dy;
}
inline
void Move(CvPoint& p, int dx, int dy)
{
p.x += dx;
p.y += dy;
}
inline
void Extend(CvRect& r, int d)
{
r.x -= d;
r.y -= d;
r.width += 2*d;
r.height += 2*d;
}
inline
CvPoint Center(const CvRect& r)
{
CvPoint p;
p.x = r.x + r.width / 2;
p.y = r.y + r.height / 2;
return p;
}
inline void ReallocImage(IplImage** ppImage, CvSize sz, long lChNum)
{
IplImage* pImage;
if( ppImage == NULL )
return;
pImage = *ppImage;
if( pImage != NULL )
{
if (pImage->width != sz.width || pImage->height != sz.height || pImage->nChannels != lChNum)
cvReleaseImage( &pImage );
}
if( pImage == NULL )
pImage = cvCreateImage( sz, IPL_DEPTH_8U, lChNum);
*ppImage = pImage;
}
#endif //__VECTRACK_H__

View File

@@ -0,0 +1,298 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef _CV_VM_H_
#define _CV_VM_H_
/*----------------------- Internal ViewMorphing Functions ------------------------------*/
/*======================================================================================*/
typedef struct CvMatrix4
{
float m[4][4];
}
CvMatrix4;
/* Scanline section. Find coordinates by fundamental matrix */
/* Epsilon and real zero */
#define EPSILON 1.e-4
//#define REAL_ZERO(x) ( (x) < EPSILON && (x) > -EPSILON)
#define REAL_ZERO(x) ( (x) < 1e-8 && (x) > -1e-8)
#define SIGN(x) ( (x)<0 ? -1:((x)>0?1:0 ) )
CvStatus icvMakeScanlinesLengths( int* scanlines,
int numlines,
int* lens);
/*=============================== PreWarp section ======================================*/
CV_INLINE int icvGetColor(uchar* valueRGB);
CvStatus icvFindRunsInOneImage(
int numLines, /* number of scanlines */
uchar* prewarp, /* prewarp image */
int* line_lens, /* line lengths in pixels */
int* runs, /* result runs */
int* num_runs);
/*================================ Morphing section ====================================*/
CvStatus icvMorphEpilines8uC3( uchar* first_pix, /* raster epiline from the first image */
uchar* second_pix, /* raster epiline from the second image */
uchar* dst_pix, /* raster epiline from the destination image */
/* (it's an output parameter) */
float alpha, /* relative position of camera */
int* first, /* first sequence of runs */
int first_runs, /* it's length */
int* second, /* second sequence of runs */
int second_runs,
int* first_corr, /* correspond information for the 1st seq */
int* second_corr,
int dst_len); /* correspond information for the 2nd seq */
/*========================== Dynamic correspond section ================================*/
CvStatus icvDynamicCorrespond( int* first, /* first sequence of runs */
/* s0|w0|s1|w1|...|s(n-1)|w(n-1)|sn */
int first_runs, /* number of runs */
int* second, /* second sequence of runs */
int second_runs,
int* first_corr, /* s0'|e0'|s1'|e1'|... */
int* second_corr );
/*============================= PostWarp Functions =====================================*/
CvStatus icvFetchLine8uC3R(
uchar* src, int src_step,
uchar* dst, int* dst_num,
CvSize src_size,
CvPoint start,
CvPoint end );
CvStatus icvDrawLine8uC3R(
uchar* src, int src_num,
uchar* dst, int dst_step,
CvSize dst_size,
CvPoint start,
CvPoint end );
/*============================== Fundamental Matrix Functions ==========================*/
CvStatus icvPoint7( int* points1,
int* points2,
double* F,
int* amount
);
CvStatus icvCubic( double a2, double a1,
double a0, double* squares );
double icvDet( double* M );
double icvMinor( double* M, int x, int y );
int
icvGaussMxN( double *A, double *B, int M, int N, double **solutions );
CvStatus
icvGetCoef( double *f1, double *f2, double *a2, double *a1, double *a0 );
/*================================= Scanlines Functions ================================*/
CvStatus icvGetCoefficient( CvMatrix3* matrix,
CvSize imgSize,
int* scanlines_1,
int* scanlines_2,
int* numlines);
CvStatus icvGetCoefficientDefault( CvMatrix3* matrix,
CvSize imgSize,
int* scanlines_1,
int* scanlines_2,
int* numlines);
CvStatus icvGetCoefficientStereo( CvMatrix3* matrix,
CvSize imgSize,
float* l_epipole,
float* r_epipole,
int* scanlines_1,
int* scanlines_2,
int* numlines
);
CvStatus icvGetCoefficientOrto( CvMatrix3* matrix,
CvSize imgSize,
int* scanlines_1,
int* scanlines_2,
int* numlines);
CvStatus icvGetCrossEpilineFrame( CvSize imgSize,
float* epiline,
int* x1,
int* y1,
int* x2,
int* y2
);
CvStatus icvBuildScanlineLeftStereo(
CvSize imgSize,
CvMatrix3* matrix,
float* l_epipole,
float* l_angle,
float l_radius,
int* scanlines_1,
int* scanlines_2,
int* numlines);
CvStatus icvBuildScanlineRightStereo(
CvSize imgSize,
CvMatrix3* matrix,
float* r_epipole,
float* r_angle,
float r_radius,
int* scanlines_1,
int* scanlines_2,
int* numlines);
CvStatus icvGetStartEnd1(
CvMatrix3* matrix,
CvSize imgSize,
float* l_start_end,
float* r_start_end );
CvStatus icvGetStartEnd2(
CvMatrix3* matrix,
CvSize imgSize,
float* l_start_end,
float* r_start_end );
CvStatus icvGetStartEnd3(
CvMatrix3* matrix,
CvSize imgSize,
float* l_start_end,
float* r_start_end );
CvStatus icvGetStartEnd4(
CvMatrix3* matrix,
CvSize imgSize,
float* l_start_end,
float* r_start_end );
CvStatus icvBuildScanlineLeft(
CvMatrix3* matrix,
CvSize imgSize,
int* scanlines_1,
int* scanlines_2,
float* l_start_end,
int* numlines
);
CvStatus icvBuildScanlineRight(
CvMatrix3* matrix,
CvSize imgSize,
int* scanlines_1,
int* scanlines_2,
float* r_start_end,
int* numlines
);
/*=================================== LMedS Functions ==================================*/
CvStatus icvLMedS7(
int* points1,
int* points2,
CvMatrix3* matrix);
CvStatus icvLMedS( int* points1,
int* points2,
int numPoints,
CvMatrix3* fundamentalMatrix );
/*
CvStatus icvFindFundamentalMatrix(
int* points1,
int* points2,
int numpoints,
int method,
CvMatrix3* matrix);
*/
void icvChoose7( int* ml, int* mr,
int num, int* ml7,
int* mr7 );
double icvMedian( int* ml, int* mr,
int num, double* F );
int icvBoltingPoints( int* ml, int* mr,
int num, double* F,
double Mj, int* *new_ml,
int* *new_mr, int* new_num);
CvStatus icvPoints8( int* ml, int* mr,
int num, double* F );
CvStatus icvRank2Constraint( double* F );
CvStatus icvSort( double* array, int length );
double icvAnalyticPoints8( double* A,
int num, double* F );
int icvSingularValueDecomposition( int M,
int N,
double* A,
double* W,
int get_U,
double* U,
int get_V,
double* V
);
/*======================================================================================*/
#endif/*_CV_VM_H_*/

View File

@@ -0,0 +1,285 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
CvCamShiftTracker::CvCamShiftTracker()
{
int i;
memset( &m_box, 0, sizeof(m_box));
memset( &m_comp, 0, sizeof(m_comp));
memset( m_color_planes, 0, sizeof(m_color_planes));
m_threshold = 0;
for( i = 0; i < CV_MAX_DIM; i++ )
{
m_min_ch_val[i] = 0;
m_max_ch_val[i] = 255;
m_hist_ranges[i] = m_hist_ranges_data[i];
m_hist_ranges[i][0] = 0.f;
m_hist_ranges[i][1] = 256.f;
}
m_hist = 0;
m_back_project = 0;
m_temp = 0;
m_mask = 0;
}
CvCamShiftTracker::~CvCamShiftTracker()
{
int i;
cvReleaseHist( &m_hist );
for( i = 0; i < CV_MAX_DIM; i++ )
cvReleaseImage( &m_color_planes[i] );
cvReleaseImage( &m_back_project );
cvReleaseImage( &m_temp );
cvReleaseImage( &m_mask );
}
void
CvCamShiftTracker::color_transform( const IplImage* image )
{
CvSize size = cvGetSize(image);
uchar* color_data = 0, *mask = 0;
uchar* planes[CV_MAX_DIM];
int x, color_step = 0, plane_step = 0, mask_step;
int dims[CV_MAX_DIM];
int i, n = get_hist_dims(dims);
assert( image->nChannels == 3 && m_hist != 0 );
if( !m_temp || !m_mask || !m_color_planes[0] || !m_color_planes[n-1] || !m_back_project ||
m_temp->width != size.width || m_temp->height != size.height ||
m_temp->nChannels != 3 )
{
cvReleaseImage( &m_temp );
m_temp = cvCreateImage( size, IPL_DEPTH_8U, 3 );
cvReleaseImage( &m_mask );
m_mask = cvCreateImage( size, IPL_DEPTH_8U, 1 );
cvReleaseImage( &m_back_project );
m_back_project = cvCreateImage( size, IPL_DEPTH_8U, 1 );
for( i = 0; i < CV_MAX_DIM; i++ )
{
cvReleaseImage( &m_color_planes[i] );
if( i < n )
m_color_planes[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
}
}
cvCvtColor( image, m_temp, CV_BGR2HSV );
cvGetRawData( m_temp, &color_data, &color_step, &size );
cvGetRawData( m_mask, &mask, &mask_step, &size );
for( i = 0; i < n; i++ )
cvGetRawData( m_color_planes[i], &planes[i], &plane_step, &size );
for( ; size.height--; color_data += color_step, mask += mask_step )
{
for( x = 0; x < size.width; x++ )
{
int val0 = color_data[x*3];
int val1 = color_data[x*3+1];
int val2 = color_data[x*3+2];
if( m_min_ch_val[0] <= val0 && val0 <= m_max_ch_val[0] &&
m_min_ch_val[1] <= val1 && val1 <= m_max_ch_val[1] &&
m_min_ch_val[2] <= val2 && val2 <= m_max_ch_val[2] )
{
// hue is written to the 0-th plane, saturation - to the 1-st one,
// so 1d histogram will automagically correspond to hue-based tracking,
// 2d histogram - to saturation-based tracking.
planes[0][x] = (uchar)val0;
if( n > 1 )
planes[1][x] = (uchar)val1;
if( n > 2 )
planes[2][x] = (uchar)val2;
mask[x] = (uchar)255;
}
else
{
planes[0][x] = 0;
if( n > 1 )
planes[1][x] = 0;
if( n > 2 )
planes[2][x] = 0;
mask[x] = 0;
}
}
for( i = 0; i < n; i++ )
planes[i] += plane_step;
}
}
bool
CvCamShiftTracker::update_histogram( const IplImage* cur_frame )
{
float max_val = 0;
int i, dims;
if( m_comp.rect.width == 0 || m_comp.rect.height == 0 ||
m_hist == 0 )
{
assert(0);
return false;
}
color_transform(cur_frame);
dims = cvGetDims( m_hist->bins );
for( i = 0; i < dims; i++ )
cvSetImageROI( m_color_planes[i], m_comp.rect );
cvSetImageROI( m_mask, m_comp.rect );
cvSetHistBinRanges( m_hist, m_hist_ranges, 1 );
cvCalcHist( m_color_planes, m_hist, 0, m_mask );
for( i = 0; i < dims; i++ )
cvSetImageROI( m_color_planes[i], m_comp.rect );
for( i = 0; i < dims; i++ )
cvResetImageROI( m_color_planes[i] );
cvResetImageROI( m_mask );
cvGetMinMaxHistValue( m_hist, 0, &max_val );
cvScale( m_hist->bins, m_hist->bins, max_val ? 255. / max_val : 0. );
return max_val != 0;
}
void
CvCamShiftTracker::reset_histogram()
{
if( m_hist )
cvClearHist( m_hist );
}
bool
CvCamShiftTracker::track_object( const IplImage* cur_frame )
{
CvRect rect;
CvSize bp_size;
union
{
void** arr;
IplImage** img;
} u;
if( m_comp.rect.width == 0 || m_comp.rect.height == 0 ||
m_hist == 0 )
{
return false;
}
color_transform( cur_frame );
u.img = m_color_planes;
cvCalcArrBackProject( u.arr, m_back_project, m_hist );
cvAnd( m_back_project, m_mask, m_back_project );
rect = m_comp.rect;
bp_size = cvGetSize( m_back_project );
if( rect.x < 0 )
rect.x = 0;
if( rect.x + rect.width > bp_size.width )
rect.width = bp_size.width - rect.x;
if( rect.y < 0 )
rect.y = 0;
if( rect.y + rect.height > bp_size.height )
rect.height = bp_size.height - rect.y;
cvCamShift( m_back_project, rect,
cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),
&m_comp, &m_box );
if( m_comp.rect.width == 0 || m_comp.rect.height == 0 )
m_comp.rect = rect; // do not allow tracker to loose the object
return m_comp.rect.width != 0 && m_comp.rect.height != 0;
}
bool
CvCamShiftTracker::set_hist_dims( int c_dims, int *dims )
{
if( (unsigned)(c_dims-1) >= (unsigned)CV_MAX_DIM || dims == 0 )
return false;
if( m_hist )
{
int dims2[CV_MAX_DIM];
int c_dims2 = cvGetDims( m_hist->bins, dims2 );
if( c_dims2 == c_dims && memcmp( dims, dims2, c_dims*sizeof(dims[0])) == 0 )
return true;
cvReleaseHist( &m_hist );
}
m_hist = cvCreateHist( c_dims, dims, CV_HIST_ARRAY, 0, 0 );
return true;
}
bool
CvCamShiftTracker::set_hist_bin_range( int channel, int min_val, int max_val )
{
if( (unsigned)channel >= (unsigned)CV_MAX_DIM ||
min_val >= max_val || min_val < 0 || max_val > 256 )
{
assert(0);
return false;
}
m_hist_ranges[channel][0] = (float)min_val;
m_hist_ranges[channel][1] = (float)max_val;
return true;
}
/* End of file. */

View File

@@ -0,0 +1,586 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2002, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#if _MSC_VER >= 1200
#pragma warning(disable:4786) // Disable MSVC warnings in the standard library.
#pragma warning(disable:4100)
#pragma warning(disable:4512)
#endif
#include <stdio.h>
#include <map>
#include <algorithm>
#if _MSC_VER >= 1200
#pragma warning(default:4100)
#pragma warning(default:4512)
#endif
#define ARRAY_SIZEOF(a) (sizeof(a)/sizeof((a)[0]))
static void FillObjectPoints(CvPoint3D32f *obj_points, CvSize etalon_size, float square_size);
static void DrawEtalon(IplImage *img, CvPoint2D32f *corners,
int corner_count, CvSize etalon_size, int draw_ordered);
static void MultMatrix(float rm[4][4], const float m1[4][4], const float m2[4][4]);
static void MultVectorMatrix(float rv[4], const float v[4], const float m[4][4]);
static CvPoint3D32f ImageCStoWorldCS(const Cv3dTrackerCameraInfo &camera_info, CvPoint2D32f p);
static bool intersection(CvPoint3D32f o1, CvPoint3D32f p1,
CvPoint3D32f o2, CvPoint3D32f p2,
CvPoint3D32f &r1, CvPoint3D32f &r2);
/////////////////////////////////
// cv3dTrackerCalibrateCameras //
/////////////////////////////////
CV_IMPL CvBool cv3dTrackerCalibrateCameras(int num_cameras,
const Cv3dTrackerCameraIntrinsics camera_intrinsics[], // size is num_cameras
CvSize etalon_size,
float square_size,
IplImage *samples[], // size is num_cameras
Cv3dTrackerCameraInfo camera_info[]) // size is num_cameras
{
CV_FUNCNAME("cv3dTrackerCalibrateCameras");
const int num_points = etalon_size.width * etalon_size.height;
int cameras_done = 0; // the number of cameras whose positions have been determined
CvPoint3D32f *object_points = NULL; // real-world coordinates of checkerboard points
CvPoint2D32f *points = NULL; // 2d coordinates of checkerboard points as seen by a camera
IplImage *gray_img = NULL; // temporary image for color conversion
IplImage *tmp_img = NULL; // temporary image used by FindChessboardCornerGuesses
int c, i, j;
if (etalon_size.width < 3 || etalon_size.height < 3)
CV_ERROR(CV_StsBadArg, "Chess board size is invalid");
for (c = 0; c < num_cameras; c++)
{
// CV_CHECK_IMAGE is not available in the cvaux library
// so perform the checks inline.
//CV_CALL(CV_CHECK_IMAGE(samples[c]));
if( samples[c] == NULL )
CV_ERROR( CV_HeaderIsNull, "Null image" );
if( samples[c]->dataOrder != IPL_DATA_ORDER_PIXEL && samples[c]->nChannels > 1 )
CV_ERROR( CV_BadOrder, "Unsupported image format" );
if( samples[c]->maskROI != 0 || samples[c]->tileInfo != 0 )
CV_ERROR( CV_StsBadArg, "Unsupported image format" );
if( samples[c]->imageData == 0 )
CV_ERROR( CV_BadDataPtr, "Null image data" );
if( samples[c]->roi &&
((samples[c]->roi->xOffset | samples[c]->roi->yOffset
| samples[c]->roi->width | samples[c]->roi->height) < 0 ||
samples[c]->roi->xOffset + samples[c]->roi->width > samples[c]->width ||
samples[c]->roi->yOffset + samples[c]->roi->height > samples[c]->height ||
(unsigned) (samples[c]->roi->coi) > (unsigned) (samples[c]->nChannels)))
CV_ERROR( CV_BadROISize, "Invalid ROI" );
// End of CV_CHECK_IMAGE inline expansion
if (samples[c]->depth != IPL_DEPTH_8U)
CV_ERROR(CV_BadDepth, "Channel depth of source image must be 8");
if (samples[c]->nChannels != 3 && samples[c]->nChannels != 1)
CV_ERROR(CV_BadNumChannels, "Source image must have 1 or 3 channels");
}
CV_CALL(object_points = (CvPoint3D32f *)cvAlloc(num_points * sizeof(CvPoint3D32f)));
CV_CALL(points = (CvPoint2D32f *)cvAlloc(num_points * sizeof(CvPoint2D32f)));
// fill in the real-world coordinates of the checkerboard points
FillObjectPoints(object_points, etalon_size, square_size);
for (c = 0; c < num_cameras; c++)
{
CvSize image_size = cvSize(samples[c]->width, samples[c]->height);
IplImage *img;
// The input samples are not required to all have the same size or color
// format. If they have different sizes, the temporary images are
// reallocated as necessary.
if (samples[c]->nChannels == 3)
{
// convert to gray
if (gray_img == NULL || !CV_ARE_SIZES_EQ(gray_img, samples[c]))
{
if (gray_img != NULL)
cvReleaseImage(&gray_img);
CV_CALL(gray_img = cvCreateImage(image_size, IPL_DEPTH_8U, 1));
}
CV_CALL(cvCvtColor(samples[c], gray_img, CV_BGR2GRAY));
img = gray_img;
}
else
{
// no color conversion required
img = samples[c];
}
if (tmp_img == NULL || !CV_ARE_SIZES_EQ(tmp_img, samples[c]))
{
if (tmp_img != NULL)
cvReleaseImage(&tmp_img);
CV_CALL(tmp_img = cvCreateImage(image_size, IPL_DEPTH_8U, 1));
}
int count = num_points;
bool found = cvFindChessBoardCornerGuesses(img, tmp_img, 0,
etalon_size, points, &count) != 0;
if (count == 0)
continue;
// If found is true, it means all the points were found (count = num_points).
// If found is false but count is non-zero, it means that not all points were found.
cvFindCornerSubPix(img, points, count, cvSize(5,5), cvSize(-1,-1),
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10, 0.01f));
// If the image origin is BL (bottom-left), fix the y coordinates
// so they are relative to the true top of the image.
if (samples[c]->origin == IPL_ORIGIN_BL)
{
for (i = 0; i < count; i++)
points[i].y = samples[c]->height - 1 - points[i].y;
}
if (found)
{
// Make sure x coordinates are increasing and y coordinates are decreasing.
// (The y coordinate of point (0,0) should be the greatest, because the point
// on the checkerboard that is the origin is nearest the bottom of the image.)
// This is done after adjusting the y coordinates according to the image origin.
if (points[0].x > points[1].x)
{
// reverse points in each row
for (j = 0; j < etalon_size.height; j++)
{
CvPoint2D32f *row = &points[j*etalon_size.width];
for (i = 0; i < etalon_size.width/2; i++)
std::swap(row[i], row[etalon_size.width-i-1]);
}
}
if (points[0].y < points[etalon_size.width].y)
{
// reverse points in each column
for (i = 0; i < etalon_size.width; i++)
{
for (j = 0; j < etalon_size.height/2; j++)
std::swap(points[i+j*etalon_size.width],
points[i+(etalon_size.height-j-1)*etalon_size.width]);
}
}
}
DrawEtalon(samples[c], points, count, etalon_size, found);
if (!found)
continue;
float rotVect[3];
float rotMatr[9];
float transVect[3];
cvFindExtrinsicCameraParams(count,
image_size,
points,
object_points,
const_cast<float *>(camera_intrinsics[c].focal_length),
camera_intrinsics[c].principal_point,
const_cast<float *>(camera_intrinsics[c].distortion),
rotVect,
transVect);
// Check result against an arbitrary limit to eliminate impossible values.
// (If the chess board were truly that far away, the camera wouldn't be able to
// see the squares.)
if (transVect[0] > 1000*square_size
|| transVect[1] > 1000*square_size
|| transVect[2] > 1000*square_size)
{
// ignore impossible results
continue;
}
CvMat rotMatrDescr = cvMat(3, 3, CV_32FC1, rotMatr);
CvMat rotVectDescr = cvMat(3, 1, CV_32FC1, rotVect);
/* Calc rotation matrix by Rodrigues Transform */
cvRodrigues2( &rotVectDescr, &rotMatrDescr );
//combine the two transformations into one matrix
//order is important! rotations are not commutative
float tmat[4][4] = { { 1.f, 0.f, 0.f, 0.f },
{ 0.f, 1.f, 0.f, 0.f },
{ 0.f, 0.f, 1.f, 0.f },
{ transVect[0], transVect[1], transVect[2], 1.f } };
float rmat[4][4] = { { rotMatr[0], rotMatr[1], rotMatr[2], 0.f },
{ rotMatr[3], rotMatr[4], rotMatr[5], 0.f },
{ rotMatr[6], rotMatr[7], rotMatr[8], 0.f },
{ 0.f, 0.f, 0.f, 1.f } };
MultMatrix(camera_info[c].mat, tmat, rmat);
// change the transformation of the cameras to put them in the world coordinate
// system we want to work with.
// Start with an identity matrix; then fill in the values to accomplish
// the desired transformation.
float smat[4][4] = { { 1.f, 0.f, 0.f, 0.f },
{ 0.f, 1.f, 0.f, 0.f },
{ 0.f, 0.f, 1.f, 0.f },
{ 0.f, 0.f, 0.f, 1.f } };
// First, reflect through the origin by inverting all three axes.
smat[0][0] = -1.f;
smat[1][1] = -1.f;
smat[2][2] = -1.f;
MultMatrix(tmat, camera_info[c].mat, smat);
// Scale x and y coordinates by the focal length (allowing for non-square pixels
// and/or non-symmetrical lenses).
smat[0][0] = 1.0f / camera_intrinsics[c].focal_length[0];
smat[1][1] = 1.0f / camera_intrinsics[c].focal_length[1];
smat[2][2] = 1.0f;
MultMatrix(camera_info[c].mat, smat, tmat);
camera_info[c].principal_point = camera_intrinsics[c].principal_point;
camera_info[c].valid = true;
cameras_done++;
}
exit:
cvReleaseImage(&gray_img);
cvReleaseImage(&tmp_img);
cvFree(&object_points);
cvFree(&points);
return cameras_done == num_cameras;
}
// fill in the real-world coordinates of the checkerboard points
static void FillObjectPoints(CvPoint3D32f *obj_points, CvSize etalon_size, float square_size)
{
int x, y, i;
for (y = 0, i = 0; y < etalon_size.height; y++)
{
for (x = 0; x < etalon_size.width; x++, i++)
{
obj_points[i].x = square_size * x;
obj_points[i].y = square_size * y;
obj_points[i].z = 0;
}
}
}
// Mark the points found on the input image
// The marks are drawn multi-colored if all the points were found.
static void DrawEtalon(IplImage *img, CvPoint2D32f *corners,
int corner_count, CvSize etalon_size, int draw_ordered)
{
const int r = 4;
int i;
int x, y;
CvPoint prev_pt = { 0, 0 };
static const CvScalar rgb_colors[] = {
{{0,0,255}},
{{0,128,255}},
{{0,200,200}},
{{0,255,0}},
{{200,200,0}},
{{255,0,0}},
{{255,0,255}} };
static const CvScalar gray_colors[] = {
{{80}}, {{120}}, {{160}}, {{200}}, {{100}}, {{140}}, {{180}}
};
const CvScalar* colors = img->nChannels == 3 ? rgb_colors : gray_colors;
CvScalar color = colors[0];
for (y = 0, i = 0; y < etalon_size.height; y++)
{
if (draw_ordered)
color = colors[y % ARRAY_SIZEOF(rgb_colors)];
for (x = 0; x < etalon_size.width && i < corner_count; x++, i++)
{
CvPoint pt;
pt.x = cvRound(corners[i].x);
pt.y = cvRound(corners[i].y);
if (img->origin == IPL_ORIGIN_BL)
pt.y = img->height - 1 - pt.y;
if (draw_ordered)
{
if (i != 0)
cvLine(img, prev_pt, pt, color, 1, CV_AA);
prev_pt = pt;
}
cvLine( img, cvPoint(pt.x - r, pt.y - r),
cvPoint(pt.x + r, pt.y + r), color, 1, CV_AA );
cvLine( img, cvPoint(pt.x - r, pt.y + r),
cvPoint(pt.x + r, pt.y - r), color, 1, CV_AA );
cvCircle( img, pt, r+1, color, 1, CV_AA );
}
}
}
// Find the midpoint of the line segment between two points.
static CvPoint3D32f midpoint(const CvPoint3D32f &p1, const CvPoint3D32f &p2)
{
return cvPoint3D32f((p1.x+p2.x)/2, (p1.y+p2.y)/2, (p1.z+p2.z)/2);
}
static void operator +=(CvPoint3D32f &p1, const CvPoint3D32f &p2)
{
p1.x += p2.x;
p1.y += p2.y;
p1.z += p2.z;
}
static CvPoint3D32f operator /(const CvPoint3D32f &p, int d)
{
return cvPoint3D32f(p.x/d, p.y/d, p.z/d);
}
static const Cv3dTracker2dTrackedObject *find(const Cv3dTracker2dTrackedObject v[], int num_objects, int id)
{
for (int i = 0; i < num_objects; i++)
{
if (v[i].id == id)
return &v[i];
}
return NULL;
}
#define CAMERA_POS(c) (cvPoint3D32f((c).mat[3][0], (c).mat[3][1], (c).mat[3][2]))
//////////////////////////////
// cv3dTrackerLocateObjects //
//////////////////////////////
CV_IMPL int cv3dTrackerLocateObjects(int num_cameras, int num_objects,
const Cv3dTrackerCameraInfo camera_info[], // size is num_cameras
const Cv3dTracker2dTrackedObject tracking_info[], // size is num_objects*num_cameras
Cv3dTrackerTrackedObject tracked_objects[]) // size is num_objects
{
/*CV_FUNCNAME("cv3dTrackerLocateObjects");*/
int found_objects = 0;
// count how many cameras could see each object
std::map<int, int> count;
for (int c = 0; c < num_cameras; c++)
{
if (!camera_info[c].valid)
continue;
for (int i = 0; i < num_objects; i++)
{
const Cv3dTracker2dTrackedObject *o = &tracking_info[c*num_objects+i];
if (o->id != -1)
count[o->id]++;
}
}
// process each object that was seen by at least two cameras
for (std::map<int, int>::iterator i = count.begin(); i != count.end(); i++)
{
if (i->second < 2)
continue; // ignore object seen by only one camera
int id = i->first;
// find an approximation of the objects location for each pair of cameras that
// could see this object, and average them
CvPoint3D32f total = cvPoint3D32f(0, 0, 0);
int weight = 0;
for (int c1 = 0; c1 < num_cameras-1; c1++)
{
if (!camera_info[c1].valid)
continue;
const Cv3dTracker2dTrackedObject *o1 = find(&tracking_info[c1*num_objects],
num_objects, id);
if (o1 == NULL)
continue; // this camera didn't see this object
CvPoint3D32f p1a = CAMERA_POS(camera_info[c1]);
CvPoint3D32f p1b = ImageCStoWorldCS(camera_info[c1], o1->p);
for (int c2 = c1 + 1; c2 < num_cameras; c2++)
{
if (!camera_info[c2].valid)
continue;
const Cv3dTracker2dTrackedObject *o2 = find(&tracking_info[c2*num_objects],
num_objects, id);
if (o2 == NULL)
continue; // this camera didn't see this object
CvPoint3D32f p2a = CAMERA_POS(camera_info[c2]);
CvPoint3D32f p2b = ImageCStoWorldCS(camera_info[c2], o2->p);
// these variables are initialized simply to avoid erroneous error messages
// from the compiler
CvPoint3D32f r1 = cvPoint3D32f(0, 0, 0);
CvPoint3D32f r2 = cvPoint3D32f(0, 0, 0);
// find the intersection of the two lines (or the points of closest
// approach, if they don't intersect)
if (!intersection(p1a, p1b, p2a, p2b, r1, r2))
continue;
total += midpoint(r1, r2);
weight++;
}
}
CvPoint3D32f center = total/weight;
tracked_objects[found_objects++] = cv3dTrackerTrackedObject(id, center);
}
return found_objects;
}
#define EPS 1e-9
// Compute the determinant of the 3x3 matrix represented by 3 row vectors.
static inline double det(CvPoint3D32f v1, CvPoint3D32f v2, CvPoint3D32f v3)
{
return v1.x*v2.y*v3.z + v1.z*v2.x*v3.y + v1.y*v2.z*v3.x
- v1.z*v2.y*v3.x - v1.x*v2.z*v3.y - v1.y*v2.x*v3.z;
}
static CvPoint3D32f operator +(CvPoint3D32f a, CvPoint3D32f b)
{
return cvPoint3D32f(a.x + b.x, a.y + b.y, a.z + b.z);
}
static CvPoint3D32f operator -(CvPoint3D32f a, CvPoint3D32f b)
{
return cvPoint3D32f(a.x - b.x, a.y - b.y, a.z - b.z);
}
static CvPoint3D32f operator *(CvPoint3D32f v, double f)
{
return cvPoint3D32f(f*v.x, f*v.y, f*v.z);
}
// Find the intersection of two lines, or if they don't intersect,
// the points of closest approach.
// The lines are defined by (o1,p1) and (o2, p2).
// If they intersect, r1 and r2 will be the same.
// Returns false on error.
static bool intersection(CvPoint3D32f o1, CvPoint3D32f p1,
CvPoint3D32f o2, CvPoint3D32f p2,
CvPoint3D32f &r1, CvPoint3D32f &r2)
{
CvPoint3D32f x = o2 - o1;
CvPoint3D32f d1 = p1 - o1;
CvPoint3D32f d2 = p2 - o2;
CvPoint3D32f cross = cvPoint3D32f(d1.y*d2.z - d1.z*d2.y,
d1.z*d2.x - d1.x*d2.z,
d1.x*d2.y - d1.y*d2.x);
double den = cross.x*cross.x + cross.y*cross.y + cross.z*cross.z;
if (den < EPS)
return false;
double t1 = det(x, d2, cross) / den;
double t2 = det(x, d1, cross) / den;
r1 = o1 + d1 * t1;
r2 = o2 + d2 * t2;
return true;
}
// Convert from image to camera space by transforming point p in
// the image plane by the camera matrix.
static CvPoint3D32f ImageCStoWorldCS(const Cv3dTrackerCameraInfo &camera_info, CvPoint2D32f p)
{
float tp[4];
tp[0] = (float)p.x - camera_info.principal_point.x;
tp[1] = (float)p.y - camera_info.principal_point.y;
tp[2] = 1.f;
tp[3] = 1.f;
float tr[4];
//multiply tp by mat to get tr
MultVectorMatrix(tr, tp, camera_info.mat);
return cvPoint3D32f(tr[0]/tr[3], tr[1]/tr[3], tr[2]/tr[3]);
}
// Multiply affine transformation m1 by the affine transformation m2 and
// return the result in rm.
static void MultMatrix(float rm[4][4], const float m1[4][4], const float m2[4][4])
{
for (int i=0; i<=3; i++)
for (int j=0; j<=3; j++)
{
rm[i][j]= 0.0;
for (int k=0; k <= 3; k++)
rm[i][j] += m1[i][k]*m2[k][j];
}
}
// Multiply the vector v by the affine transformation matrix m and return the
// result in rv.
void MultVectorMatrix(float rv[4], const float v[4], const float m[4][4])
{
for (int i=0; i<=3; i++)
{
rv[i] = 0.f;
for (int j=0;j<=3;j++)
rv[i] += v[j] * m[j][i];
}
}

View File

@@ -0,0 +1,44 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/* End of file. */

View File

@@ -0,0 +1,522 @@
# Microsoft Developer Studio Project File - Name="cvaux" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=cvaux - Win32 Debug64 Itanium
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "cvaux.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "cvaux.mak" CFG="cvaux - Win32 Debug64 Itanium"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "cvaux - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "cvaux - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "cvaux - Win32 Release64" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "cvaux - Win32 Debug64" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "cvaux - Win32 Release64 Itanium" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "cvaux - Win32 Debug64 Itanium" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=xicl6.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "cvaux - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\_temp\cvaux_Rls"
# PROP Intermediate_Dir "..\..\_temp\cvaux_Rls"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LIB32=link.exe -lib
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "cvaux_EXPORTS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W4 /Zi /O2 /Ob2 /I "." /I ".." /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "NDEBUG" /D "CVAPI_EXPORTS" /D "WIN32" /D "_WINDOWS" /Yu"_cvaux.h" /FD /Zm200 /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 cv.lib cxcore.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /pdb:"..\..\bin/cvaux100.pdb" /debug /machine:I386 /nodefaultlib:"libmmd.lib" /out:"..\..\bin/cvaux100.dll" /implib:"..\..\lib/cvaux.lib" /libpath:"..\..\lib"
# SUBTRACT LINK32 /profile /pdb:none
!ELSEIF "$(CFG)" == "cvaux - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\_temp\cvaux_Dbg"
# PROP Intermediate_Dir "..\..\_temp\cvaux_Dbg"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LIB32=link.exe -lib
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "cvaux_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W4 /Gm /Zi /Od /I "." /I ".." /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "_DEBUG" /D "CVAPI_EXPORTS" /D "WIN32" /D "_WINDOWS" /FR /Yu"_cvaux.h" /FD /GZ /Zm200 /c
# SUBTRACT CPP /X
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 cvd.lib cxcored.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /pdb:"..\..\bin/cvaux100d.pdb" /debug /machine:I386 /nodefaultlib:"libmmdd.lib" /out:"..\..\bin/cvaux100d.dll" /implib:"..\..\lib/cvauxd.lib" /pdbtype:sept /libpath:"..\..\lib"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "cvaux - Win32 Release64"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "cvaux___Win32_Release64"
# PROP BASE Intermediate_Dir "cvaux___Win32_Release64"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\_temp\cvaux_Rls64"
# PROP Intermediate_Dir "..\..\_temp\cvaux_Rls64"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LIB32=link.exe -lib
# ADD BASE CPP /nologo /MD /W4 /Zi /O2 /Ob2 /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "NDEBUG" /D "CVAPI_EXPORTS" /D "WIN32" /D "_WINDOWS" /Yu"_cvaux.h" /FD /Zm200 /c
# ADD CPP /nologo /MD /W4 /Zi /O2 /Ob2 /I "." /I ".." /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "CVAPI_EXPORTS" /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /D "WIN64" /D "EM64T" /Yu"_cvaux.h" /FD /Zm200 /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 cv.lib cxcore.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:IX86 /nodefaultlib:"libmmd.lib" /out:"..\..\bin/cvaux100.dll" /implib:"..\..\lib/cvaux.lib" /libpath:"..\..\lib" /machine:AMD64
# SUBTRACT BASE LINK32 /profile
# ADD LINK32 cv_64.lib cxcore_64.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:IX86 /nodefaultlib:"libmmd.lib" /out:"..\..\bin/cvaux100_64.dll" /implib:"..\..\lib/cvaux_64.lib" /libpath:"..\..\lib" /machine:AMD64
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "cvaux - Win32 Debug64"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "cvaux___Win32_Debug64"
# PROP BASE Intermediate_Dir "cvaux___Win32_Debug64"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\_temp\cvaux_Dbg64"
# PROP Intermediate_Dir "..\..\_temp\cvaux_Dbg64"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LIB32=link.exe -lib
# ADD BASE CPP /nologo /MDd /W4 /Gm /Zi /Od /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "_DEBUG" /D "CVAPI_EXPORTS" /D "WIN32" /D "_WINDOWS" /FR /Yu"_cvaux.h" /FD /GZ /Zm200 /c
# SUBTRACT BASE CPP /X
# ADD CPP /nologo /MDd /W4 /Gm /Zi /Od /I "." /I ".." /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "CVAPI_EXPORTS" /D "_WINDOWS" /D "_DEBUG" /D "WIN32" /D "WIN64" /D "EM64T" /FR /Yu"_cvaux.h" /FD /Zm200 /Wp64 /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 cvd.lib cxcored.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:IX86 /nodefaultlib:"libmmdd.lib" /out:"..\..\bin/cvaux100d.dll" /implib:"..\..\lib/cvauxd.lib" /pdbtype:sept /libpath:"..\..\lib" /machine:AMD64
# SUBTRACT BASE LINK32 /pdb:none
# ADD LINK32 cvd_64.lib cxcored_64.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /pdb:"..\..\bin/cvaux100d_64.pdb" /debug /machine:IX86 /nodefaultlib:"libmmdd.lib" /out:"..\..\bin/cvaux100d_64.dll" /implib:"..\..\lib/cvauxd_64.lib" /pdbtype:sept /libpath:"..\..\lib" /machine:AMD64
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "cvaux - Win32 Release64 Itanium"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "cvaux___Win32_Release64_Itanium"
# PROP BASE Intermediate_Dir "cvaux___Win32_Release64_Itanium"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\_temp\cvaux_RlsI7"
# PROP Intermediate_Dir "..\..\_temp\cvaux_RlsI7"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LIB32=link.exe -lib
# ADD BASE CPP /nologo /MD /W4 /Zi /O2 /Ob2 /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "CVAPI_EXPORTS" /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /D "WIN64" /D "EM64T" /Yu"_cvaux.h" /FD /Zm200 /c
# ADD CPP /nologo /MD /w /W0 /Zi /O2 /Ob2 /I "." /I ".." /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "CVAPI_EXPORTS" /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /D "WIN64" /Yu"_cvaux.h" /FD /Zm200 /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 cv_i7.lib cxcore_i7.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:IX86 /nodefaultlib:"libmmd.lib" /out:"..\..\bin/cvaux100_i7.dll" /implib:"..\..\lib/cvaux_i7.lib" /libpath:"..\..\lib" /machine:IA64
# SUBTRACT BASE LINK32 /pdb:none
# ADD LINK32 cv_i7.lib cxcore_i7.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:IX86 /out:"..\..\bin/cvaux100_i7.dll" /implib:"..\..\lib/cvaux_i7.lib" /libpath:"..\..\lib" /machine:IA64
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "cvaux - Win32 Debug64 Itanium"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "cvaux___Win32_Debug64_Itanium"
# PROP BASE Intermediate_Dir "cvaux___Win32_Debug64_Itanium"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\_temp\cvaux_DbgI7"
# PROP Intermediate_Dir "..\..\_temp\cvaux_DbgI7"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
LIB32=link.exe -lib
# ADD BASE CPP /nologo /MDd /W4 /Gm /Zi /Od /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "CVAPI_EXPORTS" /D "_WINDOWS" /D "_DEBUG" /D "WIN32" /D "WIN64" /D "EM64T" /FR /Yu"_cvaux.h" /FD /Zm200 /Wp64 /c
# ADD CPP /nologo /MDd /W3 /Gm /Zi /Od /I "." /I ".." /I "../include" /I "../../cxcore/include" /I "../../cv/include" /I "../../cv/src" /D "CVAPI_EXPORTS" /D "_WINDOWS" /D "_DEBUG" /D "WIN32" /D "WIN64" /FR /Yu"_cvaux.h" /FD /Zm200 /Qwd167 /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 cvd_i7.lib cxcored_i7.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /pdb:"..\..\bin/cvaux100d_i7.pdb" /debug /machine:IX86 /nodefaultlib:"libmmdd.lib" /out:"..\..\bin/cvaux100d_i7.dll" /implib:"..\..\lib/cvauxd_i7.lib" /pdbtype:sept /libpath:"..\..\lib" /machine:IA64
# SUBTRACT BASE LINK32 /pdb:none
# ADD LINK32 cvd_i7.lib cxcored_i7.lib kernel32.lib user32.lib gdi32.lib /nologo /dll /pdb:"..\..\bin/cvaux100d_i7.pdb" /debug /machine:IX86 /out:"..\..\bin/cvaux100d_i7.dll" /implib:"..\..\lib/cvauxd_i7.lib" /pdbtype:sept /libpath:"..\..\lib" /machine:IA64
# SUBTRACT LINK32 /pdb:none
!ENDIF
# Begin Target
# Name "cvaux - Win32 Release"
# Name "cvaux - Win32 Debug"
# Name "cvaux - Win32 Release64"
# Name "cvaux - Win32 Debug64"
# Name "cvaux - Win32 Release64 Itanium"
# Name "cvaux - Win32 Debug64 Itanium"
# Begin Group "Src"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Group "VideoSurveillance"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\vs\bgfg_estimation.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackanalysis.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackanalysishist.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackanalysisior.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackanalysistrackdist.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackgen1.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackgenyml.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackingauto.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackingcc.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackingccwithcr.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackingkalman.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackinglist.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackingmsfg.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackingmsfgs.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackpostprockalman.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackpostproclinear.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\blobtrackpostproclist.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\enteringblobdetection.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\enteringblobdetectionreal.cpp
# End Source File
# Begin Source File
SOURCE=.\vs\TestSeq.cpp
# End Source File
# End Group
# Begin Source File
SOURCE=.\camshift.cpp
# End Source File
# Begin Source File
SOURCE=.\cv3dtracker.cpp
# End Source File
# Begin Source File
SOURCE=.\cvaux.cpp
# End Source File
# Begin Source File
SOURCE=.\cvaux.rc
# End Source File
# Begin Source File
SOURCE=.\cvauxutils.cpp
# End Source File
# Begin Source File
SOURCE=.\cvbgfg_acmmm2003.cpp
# End Source File
# Begin Source File
SOURCE=.\cvbgfg_common.cpp
# End Source File
# Begin Source File
SOURCE=.\cvbgfg_gaussmix.cpp
# End Source File
# Begin Source File
SOURCE=.\cvcalibfilter.cpp
# End Source File
# Begin Source File
SOURCE=.\cvcorrespond.cpp
# End Source File
# Begin Source File
SOURCE=.\cvcorrimages.cpp
# End Source File
# Begin Source File
SOURCE=.\cvcreatehandmask.cpp
# End Source File
# Begin Source File
SOURCE=.\cvdpstereo.cpp
# End Source File
# Begin Source File
SOURCE=.\cveigenobjects.cpp
# End Source File
# Begin Source File
SOURCE=.\cvepilines.cpp
# End Source File
# Begin Source File
SOURCE=.\cvface.cpp
# End Source File
# Begin Source File
SOURCE=.\cvfacedetection.cpp
# End Source File
# Begin Source File
SOURCE=.\cvfacetemplate.cpp
# End Source File
# Begin Source File
SOURCE=.\cvfindface.cpp
# End Source File
# Begin Source File
SOURCE=.\cvfindhandregion.cpp
# End Source File
# Begin Source File
SOURCE=.\cvhmm.cpp
# End Source File
# Begin Source File
SOURCE=.\cvhmm1d.cpp
# End Source File
# Begin Source File
SOURCE=.\cvhmmobs.cpp
# End Source File
# Begin Source File
SOURCE=.\cvlcm.cpp
# End Source File
# Begin Source File
SOURCE=.\cvlee.cpp
# End Source File
# Begin Source File
SOURCE=.\cvlevmar.cpp
# End Source File
# Begin Source File
SOURCE=.\cvlevmarprojbandle.cpp
# End Source File
# Begin Source File
SOURCE=.\cvlevmartrif.cpp
# End Source File
# Begin Source File
SOURCE=.\cvlines.cpp
# End Source File
# Begin Source File
SOURCE=.\cvlmeds.cpp
# End Source File
# Begin Source File
SOURCE=.\cvmorphcontours.cpp
# End Source File
# Begin Source File
SOURCE=.\cvmorphing.cpp
# End Source File
# Begin Source File
SOURCE=.\cvprewarp.cpp
# End Source File
# Begin Source File
SOURCE=.\cvscanlines.cpp
# End Source File
# Begin Source File
SOURCE=.\cvsegment.cpp
# End Source File
# Begin Source File
SOURCE=.\cvsubdiv2.cpp
# End Source File
# Begin Source File
SOURCE=.\cvtexture.cpp
# End Source File
# Begin Source File
SOURCE=.\cvtrifocal.cpp
# End Source File
# Begin Source File
SOURCE=.\cvvecfacetracking.cpp
# End Source File
# Begin Source File
SOURCE=.\cvvideo.cpp
# End Source File
# Begin Source File
SOURCE=.\precomp.cpp
# ADD CPP /Yc"_cvaux.h"
# End Source File
# End Group
# Begin Group "Include"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Group "Internal"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\_cvaux.h
# End Source File
# Begin Source File
SOURCE=.\_cvfacedetection.h
# End Source File
# Begin Source File
SOURCE=.\_cvvectrack.h
# End Source File
# Begin Source File
SOURCE=.\_cvvm.h
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# End Group
# Begin Group "External"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\include\cvaux.h
# End Source File
# Begin Source File
SOURCE=..\include\cvaux.hpp
# End Source File
# Begin Source File
SOURCE=..\include\cvvidsurv.hpp
# End Source File
# End Group
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,121 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Russian resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // Russian resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "Intel® Open Source Computer Vision Library: The experimental part.\0"
VALUE "CompanyName", "Intel Corporation.\0"
VALUE "FileDescription", "The exterimental OpenCV functions\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "cvaux100.dll\0"
VALUE "LegalCopyright", "Copyright © 2002-2006\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "cvaux100.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Intel® Open Source Computer Vision Library\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,44 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/* End of file. */

View File

@@ -0,0 +1,686 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
//#include <algorithm>
static double* _cv_max_element( double* start, double* end )
{
double* p = start++;
for( ; start != end; start++ )
if( *p < *start )
p = start;
return p;
}
static void CV_CDECL icvReleaseFGDStatModel( CvFGDStatModel** model );
static int CV_CDECL icvUpdateFGDStatModel( IplImage* curr_frame,
CvFGDStatModel* model );
// Function cvCreateFGDStatModel initializes foreground detection process
// parameters:
// first_frame - frame from video sequence
// parameters - (optional) if NULL default parameters of the algorithm will be used
// p_model - pointer to CvFGDStatModel structure
CV_IMPL CvBGStatModel*
cvCreateFGDStatModel( IplImage* first_frame, CvFGDStatModelParams* parameters )
{
CvFGDStatModel* p_model = 0;
CV_FUNCNAME( "cvCreateFGDStatModel" );
__BEGIN__;
int i, j, k, pixel_count, buf_size;
CvFGDStatModelParams params;
if( !CV_IS_IMAGE(first_frame) )
CV_ERROR( CV_StsBadArg, "Invalid or NULL first_frame parameter" );
//init parameters
if( parameters == NULL )
{
params.Lc = CV_BGFG_FGD_LC;
params.N1c = CV_BGFG_FGD_N1C;
params.N2c = CV_BGFG_FGD_N2C;
params.Lcc = CV_BGFG_FGD_LCC;
params.N1cc = CV_BGFG_FGD_N1CC;
params.N2cc = CV_BGFG_FGD_N2CC;
params.delta = CV_BGFG_FGD_DELTA;
params.alpha1 = CV_BGFG_FGD_ALPHA_1;
params.alpha2 = CV_BGFG_FGD_ALPHA_2;
params.alpha3 = CV_BGFG_FGD_ALPHA_3;
params.T = CV_BGFG_FGD_T;
params.minArea = CV_BGFG_FGD_MINAREA;
params.is_obj_without_holes = 1;
params.perform_morphing = 1;
}
else
{
params = *parameters;
}
CV_CALL( p_model = (CvFGDStatModel*)cvAlloc( sizeof(*p_model) ));
memset( p_model, 0, sizeof(*p_model) );
p_model->type = CV_BG_MODEL_FGD;
p_model->release = (CvReleaseBGStatModel)icvReleaseFGDStatModel;
p_model->update = (CvUpdateBGStatModel)icvUpdateFGDStatModel;;
p_model->params = params;
//init storages
pixel_count = first_frame->width*first_frame->height;
buf_size = pixel_count*sizeof(p_model->pixel_stat[0]);
CV_CALL( p_model->pixel_stat = (CvBGPixelStat*)cvAlloc(buf_size) );
memset( p_model->pixel_stat, 0, buf_size );
buf_size = pixel_count*params.N2c*sizeof(p_model->pixel_stat[0].ctable[0]);
CV_CALL( p_model->pixel_stat[0].ctable = (CvBGPixelCStatTable*)cvAlloc(buf_size) );
memset( p_model->pixel_stat[0].ctable, 0, buf_size );
buf_size = pixel_count*params.N2cc*sizeof(p_model->pixel_stat[0].cctable[0]);
CV_CALL( p_model->pixel_stat[0].cctable = (CvBGPixelCCStatTable*)cvAlloc(buf_size) );
memset( p_model->pixel_stat[0].cctable, 0, buf_size );
for( i = 0, k = 0; i < first_frame->height; i++ )
for( j = 0; j < first_frame->width; j++, k++ )
{
p_model->pixel_stat[k].ctable = p_model->pixel_stat[0].ctable + k*params.N2c;
p_model->pixel_stat[k].cctable = p_model->pixel_stat[0].cctable + k*params.N2cc;
}
//init temporary images
CV_CALL( p_model->Ftd = cvCreateImage(cvSize(first_frame->width, first_frame->height), IPL_DEPTH_8U, 1));
CV_CALL( p_model->Fbd = cvCreateImage(cvSize(first_frame->width, first_frame->height), IPL_DEPTH_8U, 1));
CV_CALL( p_model->foreground = cvCreateImage(cvSize(first_frame->width, first_frame->height), IPL_DEPTH_8U, 1));
CV_CALL( p_model->background = cvCloneImage(first_frame));
CV_CALL( p_model->prev_frame = cvCloneImage(first_frame));
CV_CALL( p_model->storage = cvCreateMemStorage());
__END__;
if( cvGetErrStatus() < 0 )
{
CvBGStatModel* base_ptr = (CvBGStatModel*)p_model;
if( p_model && p_model->release )
p_model->release( &base_ptr );
else
cvFree( &p_model );
p_model = 0;
}
return (CvBGStatModel*)p_model;
}
static void CV_CDECL
icvReleaseFGDStatModel( CvFGDStatModel** _model )
{
CV_FUNCNAME( "icvReleaseFGDStatModel" );
__BEGIN__;
if( !_model )
CV_ERROR( CV_StsNullPtr, "" );
if( *_model )
{
CvFGDStatModel* model = *_model;
if( model->pixel_stat )
{
cvFree( &model->pixel_stat[0].ctable );
cvFree( &model->pixel_stat[0].cctable );
cvFree( &model->pixel_stat );
}
cvReleaseImage( &model->Ftd );
cvReleaseImage( &model->Fbd );
cvReleaseImage( &model->foreground );
cvReleaseImage( &model->background );
cvReleaseImage( &model->prev_frame );
cvReleaseMemStorage(&model->storage);
cvFree( _model );
}
__END__;
}
// Function cvChangeDetection performs change detection for Foreground detection algorithm
// parameters:
// prev_frame -
// curr_frame -
// change_mask -
CV_IMPL int
cvChangeDetection( IplImage* prev_frame,
IplImage* curr_frame,
IplImage* change_mask )
{
int i, j, b, x, y, thres;
const int PIXELRANGE=256;
if( !prev_frame || !curr_frame || !change_mask ||
prev_frame->nChannels != 3 || curr_frame->nChannels != 3 || change_mask->nChannels != 1 ||
prev_frame->depth != IPL_DEPTH_8U || curr_frame->depth != IPL_DEPTH_8U || change_mask->depth != IPL_DEPTH_8U ||
!CV_ARE_SIZES_EQ( prev_frame, curr_frame ) || !CV_ARE_SIZES_EQ( prev_frame, change_mask ) ) return 0;
cvZero ( change_mask );
// All operations per colour
for (b=0 ; b<prev_frame->nChannels ; b++) {
// create histogram
long HISTOGRAM[PIXELRANGE];
for (i=0 ; i<PIXELRANGE; i++) HISTOGRAM[i]=0;
for (y=0 ; y<curr_frame->height ; y++)
{
uchar* rowStart1 = (uchar*)curr_frame->imageData + y * curr_frame->widthStep + b;
uchar* rowStart2 = (uchar*)prev_frame->imageData + y * prev_frame->widthStep + b;
for (x=0 ; x<curr_frame->width ; x++, rowStart1+=curr_frame->nChannels, rowStart2+=prev_frame->nChannels) {
int diff = abs( int(*rowStart1) - int(*rowStart2) );
HISTOGRAM[diff]++;
}
}
double relativeVariance[PIXELRANGE];
for (i=0 ; i<PIXELRANGE; i++) relativeVariance[i]=0;
for (thres=PIXELRANGE-2; thres>=0 ; thres--)
{
// fprintf(stderr, "Iter %d\n", thres);
double sum=0;
double sqsum=0;
int count=0;
// fprintf(stderr, "Iter %d entering loop\n", thres);
for (j=thres ; j<PIXELRANGE ; j++) {
sum += double(j)*double(HISTOGRAM[j]);
sqsum += double(j*j)*double(HISTOGRAM[j]);
count += HISTOGRAM[j];
}
count = count == 0 ? 1 : count;
// fprintf(stderr, "Iter %d finishing loop\n", thres);
double my = sum / count;
double sigma = sqrt( sqsum/count - my*my);
// fprintf(stderr, "Iter %d sum=%g sqsum=%g count=%d sigma = %g\n", thres, sum, sqsum, count, sigma);
// fprintf(stderr, "Writing to %x\n", &(relativeVariance[thres]));
relativeVariance[thres] = sigma;
// fprintf(stderr, "Iter %d finished\n", thres);
}
// find maximum
uchar bestThres = 0;
double* pBestThres = _cv_max_element(relativeVariance, relativeVariance+PIXELRANGE);
bestThres = (uchar)(*pBestThres); if (bestThres <10) bestThres=10;
for (y=0 ; y<prev_frame->height ; y++)
{
uchar* rowStart1 = (uchar*)(curr_frame->imageData) + y * curr_frame->widthStep + b;
uchar* rowStart2 = (uchar*)(prev_frame->imageData) + y * prev_frame->widthStep + b;
uchar* rowStart3 = (uchar*)(change_mask->imageData) + y * change_mask->widthStep;
for (x = 0; x < curr_frame->width; x++, rowStart1+=curr_frame->nChannels,
rowStart2+=prev_frame->nChannels, rowStart3+=change_mask->nChannels) {
// OR between different color channels
int diff = abs( int(*rowStart1) - int(*rowStart2) );
if ( diff > bestThres)
*rowStart3 |=255;
}
}
}
return 1;
}
#define MIN_PV 1E-10
#define V_C(k,l) ctable[k].v[l]
#define PV_C(k) ctable[k].Pv
#define PVB_C(k) ctable[k].Pvb
#define V_CC(k,l) cctable[k].v[l]
#define PV_CC(k) cctable[k].Pv
#define PVB_CC(k) cctable[k].Pvb
// Function cvUpdateFGDStatModel updates statistical model and returns number of foreground regions
// parameters:
// curr_frame - current frame from video sequence
// p_model - pointer to CvFGDStatModel structure
static int CV_CDECL
icvUpdateFGDStatModel( IplImage* curr_frame, CvFGDStatModel* model )
{
int mask_step = model->Ftd->widthStep;
CvSeq *first_seq = NULL, *prev_seq = NULL, *seq = NULL;
IplImage* prev_frame = model->prev_frame;
int region_count = 0;
int FG_pixels_count = 0;
int deltaC = cvRound(model->params.delta * 256 / model->params.Lc);
int deltaCC = cvRound(model->params.delta * 256 / model->params.Lcc);
int i, j, k, l;
//clear storages
cvClearMemStorage(model->storage);
cvZero(model->foreground);
//form FG pixels candidates using image differencing with adaptive threshold [P.Rosin, Thresholding for change detection, ICCV, 1998 ]
cvChangeDetection( prev_frame, curr_frame, model->Ftd );
cvChangeDetection( model->background, curr_frame, model->Fbd );
for( i = 0; i < model->Ftd->height; i++ )
{
for( j = 0; j < model->Ftd->width; j++ )
{
if( ((uchar*)model->Fbd->imageData)[i*mask_step+j] || ((uchar*)model->Ftd->imageData)[i*mask_step+j] )
{
float Pb=0, Pv=0, Pvb=0;
CvBGPixelStat* stat = model->pixel_stat + i * model->Ftd->width + j;
CvBGPixelCStatTable* ctable = stat->ctable;
CvBGPixelCCStatTable* cctable = stat->cctable;
uchar* curr_data = (uchar*)(curr_frame->imageData)+i*curr_frame->widthStep+j*3;
uchar* prev_data = (uchar*)(prev_frame->imageData)+i*prev_frame->widthStep+j*3;
int val = 0;
// is it a motion pixel?
if( ((uchar*)model->Ftd->imageData)[i*mask_step+j] )
{
if( !stat->is_trained_dyn_model ) val = 1;
else
{
//compare with stored CCt vectors
for( k = 0; PV_CC(k) > model->params.alpha2 && k < model->params.N1cc; k++ )
{
if ( abs( V_CC(k,0) - prev_data[0]) <= deltaCC &&
abs( V_CC(k,1) - prev_data[1]) <= deltaCC &&
abs( V_CC(k,2) - prev_data[2]) <= deltaCC &&
abs( V_CC(k,3) - curr_data[0]) <= deltaCC &&
abs( V_CC(k,4) - curr_data[1]) <= deltaCC &&
abs( V_CC(k,5) - curr_data[2]) <= deltaCC)
{
Pv += PV_CC(k);
Pvb += PVB_CC(k);
}
}
Pb = stat->Pbcc;
if( 2 * Pvb * Pb <= Pv ) val = 1;
}
}
else if( stat->is_trained_st_model )
{
//compare with stored Ct vectors
for( k = 0; PV_C(k) > model->params.alpha2 && k < model->params.N1c; k++ )
{
if ( abs( V_C(k,0) - curr_data[0]) <= deltaC &&
abs( V_C(k,1) - curr_data[1]) <= deltaC &&
abs( V_C(k,2) - curr_data[2]) <= deltaC )
{
Pv += PV_C(k);
Pvb += PVB_C(k);
}
}
Pb = stat->Pbc;
if( 2 * Pvb * Pb <= Pv ) val = 1;
}
//update FG
((uchar*)model->foreground->imageData)[i*mask_step+j] = (uchar)(val*255);
FG_pixels_count += val;
}// end if( change detection...
}//for j...
} //for i...
//end BG/FG classification
//foreground segmentation
//smooth FG map
if( model->params.perform_morphing ){
cvMorphologyEx( model->foreground, model->foreground, 0, 0, CV_MOP_OPEN, 1 );
cvMorphologyEx( model->foreground, model->foreground, 0, 0, CV_MOP_CLOSE, 1 );
}
if( model->params.minArea > 0 || model->params.is_obj_without_holes ){
//filter small regions
cvFindContours( model->foreground, model->storage, &first_seq, sizeof(CvContour), CV_RETR_LIST );
for( seq = first_seq; seq; seq = seq->h_next )
{
CvContour* cnt = (CvContour*)seq;
if( cnt->rect.width * cnt->rect.height < model->params.minArea ||
(model->params.is_obj_without_holes && CV_IS_SEQ_HOLE(seq)) )
{
//delete small contour
prev_seq = seq->h_prev;
if( prev_seq )
{
prev_seq->h_next = seq->h_next;
if( seq->h_next ) seq->h_next->h_prev = prev_seq;
}
else
{
first_seq = seq->h_next;
if( seq->h_next ) seq->h_next->h_prev = NULL;
}
}
else
{
region_count++;
}
}
model->foreground_regions = first_seq;
cvZero(model->foreground);
cvDrawContours(model->foreground, first_seq, CV_RGB(0, 0, 255), CV_RGB(0, 0, 255), 10, -1);
}
else{
model->foreground_regions = NULL;
}
//check ALL BG update condition
if( ((float)FG_pixels_count/(model->Ftd->width*model->Ftd->height)) > CV_BGFG_FGD_BG_UPDATE_TRESH )
{
for( i = 0; i < model->Ftd->height; i++ )
for( j = 0; j < model->Ftd->width; j++ )
{
CvBGPixelStat* stat = model->pixel_stat + i * model->Ftd->width + j;
stat->is_trained_st_model = stat->is_trained_dyn_model = 1;
}
}
//update BG model
for( i = 0; i < model->Ftd->height; i++ )
{
for( j = 0; j < model->Ftd->width; j++ )
{
CvBGPixelStat* stat = model->pixel_stat + i * model->Ftd->width + j;
CvBGPixelCStatTable* ctable = stat->ctable;
CvBGPixelCCStatTable* cctable = stat->cctable;
uchar *curr_data = (uchar*)(curr_frame->imageData)+i*curr_frame->widthStep+j*3;
uchar *prev_data = (uchar*)(prev_frame->imageData)+i*prev_frame->widthStep+j*3;
if( ((uchar*)model->Ftd->imageData)[i*mask_step+j] || !stat->is_trained_dyn_model )
{
float alpha = stat->is_trained_dyn_model ? model->params.alpha2 : model->params.alpha3;
float diff = 0;
int dist, min_dist = 2147483647, indx = -1;
//update Pb
stat->Pbcc *= (1.f-alpha);
if( !((uchar*)model->foreground->imageData)[i*mask_step+j] )
{
stat->Pbcc += alpha;
}
// find best Vi match
for(k = 0; PV_CC(k) && k < model->params.N2cc; k++ )
{
// Exponential decay of memory
PV_CC(k) *= (1-alpha);
PVB_CC(k) *= (1-alpha);
if( PV_CC(k) < MIN_PV )
{
PV_CC(k) = 0;
PVB_CC(k) = 0;
continue;
}
dist = 0;
for( l = 0; l < 3; l++ )
{
int val = abs( V_CC(k,l) - prev_data[l] );
if( val > deltaCC ) break;
dist += val;
val = abs( V_CC(k,l+3) - curr_data[l] );
if( val > deltaCC) break;
dist += val;
}
if( l == 3 && dist < min_dist )
{
min_dist = dist;
indx = k;
}
}
if( indx < 0 )
{//N2th elem in the table is replaced by a new features
indx = model->params.N2cc - 1;
PV_CC(indx) = alpha;
PVB_CC(indx) = alpha;
//udate Vt
for( l = 0; l < 3; l++ )
{
V_CC(indx,l) = prev_data[l];
V_CC(indx,l+3) = curr_data[l];
}
}
else
{//update
PV_CC(indx) += alpha;
if( !((uchar*)model->foreground->imageData)[i*mask_step+j] )
{
PVB_CC(indx) += alpha;
}
}
//re-sort CCt table by Pv
for( k = 0; k < indx; k++ )
{
if( PV_CC(k) <= PV_CC(indx) )
{
//shift elements
CvBGPixelCCStatTable tmp1, tmp2 = cctable[indx];
for( l = k; l <= indx; l++ )
{
tmp1 = cctable[l];
cctable[l] = tmp2;
tmp2 = tmp1;
}
break;
}
}
float sum1=0, sum2=0;
//check "once-off" changes
for(k = 0; PV_CC(k) && k < model->params.N1cc; k++ )
{
sum1 += PV_CC(k);
sum2 += PVB_CC(k);
}
if( sum1 > model->params.T ) stat->is_trained_dyn_model = 1;
diff = sum1 - stat->Pbcc * sum2;
//update stat table
if( diff > model->params.T )
{
//printf("once off change at motion mode\n");
//new BG features are discovered
for( k = 0; PV_CC(k) && k < model->params.N1cc; k++ )
{
PVB_CC(k) =
(PV_CC(k)-stat->Pbcc*PVB_CC(k))/(1-stat->Pbcc);
}
assert(stat->Pbcc<=1 && stat->Pbcc>=0);
}
}
//case of stational pixel
if( !((uchar*)model->Ftd->imageData)[i*mask_step+j] )
{
float alpha = stat->is_trained_st_model ? model->params.alpha2 : model->params.alpha3;
float diff = 0;
int dist, min_dist = 2147483647, indx = -1;
//update Pb
stat->Pbc *= (1.f-alpha);
if( !((uchar*)model->foreground->imageData)[i*mask_step+j] )
{
stat->Pbc += alpha;
}
//find best Vi match
for( k = 0; k < model->params.N2c; k++ )
{
// Exponential decay of memory
PV_C(k) *= (1-alpha);
PVB_C(k) *= (1-alpha);
if( PV_C(k) < MIN_PV )
{
PV_C(k) = 0;
PVB_C(k) = 0;
continue;
}
dist = 0;
for( l = 0; l < 3; l++ )
{
int val = abs( V_C(k,l) - curr_data[l] );
if( val > deltaC ) break;
dist += val;
}
if( l == 3 && dist < min_dist )
{
min_dist = dist;
indx = k;
}
}
if( indx < 0 )
{//N2th elem in the table is replaced by a new features
indx = model->params.N2c - 1;
PV_C(indx) = alpha;
PVB_C(indx) = alpha;
//udate Vt
for( l = 0; l < 3; l++ )
{
V_C(indx,l) = curr_data[l];
}
} else
{//update
PV_C(indx) += alpha;
if( !((uchar*)model->foreground->imageData)[i*mask_step+j] )
{
PVB_C(indx) += alpha;
}
}
//re-sort Ct table by Pv
for( k = 0; k < indx; k++ )
{
if( PV_C(k) <= PV_C(indx) )
{
//shift elements
CvBGPixelCStatTable tmp1, tmp2 = ctable[indx];
for( l = k; l <= indx; l++ )
{
tmp1 = ctable[l];
ctable[l] = tmp2;
tmp2 = tmp1;
}
break;
}
}
//check "once-off" changes
float sum1=0, sum2=0;
for( k = 0; PV_C(k) && k < model->params.N1c; k++ )
{
sum1 += PV_C(k);
sum2 += PVB_C(k);
}
diff = sum1 - stat->Pbc * sum2;
if( sum1 > model->params.T ) stat->is_trained_st_model = 1;
//update stat table
if( diff > model->params.T )
{
//printf("once off change at stat mode\n");
//new BG features are discovered
for( k = 0; PV_C(k) && k < model->params.N1c; k++ )
{
PVB_C(k) = (PV_C(k)-stat->Pbc*PVB_C(k))/(1-stat->Pbc);
}
stat->Pbc = 1 - stat->Pbc;
}
}//if !(change detection) at pixel (i,j)
//update the reference BG image
if( !((uchar*)model->foreground->imageData)[i*mask_step+j])
{
uchar* ptr = ((uchar*)model->background->imageData) + i*model->background->widthStep+j*3;
if( !((uchar*)model->Ftd->imageData)[i*mask_step+j] &&
!((uchar*)model->Fbd->imageData)[i*mask_step+j] )
{
//apply IIR filter
for( l = 0; l < 3; l++ )
{
int a = cvRound(ptr[l]*(1 - model->params.alpha1) + model->params.alpha1*curr_data[l]);
ptr[l] = (uchar)a;
//((uchar*)model->background->imageData)[i*model->background->widthStep+j*3+l]*=(1 - model->params.alpha1);
//((uchar*)model->background->imageData)[i*model->background->widthStep+j*3+l] += model->params.alpha1*curr_data[l];
}
}
else
{
//background change is detected
for( l = 0; l < 3; l++ )
{
//((uchar*)model->background->imageData)[i*model->background->widthStep+j*3+l] = curr_data[l];
ptr[l] = curr_data[l];
}
}
}
}//j
}//i
//keep prev frame
cvCopy( curr_frame, model->prev_frame );
return region_count;
}
/* End of file. */

View File

@@ -0,0 +1,70 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
// Function cvRefineForegroundMaskBySegm preforms FG post-processing based on segmentation
// (all pixels of the segment will be classified as FG if majority of pixels of the region are FG).
// parameters:
// segments - pointer to result of segmentation (for example MeanShiftSegmentation)
// bg_model - pointer to CvBGStatModel structure
CV_IMPL void cvRefineForegroundMaskBySegm( CvSeq* segments, CvBGStatModel* bg_model )
{
IplImage* tmp_image = cvCreateImage(cvSize(bg_model->foreground->width,bg_model->foreground->height),
IPL_DEPTH_8U, 1);
for( ; segments; segments = ((CvSeq*)segments)->h_next )
{
CvSeq seq = *segments;
seq.v_next = seq.h_next = NULL;
cvZero(tmp_image);
cvDrawContours( tmp_image, &seq, CV_RGB(0, 0, 255), CV_RGB(0, 0, 255), 10, -1);
int num1 = cvCountNonZero(tmp_image);
cvAnd(tmp_image, bg_model->foreground, tmp_image);
int num2 = cvCountNonZero(tmp_image);
if( num2 > num1*0.5 )
cvDrawContours( bg_model->foreground, &seq, CV_RGB(0, 0, 255), CV_RGB(0, 0, 255), 10, -1);
else
cvDrawContours( bg_model->foreground, &seq, CV_RGB(0, 0, 0), CV_RGB(0, 0, 0), 10, -1);
}
cvReleaseImage(&tmp_image);
}
/* End of file. */

View File

@@ -0,0 +1,592 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
//This is based on the "An Improved Adaptive Background Mixture Model for
//Real-time Tracking and Shadow Detection" by P. KaewTraKulPong and R. Bowden
//The windowing method is used, but not the shadow detection. I make some of my
//own modifications which make more sense. There are some errors in some of their
//equations.
//IplImage values of image that are useful
//int nSize; /* sizeof(IplImage) */
//int depth; /* pixel depth in bits: IPL_DEPTH_8U ...*/
//int nChannels; /* OpenCV functions support 1,2,3 or 4 channels */
//int width; /* image width in pixels */
//int height; /* image height in pixels */
//int imageSize; /* image data size in bytes in case of interleaved data)*/
//char *imageData; /* pointer to aligned image data */
//char *imageDataOrigin; /* pointer to very origin of image -deallocation */
//Values useful for gaussian integral
//0.5 - 0.19146 - 0.38292
//1.0 - 0.34134 - 0.68268
//1.5 - 0.43319 - 0.86638
//2.0 - 0.47725 - 0.95450
//2.5 - 0.49379 - 0.98758
//3.0 - 0.49865 - 0.99730
//3.5 - 0.4997674 - 0.9995348
//4.0 - 0.4999683 - 0.9999366
#include "_cvaux.h"
//internal functions for gaussian background detection
static void icvInsertionSortGaussians( CvGaussBGPoint* g_point, double* sort_key, CvGaussBGStatModelParams *bg_model_params );
/*
Test whether pixel can be explained by background model;
Return -1 if no match was found; otherwise the index in match[] is returned
icvMatchTest(...) assumes what all color channels component exhibit the same variance
icvMatchTest2(...) accounts for different variances per color channel
*/
static int icvMatchTest( double* src_pixel, int nChannels, int* match,
const CvGaussBGPoint* g_point, const CvGaussBGStatModelParams *bg_model_params );
/*static int icvMatchTest2( double* src_pixel, int nChannels, int* match,
const CvGaussBGPoint* g_point, const CvGaussBGStatModelParams *bg_model_params );*/
/*
The update procedure differs between
* the initialization phase (named *Partial* ) and
* the normal phase (named *Full* )
The initalization phase is defined as not having processed <win_size> frames yet
*/
static void icvUpdateFullWindow( double* src_pixel, int nChannels,
int* match,
CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params );
static void icvUpdateFullNoMatch( IplImage* gm_image, int p,
int* match,
CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params);
static void icvUpdatePartialWindow( double* src_pixel, int nChannels, int* match,
CvGaussBGPoint* g_point, const CvGaussBGStatModelParams *bg_model_params );
static void icvUpdatePartialNoMatch( double* src_pixel, int nChannels,
int* match,
CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params);
static void icvGetSortKey( const int nChannels, double* sort_key, const CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params );
static void icvBackgroundTest( const int nChannels, int n, int p, int *match, CvGaussBGModel* bg_model );
static void CV_CDECL icvReleaseGaussianBGModel( CvGaussBGModel** bg_model );
static int CV_CDECL icvUpdateGaussianBGModel( IplImage* curr_frame, CvGaussBGModel* bg_model );
//#define for if(0);else for
//g = 1 for first gaussian in list that matches else g = 0
//Rw is the learning rate for weight and Rg is leaning rate for mean and variance
//Ms is the match_sum which is the sum of matches for a particular gaussian
//Ms values are incremented until the sum of Ms values in the list equals window size L
//SMs is the sum of match_sums for gaussians in the list
//Rw = 1/SMs note the smallest Rw gets is 1/L
//Rg = g/Ms for SMs < L and Rg = g/(w*L) for SMs = L
//The list is maintained in sorted order using w/sqrt(variance) as a key
//If there is no match the last gaussian in the list is replaced by the new gaussian
//This will result in changes to SMs which results in changes in Rw and Rg.
//If a gaussian is replaced and SMs previously equaled L values of Ms are computed from w
//w[n+1] = w[n] + Rw*(g - w[n]) weight
//u[n+1] = u[n] + Rg*(x[n+1] - u[n]) mean value Sg is sum n values of g
//v[n+1] = v[n] + Rg*((x[n+1] - u[n])*(x[n+1] - u[n])) - v[n]) variance
//
CV_IMPL CvBGStatModel*
cvCreateGaussianBGModel( IplImage* first_frame, CvGaussBGStatModelParams* parameters )
{
CvGaussBGModel* bg_model = 0;
CV_FUNCNAME( "cvCreateGaussianBGModel" );
__BEGIN__;
double var_init;
CvGaussBGStatModelParams params;
int i, j, k, n, m, p;
//init parameters
if( parameters == NULL )
{
params.win_size = CV_BGFG_MOG_WINDOW_SIZE;
params.bg_threshold = CV_BGFG_MOG_BACKGROUND_THRESHOLD;
params.std_threshold = CV_BGFG_MOG_STD_THRESHOLD;
params.weight_init = CV_BGFG_MOG_WEIGHT_INIT;
params.variance_init = CV_BGFG_MOG_SIGMA_INIT*CV_BGFG_MOG_SIGMA_INIT;
params.minArea = CV_BGFG_MOG_MINAREA;
params.n_gauss = CV_BGFG_MOG_NGAUSSIANS;
}
else
{
params = *parameters;
}
if( !CV_IS_IMAGE(first_frame) )
CV_ERROR( CV_StsBadArg, "Invalid or NULL first_frame parameter" );
CV_CALL( bg_model = (CvGaussBGModel*)cvAlloc( sizeof(*bg_model) ));
memset( bg_model, 0, sizeof(*bg_model) );
bg_model->type = CV_BG_MODEL_MOG;
bg_model->release = (CvReleaseBGStatModel)icvReleaseGaussianBGModel;
bg_model->update = (CvUpdateBGStatModel)icvUpdateGaussianBGModel;
bg_model->params = params;
//prepare storages
CV_CALL( bg_model->g_point = (CvGaussBGPoint*)cvAlloc(sizeof(CvGaussBGPoint)*
((first_frame->width*first_frame->height) + 256)));
CV_CALL( bg_model->background = cvCreateImage(cvSize(first_frame->width,
first_frame->height), IPL_DEPTH_8U, first_frame->nChannels));
CV_CALL( bg_model->foreground = cvCreateImage(cvSize(first_frame->width,
first_frame->height), IPL_DEPTH_8U, 1));
CV_CALL( bg_model->storage = cvCreateMemStorage());
//initializing
var_init = 2 * params.std_threshold * params.std_threshold;
CV_CALL( bg_model->g_point[0].g_values =
(CvGaussBGValues*)cvAlloc( sizeof(CvGaussBGValues)*params.n_gauss*
(first_frame->width*first_frame->height + 128)));
for( i = 0, p = 0, n = 0; i < first_frame->height; i++ )
{
for( j = 0; j < first_frame->width; j++, n++ )
{
bg_model->g_point[n].g_values =
bg_model->g_point[0].g_values + n*params.n_gauss;
bg_model->g_point[n].g_values[0].weight = 1; //the first value seen has weight one
bg_model->g_point[n].g_values[0].match_sum = 1;
for( m = 0; m < first_frame->nChannels; m++)
{
bg_model->g_point[n].g_values[0].variance[m] = var_init;
bg_model->g_point[n].g_values[0].mean[m] = (unsigned char)first_frame->imageData[p + m];
}
for( k = 1; k < params.n_gauss; k++)
{
bg_model->g_point[n].g_values[k].weight = 0;
bg_model->g_point[n].g_values[k].match_sum = 0;
for( m = 0; m < first_frame->nChannels; m++){
bg_model->g_point[n].g_values[k].variance[m] = var_init;
bg_model->g_point[n].g_values[k].mean[m] = 0;
}
}
p += first_frame->nChannels;
}
}
bg_model->countFrames = 0;
__END__;
if( cvGetErrStatus() < 0 )
{
CvBGStatModel* base_ptr = (CvBGStatModel*)bg_model;
if( bg_model && bg_model->release )
bg_model->release( &base_ptr );
else
cvFree( &bg_model );
bg_model = 0;
}
return (CvBGStatModel*)bg_model;
}
static void CV_CDECL
icvReleaseGaussianBGModel( CvGaussBGModel** _bg_model )
{
CV_FUNCNAME( "icvReleaseGaussianBGModel" );
__BEGIN__;
if( !_bg_model )
CV_ERROR( CV_StsNullPtr, "" );
if( *_bg_model )
{
CvGaussBGModel* bg_model = *_bg_model;
if( bg_model->g_point )
{
cvFree( &bg_model->g_point[0].g_values );
cvFree( &bg_model->g_point );
}
cvReleaseImage( &bg_model->background );
cvReleaseImage( &bg_model->foreground );
cvReleaseMemStorage(&bg_model->storage);
memset( bg_model, 0, sizeof(*bg_model) );
cvFree( _bg_model );
}
__END__;
}
static int CV_CDECL
icvUpdateGaussianBGModel( IplImage* curr_frame, CvGaussBGModel* bg_model )
{
int i, j, k;
int region_count = 0;
CvSeq *first_seq = NULL, *prev_seq = NULL, *seq = NULL;
bg_model->countFrames++;
for( i = 0; i < curr_frame->height; i++ )
{
for( j = 0; j < curr_frame->width; j++ )
{
int match[CV_BGFG_MOG_MAX_NGAUSSIANS];
double sort_key[CV_BGFG_MOG_MAX_NGAUSSIANS];
const int nChannels = curr_frame->nChannels;
const int n = i*curr_frame->width+j;
const int p = n*curr_frame->nChannels;
// A few short cuts
CvGaussBGPoint* g_point = &bg_model->g_point[n];
const CvGaussBGStatModelParams bg_model_params = bg_model->params;
double pixel[4];
int no_match;
for( k = 0; k < nChannels; k++ )
pixel[k] = (uchar)curr_frame->imageData[p+k];
no_match = icvMatchTest( pixel, nChannels, match, g_point, &bg_model_params );
if( bg_model->countFrames == bg_model->params.win_size )
{
icvUpdateFullWindow( pixel, nChannels, match, g_point, &bg_model->params );
if( no_match == -1)
icvUpdateFullNoMatch( curr_frame, p, match, g_point, &bg_model_params );
}
else
{
icvUpdatePartialWindow( pixel, nChannels, match, g_point, &bg_model_params );
if( no_match == -1)
icvUpdatePartialNoMatch( pixel, nChannels, match, g_point, &bg_model_params );
}
icvGetSortKey( nChannels, sort_key, g_point, &bg_model_params );
icvInsertionSortGaussians( g_point, sort_key, (CvGaussBGStatModelParams *)&bg_model_params );
icvBackgroundTest( nChannels, n, p, match, bg_model );
}
}
//foreground filtering
//filter small regions
cvClearMemStorage(bg_model->storage);
//cvMorphologyEx( bg_model->foreground, bg_model->foreground, 0, 0, CV_MOP_OPEN, 1 );
//cvMorphologyEx( bg_model->foreground, bg_model->foreground, 0, 0, CV_MOP_CLOSE, 1 );
cvFindContours( bg_model->foreground, bg_model->storage, &first_seq, sizeof(CvContour), CV_RETR_LIST );
for( seq = first_seq; seq; seq = seq->h_next )
{
CvContour* cnt = (CvContour*)seq;
if( cnt->rect.width * cnt->rect.height < bg_model->params.minArea )
{
//delete small contour
prev_seq = seq->h_prev;
if( prev_seq )
{
prev_seq->h_next = seq->h_next;
if( seq->h_next ) seq->h_next->h_prev = prev_seq;
}
else
{
first_seq = seq->h_next;
if( seq->h_next ) seq->h_next->h_prev = NULL;
}
}
else
{
region_count++;
}
}
bg_model->foreground_regions = first_seq;
cvZero(bg_model->foreground);
cvDrawContours(bg_model->foreground, first_seq, CV_RGB(0, 0, 255), CV_RGB(0, 0, 255), 10, -1);
return region_count;
}
static void icvInsertionSortGaussians( CvGaussBGPoint* g_point, double* sort_key, CvGaussBGStatModelParams *bg_model_params )
{
int i, j;
for( i = 1; i < bg_model_params->n_gauss; i++ )
{
double index = sort_key[i];
for( j = i; j > 0 && sort_key[j-1] < index; j-- ) //sort decending order
{
double temp_sort_key = sort_key[j];
sort_key[j] = sort_key[j-1];
sort_key[j-1] = temp_sort_key;
CvGaussBGValues temp_gauss_values = g_point->g_values[j];
g_point->g_values[j] = g_point->g_values[j-1];
g_point->g_values[j-1] = temp_gauss_values;
}
// sort_key[j] = index;
}
}
static int icvMatchTest( double* src_pixel, int nChannels, int* match,
const CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params )
{
int k;
int matchPosition=-1;
for ( k = 0; k < bg_model_params->n_gauss; k++) match[k]=0;
for ( k = 0; k < bg_model_params->n_gauss; k++) {
double sum_d2 = 0.0;
double var_threshold = 0.0;
for(int m = 0; m < nChannels; m++){
double d = g_point->g_values[k].mean[m]- src_pixel[m];
sum_d2 += (d*d);
var_threshold += g_point->g_values[k].variance[m];
} //difference < STD_LIMIT*STD_LIMIT or difference**2 < STD_LIMIT*STD_LIMIT*VAR
var_threshold = bg_model_params->std_threshold*bg_model_params->std_threshold*var_threshold;
if(sum_d2 < var_threshold){
match[k] = 1;
matchPosition = k;
break;
}
}
return matchPosition;
}
/*
static int icvMatchTest2( double* src_pixel, int nChannels, int* match,
const CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params )
{
int k, m;
int matchPosition=-1;
for( k = 0; k < bg_model_params->n_gauss; k++ )
match[k] = 0;
for( k = 0; k < bg_model_params->n_gauss; k++ )
{
double sum_d2 = 0.0, var_threshold;
for( m = 0; m < nChannels; m++ )
{
double d = g_point->g_values[k].mean[m]- src_pixel[m];
sum_d2 += (d*d) / (g_point->g_values[k].variance[m] * g_point->g_values[k].variance[m]);
} //difference < STD_LIMIT*STD_LIMIT or difference**2 < STD_LIMIT*STD_LIMIT*VAR
var_threshold = bg_model_params->std_threshold*bg_model_params->std_threshold;
if( sum_d2 < var_threshold )
{
match[k] = 1;
matchPosition = k;
break;
}
}
return matchPosition;
}
*/
static void icvUpdateFullWindow( double* src_pixel, int nChannels, int* match,
CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params )
{
const double learning_rate_weight = (1.0/(double)bg_model_params->win_size);
for(int k = 0; k < bg_model_params->n_gauss; k++){
g_point->g_values[k].weight = g_point->g_values[k].weight +
(learning_rate_weight*((double)match[k] -
g_point->g_values[k].weight));
if(match[k]){
double learning_rate_gaussian = (double)match[k]/(g_point->g_values[k].weight*
(double)bg_model_params->win_size);
for(int m = 0; m < nChannels; m++){
const double tmpDiff = src_pixel[m] - g_point->g_values[k].mean[m];
g_point->g_values[k].mean[m] = g_point->g_values[k].mean[m] +
(learning_rate_gaussian * tmpDiff);
g_point->g_values[k].variance[m] = g_point->g_values[k].variance[m]+
(learning_rate_gaussian*((tmpDiff*tmpDiff) - g_point->g_values[k].variance[m]));
}
}
}
}
static void icvUpdatePartialWindow( double* src_pixel, int nChannels, int* match, CvGaussBGPoint* g_point, const CvGaussBGStatModelParams *bg_model_params )
{
int k, m;
int window_current = 0;
for( k = 0; k < bg_model_params->n_gauss; k++ )
window_current += g_point->g_values[k].match_sum;
for( k = 0; k < bg_model_params->n_gauss; k++ )
{
g_point->g_values[k].match_sum += match[k];
double learning_rate_weight = (1.0/((double)window_current + 1.0)); //increased by one since sum
g_point->g_values[k].weight = g_point->g_values[k].weight +
(learning_rate_weight*((double)match[k] - g_point->g_values[k].weight));
if( g_point->g_values[k].match_sum > 0 && match[k] )
{
double learning_rate_gaussian = (double)match[k]/((double)g_point->g_values[k].match_sum);
for( m = 0; m < nChannels; m++ )
{
const double tmpDiff = src_pixel[m] - g_point->g_values[k].mean[m];
g_point->g_values[k].mean[m] = g_point->g_values[k].mean[m] +
(learning_rate_gaussian*tmpDiff);
g_point->g_values[k].variance[m] = g_point->g_values[k].variance[m]+
(learning_rate_gaussian*((tmpDiff*tmpDiff) - g_point->g_values[k].variance[m]));
}
}
}
}
static void icvUpdateFullNoMatch( IplImage* gm_image, int p, int* match,
CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params)
{
int k, m;
double alpha;
int match_sum_total = 0;
//new value of last one
g_point->g_values[bg_model_params->n_gauss - 1].match_sum = 1;
//get sum of all but last value of match_sum
for( k = 0; k < bg_model_params->n_gauss ; k++ )
match_sum_total += g_point->g_values[k].match_sum;
g_point->g_values[bg_model_params->n_gauss - 1].weight = 1./(double)match_sum_total;
for( m = 0; m < gm_image->nChannels ; m++ )
{
// first pass mean is image value
g_point->g_values[bg_model_params->n_gauss - 1].variance[m] = bg_model_params->variance_init;
g_point->g_values[bg_model_params->n_gauss - 1].mean[m] = (unsigned char)gm_image->imageData[p + m];
}
alpha = 1.0 - (1.0/bg_model_params->win_size);
for( k = 0; k < bg_model_params->n_gauss - 1; k++ )
{
g_point->g_values[k].weight *= alpha;
if( match[k] )
g_point->g_values[k].weight += alpha;
}
}
static void
icvUpdatePartialNoMatch(double *pixel,
int nChannels,
int* /*match*/,
CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params)
{
int k, m;
//new value of last one
g_point->g_values[bg_model_params->n_gauss - 1].match_sum = 1;
//get sum of all but last value of match_sum
int match_sum_total = 0;
for(k = 0; k < bg_model_params->n_gauss ; k++)
match_sum_total += g_point->g_values[k].match_sum;
for(m = 0; m < nChannels; m++)
{
//first pass mean is image value
g_point->g_values[bg_model_params->n_gauss - 1].variance[m] = bg_model_params->variance_init;
g_point->g_values[bg_model_params->n_gauss - 1].mean[m] = pixel[m];
}
for(k = 0; k < bg_model_params->n_gauss; k++)
{
g_point->g_values[k].weight = (double)g_point->g_values[k].match_sum /
(double)match_sum_total;
}
}
static void icvGetSortKey( const int nChannels, double* sort_key, const CvGaussBGPoint* g_point,
const CvGaussBGStatModelParams *bg_model_params )
{
int k, m;
for( k = 0; k < bg_model_params->n_gauss; k++ )
{
// Avoid division by zero
if( g_point->g_values[k].match_sum > 0 )
{
// Independence assumption between components
double variance_sum = 0.0;
for( m = 0; m < nChannels; m++ )
variance_sum += g_point->g_values[k].variance[m];
sort_key[k] = g_point->g_values[k].weight/sqrt(variance_sum);
}
else
sort_key[k]= 0.0;
}
}
static void icvBackgroundTest( const int nChannels, int n, int p, int *match, CvGaussBGModel* bg_model )
{
int m, b;
uchar pixelValue = (uchar)255; // will switch to 0 if match found
double weight_sum = 0.0;
CvGaussBGPoint* g_point = bg_model->g_point;
for( m = 0; m < nChannels; m++)
bg_model->background->imageData[p+m] = (unsigned char)(g_point[n].g_values[0].mean[m]+0.5);
for( b = 0; b < bg_model->params.n_gauss; b++)
{
weight_sum += g_point[n].g_values[b].weight;
if( match[b] )
pixelValue = 0;
if( weight_sum > bg_model->params.bg_threshold )
break;
}
bg_model->foreground->imageData[p/nChannels] = pixelValue;
}
/* End of file. */

View File

@@ -0,0 +1,905 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#include <stdio.h>
#undef quad
#if _MSC_VER >= 1200
#pragma warning( disable: 4701 )
#endif
CvCalibFilter::CvCalibFilter()
{
/* etalon data */
etalonType = CV_CALIB_ETALON_USER;
etalonParamCount = 0;
etalonParams = 0;
etalonPointCount = 0;
etalonPoints = 0;
/* camera data */
cameraCount = 1;
memset( points, 0, sizeof(points));
memset( undistMap, 0, sizeof(undistMap));
undistImg = 0;
memset( latestCounts, 0, sizeof(latestCounts));
memset( latestPoints, 0, sizeof(latestPoints));
maxPoints = 0;
framesTotal = 15;
framesAccepted = 0;
isCalibrated = false;
imgSize = cvSize(0,0);
grayImg = 0;
tempImg = 0;
storage = 0;
memset( rectMap, 0, sizeof(rectMap));
}
CvCalibFilter::~CvCalibFilter()
{
SetCameraCount(0);
cvFree( &etalonParams );
cvFree( &etalonPoints );
cvReleaseMat( &grayImg );
cvReleaseMat( &tempImg );
cvReleaseMat( &undistImg );
cvReleaseMemStorage( &storage );
}
bool CvCalibFilter::SetEtalon( CvCalibEtalonType type, double* params,
int pointCount, CvPoint2D32f* points )
{
int i, arrSize;
Stop();
for( i = 0; i < MAX_CAMERAS; i++ )
cvFree( latestPoints + i );
if( type == CV_CALIB_ETALON_USER || type != etalonType )
{
cvFree( &etalonParams );
}
etalonType = type;
switch( etalonType )
{
case CV_CALIB_ETALON_CHESSBOARD:
etalonParamCount = 3;
if( !params || cvRound(params[0]) != params[0] || params[0] < 3 ||
cvRound(params[1]) != params[1] || params[1] < 3 || params[2] <= 0 )
{
assert(0);
return false;
}
pointCount = cvRound((params[0] - 1)*(params[1] - 1));
break;
case CV_CALIB_ETALON_USER:
etalonParamCount = 0;
if( !points || pointCount < 4 )
{
assert(0);
return false;
}
break;
default:
assert(0);
return false;
}
if( etalonParamCount > 0 )
{
arrSize = etalonParamCount * sizeof(etalonParams[0]);
etalonParams = (double*)cvAlloc( arrSize );
}
arrSize = pointCount * sizeof(etalonPoints[0]);
if( etalonPointCount != pointCount )
{
cvFree( &etalonPoints );
etalonPointCount = pointCount;
etalonPoints = (CvPoint2D32f*)cvAlloc( arrSize );
}
switch( etalonType )
{
case CV_CALIB_ETALON_CHESSBOARD:
{
int etalonWidth = cvRound( params[0] ) - 1;
int etalonHeight = cvRound( params[1] ) - 1;
int x, y, k = 0;
etalonParams[0] = etalonWidth;
etalonParams[1] = etalonHeight;
etalonParams[2] = params[2];
for( y = 0; y < etalonHeight; y++ )
for( x = 0; x < etalonWidth; x++ )
{
etalonPoints[k++] = cvPoint2D32f( (etalonWidth - 1 - x)*params[2],
y*params[2] );
}
}
break;
case CV_CALIB_ETALON_USER:
memcpy( etalonParams, params, arrSize );
memcpy( etalonPoints, points, arrSize );
break;
default:
assert(0);
return false;
}
return true;
}
CvCalibEtalonType
CvCalibFilter::GetEtalon( int* paramCount, const double** params,
int* pointCount, const CvPoint2D32f** points ) const
{
if( paramCount )
*paramCount = etalonParamCount;
if( params )
*params = etalonParams;
if( pointCount )
*pointCount = etalonPointCount;
if( points )
*points = etalonPoints;
return etalonType;
}
void CvCalibFilter::SetCameraCount( int count )
{
Stop();
if( count != cameraCount )
{
for( int i = 0; i < cameraCount; i++ )
{
cvFree( points + i );
cvFree( latestPoints + i );
cvReleaseMat( &undistMap[i][0] );
cvReleaseMat( &undistMap[i][1] );
cvReleaseMat( &rectMap[i][0] );
cvReleaseMat( &rectMap[i][1] );
}
memset( latestCounts, 0, sizeof(latestPoints) );
maxPoints = 0;
cameraCount = count;
}
}
bool CvCalibFilter::SetFrames( int frames )
{
if( frames < 5 )
{
assert(0);
return false;
}
framesTotal = frames;
return true;
}
void CvCalibFilter::Stop( bool calibrate )
{
int i, j;
isCalibrated = false;
// deallocate undistortion maps
for( i = 0; i < cameraCount; i++ )
{
cvReleaseMat( &undistMap[i][0] );
cvReleaseMat( &undistMap[i][1] );
cvReleaseMat( &rectMap[i][0] );
cvReleaseMat( &rectMap[i][1] );
}
if( calibrate && framesAccepted > 0 )
{
int n = framesAccepted;
CvPoint3D32f* buffer =
(CvPoint3D32f*)cvAlloc( n * etalonPointCount * sizeof(buffer[0]));
CvMat mat;
float* rotMatr = (float*)cvAlloc( n * 9 * sizeof(rotMatr[0]));
float* transVect = (float*)cvAlloc( n * 3 * sizeof(transVect[0]));
int* counts = (int*)cvAlloc( n * sizeof(counts[0]));
cvInitMatHeader( &mat, 1, sizeof(CvCamera)/sizeof(float), CV_32FC1, 0 );
memset( cameraParams, 0, cameraCount * sizeof(cameraParams[0]));
for( i = 0; i < framesAccepted; i++ )
{
counts[i] = etalonPointCount;
for( j = 0; j < etalonPointCount; j++ )
buffer[i * etalonPointCount + j] = cvPoint3D32f( etalonPoints[j].x,
etalonPoints[j].y, 0 );
}
for( i = 0; i < cameraCount; i++ )
{
cvCalibrateCamera( framesAccepted, counts,
imgSize, points[i], buffer,
cameraParams[i].distortion,
cameraParams[i].matrix,
transVect, rotMatr, 0 );
cameraParams[i].imgSize[0] = (float)imgSize.width;
cameraParams[i].imgSize[1] = (float)imgSize.height;
// cameraParams[i].focalLength[0] = cameraParams[i].matrix[0];
// cameraParams[i].focalLength[1] = cameraParams[i].matrix[4];
// cameraParams[i].principalPoint[0] = cameraParams[i].matrix[2];
// cameraParams[i].principalPoint[1] = cameraParams[i].matrix[5];
memcpy( cameraParams[i].rotMatr, rotMatr, 9 * sizeof(rotMatr[0]));
memcpy( cameraParams[i].transVect, transVect, 3 * sizeof(transVect[0]));
mat.data.ptr = (uchar*)(cameraParams + i);
/* check resultant camera parameters: if there are some INF's or NAN's,
stop and reset results */
if( !cvCheckArr( &mat, CV_CHECK_RANGE | CV_CHECK_QUIET, -10000, 10000 ))
break;
}
isCalibrated = i == cameraCount;
{/* calibrate stereo cameras */
if( cameraCount == 2 )
{
stereo.camera[0] = &cameraParams[0];
stereo.camera[1] = &cameraParams[1];
icvStereoCalibration( framesAccepted, counts,
imgSize,
points[0],points[1],
buffer,
&stereo);
for( i = 0; i < 9; i++ )
{
stereo.fundMatr[i] = stereo.fundMatr[i];
}
}
}
cvFree( &buffer );
cvFree( &counts );
cvFree( &rotMatr );
cvFree( &transVect );
}
framesAccepted = 0;
}
bool CvCalibFilter::FindEtalon( IplImage** imgs )
{
return FindEtalon( (CvMat**)imgs );
}
bool CvCalibFilter::FindEtalon( CvMat** mats )
{
bool result = true;
if( !mats || etalonPointCount == 0 )
{
assert(0);
result = false;
}
if( result )
{
int i, tempPointCount0 = etalonPointCount*2;
for( i = 0; i < cameraCount; i++ )
{
if( !latestPoints[i] )
latestPoints[i] = (CvPoint2D32f*)
cvAlloc( tempPointCount0*2*sizeof(latestPoints[0]));
}
for( i = 0; i < cameraCount; i++ )
{
CvSize size;
int tempPointCount = tempPointCount0;
bool found = false;
if( !CV_IS_MAT(mats[i]) && !CV_IS_IMAGE(mats[i]))
{
assert(0);
break;
}
size = cvGetSize(mats[i]);
if( size.width != imgSize.width || size.height != imgSize.height )
{
imgSize = size;
}
if( !grayImg || grayImg->width != imgSize.width ||
grayImg->height != imgSize.height )
{
cvReleaseMat( &grayImg );
cvReleaseMat( &tempImg );
grayImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 );
tempImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 );
}
if( !storage )
storage = cvCreateMemStorage();
switch( etalonType )
{
case CV_CALIB_ETALON_CHESSBOARD:
if( CV_MAT_CN(cvGetElemType(mats[i])) == 1 )
cvCopy( mats[i], grayImg );
else
cvCvtColor( mats[i], grayImg, CV_BGR2GRAY );
found = cvFindChessBoardCornerGuesses( grayImg, tempImg, storage,
cvSize( cvRound(etalonParams[0]),
cvRound(etalonParams[1])),
latestPoints[i], &tempPointCount ) != 0;
if( found )
cvFindCornerSubPix( grayImg, latestPoints[i], tempPointCount,
cvSize(5,5), cvSize(-1,-1),
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10,0.1));
break;
default:
assert(0);
result = false;
break;
}
latestCounts[i] = found ? tempPointCount : -tempPointCount;
result = result && found;
}
}
if( storage )
cvClearMemStorage( storage );
return result;
}
bool CvCalibFilter::Push( const CvPoint2D32f** pts )
{
bool result = true;
int i, newMaxPoints = etalonPointCount*(MAX(framesAccepted,framesTotal) + 1);
isCalibrated = false;
if( !pts )
{
for( i = 0; i < cameraCount; i++ )
if( latestCounts[i] <= 0 )
return false;
pts = (const CvPoint2D32f**)latestPoints;
}
for( i = 0; i < cameraCount; i++ )
{
if( !pts[i] )
{
assert(0);
break;
}
if( maxPoints < newMaxPoints )
{
CvPoint2D32f* prev = points[i];
cvFree( points + i );
points[i] = (CvPoint2D32f*)cvAlloc( newMaxPoints * sizeof(prev[0]));
memcpy( points[i], prev, maxPoints * sizeof(prev[0]));
}
memcpy( points[i] + framesAccepted*etalonPointCount, pts[i],
etalonPointCount*sizeof(points[0][0]));
}
if( maxPoints < newMaxPoints )
maxPoints = newMaxPoints;
result = i == cameraCount;
if( ++framesAccepted >= framesTotal )
Stop( true );
return result;
}
bool CvCalibFilter::GetLatestPoints( int idx, CvPoint2D32f** pts,
int* count, bool* found )
{
int n;
if( (unsigned)idx >= (unsigned)cameraCount ||
!pts || !count || !found )
{
assert(0);
return false;
}
n = latestCounts[idx];
*found = n > 0;
*count = abs(n);
*pts = latestPoints[idx];
return true;
}
void CvCalibFilter::DrawPoints( IplImage** dst )
{
DrawPoints( (CvMat**)dst );
}
void CvCalibFilter::DrawPoints( CvMat** dstarr )
{
int i, j;
if( !dstarr )
{
assert(0);
return;
}
if( latestCounts )
{
for( i = 0; i < cameraCount; i++ )
{
if( dstarr[i] && latestCounts[i] )
{
CvMat dst_stub, *dst;
int count = 0;
bool found = false;
CvPoint2D32f* pts = 0;
GetLatestPoints( i, &pts, &count, &found );
dst = cvGetMat( dstarr[i], &dst_stub );
static const CvScalar line_colors[] =
{
{{0,0,255}},
{{0,128,255}},
{{0,200,200}},
{{0,255,0}},
{{200,200,0}},
{{255,0,0}},
{{255,0,255}}
};
const int colorCount = sizeof(line_colors)/sizeof(line_colors[0]);
const int r = 4;
CvScalar color = line_colors[0];
CvPoint prev_pt = { 0, 0};
for( j = 0; j < count; j++ )
{
CvPoint pt;
pt.x = cvRound(pts[j].x);
pt.y = cvRound(pts[j].y);
if( found )
{
if( etalonType == CV_CALIB_ETALON_CHESSBOARD )
color = line_colors[(j/cvRound(etalonParams[0]))%colorCount];
else
color = CV_RGB(0,255,0);
if( j != 0 )
cvLine( dst, prev_pt, pt, color, 1, CV_AA );
}
cvLine( dst, cvPoint( pt.x - r, pt.y - r ),
cvPoint( pt.x + r, pt.y + r ), color, 1, CV_AA );
cvLine( dst, cvPoint( pt.x - r, pt.y + r),
cvPoint( pt.x + r, pt.y - r), color, 1, CV_AA );
cvCircle( dst, pt, r+1, color, 1, CV_AA );
prev_pt = pt;
}
}
}
}
}
/* Get total number of frames and already accepted pair of frames */
int CvCalibFilter::GetFrameCount( int* total ) const
{
if( total )
*total = framesTotal;
return framesAccepted;
}
/* Get camera parameters for specified camera. If camera is not calibrated
the function returns 0 */
const CvCamera* CvCalibFilter::GetCameraParams( int idx ) const
{
if( (unsigned)idx >= (unsigned)cameraCount )
{
assert(0);
return 0;
}
return isCalibrated ? cameraParams + idx : 0;
}
/* Get camera parameters for specified camera. If camera is not calibrated
the function returns 0 */
const CvStereoCamera* CvCalibFilter::GetStereoParams() const
{
if( !(isCalibrated && cameraCount == 2) )
{
assert(0);
return 0;
}
return &stereo;
}
/* Sets camera parameters for all cameras */
bool CvCalibFilter::SetCameraParams( CvCamera* params )
{
CvMat mat;
int arrSize;
Stop();
if( !params )
{
assert(0);
return false;
}
arrSize = cameraCount * sizeof(params[0]);
cvInitMatHeader( &mat, 1, cameraCount * (arrSize/sizeof(float)),
CV_32FC1, params );
cvCheckArr( &mat, CV_CHECK_RANGE, -10000, 10000 );
memcpy( cameraParams, params, arrSize );
isCalibrated = true;
return true;
}
bool CvCalibFilter::SaveCameraParams( const char* filename )
{
if( isCalibrated )
{
int i, j;
FILE* f = fopen( filename, "w" );
if( !f ) return false;
fprintf( f, "%d\n\n", cameraCount );
for( i = 0; i < cameraCount; i++ )
{
for( j = 0; j < (int)(sizeof(cameraParams[i])/sizeof(float)); j++ )
{
fprintf( f, "%15.10f ", ((float*)(cameraParams + i))[j] );
}
fprintf( f, "\n\n" );
}
/* Save stereo params */
/* Save quad */
for( i = 0; i < 2; i++ )
{
for( j = 0; j < 4; j++ )
{
fprintf(f, "%15.10f ", stereo.quad[i][j].x );
fprintf(f, "%15.10f ", stereo.quad[i][j].y );
}
fprintf(f, "\n");
}
/* Save coeffs */
for( i = 0; i < 2; i++ )
{
for( j = 0; j < 9; j++ )
{
fprintf(f, "%15.10lf ", stereo.coeffs[i][j/3][j%3] );
}
fprintf(f, "\n");
}
fclose(f);
return true;
}
return true;
}
bool CvCalibFilter::LoadCameraParams( const char* filename )
{
int i, j;
int d = 0;
FILE* f = fopen( filename, "r" );
isCalibrated = false;
if( !f ) return false;
if( fscanf( f, "%d", &d ) != 1 || d <= 0 || d > 10 )
return false;
SetCameraCount( d );
for( i = 0; i < cameraCount; i++ )
{
for( j = 0; j < (int)(sizeof(cameraParams[i])/sizeof(float)); j++ )
{
fscanf( f, "%f", &((float*)(cameraParams + i))[j] );
}
}
/* Load stereo params */
/* load quad */
for( i = 0; i < 2; i++ )
{
for( j = 0; j < 4; j++ )
{
fscanf(f, "%f ", &(stereo.quad[i][j].x) );
fscanf(f, "%f ", &(stereo.quad[i][j].y) );
}
}
/* Load coeffs */
for( i = 0; i < 2; i++ )
{
for( j = 0; j < 9; j++ )
{
fscanf(f, "%lf ", &(stereo.coeffs[i][j/3][j%3]) );
}
}
fclose(f);
stereo.warpSize = cvSize( cvRound(cameraParams[0].imgSize[0]), cvRound(cameraParams[0].imgSize[1]));
isCalibrated = true;
return true;
}
bool CvCalibFilter::Rectify( IplImage** srcarr, IplImage** dstarr )
{
return Rectify( (CvMat**)srcarr, (CvMat**)dstarr );
}
bool CvCalibFilter::Rectify( CvMat** srcarr, CvMat** dstarr )
{
int i;
if( !srcarr || !dstarr )
{
assert(0);
return false;
}
if( isCalibrated && cameraCount == 2 )
{
for( i = 0; i < cameraCount; i++ )
{
if( srcarr[i] && dstarr[i] )
{
IplImage src_stub, *src;
IplImage dst_stub, *dst;
src = cvGetImage( srcarr[i], &src_stub );
dst = cvGetImage( dstarr[i], &dst_stub );
if( src->imageData == dst->imageData )
{
if( !undistImg ||
undistImg->width != src->width ||
undistImg->height != src->height ||
CV_MAT_CN(undistImg->type) != src->nChannels )
{
cvReleaseMat( &undistImg );
undistImg = cvCreateMat( src->height, src->width,
CV_8U + (src->nChannels-1)*8 );
}
cvCopy( src, undistImg );
src = cvGetImage( undistImg, &src_stub );
}
cvZero( dst );
if( !rectMap[i][0] || rectMap[i][0]->width != src->width ||
rectMap[i][0]->height != src->height )
{
cvReleaseMat( &rectMap[i][0] );
cvReleaseMat( &rectMap[i][1] );
rectMap[i][0] = cvCreateMat(stereo.warpSize.height,stereo.warpSize.width,CV_32FC1);
rectMap[i][1] = cvCreateMat(stereo.warpSize.height,stereo.warpSize.width,CV_32FC1);
cvComputePerspectiveMap(stereo.coeffs[i], rectMap[i][0], rectMap[i][1]);
}
cvRemap( src, dst, rectMap[i][0], rectMap[i][1] );
}
}
}
else
{
for( i = 0; i < cameraCount; i++ )
{
if( srcarr[i] != dstarr[i] )
cvCopy( srcarr[i], dstarr[i] );
}
}
return true;
}
bool CvCalibFilter::Undistort( IplImage** srcarr, IplImage** dstarr )
{
return Undistort( (CvMat**)srcarr, (CvMat**)dstarr );
}
bool CvCalibFilter::Undistort( CvMat** srcarr, CvMat** dstarr )
{
int i;
if( !srcarr || !dstarr )
{
assert(0);
return false;
}
if( isCalibrated )
{
for( i = 0; i < cameraCount; i++ )
{
if( srcarr[i] && dstarr[i] )
{
CvMat src_stub, *src;
CvMat dst_stub, *dst;
src = cvGetMat( srcarr[i], &src_stub );
dst = cvGetMat( dstarr[i], &dst_stub );
if( src->data.ptr == dst->data.ptr )
{
if( !undistImg || undistImg->width != src->width ||
undistImg->height != src->height ||
CV_ARE_TYPES_EQ( undistImg, src ))
{
cvReleaseMat( &undistImg );
undistImg = cvCreateMat( src->height, src->width, src->type );
}
cvCopy( src, undistImg );
src = undistImg;
}
#if 1
{
CvMat A = cvMat( 3, 3, CV_32FC1, cameraParams[i].matrix );
CvMat k = cvMat( 1, 4, CV_32FC1, cameraParams[i].distortion );
if( !undistMap[i][0] || undistMap[i][0]->width != src->width ||
undistMap[i][0]->height != src->height )
{
cvReleaseMat( &undistMap[i][0] );
cvReleaseMat( &undistMap[i][1] );
undistMap[i][0] = cvCreateMat( src->height, src->width, CV_32FC1 );
undistMap[i][1] = cvCreateMat( src->height, src->width, CV_32FC1 );
cvInitUndistortMap( &A, &k, undistMap[i][0], undistMap[i][1] );
}
cvRemap( src, dst, undistMap[i][0], undistMap[i][1] );
#else
cvUndistort2( src, dst, &A, &k );
#endif
}
}
}
}
else
{
for( i = 0; i < cameraCount; i++ )
{
if( srcarr[i] != dstarr[i] )
cvCopy( srcarr[i], dstarr[i] );
}
}
return true;
}

View File

@@ -0,0 +1,709 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#if 0
#include <float.h>
#include <limits.h>
#include <stdio.h>
#include "_cvutils.h"
#include "_cvwrap.h"
/*typedef struct CvCliqueFinder
{
CvGraph* graph;
int** adj_matr;
int N; //graph size
// stacks, counters etc/
int k; //stack size
int* current_comp;
int** All;
int* ne;
int* ce;
int* fixp; //node with minimal disconnections
int* nod;
int* s; //for selected candidate
int status;
int best_score;
} CvCliqueFinder;
*/
#define GO 1
#define BACK 2
#define PEREBOR 3
#define NEXT PEREBOR
#define END 4
#define CV_GET_ADJ_VTX( vertex, edge ) \
( \
assert(edge->vtx[0]==vertex||edge->vtx[1] == vertex ), \
(edge->vtx[0] == vertex)?edge->vtx[1]:edge->vtx[0] \
)
#define NUMBER( v ) ((v)->flags >> 1 )
void _MarkNodes( CvGraph* graph )
{
//set number of vertices to their flags
for( int i = 0; i < graph->total; i++ )
{
CvGraphVtx* ver = cvGetGraphVtx( graph, i );
if( ver )
{
ver->flags = i<<1;
}
}
}
void _FillAdjMatrix( CvGraph* graph, int** connected, int reverse )
{
//assume all vertices are marked
for( int i = 0; i < graph->total; i++ )
{
for( int j = 0; j < graph->total; j++ )
{
connected[i][j] = 0|reverse;
}
//memset( connected[i], 0, sizeof(int)*graph->total );
CvGraphVtx* ver = cvGetGraphVtx( graph, i );
if( ver )
{
connected[i][i] = 1;
for( CvGraphEdge* e = ver->first; e ; e = CV_NEXT_GRAPH_EDGE( e, ver ) )
{
CvGraphVtx* v = CV_GET_ADJ_VTX( ver, e );
connected[i][NUMBER(v)] = 1^reverse;
}
}
}
}
void cvStartFindCliques( CvGraph* graph, CvCliqueFinder* finder, int reverse, int weighted, int weighted_edges )
{
int i;
if (weighted)
{
finder->weighted = 1;
finder->best_weight = 0;
finder->vertex_weights = (float*)malloc( sizeof(float)*(graph->total+1));
finder->cur_weight = (float*)malloc( sizeof(float)*(graph->total+1));
finder->cand_weight = (float*)malloc( sizeof(float)*(graph->total+1));
finder->cur_weight[0] = 0;
finder->cand_weight[0] = 0;
for( i = 0 ; i < graph->total; i++ )
{
CvGraphWeightedVtx* ver = (CvGraphWeightedVtx*)cvGetGraphVtx( graph, i );
assert(ver);
assert(ver->weight>=0);
finder->vertex_weights[i] = ver->weight;
finder->cand_weight[0] += ver->weight;
}
}
else finder->weighted = 0;
if (weighted_edges)
{
finder->weighted_edges = 1;
//finder->best_weight = 0;
finder->edge_weights = (float*)malloc( sizeof(float)*(graph->total)*(graph->total));
//finder->cur_weight = (float*)malloc( sizeof(float)*(graph->total+1));
//finder->cand_weight = (float*)malloc( sizeof(float)*(graph->total+1));
//finder->cur_weight[0] = 0;
//finder->cand_weight[0] = 0;
memset( finder->edge_weights, 0, sizeof(float)*(graph->total)*(graph->total) );
for( i = 0 ; i < graph->total; i++ )
{
CvGraphVtx* ver1 = cvGetGraphVtx( graph, i );
if(!ver1) continue;
for( int j = i ; j < graph->total; j++ )
{
CvGraphVtx* ver2 = cvGetGraphVtx( graph, j );
if(!ver2) continue;
CvGraphEdge* edge = cvFindGraphEdgeByPtr( graph, ver1, ver2 );
if( edge )
{
assert( ((CvGraphWeightedEdge*)edge)->weight >= 0 );
finder->edge_weights[ i * graph->total + j ] =
finder->edge_weights[ j * graph->total + i ] = ((CvGraphWeightedEdge*)edge)->weight;
}
}
}
}
else finder->weighted_edges = 0;
//int* Compsub; //current component (vertex stack)
finder->k = 0; //counter of steps
int N = finder->N = graph->total;
finder->current_comp = new int[N];
finder->All = new int*[N];
for( i = 0 ; i < finder->N; i++ )
{
finder->All[i] = new int[N];
}
finder->ne = new int[N+1];
finder->ce = new int[N+1];
finder->fixp = new int[N+1]; //node with minimal disconnections
finder->nod = new int[N+1];
finder->s = new int[N+1]; //for selected candidate
//form adj matrix
finder->adj_matr = new int*[N]; //assume filled with 0
for( i = 0 ; i < N; i++ )
{
finder->adj_matr[i] = new int[N];
}
//set number to vertices
_MarkNodes( graph );
_FillAdjMatrix( graph, finder->adj_matr, reverse );
//init all arrays
int k = finder->k = 0; //stack size
memset( finder->All[k], 0, sizeof(int) * N );
for( i = 0; i < N; i++ ) finder->All[k][i] = i;
finder->ne[0] = 0;
finder->ce[0] = N;
finder->status = GO;
finder->best_score = 0;
}
void cvEndFindCliques( CvCliqueFinder* finder )
{
int i;
//int* Compsub; //current component (vertex stack)
delete finder->current_comp;
for( i = 0 ; i < finder->N; i++ )
{
delete finder->All[i];
}
delete finder->All;
delete finder->ne;
delete finder->ce;
delete finder->fixp; //node with minimal disconnections
delete finder->nod;
delete finder->s; //for selected candidate
//delete adj matrix
for( i = 0 ; i < finder->N; i++ )
{
delete finder->adj_matr[i];
}
delete finder->adj_matr;
if(finder->weighted)
{
free(finder->vertex_weights);
free(finder->cur_weight);
free(finder->cand_weight);
}
if(finder->weighted_edges)
{
free(finder->edge_weights);
}
}
int cvFindNextMaximalClique( CvCliqueFinder* finder )
{
int** connected = finder->adj_matr;
// int N = finder->N; //graph size
// stacks, counters etc/
int k = finder->k; //stack size
int* Compsub = finder->current_comp;
int** All = finder->All;
int* ne = finder->ne;
int* ce = finder->ce;
int* fixp = finder->fixp; //node with minimal disconnections
int* nod = finder->nod;
int* s = finder->s; //for selected candidate
//START
while( k >= 0)
{
int* old = All[k];
switch(finder->status)
{
case GO://Forward step
/* we have all sets and will choose fixed point */
{
//check potential size of clique
if( (!finder->weighted) && (k + ce[k] - ne[k] < finder->best_score) )
{
finder->status = BACK;
break;
}
//check potential weight
if( finder->weighted && !finder->weighted_edges &&
finder->cur_weight[k] + finder->cand_weight[k] < finder->best_weight )
{
finder->status = BACK;
break;
}
int minnod = ce[k];
nod[k] = 0;
//for every vertex of All determine counter value and choose minimum
for( int i = 0; i < ce[k] && minnod != 0; i++)
{
int p = old[i]; //current point
int count = 0; //counter
int pos = 0;
/* Count disconnections with candidates */
for (int j = ne[k]; j < ce[k] && (count < minnod); j++)
{
if ( !connected[p][old[j]] )
{
count++;
/* Save position of potential candidate */
pos = j;
}
}
/* Test new minimum */
if (count < minnod)
{
fixp[k] = p; //set current point as fixed
minnod = count; //new value for minnod
if (i < ne[k]) //if current fixed point belongs to 'not'
{
s[k] = pos; //s - selected candidate
}
else
{
s[k] = i; //selected candidate is fixed point itself
/* preincr */
nod[k] = 1; //nod is aux variable, 1 means fixp == s
}
}
}//for
nod[k] = minnod + nod[k];
finder->status = NEXT;//go to backtrackcycle
}
break;
case NEXT:
//here we will look for candidate to translate into not
//s[k] now contains index of choosen candidate
{
int* new_ = All[k+1];
if( nod[k] != 0 )
{
//swap selected and first candidate
int i, p = old[s[k]];
old[s[k]] = old[ne[k]];
int sel = old[ne[k]] = p;
int newne = 0;
//fill new set 'not'
for ( i = 0; i < ne[k]; i++)
{
if (connected[sel][old[i]])
{
new_[newne] = old[i];
newne++;
}
}
//fill new set 'candidate'
int newce = newne;
i++;//skip selected candidate
float candweight = 0;
for (; i < ce[k]; i++)
{
if (connected[sel][old[i]])
{
new_[newce] = old[i];
if( finder->weighted )
candweight += finder->vertex_weights[old[i]];
newce++;
}
}
nod[k]--;
//add selected to stack
Compsub[k] = sel;
k++;
assert( k <= finder->N );
if( finder->weighted )
{
//update weights of current clique and candidates
finder->cur_weight[k] = finder->cur_weight[k-1] + finder->vertex_weights[sel];
finder->cand_weight[k] = candweight;
}
if( finder->weighted_edges )
{
//update total weight by edge weights
float added = 0;
for( int ind = 0; ind < k-1; ind++ )
{
added += finder->edge_weights[ Compsub[ind] * finder->N + sel ];
}
finder->cur_weight[k] += added;
}
//check if 'not' and 'cand' are both empty
if( newce == 0 )
{
finder->best_score = MAX(finder->best_score, k );
if( finder->weighted )
finder->best_weight = MAX( finder->best_weight, finder->cur_weight[k] );
/*FILE* file = fopen("cliques.txt", "a" );
for (int t=0; t<k; t++)
{
fprintf(file, "%d ", Compsub[t]);
}
fprintf(file, "\n");
fclose(file);
*/
//output new clique//************************
finder->status = BACK;
finder->k = k;
return CLIQUE_FOUND;
}
else //check nonempty set of candidates
if( newne < newce )
{
//go further
ne[k] = newne;
ce[k] = newce;
finder->status = GO;
break;
}
}
else
finder->status = BACK;
}
break;
case BACK:
{
//decrease stack
k--;
old = All[k];
if( k < 0 ) break;
//add to not
ne[k]++;
if( nod[k] > 0 )
{
//select next candidate
for( s[k] = ne[k]; s[k] < ce[k]; s[k]++ )
{
if( !connected[fixp[k]][old[s[k]]])
break;
}
assert( s[k] < ce[k] );
finder->status = NEXT;
}
else
finder->status = BACK;
}
break;
case END: assert(0);
}
}//end while
finder->status = END;
return CLIQUE_END;
}
void cvBronKerbosch( CvGraph* graph )
{
int* Compsub; //current component (vertex stack)
int k = 0; //counter of steps
int N = graph->total;
int i;
Compsub = new int[N];
int** All = new int*[N];
for( i = 0 ; i < N; i++ )
{
All[i] = new int[N];
}
int* ne = new int[N];
int* ce = new int[N];
int* fixp = new int[N]; //node with minimal disconnections
int* nod = new int[N];
int* s = new int[N]; //for selected candidate
//form adj matrix
int** connected = new int*[N]; //assume filled with 0
for( i = 0 ; i < N; i++ )
{
connected[i] = new int[N];
}
//set number to vertices
_MarkNodes( graph );
_FillAdjMatrix( graph, connected, 0 );
//init all arrays
k = 0; //stack size
memset( All[k], 0, sizeof(int) * N );
for( i = 0; i < N; i++ ) All[k][i] = i;
ne[0] = 0;
ce[0] = N;
int status = GO;
int best_score = 0;
//START
while( k >= 0)
{
int* old = All[k];
switch(status)
{
case GO://Forward step
/* we have all sets and will choose fixed point */
{
if( k + ce[k] - ne[k] < best_score )
{
status = BACK;
break;
}
int minnod = ce[k];
nod[k] = 0;
//for every vertex of All determine counter value and choose minimum
for( int i = 0; i < ce[k] && minnod != 0; i++)
{
int p = old[i]; //current point
int count = 0; //counter
int pos = 0;
/* Count disconnections with candidates */
for (int j = ne[k]; j < ce[k] && (count < minnod); j++)
{
if ( !connected[p][old[j]] )
{
count++;
/* Save position of potential candidate */
pos = j;
}
}
/* Test new minimum */
if (count < minnod)
{
fixp[k] = p; //set current point as fixed
minnod = count; //new value for minnod
if (i < ne[k]) //if current fixed point belongs to 'not'
{
s[k] = pos; //s - selected candidate
}
else
{
s[k] = i; //selected candidate is fixed point itself
/* preincr */
nod[k] = 1; //nod is aux variable, 1 means fixp == s
}
}
}//for
nod[k] = minnod + nod[k];
status = NEXT;//go to backtrackcycle
}
break;
case NEXT:
//here we will look for candidate to translate into not
//s[k] now contains index of choosen candidate
{
int* new_ = All[k+1];
if( nod[k] != 0 )
{
//swap selected and first candidate
int p = old[s[k]];
old[s[k]] = old[ne[k]];
int sel = old[ne[k]] = p;
int newne = 0;
//fill new set 'not'
for ( i = 0; i < ne[k]; i++)
{
if (connected[sel][old[i]])
{
new_[newne] = old[i];
newne++;
}
}
//fill new set 'candidate'
int newce = newne;
i++;//skip selected candidate
for (; i < ce[k]; i++)
{
if (connected[sel][old[i]])
{
new_[newce] = old[i];
newce++;
}
}
nod[k]--;
//add selected to stack
Compsub[k] = sel;
k++;
//check if 'not' and 'cand' are both empty
if( newce == 0 )
{
best_score = MAX(best_score, k );
FILE* file = fopen("cliques.txt", "a" );
for (int t=0; t<k; t++)
{
fprintf(file, "%d ", Compsub[t]);
}
fprintf(file, "\n");
fclose(file);
/*for( int t = 0; t < k; t++ )
{
printf("%d ", Compsub[t] );
}
printf("\n"); */
//printf("found %d\n", k);
//output new clique//************************
status = BACK;
}
else //check nonempty set of candidates
if( newne < newce )
{
//go further
ne[k] = newne;
ce[k] = newce;
status = GO;
break;
}
}
else
status = BACK;
}
break;
case BACK:
{
//decrease stack
k--;
old = All[k];
if( k < 0 ) break;
//add to not
ne[k]++;
if( nod[k] > 0 )
{
//select next candidate
for( s[k] = ne[k]; s[k] < ce[k]; s[k]++ )
{
if( !connected[fixp[k]][old[s[k]]])
break;
}
assert( s[k] < ce[k] );
status = NEXT;
}
else
status = BACK;
}
break;
}
}//end while
}//end cvBronKerbosch
#endif

View File

@@ -0,0 +1,403 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#include "_cvvm.h"
#include <stdlib.h>
#include <assert.h>
/*======================================================================================*/
CvStatus
icvDynamicCorrespond( int *first, /* first sequence of runs */
/* s0|w0|s1|w1|...|s(n-1)|w(n-1)|sn */
int first_runs, /* number of runs */
int *second, /* second sequence of runs */
int second_runs, int *first_corr, /* s0'|e0'|s1'|e1'|... */
int *second_corr )
{
float Pd, Fi, S;
float Occlusion;
float *costTable;
uchar *matchEdges;
int prev;
int curr;
int baseIndex;
int i, j;
int i_1, j_1;
int n;
int l_beg, r_beg, l_end, r_end, l_len, r_len;
int first_curr;
int second_curr;
int l_color, r_color;
int len_color;
float cost, cost1;
float min1, min2, min3;
float cmin;
uchar cpath;
int row_size;
/* Test arguments for errors */
if( (first == 0) ||
(first_runs < 1) ||
(second == 0) || (second_runs < 1) || (first_corr == 0) || (second_corr == 0) )
return CV_BADFACTOR_ERR;
Pd = 0.95f;
Fi = (float) CV_PI;
S = 1;
Occlusion = (float) log( Pd * Fi / ((1 - Pd) * sqrt( fabs( (CV_PI * 2) * (1. / S) ))));
costTable = (float *)cvAlloc( (first_runs + 1) * (second_runs + 1) * sizeof( float ));
if( costTable == 0 )
return CV_OUTOFMEM_ERR;
matchEdges = (uchar *)cvAlloc( (first_runs + 1) * (second_runs + 1) * sizeof( uchar ));
if( matchEdges == 0 )
{
cvFree( &costTable );
return CV_OUTOFMEM_ERR;
}
row_size = first_runs + 1;
/* ============= Fill costTable ============= */
costTable[0] = 0.0f;
/* Fill upper line in the cost Table */
prev = first[0];
curr = 2;
for( n = 0; n < first_runs; n++ )
{
l_end = first[curr];
curr += 2;
costTable[n + 1] = costTable[n] + Occlusion * (l_end - prev);
prev = l_end;
} /* for */
/* Fill lefter line in the cost Table */
prev = second[0];
curr = 2;
baseIndex = 0;
for( n = 0; n < second_runs; n++ )
{
l_end = second[curr];
curr += 2;
costTable[baseIndex + row_size] = costTable[baseIndex] + Occlusion * (l_end - prev);
baseIndex += row_size;
prev = l_end;
} /* for */
/* Count costs in the all rest cells */
first_curr = 0;
second_curr = 0;
for( i = 1; i <= first_runs; i++ )
{
for( j = 1; j <= second_runs; j++ )
{
first_curr = (i - 1) * 2;
second_curr = (j - 1) * 2;
l_beg = first[first_curr];
first_curr++;
l_color = first[first_curr];
first_curr++;
l_end = first[first_curr];
l_len = l_end - l_beg + 1;
r_beg = second[second_curr];
second_curr++;
r_color = second[second_curr];
second_curr++;
r_end = second[second_curr];
r_len = r_end - r_beg + 1;
i_1 = i - 1;
j_1 = j - 1;
if( r_len == l_len )
{
cost = 0;
}
else
{
if( r_len > l_len )
{
cost = (float) (r_len * r_len - l_len * l_len) * (1 / (r_len * l_len));
}
else
{
cost = (float) (l_len * l_len - r_len * r_len) * (1 / (r_len * l_len));
}
} /* if */
len_color = r_color - l_color;
cost1 = (float) ((len_color * len_color) >> 2);
min2 = costTable[i_1 + j * row_size] + Occlusion * l_len;
min3 = costTable[i + j_1 * row_size] + Occlusion * r_len;
min1 = costTable[i_1 + j_1 * row_size] + cost + (float) cost1;
if( min1 < min2 )
{
if( min1 < min3 )
{
cmin = min1;
cpath = 1;
}
else
{
cmin = min3;
cpath = 3;
} /* if */
}
else
{
if( min2 < min3 )
{
cmin = min2;
cpath = 2;
}
else
{
cmin = min3;
cpath = 3;
} /* if */
} /* if */
costTable[i + j * row_size] = cmin;
matchEdges[i + j * row_size] = cpath;
} /* for */
} /* for */
/* =========== Reconstruct the Path =========== */
i = first_runs;
j = second_runs;
first_curr = i * 2 - 2;
second_curr = j * 2 - 2;
while( i > 0 && j > 0 )
{
/* Connect begins */
switch (matchEdges[i + j * row_size])
{
case 1: /* to diagonal */
first_corr[first_curr] = second[second_curr];
first_corr[first_curr + 1] = second[second_curr + 2];
second_corr[second_curr] = first[first_curr];
second_corr[second_curr + 1] = first[first_curr + 2];
first_curr -= 2;
second_curr -= 2;
i--;
j--;
break;
case 2: /* to left */
first_corr[first_curr] = second[second_curr + 2];
first_corr[first_curr + 1] = second[second_curr + 2];
first_curr -= 2;
i--;
break;
case 3: /* to up */
second_corr[second_curr] = first[first_curr + 2];
second_corr[second_curr + 1] = first[first_curr + 2];
second_curr -= 2;
j--;
break;
} /* switch */
} /* while */
/* construct rest of horisontal path if its need */
while( i > 0 )
{
first_corr[first_curr] = second[second_curr + 2]; /* connect to begin */
first_corr[first_curr + 1] = second[second_curr + 2]; /* connect to begin */
first_curr -= 2;
i--;
} /* while */
/* construct rest of vertical path if its need */
while( j > 0 )
{
second_corr[second_curr] = first[first_curr + 2];
second_corr[second_curr + 1] = first[first_curr + 2];
second_curr -= 2;
j--;
} /* while */
cvFree( &costTable );
cvFree( &matchEdges );
return CV_NO_ERR;
} /* icvDynamicCorrespond */
/*======================================================================================*/
static CvStatus
icvDynamicCorrespondMulti( int lines, /* number of scanlines */
int *first, /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
int *first_runs, /* numbers of runs */
int *second, int *second_runs, int *first_corr, /* s0'|e0'|s1'|e1'|... */
int *second_corr )
{
CvStatus error;
int currFirst;
int currSecond;
int currFirstCorr;
int currSecondCorr;
int n;
/* Test errors */
if( (lines < 1) ||
(first == 0) ||
(first_runs == 0) ||
(second == 0) || (second_runs == 0) || (first_corr == 0) || (second_corr == 0) )
return CV_BADFACTOR_ERR;
currFirst = 0;
currSecond = 0;
currFirstCorr = 0;
currSecondCorr = 0;
for( n = 0; n < lines; n++ )
{
error = icvDynamicCorrespond( &(first[currFirst]),
first_runs[n],
&(second[currSecond]),
second_runs[n],
&(first_corr[currFirstCorr]),
&(second_corr[currSecondCorr]) );
if( error != CV_NO_ERR )
return error;
currFirst += first_runs[n] * 2 + 1;
currSecond += second_runs[n] * 2 + 1;
currFirstCorr += first_runs[n] * 2;
currSecondCorr += second_runs[n] * 2;
}
return CV_NO_ERR;
} /* icvDynamicCorrespondMulti */
/*======================================================================================*/
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvDynamicCorrespondMulti
// Purpose: The functions
// Context:
// Parameters:
//
// Notes:
//F*/
CV_IMPL void
cvDynamicCorrespondMulti( int lines, /* number of scanlines */
int *first, /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
int *first_runs, /* numbers of runs */
int *second, int *second_runs, int *first_corr, /* s0'|e0'|s1'|e1'|... */
int *second_corr )
{
CV_FUNCNAME( "cvDynamicCorrespondMulti" );
__BEGIN__;
IPPI_CALL( icvDynamicCorrespondMulti( lines, /* number of scanlines */
first, /* s0|w0|s1|w1|...s(n-1)|w(n-1)|sn */
first_runs, /* numbers of runs */
second, second_runs, first_corr, /* s0'|e0'|s1'|e1'|... */
second_corr ));
__CLEANUP__;
__END__;
}

View File

@@ -0,0 +1,138 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#define CV_MAX2( a, b ) ((a)>(b) ? (a) : (b))
#define CV_MIN2( a, b ) ((a)<(b) ? (a) : (b))
/****************************************************************************************\
create hand mask
\****************************************************************************************/
static CvStatus icvCreateHandMask8uC1R(CvSeq * numbers,
uchar * image_mask, int step,
CvSize size, CvRect * roi )
{
CvSeqReader reader;
CvPoint pt;
int k_point;
int i_min, i_max, j_min, j_max;
if( numbers == NULL )
return CV_NULLPTR_ERR;
if( !CV_IS_SEQ_POINT_SET( numbers ))
return CV_BADFLAG_ERR;
i_max = j_max = 0;
i_min = size.height;
j_min = size.width;
cvStartReadSeq( numbers, &reader, 0 );
k_point = numbers->total;
assert( k_point > 0 );
if( k_point <= 0 )
return CV_BADSIZE_ERR;
memset( image_mask, 0, step * size.height );
while( k_point-- > 0 )
{
CV_READ_SEQ_ELEM( pt, reader );
i_min = CV_MIN2( i_min, pt.y );
i_max = CV_MAX2( i_max, pt.y );
j_min = CV_MIN2( j_min, pt.x );
j_max = CV_MAX2( j_max, pt.x );
*(image_mask + pt.y * step + pt.x) = 255;
}
roi->x = j_min;
roi->y = i_min;
roi->width = j_max - j_min + 1;
roi->height = i_max - i_min + 1;
return CV_OK;
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvCreateHandMask
// Purpose: creates hand mask image
// Context:
// Parameters:
// numbers - pointer to the input sequence of the point's indexes inside
// hand region
// img_mask - pointer to the result mask image
// roi - result hand mask ROI
//
// Notes:
//F*/
CV_IMPL void
cvCreateHandMask( CvSeq * numbers, IplImage * img_mask, CvRect * roi )
{
uchar *img_mask_data = 0;
int img_mask_step = 0;
CvSize img_mask_size;
CV_FUNCNAME( "cvCreateHandMask" );
__BEGIN__;
if( img_mask->depth != IPL_DEPTH_8U )
CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
if( img_mask->nChannels != 1 )
CV_ERROR( CV_BadNumChannels, "output image have wrong number of channels" );
cvGetImageRawData( img_mask, &img_mask_data, &img_mask_step, &img_mask_size );
IPPI_CALL( icvCreateHandMask8uC1R( numbers, img_mask_data,
img_mask_step, img_mask_size, roi ));
__END__;
}

View File

@@ -0,0 +1,554 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/****************************************************************************************\
The code below is some modification of Stan Birchfield's algorithm described in:
Depth Discontinuities by Pixel-to-Pixel Stereo
Stan Birchfield and Carlo Tomasi
International Journal of Computer Vision,
35(3): 269-293, December 1999.
This implementation uses different cost function that results in
O(pixPerRow*maxDisparity) complexity of dynamic programming stage versus
O(pixPerRow*log(pixPerRow)*maxDisparity) in the above paper.
\****************************************************************************************/
/****************************************************************************************\
* Find stereo correspondence by dynamic programming algorithm *
\****************************************************************************************/
#define ICV_DP_STEP_LEFT 0
#define ICV_DP_STEP_UP 1
#define ICV_DP_STEP_DIAG 2
#define ICV_BIRCH_DIFF_LUM 5
#define ICV_MAX_DP_SUM_VAL (INT_MAX/4)
typedef struct _CvDPCell
{
uchar step; //local-optimal step
int sum; //current sum
}_CvDPCell;
typedef struct _CvRightImData
{
uchar min_val, max_val;
} _CvRightImData;
#define CV_IMAX3(a,b,c) ((temp3 = (a) >= (b) ? (a) : (b)),(temp3 >= (c) ? temp3 : (c)))
#define CV_IMIN3(a,b,c) ((temp3 = (a) <= (b) ? (a) : (b)),(temp3 <= (c) ? temp3 : (c)))
void icvFindStereoCorrespondenceByBirchfieldDP( uchar* src1, uchar* src2,
uchar* disparities,
CvSize size, int widthStep,
int maxDisparity,
float _param1, float _param2,
float _param3, float _param4,
float _param5 )
{
int x, y, i, j, temp3;
int d, s;
int dispH = maxDisparity + 3;
uchar *dispdata;
int imgW = size.width;
int imgH = size.height;
uchar val, prevval, prev, curr;
int min_val;
uchar* dest = disparities;
int param1 = cvRound(_param1);
int param2 = cvRound(_param2);
int param3 = cvRound(_param3);
int param4 = cvRound(_param4);
int param5 = cvRound(_param5);
#define CELL(d,x) cells[(d)+(x)*dispH]
uchar* dsi = (uchar*)cvAlloc(sizeof(uchar)*imgW*dispH);
uchar* edges = (uchar*)cvAlloc(sizeof(uchar)*imgW*imgH);
_CvDPCell* cells = (_CvDPCell*)cvAlloc(sizeof(_CvDPCell)*imgW*MAX(dispH,(imgH+1)/2));
_CvRightImData* rData = (_CvRightImData*)cvAlloc(sizeof(_CvRightImData)*imgW);
int* reliabilities = (int*)cells;
for( y = 0; y < imgH; y++ )
{
uchar* srcdata1 = src1 + widthStep * y;
uchar* srcdata2 = src2 + widthStep * y;
//init rData
prevval = prev = srcdata2[0];
for( j = 1; j < imgW; j++ )
{
curr = srcdata2[j];
val = (uchar)((curr + prev)>>1);
rData[j-1].max_val = (uchar)CV_IMAX3( val, prevval, prev );
rData[j-1].min_val = (uchar)CV_IMIN3( val, prevval, prev );
prevval = val;
prev = curr;
}
rData[j-1] = rData[j-2];//last elem
// fill dissimularity space image
for( i = 1; i <= maxDisparity + 1; i++ )
{
dsi += imgW;
rData--;
for( j = i - 1; j < imgW - 1; j++ )
{
int t;
if( (t = srcdata1[j] - rData[j+1].max_val) >= 0 )
{
dsi[j] = (uchar)t;
}
else if( (t = rData[j+1].min_val - srcdata1[j]) >= 0 )
{
dsi[j] = (uchar)t;
}
else
{
dsi[j] = 0;
}
}
}
dsi -= (maxDisparity+1)*imgW;
rData += maxDisparity+1;
//intensity gradients image construction
//left row
edges[y*imgW] = edges[y*imgW+1] = edges[y*imgW+2] = 2;
edges[y*imgW+imgW-1] = edges[y*imgW+imgW-2] = edges[y*imgW+imgW-3] = 1;
for( j = 3; j < imgW-4; j++ )
{
edges[y*imgW+j] = 0;
if( ( CV_IMAX3( srcdata1[j-3], srcdata1[j-2], srcdata1[j-1] ) -
CV_IMIN3( srcdata1[j-3], srcdata1[j-2], srcdata1[j-1] ) ) >= ICV_BIRCH_DIFF_LUM )
{
edges[y*imgW+j] |= 1;
}
if( ( CV_IMAX3( srcdata2[j+3], srcdata2[j+2], srcdata2[j+1] ) -
CV_IMIN3( srcdata2[j+3], srcdata2[j+2], srcdata2[j+1] ) ) >= ICV_BIRCH_DIFF_LUM )
{
edges[y*imgW+j] |= 2;
}
}
//find correspondence using dynamical programming
//init DP table
for( x = 0; x < imgW; x++ )
{
CELL(0,x).sum = CELL(dispH-1,x).sum = ICV_MAX_DP_SUM_VAL;
CELL(0,x).step = CELL(dispH-1,x).step = ICV_DP_STEP_LEFT;
}
for( d = 2; d < dispH; d++ )
{
CELL(d,d-2).sum = ICV_MAX_DP_SUM_VAL;
CELL(d,d-2).step = ICV_DP_STEP_UP;
}
CELL(1,0).sum = 0;
CELL(1,0).step = ICV_DP_STEP_LEFT;
for( x = 1; x < imgW; x++ )
{
int d = MIN( x + 1, maxDisparity + 1);
uchar* _edges = edges + y*imgW + x;
int e0 = _edges[0] & 1;
_CvDPCell* _cell = cells + x*dispH;
do
{
int s = dsi[d*imgW+x];
int sum[3];
//check left step
sum[0] = _cell[d-dispH].sum - param2;
//check up step
if( _cell[d+1].step != ICV_DP_STEP_DIAG && e0 )
{
sum[1] = _cell[d+1].sum + param1;
if( _cell[d-1-dispH].step != ICV_DP_STEP_UP && (_edges[1-d] & 2) )
{
int t;
sum[2] = _cell[d-1-dispH].sum + param1;
t = sum[1] < sum[0];
//choose local-optimal pass
if( sum[t] <= sum[2] )
{
_cell[d].step = (uchar)t;
_cell[d].sum = sum[t] + s;
}
else
{
_cell[d].step = ICV_DP_STEP_DIAG;
_cell[d].sum = sum[2] + s;
}
}
else
{
if( sum[0] <= sum[1] )
{
_cell[d].step = ICV_DP_STEP_LEFT;
_cell[d].sum = sum[0] + s;
}
else
{
_cell[d].step = ICV_DP_STEP_UP;
_cell[d].sum = sum[1] + s;
}
}
}
else if( _cell[d-1-dispH].step != ICV_DP_STEP_UP && (_edges[1-d] & 2) )
{
sum[2] = _cell[d-1-dispH].sum + param1;
if( sum[0] <= sum[2] )
{
_cell[d].step = ICV_DP_STEP_LEFT;
_cell[d].sum = sum[0] + s;
}
else
{
_cell[d].step = ICV_DP_STEP_DIAG;
_cell[d].sum = sum[2] + s;
}
}
else
{
_cell[d].step = ICV_DP_STEP_LEFT;
_cell[d].sum = sum[0] + s;
}
}
while( --d );
}// for x
//extract optimal way and fill disparity image
dispdata = dest + widthStep * y;
//find min_val
min_val = ICV_MAX_DP_SUM_VAL;
for( i = 1; i <= maxDisparity + 1; i++ )
{
if( min_val > CELL(i,imgW-1).sum )
{
d = i;
min_val = CELL(i,imgW-1).sum;
}
}
//track optimal pass
for( x = imgW - 1; x > 0; x-- )
{
dispdata[x] = (uchar)(d - 1);
while( CELL(d,x).step == ICV_DP_STEP_UP ) d++;
if ( CELL(d,x).step == ICV_DP_STEP_DIAG )
{
s = x;
while( CELL(d,x).step == ICV_DP_STEP_DIAG )
{
d--;
x--;
}
for( i = x; i < s; i++ )
{
dispdata[i] = (uchar)(d-1);
}
}
}//for x
}// for y
//Postprocessing the Disparity Map
//remove obvious errors in the disparity map
for( x = 0; x < imgW; x++ )
{
for( y = 1; y < imgH - 1; y++ )
{
if( dest[(y-1)*widthStep+x] == dest[(y+1)*widthStep+x] )
{
dest[y*widthStep+x] = dest[(y-1)*widthStep+x];
}
}
}
//compute intensity Y-gradients
for( x = 0; x < imgW; x++ )
{
for( y = 1; y < imgH - 1; y++ )
{
if( ( CV_IMAX3( src1[(y-1)*widthStep+x], src1[y*widthStep+x],
src1[(y+1)*widthStep+x] ) -
CV_IMIN3( src1[(y-1)*widthStep+x], src1[y*widthStep+x],
src1[(y+1)*widthStep+x] ) ) >= ICV_BIRCH_DIFF_LUM )
{
edges[y*imgW+x] |= 4;
edges[(y+1)*imgW+x] |= 4;
edges[(y-1)*imgW+x] |= 4;
y++;
}
}
}
//remove along any particular row, every gradient
//for which two adjacent columns do not agree.
for( y = 0; y < imgH; y++ )
{
prev = edges[y*imgW];
for( x = 1; x < imgW - 1; x++ )
{
curr = edges[y*imgW+x];
if( (curr & 4) &&
( !( prev & 4 ) ||
!( edges[y*imgW+x+1] & 4 ) ) )
{
edges[y*imgW+x] -= 4;
}
prev = curr;
}
}
// define reliability
for( x = 0; x < imgW; x++ )
{
for( y = 1; y < imgH; y++ )
{
i = y - 1;
for( ; y < imgH && dest[y*widthStep+x] == dest[(y-1)*widthStep+x]; y++ )
;
s = y - i;
for( ; i < y; i++ )
{
reliabilities[i*imgW+x] = s;
}
}
}
//Y - propagate reliable regions
for( x = 0; x < imgW; x++ )
{
for( y = 0; y < imgH; y++ )
{
d = dest[y*widthStep+x];
if( reliabilities[y*imgW+x] >= param4 && !(edges[y*imgW+x] & 4) &&
d > 0 )//highly || moderately
{
disparities[y*widthStep+x] = (uchar)d;
//up propagation
for( i = y - 1; i >= 0; i-- )
{
if( ( edges[i*imgW+x] & 4 ) ||
( dest[i*widthStep+x] < d &&
reliabilities[i*imgW+x] >= param3 ) ||
( reliabilities[y*imgW+x] < param5 &&
dest[i*widthStep+x] - 1 == d ) ) break;
disparities[i*widthStep+x] = (uchar)d;
}
//down propagation
for( i = y + 1; i < imgH; i++ )
{
if( ( edges[i*imgW+x] & 4 ) ||
( dest[i*widthStep+x] < d &&
reliabilities[i*imgW+x] >= param3 ) ||
( reliabilities[y*imgW+x] < param5 &&
dest[i*widthStep+x] - 1 == d ) ) break;
disparities[i*widthStep+x] = (uchar)d;
}
y = i - 1;
}
else
{
disparities[y*widthStep+x] = (uchar)d;
}
}
}
// define reliability along X
for( y = 0; y < imgH; y++ )
{
for( x = 1; x < imgW; x++ )
{
i = x - 1;
for( ; x < imgW && dest[y*widthStep+x] == dest[y*widthStep+x-1]; x++ );
s = x - i;
for( ; i < x; i++ )
{
reliabilities[y*imgW+i] = s;
}
}
}
//X - propagate reliable regions
for( y = 0; y < imgH; y++ )
{
for( x = 0; x < imgW; x++ )
{
d = dest[y*widthStep+x];
if( reliabilities[y*imgW+x] >= param4 && !(edges[y*imgW+x] & 1) &&
d > 0 )//highly || moderately
{
disparities[y*widthStep+x] = (uchar)d;
//up propagation
for( i = x - 1; i >= 0; i-- )
{
if( (edges[y*imgW+i] & 1) ||
( dest[y*widthStep+i] < d &&
reliabilities[y*imgW+i] >= param3 ) ||
( reliabilities[y*imgW+x] < param5 &&
dest[y*widthStep+i] - 1 == d ) ) break;
disparities[y*widthStep+i] = (uchar)d;
}
//down propagation
for( i = x + 1; i < imgW; i++ )
{
if( (edges[y*imgW+i] & 1) ||
( dest[y*widthStep+i] < d &&
reliabilities[y*imgW+i] >= param3 ) ||
( reliabilities[y*imgW+x] < param5 &&
dest[y*widthStep+i] - 1 == d ) ) break;
disparities[y*widthStep+i] = (uchar)d;
}
x = i - 1;
}
else
{
disparities[y*widthStep+x] = (uchar)d;
}
}
}
//release resources
cvFree( &dsi );
cvFree( &edges );
cvFree( &cells );
cvFree( &rData );
}
/*F///////////////////////////////////////////////////////////////////////////
//
// Name: cvFindStereoCorrespondence
// Purpose: find stereo correspondence on stereo-pair
// Context:
// Parameters:
// leftImage - left image of stereo-pair (format 8uC1).
// rightImage - right image of stereo-pair (format 8uC1).
// mode -mode of correspondance retrieval (now CV_RETR_DP_BIRCHFIELD only)
// dispImage - destination disparity image
// maxDisparity - maximal disparity
// param1, param2, param3, param4, param5 - parameters of algorithm
// Returns:
// Notes:
// Images must be rectified.
// All images must have format 8uC1.
//F*/
CV_IMPL void
cvFindStereoCorrespondence(
const CvArr* leftImage, const CvArr* rightImage,
int mode,
CvArr* depthImage,
int maxDisparity,
double param1, double param2, double param3,
double param4, double param5 )
{
CV_FUNCNAME( "cvFindStereoCorrespondence" );
__BEGIN__;
CvMat *src1, *src2;
CvMat *dst;
CvMat src1_stub, src2_stub, dst_stub;
int coi;
CV_CALL( src1 = cvGetMat( leftImage, &src1_stub, &coi ));
if( coi ) CV_ERROR( CV_BadCOI, "COI is not supported by the function" );
CV_CALL( src2 = cvGetMat( rightImage, &src2_stub, &coi ));
if( coi ) CV_ERROR( CV_BadCOI, "COI is not supported by the function" );
CV_CALL( dst = cvGetMat( depthImage, &dst_stub, &coi ));
if( coi ) CV_ERROR( CV_BadCOI, "COI is not supported by the function" );
// check args
if( CV_MAT_TYPE( src1->type ) != CV_8UC1 ||
CV_MAT_TYPE( src2->type ) != CV_8UC1 ||
CV_MAT_TYPE( dst->type ) != CV_8UC1) CV_ERROR(CV_StsUnsupportedFormat,
"All images must be single-channel and have 8u" );
if( !CV_ARE_SIZES_EQ( src1, src2 ) || !CV_ARE_SIZES_EQ( src1, dst ) )
CV_ERROR( CV_StsUnmatchedSizes, "" );
if( maxDisparity <= 0 || maxDisparity >= src1->width || maxDisparity > 255 )
CV_ERROR(CV_StsOutOfRange,
"parameter /maxDisparity/ is out of range");
if( mode == CV_DISPARITY_BIRCHFIELD )
{
if( param1 == CV_UNDEF_SC_PARAM ) param1 = CV_IDP_BIRCHFIELD_PARAM1;
if( param2 == CV_UNDEF_SC_PARAM ) param2 = CV_IDP_BIRCHFIELD_PARAM2;
if( param3 == CV_UNDEF_SC_PARAM ) param3 = CV_IDP_BIRCHFIELD_PARAM3;
if( param4 == CV_UNDEF_SC_PARAM ) param4 = CV_IDP_BIRCHFIELD_PARAM4;
if( param5 == CV_UNDEF_SC_PARAM ) param5 = CV_IDP_BIRCHFIELD_PARAM5;
CV_CALL( icvFindStereoCorrespondenceByBirchfieldDP( src1->data.ptr,
src2->data.ptr, dst->data.ptr,
cvGetMatSize( src1 ), src1->step,
maxDisparity, (float)param1, (float)param2, (float)param3,
(float)param4, (float)param5 ) );
}
else
{
CV_ERROR( CV_StsBadArg, "Unsupported mode of function" );
}
__END__;
}
/* End of file. */

View File

@@ -0,0 +1,354 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
///////////////////////////////////////////////
//// Created by Khudyakov V.A. bober@gorodok.net
//////////////////////////////////////////////
#include "_cvaux.h"
#include "_cvfacedetection.h"
Face::Face(FaceTemplate * lpFaceTemplate)
{
//init number of face elements;
m_lFaceFeaturesNumber = lpFaceTemplate->GetCount();
//init array of numbers of foundet face elements of each type
m_lplFaceFeaturesCount = new long[m_lFaceFeaturesNumber];
memset(m_lplFaceFeaturesCount,0,m_lFaceFeaturesNumber*sizeof(long));
//init array of ideal face features
m_lpIdealFace = new FaceFeature[m_lFaceFeaturesNumber];
//init array of founded features
m_lppFoundedFaceFeatures = new FaceFeature*[m_lFaceFeaturesNumber];
for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
{
m_lppFoundedFaceFeatures[i] = (new FaceFeature[3*MAX_LAYERS]);
}
//set start weight 0
m_dWeight = 0;
}//Face::Face(FaceTemplate * lpFaceTemplate)
Face::~Face()
{
for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
{
delete [] (m_lppFoundedFaceFeatures[i]);
}
delete [] m_lppFoundedFaceFeatures;
delete [] m_lplFaceFeaturesCount;
delete [] m_lpIdealFace;
}//Face::~Face()
#define UP_SCALE 1
#define DOWN_SCALE 2
////////////
//class RFace(rect based face)
////////////
RFace::RFace(FaceTemplate * lpFaceTemplate):Face(lpFaceTemplate)
{
//init ideal face
FaceFeature * lpTmp = lpFaceTemplate->GetFeatures();
for (int j = 0;j < m_lFaceFeaturesNumber;j ++)
{
CvRect * lpTmpRect = NULL;
lpTmpRect = new CvRect;
*lpTmpRect = *(CvRect*)lpTmp[j].GetContour();
m_lpIdealFace[j].SetContour( lpTmpRect );
m_lpIdealFace[j].SetWeight( lpTmp[j].GetWeight() );
m_lpIdealFace[j].SetFeature( lpTmp[j].isFaceFeature() );
}
m_bIsGenerated = false;
}//RFace::RFace(FaceTemplate * lpFaceTemplate)
RFace::~RFace()
{
}//RFace::~RFace()
inline bool RFace::isPointInRect(CvPoint p,CvRect rect)
{
if ( (p.x >= rect.x) && (p.y >= rect.y) && (p.x <= rect.x + rect.width) && (p.y <= rect.y + rect.height) )
return true;
return false;
}//inline bool RFace::isPointInRect(CvPoint,CvRect rect)
double RFace::GetWeight()
{
return m_dWeight;
}//double RFace::GetWeight()
bool RFace::CheckElem(void * lpCandidat,void * lpIdeal)
{
CvRect IdealRect = *(CvRect*)lpIdeal;
CvRect Rect = *(CvRect*)lpCandidat;
if (Rect.height > Rect.width)
return false;
long SizeIdeal = IdealRect.width*IdealRect.height;
long Size = Rect.width*Rect.height;
if ( (Size > SizeIdeal) || ( Size < (SizeIdeal/5) ) )
return false;
// CvRect UpRect;
// CvRect DownRect;
// ResizeRect(IdealRect,&UpRect,UP_SCALE,7);
// ResizeRect(IdealRect,&DownRect,DOWN_SCALE,7);
long x = Rect.x + cvRound(Rect.width/2);
long y = Rect.y + cvRound(Rect.height/2);
if ( isPointInRect(cvPoint(x,y),IdealRect) )
return true;
// if ( isPointInRect(cvPoint(Rect.x,Rect.y),UpRect) &&
// isPointInRect(cvPoint(Rect.x + Rect.width,Rect.y + Rect.height),UpRect ) &&
// isPointInRect(cvPoint(DownRect.x,DownRect.y),Rect) &&
// isPointInRect(cvPoint(DownRect.x + DownRect.width,DownRect.y + DownRect.height),Rect) )
// return true;
// if ( isPointInRect(cvPoint(Rect.x,Rect.y),IdealRect) &&
// isPointInRect(cvPoint(Rect.x + Rect.width,Rect.y + Rect.height),IdealRect ) )
// return true;
return false;
}//inline bool RFace::CheckElem(CvRect rect)
void RFace::CalculateError(FaceData * lpFaceData)
{
CvRect LeftEyeRect = lpFaceData->LeftEyeRect;
CvRect RightEyeRect = lpFaceData->RightEyeRect;
CvRect MouthRect = lpFaceData->MouthRect;
long LeftSquare = LeftEyeRect.width*LeftEyeRect.height;
long RightSquare = RightEyeRect.width*RightEyeRect.height;
long dy = LeftEyeRect.y - RightEyeRect.y;
long dx1 = LeftEyeRect.x + LeftEyeRect.width/2 - MouthRect.x;
long dx2 = RightEyeRect.x + RightEyeRect.width/2 - MouthRect.x - MouthRect.width;
lpFaceData->Error = (double)(LeftSquare - RightSquare)*(double)(LeftSquare - RightSquare)/((double)(LeftSquare + RightSquare)*(LeftSquare + RightSquare)) +
(double)(dy*dy)/((double)(LeftEyeRect.height + RightEyeRect.height)*(LeftEyeRect.height + RightEyeRect.height)) +
(double)(dx1*dx1)/((double)MouthRect.width*MouthRect.width) +
(double)(dx2*dx2)/((double)MouthRect.width*MouthRect.width);
}//void RFace::CalculateError(FaceData * lpFaceData)
#define MAX_ERROR 0xFFFFFFFF
void RFace::CreateFace(void * lpData)
{
FaceData Data;
double Error = MAX_ERROR;
double CurError = MAX_ERROR;
FaceData * lpFaceData = (FaceData*)lpData;
int im = 0;//mouth was find
int jl = 0;//left eye was find
int kr = 0;//right eye was find
long MouthNumber = 0;
long LeftEyeNumber = 0;
long RightEyeNumber = 0;
for (int i = 0;i < m_lplFaceFeaturesCount[0] + 1;i ++)
{
if ( !m_lplFaceFeaturesCount[0] )
Data.MouthRect = *(CvRect*)m_lpIdealFace[0].GetContour();
else
{
if ( i != m_lplFaceFeaturesCount[0] )
Data.MouthRect = *(CvRect*)m_lppFoundedFaceFeatures[0][i].GetContour();
im = 1;
}
for (int j = 0;j < m_lplFaceFeaturesCount[1] + 1;j ++)
{
if ( !m_lplFaceFeaturesCount[1] )
Data.LeftEyeRect = *(CvRect*)m_lpIdealFace[1].GetContour();
else
{
if (j != m_lplFaceFeaturesCount[1] )
Data.LeftEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[1][j].GetContour();
jl = 1;
}
for (int k = 0;k < m_lplFaceFeaturesCount[2] + 1;k ++)
{
if ( !m_lplFaceFeaturesCount[2] )
Data.RightEyeRect = *(CvRect*)m_lpIdealFace[2].GetContour();
else
{
if (k != m_lplFaceFeaturesCount[2] )
Data.RightEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[2][k].GetContour();
kr = 1;
}
CalculateError(&Data);
if ( (im + jl + kr) )
{
Error = Data.Error/(im + jl + kr);
}else
Error = MAX_ERROR;
if (CurError > Error)
{
CurError = Error;
MouthNumber = i;
LeftEyeNumber = j;
RightEyeNumber = k;
}
}
}
}
if ( m_lplFaceFeaturesCount[0] )
lpFaceData->MouthRect = *(CvRect*)m_lppFoundedFaceFeatures[0][MouthNumber].GetContour();
else
lpFaceData->MouthRect = *(CvRect*)m_lpIdealFace[0].GetContour();
if ( m_lplFaceFeaturesCount[1] )
lpFaceData->LeftEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[1][LeftEyeNumber].GetContour();
else
lpFaceData->LeftEyeRect = *(CvRect*)m_lpIdealFace[1].GetContour();
if ( m_lplFaceFeaturesCount[2] )
lpFaceData->RightEyeRect = *(CvRect*)m_lppFoundedFaceFeatures[2][RightEyeNumber].GetContour();
else
lpFaceData->RightEyeRect = *(CvRect*)m_lpIdealFace[2].GetContour();
lpFaceData->Error = CurError;
}//void * RFace::CreateFace()
void RFace::Show(IplImage * Image)
{
for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
{
if (m_lplFaceFeaturesCount[i])
{
for (int j = 0;j < m_lplFaceFeaturesCount[i];j ++)
{
CvRect rect = *(CvRect*)m_lppFoundedFaceFeatures[i][j].GetContour();
CvPoint p1 = cvPoint(rect.x,rect.y);
CvPoint p2 = cvPoint(rect.x + rect.width,rect.y + rect.height);
cvRectangle(Image,p1,p2,CV_RGB(255,0,0),1);
}
}
}
}//void RFace::Show(IplImage * Image)
void RFace::ShowIdeal(IplImage* Image)
{
for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
{
CvRect Rect = *(CvRect*)m_lpIdealFace[i].GetContour();
CvPoint p1 = cvPoint(Rect.x,Rect.y);
CvPoint p2 = cvPoint(Rect.x + Rect.width,Rect.y + Rect.height);
cvRectangle(Image,p1,p2,CV_RGB(0,0,255),1);
}
}//void RFace::ShowIdeal(IplImage* Image)
inline void RFace::ResizeRect(CvRect Rect,CvRect * lpRect,long lDir,long lD)
{
if (lDir == UP_SCALE)
{
lpRect->x = Rect.x - lD;
lpRect->y = Rect.y - lD;
lpRect->width = Rect.width + 2*lD;
lpRect->height = Rect.height + 2*lD;
}
if (lDir == DOWN_SCALE)
{
lpRect->x = Rect.x + lD;
lpRect->y = Rect.y + lD;
if (Rect.width - 2*lD >= 0)
{
lpRect->width = Rect.width - 2*lD;
}else
lpRect->width = 0;
if (Rect.height - 2*lD >= 0)
{
lpRect->height = Rect.height - 2*lD;
}else
lpRect->height = 0;
}
}// inline void RFace::ResizeRect(CvRect * lpRect,long lDir,long lD)

View File

@@ -0,0 +1,136 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
///////////////////////////////////////////////
//// Created by Khudyakov V.A. bober@gorodok.net
//////////////////////////////////////////////
#ifndef __CVFACE_H__
#define __CVFACE_H__
#include "cvfacetemplate.h"
#define MAX_LAYERS 64
class Face
{
public:
Face(FaceTemplate * lpFaceTemplate);
virtual ~Face();
inline bool isFeature(void * lpElem);
virtual void Show(IplImage * /*Image*/){};
virtual void ShowIdeal(IplImage* /*Image*/){};
virtual void CreateFace(void * lpData) = 0;
virtual bool CheckElem(void * lpCandidat,void * lpIdeal) = 0;
virtual double GetWeight() = 0;
protected:
FaceFeature * m_lpIdealFace;//ideal face definition
long m_lFaceFeaturesNumber; //total number of diferent face fetures
long * m_lplFaceFeaturesCount;//number of each fetures fouded for this face
FaceFeature ** m_lppFoundedFaceFeatures;//founded features of curen face
double m_dWeight;
};
inline bool Face::isFeature(void * lpElem)
{
for (int i = 0;i < m_lFaceFeaturesNumber;i ++)
{
void * lpIdeal = m_lpIdealFace[i].GetContour();
if ( CheckElem( lpElem,lpIdeal) )
{
if (m_lplFaceFeaturesCount[i] < 3*MAX_LAYERS)
{
double dWeight = m_lpIdealFace[i].GetWeight();
bool bIsFeature = m_lpIdealFace[i].isFaceFeature();
if (bIsFeature)
{
m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetWeight(dWeight);
m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetContour(lpElem);
m_lppFoundedFaceFeatures[i][m_lplFaceFeaturesCount[i]].SetFeature(bIsFeature);
m_lplFaceFeaturesCount[i] ++;
}
m_dWeight += dWeight;
if (bIsFeature)
return true;
}
}
}
return false;
}//inline bool RFace::isFeature(void * lpElem);
struct FaceData
{
CvRect LeftEyeRect;
CvRect RightEyeRect;
CvRect MouthRect;
double Error;
};//struct FaceData
class RFace:public Face
{
public:
RFace(FaceTemplate * lpFaceTemplate);
virtual ~RFace();
virtual bool CheckElem(void * lpCandidat,void * lpIdeal);
virtual void CreateFace(void * lpData);
virtual void Show(IplImage* Image);
virtual void ShowIdeal(IplImage* Image);
virtual double GetWeight();
private:
bool isPointInRect(CvPoint p,CvRect rect);
bool m_bIsGenerated;
void ResizeRect(CvRect Rect,CvRect * lpRect,long lDir,long lD);
void CalculateError(FaceData * lpFaceData);
};
#endif //__FACE_H__

View File

@@ -0,0 +1,486 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
///////////////////////////////////////////////
//// Created by Khudyakov V.A. bober@gorodok.net
//////////////////////////////////////////////
// FaceDetection.cpp: implementation of the FaceDetection class.
//
//////////////////////////////////////////////////////////////////////
#include "_cvaux.h"
#include "_cvfacedetection.h"
int CV_CDECL CompareContourRect(const void* el1, const void* el2, void* userdata);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
FaceDetection::FaceDetection()
{
m_imgGray = NULL;
m_imgThresh = NULL;
m_mstgContours = NULL;
memset(m_seqContours, 0, sizeof(CvSeq*) * MAX_LAYERS);
m_mstgRects = NULL;
m_seqRects = NULL;
m_iNumLayers = 16;
assert(m_iNumLayers <= MAX_LAYERS);
m_pFaceList = new List();
m_bBoosting = false;
}// FaceDetection()
FaceDetection::~FaceDetection()
{
if (m_imgGray)
cvReleaseImage(&m_imgGray);
if (m_imgThresh)
cvReleaseImage(&m_imgThresh);
if (m_mstgContours)
cvReleaseMemStorage(&m_mstgContours);
if (m_mstgRects)
cvReleaseMemStorage(&m_mstgRects);
}// ~FaceDetection()
void FaceDetection::FindContours(IplImage* imgGray)
{
ReallocImage(&m_imgThresh, cvGetSize(imgGray), 1);
if (NULL == m_imgThresh)
return;
//
int iNumLayers = m_iNumLayers;
int iMinLevel = 0, iMaxLevel = 255, iStep = 255 / iNumLayers;
ThresholdingParam(imgGray, iNumLayers, iMinLevel, iMaxLevel, iStep);
// init
cvReleaseMemStorage(&m_mstgContours);
m_mstgContours = cvCreateMemStorage();
if (NULL == m_mstgContours)
return;
memset(m_seqContours, 0, sizeof(CvSeq*) * MAX_LAYERS);
cvReleaseMemStorage(&m_mstgRects);
m_mstgRects = cvCreateMemStorage();
if (NULL == m_mstgRects)
return;
m_seqRects = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvContourRect), m_mstgRects);
if (NULL == m_seqRects)
return;
// find contours
for (int l = iMinLevel, i = 0; l < iMaxLevel; l += iStep, i++)
{
cvThreshold(imgGray, m_imgThresh, (double)l, (double)255, CV_THRESH_BINARY);
if (cvFindContours(m_imgThresh, m_mstgContours, &m_seqContours[i], sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE))
AddContours2Rect(m_seqContours[i], l, i);
}
// sort rects
cvSeqSort(m_seqRects, CompareContourRect, NULL);
}// void FaceDetection::FindContours(IplImage* imgGray)
#define GIST_STEP 10
#define GIST_NUM (256 / GIST_STEP)
#define GIST_MIN 32
void FaceDetection::ThresholdingParam(IplImage *imgGray, int iNumLayers, int &iMinLevel, int &iMaxLevel, int &iStep)
{
assert(imgGray != NULL);
assert(imgGray->nChannels == 1);
int i, j;
// create gistogramm
uchar* buffImg = (uchar*)imgGray->imageData;
int gistImg[GIST_NUM + 1] = {0};
for (j = 0; j < imgGray->height; j ++)
{
for (i = 0; i < imgGray->width; i ++)
{
int ind = buffImg[i] / GIST_STEP;
gistImg[ind] ++;
}
buffImg += imgGray->widthStep;
}
// params
for (i = 0; i <= GIST_NUM; i ++)
{
if (gistImg[i] >= GIST_MIN)
break;
}
iMinLevel = i * GIST_STEP;
for (i = GIST_NUM; i >= 0; i --)
{
if (gistImg[i] >= GIST_MIN)
break;
}
iMaxLevel = i * GIST_STEP;
int dLevels = iMaxLevel - iMinLevel;
if (dLevels <= 0)
{
iMinLevel = 0;
iMaxLevel = 255;
}
else if (dLevels <= iNumLayers)
{
iMinLevel = iMaxLevel - iNumLayers;
if (iMinLevel < 0)
{
iMinLevel = 0;
iMaxLevel = iNumLayers;
}
}
iStep = (iMaxLevel - iMinLevel) / iNumLayers;
}// void FaceDetection::ThresholdingParam(IplImage *imgGray, int iNumLayers, int &iMinLevel, int &iMaxLevel, int &iStep)
#ifndef MAX_ERROR
#define MAX_ERROR 0xFFFFFFFF
#endif //MAX_ERROR
void FaceDetection::CreateResults(CvSeq * lpSeq)
{
Face * tmp;
double Max = 0;
double CurStat = 0;
FaceData tmpData;
if (m_bBoosting)
{
tmp = m_pFaceList->GetData();
tmp->CreateFace(&tmpData);
CvFace tmpFace;
tmpFace.MouthRect = tmpData.MouthRect;
tmpFace.LeftEyeRect = tmpData.LeftEyeRect;
tmpFace.RightEyeRect = tmpData.RightEyeRect;
cvSeqPush(lpSeq,&tmpFace);
}else
{
while ( (tmp = m_pFaceList->GetData()) != 0 )
{
CurStat = tmp->GetWeight();
if (CurStat > Max)
Max = CurStat;
}
while ( (tmp = m_pFaceList->GetData()) != 0 )
{
tmp->CreateFace(&tmpData);
CurStat = tmp->GetWeight();
if (CurStat == Max)
{
CvFace tmpFace;
tmpFace.MouthRect = tmpData.MouthRect;
tmpFace.LeftEyeRect = tmpData.LeftEyeRect;
tmpFace.RightEyeRect = tmpData.RightEyeRect;
cvSeqPush(lpSeq,&tmpFace);
}
}
}
}// void FaceDetection::DrawResult(IplImage* img)
void FaceDetection::ResetImage()
{
delete m_pFaceList;
m_pFaceList = new List();
}//FaceDetection::ResetImage
void FaceDetection::AddContours2Rect(CvSeq *seq, int color, int iLayer)
{
assert(m_mstgRects != NULL);
assert(m_seqRects != NULL);
CvContourRect cr;
for (CvSeq* external = seq; external; external = external->h_next)
{
cr.r = cvContourBoundingRect(external, 1 );
cr.pCenter.x = cr.r.x + cr.r.width / 2;
cr.pCenter.y = cr.r.y + cr.r.height / 2;
cr.iNumber = iLayer;
cr.iType = 6;
cr.iFlags = 0;
cr.seqContour = external;
cr.iContourLength = external->total;
cr.iColor = color;
cvSeqPush(m_seqRects, &cr);
for (CvSeq* internal = external->v_next; internal; internal = internal->h_next)
{
cr.r = cvContourBoundingRect(internal, 0);
cr.pCenter.x = cr.r.x + cr.r.width / 2;
cr.pCenter.y = cr.r.y + cr.r.height / 2;
cr.iNumber = iLayer;
cr.iType = 12;
cr.iFlags = 0;
cr.seqContour = internal;
cr.iContourLength = internal->total;
cr.iColor = color;
cvSeqPush(m_seqRects, &cr);
}
}
}// void FaceDetection::AddContours2Rect(CvSeq *seq, int color, int iLayer)
int CV_CDECL CompareContourRect(const void* el1, const void* el2, void* /*userdata*/)
{
return (((CvContourRect*)el1)->pCenter.y - ((CvContourRect*)el2)->pCenter.y);
}// int CV_CDECL CompareContourRect(const void* el1, const void* el2, void* userdata)
void FaceDetection::FindFace(IplImage *img)
{
// find all contours
FindContours(img);
//
ResetImage();
if (m_bBoosting)
PostBoostingFindCandidats(img);
else
FindCandidats();
}// void FaceDetection::FindFace(IplImage *img)
void FaceDetection::FindCandidats()
{
bool bFound1 = false;
MouthFaceTemplate * lpFaceTemplate1;
RFace * lpFace1;
bool bInvalidRect1 = false;
CvRect * lpRect1 = NULL;
for (int i = 0; i < m_seqRects->total; i++)
{
CvContourRect* pRect = (CvContourRect*)cvGetSeqElem(m_seqRects, i);
CvRect rect = pRect->r;
if (rect.width >= 2*rect.height)
{
lpFaceTemplate1 = new MouthFaceTemplate(3,rect,3*(double)rect.width/(double)4,
3*(double)rect.width/(double)4,
(double)rect.width/(double)2,
(double)rect.width/(double)2);
lpFace1 = new RFace(lpFaceTemplate1);
for (int j = 0; j < m_seqRects->total; j++)
{
CvContourRect* pRect = (CvContourRect*)cvGetSeqElem(m_seqRects, j);
if ( !bInvalidRect1 )
{
lpRect1 = NULL;
lpRect1 = new CvRect();
*lpRect1 = pRect->r;
}else
{
delete lpRect1;
lpRect1 = new CvRect();
*lpRect1 = pRect->r;
}
if ( lpFace1->isFeature(lpRect1) )
{
bFound1 = true;
bInvalidRect1 = false;
}else
bInvalidRect1 = true;
}
if (bFound1)
{
m_pFaceList->AddElem(lpFace1);
bFound1 = false;
lpFace1 = NULL;
}else
{
delete lpFace1;
lpFace1 = NULL;
}
delete lpFaceTemplate1;
}
}
}
void FaceDetection::PostBoostingFindCandidats(IplImage * FaceImage)
{
BoostingFaceTemplate * lpFaceTemplate1;
RFace * lpFace1;
bool bInvalidRect1 = false;
CvRect * lpRect1 = NULL;
if ( ( !FaceImage->roi ) )
lpFaceTemplate1 = new BoostingFaceTemplate(3,cvRect(0,0,FaceImage->width,FaceImage->height));
else
lpFaceTemplate1 = new BoostingFaceTemplate(3,cvRect(FaceImage->roi->xOffset,FaceImage->roi->yOffset,
FaceImage->roi->width,FaceImage->roi->height));
lpFace1 = new RFace(lpFaceTemplate1);
for (int i = 0; i < m_seqRects->total; i++)
{
CvContourRect* pRect = (CvContourRect*)cvGetSeqElem(m_seqRects, i);
if ( !bInvalidRect1 )
{
lpRect1 = NULL;
lpRect1 = new CvRect();
*lpRect1 = pRect->r;
}else
{
delete lpRect1;
lpRect1 = new CvRect();
*lpRect1 = pRect->r;
}
if ( lpFace1->isFeature(lpRect1) )
{
//bFound1 = true;
bInvalidRect1 = false;
}else
bInvalidRect1 = true;
}
m_pFaceList->AddElem(lpFace1);
delete lpFaceTemplate1;
}//void FaceDetection::PostBoostingFindCandidats(IplImage * FaceImage)
/////////////////////////
//class Face
//////
//List Class
/////
ListElem::ListElem()
{
m_pNext = this;
m_pPrev = this;
m_pFace = NULL;
}///ListElem::ListElem()
ListElem::ListElem(Face * pFace,ListElem * pHead)
{
m_pNext = pHead;
m_pPrev = pHead->m_pPrev;
pHead->m_pPrev->m_pNext = this;
pHead->m_pPrev = this;
m_pFace = pFace;
}//ListElem::ListElem(Face * pFace)
ListElem::~ListElem()
{
delete m_pFace;
m_pNext->m_pPrev = m_pPrev;
m_pPrev->m_pNext = m_pNext;
}//ListElem::~ListElem()
List::List()
{
m_pHead = new ListElem();
m_FacesCount = 0;
m_pCurElem = m_pHead;
}//List::List()
List::~List()
{
void * tmp;
while((tmp = m_pHead->m_pNext->m_pFace) != 0)
delete m_pHead->m_pNext;
delete m_pHead;
}//List::~List()
int List::AddElem(Face * pFace)
{
new ListElem(pFace,m_pHead);
return m_FacesCount++;
}//List::AddElem(Face * pFace)
Face * List::GetData()
{
m_pCurElem = m_pCurElem->m_pNext;
return m_pCurElem->m_pFace;
}//Face * List::GetData()

View File

@@ -0,0 +1,100 @@
// FaceDetection.h: interface for the FaceDetection class.
//
//////////////////////////////////////////////////////////////////////
#ifndef _CVFACEDETECTION_H_
#define _CVFACEDETECTION_H_
#include "cvfacetemplate.h"
#include "cvface.h"
#include "cvboostingtemplate.h"
typedef struct CvContourRect
{
int iNumber; //ïîðÿäêîâûé íîìåð àòðèáóòà
int iType; //òèï îáúåêòà
int iFlags; //ñâîáîäíîå ïîëå
CvSeq *seqContour; //àäðåñ íà÷àëà çàïèñè îáúåêòà
int iContourLength; //äëèíà çàïèñè âåêòîðîâ
CvRect r; //îïèñàíûé ïðÿìîóãîëüíèê
CvPoint pCenter; // center of rect
int iColor;// öâåò çàïîëíåíèÿ êîíòóðà
} CvContourRect;
//class Face;
class ListElem
{
public:
ListElem();
ListElem(Face * pFace,ListElem * pHead);
virtual ~ListElem();
ListElem * m_pNext;
ListElem * m_pPrev;
Face * m_pFace;
};//class ListElem
class List
{
public:
List();
int AddElem(Face * pFace);
virtual ~List();
Face* GetData();
long m_FacesCount;
private:
ListElem * m_pHead;
ListElem * m_pCurElem;
};//class List
class FaceDetection
{
public:
void FindFace(IplImage* img);
void CreateResults(CvSeq * lpSeq);
FaceDetection();
virtual ~FaceDetection();
void SetBoosting(bool bBoosting) {m_bBoosting = bBoosting;}
bool isPostBoosting() {return m_bBoosting;}
protected:
IplImage* m_imgGray;
IplImage* m_imgThresh;
int m_iNumLayers;
CvMemStorage* m_mstgContours;
CvSeq* m_seqContours[MAX_LAYERS];
CvMemStorage* m_mstgRects;
CvSeq* m_seqRects;
bool m_bBoosting;
List * m_pFaceList;
protected:
void ResetImage();
void FindContours(IplImage* imgGray);
void AddContours2Rect(CvSeq* seq, int color, int iLayer);
void ThresholdingParam(IplImage* imgGray, int iNumLayers, int& iMinLevel, int& iMaxLevel, int& iStep);
void FindCandidats();
void PostBoostingFindCandidats(IplImage * FaceImage);
};
inline void ReallocImage(IplImage** ppImage, CvSize sz, long lChNum)
{
IplImage* pImage;
if( ppImage == NULL )
return;
pImage = *ppImage;
if( pImage != NULL )
{
if (pImage->width != sz.width || pImage->height != sz.height || pImage->nChannels != lChNum)
cvReleaseImage( &pImage );
}
if( pImage == NULL )
pImage = cvCreateImage( sz, IPL_DEPTH_8U, lChNum);
*ppImage = pImage;
};
#endif // !defined(AFX_FACEDETECTION_H__55865033_D8E5_4DD5_8925_34C2285BB1BE__INCLUDED_)

View File

@@ -0,0 +1,86 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
///////////////////////////////////////////////
//// Created by Khudyakov V.A. bober@gorodok.net
//////////////////////////////////////////////
#include "_cvaux.h"
#include "_cvfacedetection.h"
///class FaceFeature
FaceFeature::FaceFeature(double dWeight,void * lpContour,bool bIsFeature)
{
m_lpContour = lpContour;
m_dWeight = dWeight;
m_bIsFaceFeature = bIsFeature;
}//FaceFeature::FaceFeature(long lWeight,void * lpContour)
FaceFeature::~FaceFeature()
{
if (m_lpContour)
delete (char*)m_lpContour;
}//FaceFeature::~FaceFeature()
FaceFeature::FaceFeature()
{
m_lpContour = NULL;
m_dWeight = 0;
m_bIsFaceFeature = false;
}
////class FaceTemplate
FaceTemplate::~FaceTemplate()
{
delete [] m_lpFeaturesList;
}//FaceTemplate::~FaceTemplate()
/////
//class RFaceTemplate
/////
MouthFaceTemplate::~MouthFaceTemplate()
{
}//RFaceTemplate::~RFaceTemplate()

View File

@@ -0,0 +1,202 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
///////////////////////////////////////////////
//// Created by Khudyakov V.A. bober@gorodok.net
//////////////////////////////////////////////
#ifndef __CVFACETEMPLATE_H__
#define __CVFACETEMPLATE_H__
class FaceFeature
{
public:
FaceFeature(double dWeight,void * lpContour,bool bIsFeature);
FaceFeature();
virtual ~FaceFeature();
inline bool isFaceFeature();
inline void * GetContour();
inline double GetWeight();
inline void SetContour(void * lpContour);
inline void SetWeight(double dWeight);
inline void SetFeature(bool bIsFeature);
private:
double m_dWeight;
void * m_lpContour;
bool m_bIsFaceFeature;
};//class FaceFeature
inline void FaceFeature::SetFeature(bool bIsFeature)
{
m_bIsFaceFeature = bIsFeature;
}
inline bool FaceFeature::isFaceFeature()
{
return m_bIsFaceFeature;
}//inline bool FaceFeature::isFaceFeature()
inline void * FaceFeature::GetContour()
{
return m_lpContour;
}//inline void * FaceFeature::GetContour()
inline double FaceFeature::GetWeight()
{
return m_dWeight;
}//inline long FaceFeature::GetWeight()
inline void FaceFeature::SetContour(void * lpContour)
{
m_lpContour = lpContour;
}//inline void FaceFeature::SetContour(void * lpContour)
inline void FaceFeature::SetWeight(double dWeight)
{
m_dWeight = dWeight;
}//inline void FaceFeature::SetWeight(double * dWeight)
class FaceTemplate
{
public:
FaceTemplate(long lFeatureCount) {m_lFeturesCount = lFeatureCount; m_lpFeaturesList = new FaceFeature[lFeatureCount];};
virtual ~FaceTemplate();
inline long GetCount();
inline FaceFeature * GetFeatures();
protected:
FaceFeature * m_lpFeaturesList;
private:
long m_lFeturesCount;
};//class FaceTemplate
inline long FaceTemplate::GetCount()
{
return m_lFeturesCount;
}//inline long FaceTemplate::GetCount()
inline FaceFeature * FaceTemplate::GetFeatures()
{
return m_lpFeaturesList;
}//inline FaceFeature * FaceTemplate::GetFeatures()
////////////
//class RFaceTemplate
///////////
class MouthFaceTemplate:public FaceTemplate
{
public:
inline MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth);
~MouthFaceTemplate();
};//class MouthFaceTemplate:public FaceTemplate
inline MouthFaceTemplate::MouthFaceTemplate(long lNumber,CvRect rect,double dEyeWidth,double dEyeHeight,
double dDistanceBetweenEye,double dDistanceEyeAboveMouth):FaceTemplate(lNumber)
{
CvRect MouthRect = rect;
CvRect LeftEyeRect = cvRect(cvRound(rect.x - (dEyeWidth + dDistanceBetweenEye/(double)2 - (double)rect.width/(double)2)),
cvRound(rect.y - dDistanceEyeAboveMouth - dEyeHeight),
cvRound(dEyeWidth),
cvRound(dEyeHeight) );
CvRect RightEyeRect = cvRect(cvRound(rect.x + (double)rect.width/(double)2 + dDistanceBetweenEye/(double)2),
cvRound(rect.y - dDistanceEyeAboveMouth - dEyeHeight),
cvRound(dEyeWidth),
cvRound(dEyeHeight) );
// CvRect NoseRect = cvRect(cvRound(rect.x + (double)rect.width/(double)4),
// cvRound(rect.y - (double)rect.width/(double)2 - (double)rect.height/(double)4),
// cvRound((double)rect.width/(double)2),
// cvRound((double)rect.width/(double)2) );
/*
CvRect CheenRect = cvRect(rect.x,rect.y + 3*rect.height/2,rect.width,rect.height);
*/
CvRect * lpMouthRect = new CvRect();
*lpMouthRect = MouthRect;
m_lpFeaturesList[0].SetContour(lpMouthRect);
m_lpFeaturesList[0].SetWeight(1);
m_lpFeaturesList[0].SetFeature(false);
CvRect * lpLeftEyeRect = new CvRect();
*lpLeftEyeRect = LeftEyeRect;
m_lpFeaturesList[1].SetContour(lpLeftEyeRect);
m_lpFeaturesList[1].SetWeight(1);
m_lpFeaturesList[1].SetFeature(true);
CvRect * lpRightEyeRect = new CvRect();
*lpRightEyeRect = RightEyeRect;
m_lpFeaturesList[2].SetContour(lpRightEyeRect);
m_lpFeaturesList[2].SetWeight(1);
m_lpFeaturesList[2].SetFeature(true);
// CvRect * lpNoseRect = new CvRect();
// *lpNoseRect = NoseRect;
// m_lpFeaturesList[3].SetContour(lpNoseRect);
// m_lpFeaturesList[3].SetWeight(0);
// m_lpFeaturesList[3].SetFeature(true);
/* CvRect * lpCheenRect = new CvRect();
*lpCheenRect = CheenRect;
m_lpFeaturesList[4].SetContour(lpCheenRect);
m_lpFeaturesList[4].SetWeight(1);
m_lpFeaturesList[4].SetFeature(false);
*/
};//constructor MouthFaceTemplate(long lNumFeatures,CvRect rect,double dEyeWidth,double dEyeHeight,double dDistanceBetweenEye,double dDistanceEyeAboveMouth);
#endif//__FACETEMPLATE_H__

View File

@@ -0,0 +1,68 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
///////////////////////////////////////////////
//// Created by Khudyakov V.A. bober@gorodok.net
//////////////////////////////////////////////
#include "_cvaux.h"
#include "_cvfacedetection.h"
CvSeq * cvFindFace(IplImage * Image,CvMemStorage* lpStorage)
{
FaceDetection FD;
FD.SetBoosting(false);
FD.FindFace(Image);
CvSeq * lpSeq = cvCreateSeq(0,sizeof(*lpSeq),sizeof(CvFace),lpStorage);
FD.CreateResults(lpSeq);
return lpSeq;
}//cvFindFace(IplImage * Image)
CvSeq * cvPostBoostingFindFace(IplImage * Image,CvMemStorage* lpStorage)
{
FaceDetection FD;
FD.SetBoosting(true);
FD.FindFace(Image);
CvSeq * lpSeq = cvCreateSeq(0,sizeof(*lpSeq),sizeof(CvFace),lpStorage);
FD.CreateResults(lpSeq);
return lpSeq;
}//cvPostBoostingFindFace(IplImage * Image)

View File

@@ -0,0 +1,645 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#define _CV_NORM_L2(a) (float)(icvSqrt32f(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]))
#define _CV_NORM_L22(a) (float)(a[0]*a[0] + a[1]*a[1] + a[2]*a[2])
/****************************************************************************************\
find region where hand is (for gesture recognition)
flag = 0 (use left bucket) flag = 1 (use right bucket)
\****************************************************************************************/
static CvStatus CV_STDCALL
icvFindHandRegion( CvPoint3D32f * points, int count,
CvSeq * indexs,
float *line, CvSize2D32f size, int flag,
CvPoint3D32f * center,
CvMemStorage * storage, CvSeq ** numbers )
{
/* IppmVect32f sub, cros; */
float *sub, *cros;
CvSeqWriter writer;
CvSeqReader reader;
CvStatus status;
int nbins = 20, i, l, i_point, left, right;
int *bin_counts = 0; // pointer to the point's counter in the bickets
int low_count; // low threshold
CvPoint *tmp_number = 0, *pt;
float value, vmin, vmax, vl, bsize, vc;
float hand_length, hand_length2, hand_left, hand_right;
float threshold, threshold2;
float *vv = 0;
float a[3];
status = CV_OK;
hand_length = size.width;
hand_length2 = hand_length / 2;
threshold = (float) (size.height * 3 / 5.);
threshold2 = threshold * threshold;
/* low_count = count/nbins; */
low_count = (int) (count / 60.);
assert( points != NULL && line != NULL );
if( points == NULL || line == NULL )
return CV_NULLPTR_ERR;
assert( count > 5 );
if( count < 5 )
return CV_BADFLAG_ERR;
assert( flag == 0 || flag == 1 );
if( flag != 0 && flag != 1 )
return CV_BADFLAG_ERR;
/* create vectors */
sub = icvCreateVector_32f( 3 );
cros = icvCreateVector_32f( 3 );
if( sub == NULL || cros == NULL )
return CV_OUTOFMEM_ERR;
/* alloc memory for the point's projections on the line */
vv = (float *) cvAlloc( count * sizeof( float ));
if( vv == NULL )
return CV_OUTOFMEM_ERR;
/* alloc memory for the point's counter in the bickets */
bin_counts = (int *) cvAlloc( nbins * sizeof( int ));
if( bin_counts == NULL )
{
status = CV_OUTOFMEM_ERR;
goto M_END;
}
memset( bin_counts, 0, nbins * sizeof( int ));
cvStartReadSeq( indexs, &reader, 0 );
/* alloc memory for the temporale point's numbers */
tmp_number = (CvPoint *) cvAlloc( count * sizeof( CvPoint ));
if( tmp_number == NULL )
{
status = CV_OUTOFMEM_ERR;
goto M_END;
}
/* find min and max point's projection on the line */
vmin = 1000;
vmax = -1000;
i_point = 0;
for( i = 0; i < count; i++ )
{
/*
icvSubVector_32f ((IppmVect32f )&points[i], (IppmVect32f )&line[3], sub, 3);
icvCrossProduct2L_32f ((IppmVect32f )&line[0], sub, cros);
*/
sub[0] = points[i].x - line[3];
sub[1] = points[i].y - line[4];
sub[2] = points[i].z - line[5];
a[0] = sub[0] * line[1] - sub[1] * line[0];
a[1] = sub[1] * line[2] - sub[2] * line[1];
a[2] = sub[2] * line[0] - sub[0] * line[2];
/* if(IPPI_NORM_L22 ( cros ) < threshold2) */
if( _CV_NORM_L22( a ) < threshold2 )
{
value = (float)icvDotProduct_32f( sub, &line[0], 3 );
if( value > vmax )
vmax = value;
if( value < vmin )
vmin = value;
vv[i_point] = value;
pt = (CvPoint*)cvGetSeqElem( indexs, i );
tmp_number[i_point] = *pt;
i_point++;
}
}
/* compute the length of one bucket */
vl = vmax - vmin;
bsize = vl / nbins;
/* compute the number of points in each bucket */
for( i = 0; i < i_point; i++ )
{
l = cvRound( (vv[i] - vmin) / bsize );
bin_counts[l]++;
}
*numbers = cvCreateSeq( CV_SEQ_POINT_SET, sizeof( CvSeq ), sizeof( CvPoint ), storage );
assert( numbers != 0 );
if( numbers == NULL )
{
status = CV_OUTOFMEM_ERR;
goto M_END;
}
cvStartAppendToSeq( *numbers, &writer );
if( flag == 0 )
{
/* find the leftmost bucket */
for( l = 0; l < nbins; l++ )
{
if( bin_counts[l] > low_count )
break;
}
left = l;
/* compute center point of the left hand */
hand_left = vmin + left * bsize;
vc = hand_left + hand_length2;
hand_right = hand_left + hand_length;
}
else
{
/* find the rightmost bucket */
for( l = nbins - 1; l >= 0; l-- )
{
if( bin_counts[l] > low_count )
break;
}
right = l;
/* compute center point of the right hand */
hand_right = vmax - (nbins - right - 1) * bsize;
vc = hand_right - hand_length2;
hand_left = hand_right - hand_length;
}
icvScaleVector_32f( &line[0], sub, 3, vc );
icvAddVector_32f( &line[3], sub, (float *) center, 3 );
/* select hand's points and calculate mean value */
//ss.x = ss.y = ss.z = 0;
for( l = 0; l < i_point; l++ )
{
if( vv[l] >= hand_left && vv[l] <= hand_right )
{
CV_WRITE_SEQ_ELEM( tmp_number[l], writer );
}
}
cvEndWriteSeq( &writer );
M_END:
if( tmp_number != NULL )
cvFree( &tmp_number );
if( bin_counts != NULL )
cvFree( &bin_counts );
if( vv != NULL )
cvFree( &vv );
if( sub != NULL ) icvDeleteVector (sub);
if( cros != NULL ) icvDeleteVector (cros);
return status;
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
#define _CV_NORM_L31(a) (float)(icvSqrt32f(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]))
#define _CV_NORM_L32(a) (float)(a[0]*a[0] + a[1]*a[1] + a[2]*a[2])
/****************************************************************************************\
find region where hand is (for gesture recognition)
flag = 0 (use left bucket) flag = 1 (use right bucket)
\****************************************************************************************/
static CvStatus CV_STDCALL
icvFindHandRegionA( CvPoint3D32f * points, int count,
CvSeq * indexs,
float *line, CvSize2D32f size, int jc,
CvPoint3D32f * center,
CvMemStorage * storage, CvSeq ** numbers )
{
/* IppmVect32f sub, cros; */
float *sub, *cros;
float eps = (float) 0.01;
CvSeqWriter writer;
CvSeqReader reader;
CvStatus status;
float gor[3] = { 1, 0, 0 };
float ver[3] = { 0, 1, 0 };
int nbins = 20, i, l, i_point, left, right, jmin, jmax, jl;
int j_left, j_right;
int *bin_counts = 0; // pointer to the point's counter in the bickets
// int *bin_countsj = 0; // pointer to the index's counter in the bickets
int low_count; // low threshold
CvPoint *tmp_number = 0, *pt;
float value, vmin, vmax, vl, bsize, bsizej, vc, vcl, vcr;
double v_ver, v_gor;
float hand_length, hand_length2, hand_left, hand_right;
float threshold, threshold2;
float *vv = 0;
float a[3];
char log;
status = CV_OK;
hand_length = size.width;
hand_length2 = hand_length / 2;
threshold = (float) (size.height * 3 / 5.);
threshold2 = threshold * threshold;
/* low_count = count/nbins; */
low_count = (int) (count / 60.);
assert( points != NULL && line != NULL );
if( points == NULL || line == NULL )
return CV_NULLPTR_ERR;
assert( count > 5 );
if( count < 5 )
return CV_BADFLAG_ERR;
/* create vectors */
sub = icvCreateVector_32f( 3 );
cros = icvCreateVector_32f( 3 );
if( sub == NULL || cros == NULL )
return CV_OUTOFMEM_ERR;
/* alloc memory for the point's projections on the line */
vv = (float *) cvAlloc( count * sizeof( float ));
if( vv == NULL )
return CV_OUTOFMEM_ERR;
/* alloc memory for the point's counter in the bickets */
bin_counts = (int *) cvAlloc( nbins * sizeof( int ));
if( bin_counts == NULL )
{
status = CV_OUTOFMEM_ERR;
goto M_END;
}
memset( bin_counts, 0, nbins * sizeof( int ));
/* alloc memory for the point's counter in the bickets */
// bin_countsj = (int*) icvAlloc(nbins*sizeof(int));
// if(bin_countsj == NULL) {status = CV_OUTOFMEM_ERR; goto M_END;}
// memset(bin_countsj,0,nbins*sizeof(int));
cvStartReadSeq( indexs, &reader, 0 );
/* alloc memory for the temporale point's numbers */
tmp_number = (CvPoint *) cvAlloc( count * sizeof( CvPoint ));
if( tmp_number == NULL )
{
status = CV_OUTOFMEM_ERR;
goto M_END;
}
/* find min and max point's projection on the line */
vmin = 1000;
vmax = -1000;
jmin = 1000;
jmax = -1000;
i_point = 0;
for( i = 0; i < count; i++ )
{
/*
icvSubVector_32f ((IppmVect32f )&points[i], (IppmVect32f )&line[3], sub, 3);
icvCrossProduct2L_32f ((IppmVect32f )&line[0], sub, cros);
*/
sub[0] = points[i].x - line[3];
sub[1] = points[i].y - line[4];
sub[2] = points[i].z - line[5];
// if(fabs(sub[0])<eps||fabs(sub[1])<eps||fabs(sub[2])<eps) continue;
a[0] = sub[0] * line[1] - sub[1] * line[0];
a[1] = sub[1] * line[2] - sub[2] * line[1];
a[2] = sub[2] * line[0] - sub[0] * line[2];
v_gor = icvDotProduct_32f( gor, &line[0], 3 );
v_ver = icvDotProduct_32f( ver, &line[0], 3 );
if( v_ver > v_gor )
log = true;
else
log = false;
/* if(IPPI_NORM_L22 ( cros ) < threshold2) */
/*
if(fabs(a[0])<eps && fabs(a[1])<eps && fabs(a[2])<eps)
{
icvDotProduct_32f( sub, &line[0], 3, &value);
if(value > vmax) vmax = value;
if(value < vmin) vmin = value;
vv[i_point] = value;
pt = (CvPoint* )icvGetSeqElem ( indexs, i, 0);
if(pt->x > jmax) jmax = pt->x;
if(pt->x < jmin) jmin = pt->x;
tmp_number[i_point] = *pt;
i_point++;
}
else
*/
{
if( _CV_NORM_L32( a ) < threshold2 )
{
value = (float)icvDotProduct_32f( sub, &line[0], 3 );
if( value > vmax )
vmax = value;
if( value < vmin )
vmin = value;
vv[i_point] = value;
pt = (CvPoint*)cvGetSeqElem( indexs, i );
if( !log )
{
if( pt->x > jmax )
jmax = pt->x;
if( pt->x < jmin )
jmin = pt->x;
}
else
{
if( pt->y > jmax )
jmax = pt->y;
if( pt->y < jmin )
jmin = pt->y;
}
tmp_number[i_point] = *pt;
i_point++;
}
}
}
/* compute the length of one bucket along the line */
vl = vmax - vmin;
/* examining on the arm's existence */
if( vl < eps )
{
*numbers = NULL;
status = CV_OK;
goto M_END;
}
bsize = vl / nbins;
/* compute the number of points in each bucket along the line */
for( i = 0; i < i_point; i++ )
{
l = cvRound( (vv[i] - vmin) / bsize );
bin_counts[l]++;
}
/* compute the length of one bucket along the X axe */
jl = jmax - jmin;
if( jl <= 1 )
{
*numbers = NULL;
status = CV_OK;
goto M_END;
}
bsizej = (float) (jl / (nbins + 0.));
/* compute the number of points in each bucket along the X axe */
// for(i=0;i<i_point;i++)
// {
// l = cvRound((tmp_number[i].x - jmin)/bsizej);
// bin_countsj[l]++;
// }
left = right = -1;
/* find the leftmost and the rightmost buckets */
for( l = 0; l < nbins; l++ )
{
if( bin_counts[l] > low_count && left == -1 )
left = l;
else if( bin_counts[l] > low_count && left >= 0 )
right = l;
}
/* compute center point of the left hand */
if( left == -1 && right == -1 )
{
*numbers = NULL;
status = CV_OK;
goto M_END;
}
hand_left = vmin + left * bsize;
j_left = (int) (jmin + left * bsizej);
vcl = hand_left + hand_length2;
/* compute center point of the right hand */
hand_right = vmax - (nbins - right - 1) * bsize;
vcr = hand_right - hand_length2;
j_right = (int) (jmax - (nbins - right - 1) * bsizej);
j_left = abs( j_left - jc );
j_right = abs( j_right - jc );
if( j_left <= j_right )
{
hand_right = hand_left + hand_length;
vc = vcl;
}
else
{
hand_left = hand_right - hand_length;
vc = vcr;
}
icvScaleVector_32f( &line[0], sub, 3, vc );
icvAddVector_32f( &line[3], sub, (float *) center, 3 );
/* select hand's points and calculate mean value */
*numbers = cvCreateSeq( CV_SEQ_POINT_SET, sizeof( CvSeq ), sizeof( CvPoint ), storage );
assert( *numbers != 0 );
if( *numbers == NULL )
{
status = CV_OUTOFMEM_ERR;
goto M_END;
}
cvStartAppendToSeq( *numbers, &writer );
for( l = 0; l < i_point; l++ )
{
if( vv[l] >= hand_left && vv[l] <= hand_right )
{
CV_WRITE_SEQ_ELEM( tmp_number[l], writer );
}
}
cvEndWriteSeq( &writer );
M_END:
if( tmp_number != NULL )
cvFree( &tmp_number );
// if(bin_countsj != NULL) cvFree( &bin_countsj );
if( bin_counts != NULL )
cvFree( &bin_counts );
if( vv != NULL )
cvFree( &vv );
if( sub != NULL ) icvDeleteVector (sub);
if( cros != NULL ) icvDeleteVector (cros);
return status;
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvFindHandRegion
// Purpose: finds hand region in range image data
// Context:
// Parameters:
// points - pointer to the input point's set.
// count - the number of the input points.
// indexs - pointer to the input sequence of the point's indexes
// line - pointer to the 3D-line
// size - size of the hand in meters
// flag - hand direction's flag (0 - left, -1 - right,
// otherwise j-index of the initial image center)
// center - pointer to the output hand center
// storage - pointer to the memory storage
// numbers - pointer to the output sequence of the point's indexes inside
// hand region
//
// Notes:
//F*/
CV_IMPL void
cvFindHandRegion( CvPoint3D32f * points, int count,
CvSeq * indexs,
float *line, CvSize2D32f size, int flag,
CvPoint3D32f * center, CvMemStorage * storage, CvSeq ** numbers )
{
CV_FUNCNAME( "cvFindHandRegion" );
__BEGIN__;
if(flag == 0 || flag == -1)
{
IPPI_CALL( icvFindHandRegion( points, count, indexs, line, size, -flag,
center, storage, numbers ));
}
else
IPPI_CALL( icvFindHandRegionA( points, count, indexs, line, size, flag,
center, storage, numbers ));
__CLEANUP__;
__END__;
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvFindHandRegionA
// Purpose: finds hand region in range image data
// Context:
// Parameters:
// points - pointer to the input point's set.
// count - the number of the input points.
// indexs - pointer to the input sequence of the point's indexes
// line - pointer to the 3D-line
// size - size of the hand in meters
// jc - j-index of the initial image center
// center - pointer to the output hand center
// storage - pointer to the memory storage
// numbers - pointer to the output sequence of the point's indexes inside
// hand region
//
// Notes:
//F*/
CV_IMPL void
cvFindHandRegionA( CvPoint3D32f * points, int count,
CvSeq * indexs,
float *line, CvSize2D32f size, int jc,
CvPoint3D32f * center, CvMemStorage * storage, CvSeq ** numbers )
{
CV_FUNCNAME( "cvFindHandRegionA" );
__BEGIN__;
IPPI_CALL( icvFindHandRegionA( points, count, indexs, line, size, jc,
center, storage, numbers ));
__CLEANUP__;
__END__;
}

View File

@@ -0,0 +1,634 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
//*F///////////////////////////////////////////////////////////////////////////////////////
// Name: icvImgToObs_DCT_8u32f_C1R
// Purpose: The function takes as input an image and returns the sequnce of observations
// to be used with an embedded HMM; Each observation is top-left block of DCT
// coefficient matrix.
// Context:
// Parameters: img - pointer to the original image ROI
// imgStep - full row width of the image in bytes
// roi - width and height of ROI in pixels
// obs - pointer to resultant observation vectors
// dctSize - size of the block for which DCT is calculated
// obsSize - size of top-left block of DCT coeffs matrix, which is treated
// as observation. Each observation vector consists of
// obsSize.width * obsSize.height floats.
// The following conditions should be satisfied:
// 0 < objSize.width <= dctSize.width,
// 0 < objSize.height <= dctSize.height.
// delta - dctBlocks are overlapped and this parameter specifies horizontal
// and vertical shift.
// Returns:
// CV_NO_ERR or error code
// Notes:
// The algorithm is following:
// 1. First, number of observation vectors per row and per column are calculated:
//
// Nx = floor((roi.width - dctSize.width + delta.width)/delta.width);
// Ny = floor((roi.height - dctSize.height + delta.height)/delta.height);
//
// So, total number of observation vectors is Nx*Ny, and total size of
// array obs must be >= Nx*Ny*obsSize.width*obsSize.height*sizeof(float).
// 2. Observation vectors are calculated in the following loop
// ( actual implementation may be different ), where
// I[x1:x2,y1:y2] means block of pixels from source image with
// x1 <= x < x2, y1 <= y < y2,
// D[x1:x2,y1:y2] means sub matrix of DCT matrix D.
// O[x,y] means observation vector that corresponds to position
// (x*delta.width,y*delta.height) in the source image
// ( all indices are counted from 0 ).
//
// for( y = 0; y < Ny; y++ )
// {
// for( x = 0; x < Nx; x++ )
// {
// D = DCT(I[x*delta.width : x*delta.width + dctSize.width,
// y*delta.height : y*delta.height + dctSize.height]);
// O[x,y] = D[0:obsSize.width, 0:obsSize.height];
// }
// }
//F*/
/*comment out the following line to make DCT be calculated in floating-point arithmetics*/
//#define _CV_INT_DCT
/* for integer DCT only */
#define DCT_SCALE 15
#ifdef _CV_INT_DCT
typedef int work_t;
#define DESCALE CV_DESCALE
#define SCALE(x) CV_FLT_TO_FIX((x),DCT_SCALE)
#else
typedef float work_t;
#define DESCALE(x,n) (float)(x)
#define SCALE(x) (float)(x)
#endif
/* calculate dct transform matrix */
static void icvCalcDCTMatrix( work_t * cfs, int n );
#define MAX_DCT_SIZE 32
static CvStatus CV_STDCALL
icvImgToObs_DCT_8u32f_C1R( uchar * img, int imgStep, CvSize roi,
float *obs, CvSize dctSize,
CvSize obsSize, CvSize delta )
{
/* dct transform matrices: horizontal and vertical */
work_t tab_x[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
work_t tab_y[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
/* temporary buffers for dct */
work_t temp0[MAX_DCT_SIZE * 4];
work_t temp1[MAX_DCT_SIZE * 4];
work_t *buffer = 0;
work_t *buf_limit;
double s;
int y;
int Nx, Ny;
int n1 = dctSize.height, m1 = n1 / 2;
int n2 = dctSize.width, m2 = n2 / 2;
if( !img || !obs )
return CV_NULLPTR_ERR;
if( roi.width <= 0 || roi.height <= 0 )
return CV_BADSIZE_ERR;
if( delta.width <= 0 || delta.height <= 0 )
return CV_BADRANGE_ERR;
if( obsSize.width <= 0 || dctSize.width < obsSize.width ||
obsSize.height <= 0 || dctSize.height < obsSize.height )
return CV_BADRANGE_ERR;
if( dctSize.width > MAX_DCT_SIZE || dctSize.height > MAX_DCT_SIZE )
return CV_BADRANGE_ERR;
Nx = (roi.width - dctSize.width + delta.width) / delta.width;
Ny = (roi.height - dctSize.height + delta.height) / delta.height;
if( Nx <= 0 || Ny <= 0 )
return CV_BADRANGE_ERR;
buffer = (work_t *)cvAlloc( roi.width * obsSize.height * sizeof( buffer[0] ));
if( !buffer )
return CV_OUTOFMEM_ERR;
icvCalcDCTMatrix( tab_x, dctSize.width );
icvCalcDCTMatrix( tab_y, dctSize.height );
buf_limit = buffer + obsSize.height * roi.width;
for( y = 0; y < Ny; y++, img += delta.height * imgStep )
{
int x, i, j, k;
work_t k0 = 0;
/* do transfroms for each column. Calc only first obsSize.height DCT coefficients */
for( x = 0; x < roi.width; x++ )
{
float is = 0;
work_t *buf = buffer + x;
work_t *tab = tab_y + 2;
if( n1 & 1 )
{
is = img[x + m1 * imgStep];
k0 = ((work_t) is) * tab[-1];
}
/* first coefficient */
for( j = 0; j < m1; j++ )
{
float t0 = img[x + j * imgStep];
float t1 = img[x + (n1 - 1 - j) * imgStep];
float t2 = t0 + t1;
t0 -= t1;
temp0[j] = (work_t) t2;
is += t2;
temp1[j] = (work_t) t0;
}
buf[0] = DESCALE( is * tab[-2], PASS1_SHIFT );
if( (buf += roi.width) >= buf_limit )
continue;
/* other coefficients */
for( ;; )
{
s = 0;
for( k = 0; k < m1; k++ )
s += temp1[k] * tab[k];
buf[0] = DESCALE( s, PASS1_SHIFT );
if( (buf += roi.width) >= buf_limit )
break;
tab += m1;
s = 0;
if( n1 & 1 )
{
k0 = -k0;
s = k0;
}
for( k = 0; k < m1; k++ )
s += temp0[k] * tab[k];
buf[0] = DESCALE( s, PASS1_SHIFT );
tab += m1;
if( (buf += roi.width) >= buf_limit )
break;
}
}
k0 = 0;
/* do transforms for rows. */
for( x = 0; x + dctSize.width <= roi.width; x += delta.width )
{
for( i = 0; i < obsSize.height; i++ )
{
work_t *buf = buffer + x + roi.width * i;
work_t *tab = tab_x + 2;
float *obs_limit = obs + obsSize.width;
s = 0;
if( n2 & 1 )
{
s = buf[m2];
k0 = (work_t) (s * tab[-1]);
}
/* first coefficient */
for( j = 0; j < m2; j++ )
{
work_t t0 = buf[j];
work_t t1 = buf[n2 - 1 - j];
work_t t2 = t0 + t1;
t0 -= t1;
temp0[j] = (work_t) t2;
s += t2;
temp1[j] = (work_t) t0;
}
*obs++ = (float) DESCALE( s * tab[-2], PASS2_SHIFT );
if( obs == obs_limit )
continue;
/* other coefficients */
for( ;; )
{
s = 0;
for( k = 0; k < m2; k++ )
s += temp1[k] * tab[k];
obs[0] = (float) DESCALE( s, PASS2_SHIFT );
if( ++obs == obs_limit )
break;
tab += m2;
s = 0;
if( n2 & 1 )
{
k0 = -k0;
s = k0;
}
for( k = 0; k < m2; k++ )
s += temp0[k] * tab[k];
obs[0] = (float) DESCALE( s, PASS2_SHIFT );
tab += m2;
if( ++obs == obs_limit )
break;
}
}
}
}
cvFree( &buffer );
return CV_NO_ERR;
}
static CvStatus CV_STDCALL
icvImgToObs_DCT_32f_C1R( float * img, int imgStep, CvSize roi,
float *obs, CvSize dctSize,
CvSize obsSize, CvSize delta )
{
/* dct transform matrices: horizontal and vertical */
work_t tab_x[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
work_t tab_y[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
/* temporary buffers for dct */
work_t temp0[MAX_DCT_SIZE * 4];
work_t temp1[MAX_DCT_SIZE * 4];
work_t *buffer = 0;
work_t *buf_limit;
double s;
int y;
int Nx, Ny;
int n1 = dctSize.height, m1 = n1 / 2;
int n2 = dctSize.width, m2 = n2 / 2;
if( !img || !obs )
return CV_NULLPTR_ERR;
if( roi.width <= 0 || roi.height <= 0 )
return CV_BADSIZE_ERR;
if( delta.width <= 0 || delta.height <= 0 )
return CV_BADRANGE_ERR;
if( obsSize.width <= 0 || dctSize.width < obsSize.width ||
obsSize.height <= 0 || dctSize.height < obsSize.height )
return CV_BADRANGE_ERR;
if( dctSize.width > MAX_DCT_SIZE || dctSize.height > MAX_DCT_SIZE )
return CV_BADRANGE_ERR;
Nx = (roi.width - dctSize.width + delta.width) / delta.width;
Ny = (roi.height - dctSize.height + delta.height) / delta.height;
if( Nx <= 0 || Ny <= 0 )
return CV_BADRANGE_ERR;
buffer = (work_t *)cvAlloc( roi.width * obsSize.height * sizeof( buffer[0] ));
if( !buffer )
return CV_OUTOFMEM_ERR;
icvCalcDCTMatrix( tab_x, dctSize.width );
icvCalcDCTMatrix( tab_y, dctSize.height );
buf_limit = buffer + obsSize.height * roi.width;
imgStep /= sizeof(img[0]);
for( y = 0; y < Ny; y++, img += delta.height * imgStep )
{
int x, i, j, k;
work_t k0 = 0;
/* do transfroms for each column. Calc only first obsSize.height DCT coefficients */
for( x = 0; x < roi.width; x++ )
{
float is = 0;
work_t *buf = buffer + x;
work_t *tab = tab_y + 2;
if( n1 & 1 )
{
is = img[x + m1 * imgStep];
k0 = ((work_t) is) * tab[-1];
}
/* first coefficient */
for( j = 0; j < m1; j++ )
{
float t0 = img[x + j * imgStep];
float t1 = img[x + (n1 - 1 - j) * imgStep];
float t2 = t0 + t1;
t0 -= t1;
temp0[j] = (work_t) t2;
is += t2;
temp1[j] = (work_t) t0;
}
buf[0] = DESCALE( is * tab[-2], PASS1_SHIFT );
if( (buf += roi.width) >= buf_limit )
continue;
/* other coefficients */
for( ;; )
{
s = 0;
for( k = 0; k < m1; k++ )
s += temp1[k] * tab[k];
buf[0] = DESCALE( s, PASS1_SHIFT );
if( (buf += roi.width) >= buf_limit )
break;
tab += m1;
s = 0;
if( n1 & 1 )
{
k0 = -k0;
s = k0;
}
for( k = 0; k < m1; k++ )
s += temp0[k] * tab[k];
buf[0] = DESCALE( s, PASS1_SHIFT );
tab += m1;
if( (buf += roi.width) >= buf_limit )
break;
}
}
k0 = 0;
/* do transforms for rows. */
for( x = 0; x + dctSize.width <= roi.width; x += delta.width )
{
for( i = 0; i < obsSize.height; i++ )
{
work_t *buf = buffer + x + roi.width * i;
work_t *tab = tab_x + 2;
float *obs_limit = obs + obsSize.width;
s = 0;
if( n2 & 1 )
{
s = buf[m2];
k0 = (work_t) (s * tab[-1]);
}
/* first coefficient */
for( j = 0; j < m2; j++ )
{
work_t t0 = buf[j];
work_t t1 = buf[n2 - 1 - j];
work_t t2 = t0 + t1;
t0 -= t1;
temp0[j] = (work_t) t2;
s += t2;
temp1[j] = (work_t) t0;
}
*obs++ = (float) DESCALE( s * tab[-2], PASS2_SHIFT );
if( obs == obs_limit )
continue;
/* other coefficients */
for( ;; )
{
s = 0;
for( k = 0; k < m2; k++ )
s += temp1[k] * tab[k];
obs[0] = (float) DESCALE( s, PASS2_SHIFT );
if( ++obs == obs_limit )
break;
tab += m2;
s = 0;
if( n2 & 1 )
{
k0 = -k0;
s = k0;
}
for( k = 0; k < m2; k++ )
s += temp0[k] * tab[k];
obs[0] = (float) DESCALE( s, PASS2_SHIFT );
tab += m2;
if( ++obs == obs_limit )
break;
}
}
}
}
cvFree( &buffer );
return CV_NO_ERR;
}
static void
icvCalcDCTMatrix( work_t * cfs, int n )
{
static const double sqrt2 = 1.4142135623730950488016887242097;
static const double pi = 3.1415926535897932384626433832795;
static const double sincos[16 * 2] = {
1.00000000000000000, 0.00000000000000006,
0.70710678118654746, 0.70710678118654757,
0.49999999999999994, 0.86602540378443871,
0.38268343236508978, 0.92387953251128674,
0.30901699437494740, 0.95105651629515353,
0.25881904510252074, 0.96592582628906831,
0.22252093395631439, 0.97492791218182362,
0.19509032201612825, 0.98078528040323043,
0.17364817766693033, 0.98480775301220802,
0.15643446504023087, 0.98768834059513777,
0.14231483827328514, 0.98982144188093268,
0.13052619222005157, 0.99144486137381038,
0.12053668025532305, 0.99270887409805397,
0.11196447610330786, 0.99371220989324260,
0.10452846326765346, 0.99452189536827329,
0.09801714032956060, 0.99518472667219693,
};
#define ROTATE( c, s, dc, ds ) \
{ \
t = c*dc - s*ds; \
s = c*ds + s*dc; \
c = t; \
}
#define WRITE2( j, a, b ) \
{ \
cfs[j] = SCALE(a); \
cfs2[j] = SCALE(b); \
}
double t, scale = 1. / sqrt( (double)n );
int i, j, m = n / 2;
cfs[0] = SCALE( scale );
scale *= sqrt2;
cfs[1] = SCALE( scale );
cfs += 2 - m;
if( n > 1 )
{
double a0, b0;
double da0, db0;
work_t *cfs2 = cfs + m * n;
if( n <= 16 )
{
da0 = a0 = sincos[2 * n - 1];
db0 = b0 = sincos[2 * n - 2];
}
else
{
t = pi / (2 * n);
da0 = a0 = cos( t );
db0 = b0 = sin( t );
}
/* other rows */
for( i = 1; i <= m; i++ )
{
double a = a0 * scale;
double b = b0 * scale;
double da = a0 * a0 - b0 * b0;
double db = a0 * b0 + a0 * b0;
cfs += m;
cfs2 -= m;
for( j = 0; j < m; j += 2 )
{
WRITE2( j, a, b );
ROTATE( a, b, da, db );
if( j + 1 < m )
{
WRITE2( j + 1, a, -b );
ROTATE( a, b, da, db );
}
}
ROTATE( a0, b0, da0, db0 );
}
}
#undef ROTATE
#undef WRITE2
}
CV_IMPL void
cvImgToObs_DCT( const void* arr, float *obs, CvSize dctSize,
CvSize obsSize, CvSize delta )
{
CV_FUNCNAME( "cvImgToObs_DCT" );
__BEGIN__;
CvMat stub, *mat = (CvMat*)arr;
CV_CALL( mat = cvGetMat( arr, &stub ));
switch( CV_MAT_TYPE( mat->type ))
{
case CV_8UC1:
IPPI_CALL( icvImgToObs_DCT_8u32f_C1R( mat->data.ptr, mat->step,
cvGetMatSize(mat), obs,
dctSize, obsSize, delta ));
break;
case CV_32FC1:
IPPI_CALL( icvImgToObs_DCT_32f_C1R( mat->data.fl, mat->step,
cvGetMatSize(mat), obs,
dctSize, obsSize, delta ));
break;
default:
CV_ERROR( CV_StsUnsupportedFormat, "" );
}
__END__;
}
/* End of file. */

View File

@@ -0,0 +1,724 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/* Hybrid linear-contour model reconstruction */
#include "_cvaux.h"
#define CV_IMPL CV_EXTERN_C
const float LCM_CONST_ZERO = 1e-6f;
/****************************************************************************************\
* Auxiliary struct definitions *
\****************************************************************************************/
typedef struct CvLCM
{
CvGraph* Graph;
CvVoronoiDiagram2D* VoronoiDiagram;
CvMemStorage* ContourStorage;
CvMemStorage* EdgeStorage;
float maxWidth;
} CvLCM;
typedef struct CvLCMComplexNodeData
{
CvVoronoiNode2D edge_node;
CvPoint2D32f site_first_pt;
CvPoint2D32f site_last_pt;
CvVoronoiSite2D* site_first;
CvVoronoiSite2D* site_last;
CvVoronoiEdge2D* edge;
} CvLCMComplexNodeData;
typedef struct CvLCMData
{
CvVoronoiNode2D* pnode;
CvVoronoiSite2D* psite;
CvVoronoiEdge2D* pedge;
} CvLCMData;
/****************************************************************************************\
* Function definitions *
\****************************************************************************************/
#define _CV_READ_SEQ_ELEM( elem, reader, type ) \
{ \
assert( (reader).seq->elem_size == sizeof(*elem)); \
elem = (type)(reader).ptr; \
CV_NEXT_SEQ_ELEM( sizeof(*elem), reader ) \
}
#define _CV_IS_SITE_REFLEX( SITE ) ((SITE) ->node[0] == (SITE) ->node[1])
#define _CV_IS_EDGE_REFLEX( EDGE ) (( (EDGE)->site[0]->node[0] == (EDGE)->site[0]->node[0] ) || \
( (EDGE)->site[1]->node[0] == (EDGE)->site[1]->node[0] ) )
#define _CV_INITIALIZE_CVLCMDATA(STRUCT,SITE,EDGE,NODE)\
{ (STRUCT)->psite = SITE ; (STRUCT)->pedge = EDGE; (STRUCT)->pnode = NODE;}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvConstructLCM
// Purpose: Function constructs hybrid model
// Context:
// Parameters:
// LCM : in&out.
// Returns: 1, if hybrid model was succesfully constructed
// 0, if some error occures
//F*/
CV_IMPL
int _cvConstructLCM(CvLCM* LCM);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvConstructLCMComplexNode
// Purpose: Function constructs Complex Node (node, which consists of
// two points and more) of hybrid model
// Context:
// Parameters:
// pLCM : in&out.
// pLCMEdge: in, input edge of hybrid model
// pLCMInputData: in, input parameters
// Returns: pointer to constructed node
//F*/
CV_IMPL
CvLCMNode* _cvConstructLCMComplexNode(CvLCM* pLCM,
CvLCMEdge* pLCMEdge,
CvLCMData* pLCMInputData);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvConstructLCMSimpleNode
// Purpose: Function constructs Simple Node (node, which consists of
// one point) of hybrid model
// Context:
// Parameters:
// pLCM : in&out.
// pLCMEdge: in, input edge of hybrid model
// pLCMInputData: in, input parameters
// Returns: pointer to constructed node
//F*/
CV_IMPL
CvLCMNode* _cvConstructLCMSimpleNode(CvLCM* pLCM,
CvLCMEdge* pLCMEdge,
CvLCMData* pLCMInputData);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvConstructLCMSimpleNode
// Purpose: Function constructs Edge of hybrid model
// Context:
// Parameters:
// pLCM : in&out.
// pLCMInputData: in, input parameters
// Returns: pointer to constructed edge
//F*/
CV_IMPL
CvLCMEdge* _cvConstructLCMEdge(CvLCM* pLCM,
CvLCMData* pLCMInputData);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvTreatExeptionalCase
// Purpose: Function treats triangles and regular polygons
// Context:
// Parameters:
// pLCM : in, information about graph
// pLCMInputData: in, input parameters
// Returns: pointer to graph node
//F*/
CV_IMPL
CvLCMNode* _cvTreatExeptionalCase(CvLCM* pLCM,
CvLCMData* pLCMInputData);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvNodeMultyplicity
// Purpose: Function seeks all non-boundary edges incident to
// given node and correspondent incident sites
// Context:
// Parameters:
// pEdge : in, original edge
// pNode : in, given node
// LinkedEdges : out, matrix of incident edges
// LinkedSites : out, matrix of incident sites
// pSite: in, original site (pNode must be the begin point of pEdge
// for this pSite, this property hold out far all edges)
// Returns: number of incident edges (must be less than 10)
//F*/
CV_IMPL
int _cvNodeMultyplicity(CvVoronoiSite2D* pSite,
CvVoronoiEdge2D* pEdge,
CvVoronoiNode2D* pNode,
CvVoronoiEdge2D** LinkedEdges,
CvVoronoiSite2D** LinkedSites);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvCreateLCMNode
// Purpose: Function create graph node
// Context:
// Parameters:
// pLCM : in, information about graph
// Returns: pointer to graph node
//F*/
CV_IMPL
CvLCMNode* _cvCreateLCMNode(CvLCM* pLCM);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvCreateLCMEdge
// Purpose: Function create graph edge
// Context:
// Parameters:
// pLCM : in, information about graph
// Returns: pointer to graph edge
//F*/
CV_IMPL
CvLCMEdge* _cvCreateLCMEdge(CvLCM* pLCM);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvCreateLCMNode
// Purpose: Function establishs the connection between node and ege
// Context:
// Parameters:
// LCMNode : in, graph node
// LCMEdge : in, graph edge
// LCMEdge_prev : in&out, previous edge, connected with given node
// index: in,
// i : =0, if node is initial for edge
// =1, if node is terminal for edge
// Returns:
//F*/
CV_IMPL
void _cvAttachLCMEdgeToLCMNode(CvLCMNode* LCMNode,
CvLCMEdge* LCMEdge,
CvLCMEdge* &LCMEdge_prev,
int index,
int i);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvProjectionPointToSegment
// Purpose: Function computes the ortogonal projection of PointO to
// to segment[PointA, PointB]
// Context:
// Parameters:
// PointO, PointA,PointB: in, given points
// PrPoint : out, projection
// dist : distance from PointO to PrPoint
// Returns:
//F*/
CV_IMPL
void _cvProjectionPointToSegment(CvPoint2D32f* PointO,
CvPoint2D32f* PointA,
CvPoint2D32f* PointB,
CvPoint2D32f* PrPoint,
float* dist);
/*F///////////////////////////////////////////////////////////////////////////////////////
// Author: Andrey Sobolev
// Name: _cvPrepareData
// Purpose: Function fills up the struct CvLCMComplexNodeData
// Context:
// Parameters:
// pLCMData : in
// pLCMCCNData : out
// Returns:
//F*/
CV_IMPL
void _cvPrepareData(CvLCMComplexNodeData* pLCMCCNData,
CvLCMData* pLCMData);
/****************************************************************************************\
* Function realization *
\****************************************************************************************/
CV_IMPL CvGraph* cvLinearContorModelFromVoronoiDiagram(CvVoronoiDiagram2D* VoronoiDiagram,
float maxWidth)
{
CvMemStorage* LCMstorage;
CvSet* SiteSet;
CvLCM LCM = {NULL, VoronoiDiagram,NULL,NULL,maxWidth};
CV_FUNCNAME( "cvLinearContorModelFromVoronoiDiagram" );
__BEGIN__;
if( !VoronoiDiagram )
CV_ERROR( CV_StsBadArg,"Voronoi Diagram is not defined" );
if( maxWidth < 0 )
CV_ERROR( CV_StsBadArg,"Treshold parameter must be non negative" );
for(SiteSet = VoronoiDiagram->sites;
SiteSet != NULL;
SiteSet = (CvSet*)SiteSet->h_next)
{
if(SiteSet->v_next)
CV_ERROR( CV_StsBadArg,"Can't operate with multiconnected domains" );
if(SiteSet->total > 70000)
CV_ERROR( CV_StsBadArg,"Can't operate with large domains" );
}
LCMstorage = cvCreateMemStorage(0);
LCM.EdgeStorage = cvCreateChildMemStorage(LCMstorage);
LCM.ContourStorage = cvCreateChildMemStorage(LCMstorage);
LCM.Graph = cvCreateGraph(CV_SEQ_KIND_GRAPH|CV_GRAPH_FLAG_ORIENTED,
sizeof(CvGraph),
sizeof(CvLCMNode),
sizeof(CvLCMEdge),
LCMstorage);
if(!_cvConstructLCM(&LCM))
cvReleaseLinearContorModelStorage(&LCM.Graph);
__END__;
return LCM.Graph;
}//end of cvLinearContorModelFromVoronoiDiagram
CV_IMPL int cvReleaseLinearContorModelStorage(CvGraph** Graph)
{
CvSeq* LCMNodeSeq, *LCMEdgeSeq;
CvLCMNode* pLCMNode;
CvLCMEdge* pLCMEdge;
/*CV_FUNCNAME( "cvReleaseLinearContorModelStorage" );*/
__BEGIN__;
if(!Graph || !(*Graph))
return 0;
LCMNodeSeq = (CvSeq*)(*Graph);
LCMEdgeSeq = (CvSeq*)(*Graph)->edges;
if(LCMNodeSeq->total > 0)
{
pLCMNode = (CvLCMNode*)cvGetSeqElem(LCMNodeSeq,0);
if(pLCMNode->contour->storage)
cvReleaseMemStorage(&pLCMNode->contour->storage);
}
if(LCMEdgeSeq->total > 0)
{
pLCMEdge = (CvLCMEdge*)cvGetSeqElem(LCMEdgeSeq,0);
if(pLCMEdge->chain->storage)
cvReleaseMemStorage(&pLCMEdge->chain->storage);
}
if((*Graph)->storage)
cvReleaseMemStorage(&(*Graph)->storage);
*Graph = NULL;
__END__;
return 1;
}//end of cvReleaseLinearContorModelStorage
int _cvConstructLCM(CvLCM* LCM)
{
CvVoronoiSite2D* pSite = 0;
CvVoronoiEdge2D* pEdge = 0, *pEdge1;
CvVoronoiNode2D* pNode, *pNode1;
CvVoronoiEdge2D* LinkedEdges[10];
CvVoronoiSite2D* LinkedSites[10];
CvSeqReader reader;
CvLCMData LCMdata;
int i;
for(CvSet* SiteSet = LCM->VoronoiDiagram->sites;
SiteSet != NULL;
SiteSet = (CvSet*)SiteSet->h_next)
{
cvStartReadSeq((CvSeq*)SiteSet, &reader);
for(i = 0; i < SiteSet->total; i++)
{
_CV_READ_SEQ_ELEM(pSite,reader,CvVoronoiSite2D*);
if(pSite->node[0] == pSite->node[1])
continue;
pEdge = CV_LAST_VORONOIEDGE2D(pSite);
pNode = CV_VORONOIEDGE2D_BEGINNODE(pEdge,pSite);
if(pNode->radius > LCM->maxWidth)
goto PREPARECOMPLEXNODE;
pEdge1 = CV_PREV_VORONOIEDGE2D(pEdge,pSite);
pNode1 = CV_VORONOIEDGE2D_BEGINNODE(pEdge1,pSite);
if(pNode1->radius > LCM->maxWidth)
goto PREPARECOMPLEXNODE;
if(pNode1->radius == 0)
continue;
if(_cvNodeMultyplicity(pSite, pEdge,pNode,LinkedEdges,LinkedSites) == 1)
goto PREPARESIMPLENODE;
}
// treate triangle or regular polygon
_CV_INITIALIZE_CVLCMDATA(&LCMdata,pSite,pEdge,CV_VORONOIEDGE2D_ENDNODE(pEdge,pSite));
if(!_cvTreatExeptionalCase(LCM,&LCMdata))
return 0;
continue;
PREPARECOMPLEXNODE:
_CV_INITIALIZE_CVLCMDATA(&LCMdata,pSite,pEdge,CV_VORONOIEDGE2D_ENDNODE(pEdge,pSite));
if(!_cvConstructLCMComplexNode(LCM,NULL,&LCMdata))
return 0;
continue;
PREPARESIMPLENODE:
_CV_INITIALIZE_CVLCMDATA(&LCMdata,pSite,pEdge,CV_VORONOIEDGE2D_ENDNODE(pEdge,pSite));
if(!_cvConstructLCMSimpleNode(LCM,NULL,&LCMdata))
return 0;
continue;
}
return 1;
}//end of _cvConstructLCM
CvLCMNode* _cvConstructLCMComplexNode(CvLCM* pLCM,
CvLCMEdge* pLCMEdge,
CvLCMData* pLCMInputData)
{
CvLCMNode* pLCMNode;
CvLCMEdge* pLCMEdge_prev = NULL;
CvSeqWriter writer;
CvVoronoiSite2D* pSite, *pSite_first, *pSite_last;
CvVoronoiEdge2D* pEdge, *pEdge_stop;
CvVoronoiNode2D* pNode0, *pNode1;
CvLCMData LCMOutputData;
CvLCMComplexNodeData LCMCCNData;
int index = 0;
_cvPrepareData(&LCMCCNData,pLCMInputData);
pLCMNode = _cvCreateLCMNode(pLCM);
_cvAttachLCMEdgeToLCMNode(pLCMNode,pLCMEdge,pLCMEdge_prev,1,1);
cvStartAppendToSeq((CvSeq*)pLCMNode->contour,&writer);
CV_WRITE_SEQ_ELEM(LCMCCNData.site_last_pt, writer);
index++;
if(pLCMEdge)
{
CV_WRITE_SEQ_ELEM(LCMCCNData.edge_node.pt, writer );
CV_WRITE_SEQ_ELEM(LCMCCNData.site_first_pt, writer );
index+=2;
}
pSite_first = LCMCCNData.site_first;
pSite_last = LCMCCNData.site_last;
pEdge = LCMCCNData.edge;
for(pSite = pSite_first;
pSite != pSite_last;
pSite = CV_NEXT_VORONOISITE2D(pSite),
pEdge = CV_PREV_VORONOIEDGE2D(CV_LAST_VORONOIEDGE2D(pSite),pSite))
{
pEdge_stop = CV_FIRST_VORONOIEDGE2D(pSite);
for(;pEdge && pEdge != pEdge_stop;
pEdge = CV_PREV_VORONOIEDGE2D(pEdge,pSite))
{
pNode0 = CV_VORONOIEDGE2D_BEGINNODE(pEdge,pSite);
pNode1 = CV_VORONOIEDGE2D_ENDNODE(pEdge,pSite);
if(pNode0->radius <= pLCM->maxWidth && pNode1->radius <= pLCM->maxWidth)
{
_CV_INITIALIZE_CVLCMDATA(&LCMOutputData,pSite,pEdge,pNode1);
_cvPrepareData(&LCMCCNData,&LCMOutputData);
CV_WRITE_SEQ_ELEM(LCMCCNData.site_first_pt, writer);
CV_WRITE_SEQ_ELEM(LCMCCNData.edge_node.pt, writer );
index+=2;
pLCMEdge = _cvConstructLCMEdge(pLCM,&LCMOutputData);
_cvAttachLCMEdgeToLCMNode(pLCMNode,pLCMEdge,pLCMEdge_prev,index - 1,0);
CV_WRITE_SEQ_ELEM(LCMCCNData.site_last_pt, writer);
index++;
pSite = CV_TWIN_VORONOISITE2D(pSite,pEdge);
pEdge_stop = CV_FIRST_VORONOIEDGE2D(pSite);
if(pSite == pSite_last)
break;
}
}
if(pSite == pSite_last)
break;
CV_WRITE_SEQ_ELEM(pSite->node[1]->pt, writer);
index++;
}
if(pLCMEdge_prev)
pLCMEdge_prev->next[(pLCMEdge_prev == (CvLCMEdge*)pLCMNode->first)] = pLCMNode->first;
cvEndWriteSeq(&writer);
return pLCMNode;
}//end of _cvConstructLCMComplexNode
CvLCMNode* _cvConstructLCMSimpleNode(CvLCM* pLCM,
CvLCMEdge* pLCMEdge,
CvLCMData* pLCMInputData)
{
CvVoronoiEdge2D* pEdge = pLCMInputData->pedge;
CvVoronoiSite2D* pSite = pLCMInputData->psite;
CvVoronoiNode2D* pNode = CV_VORONOIEDGE2D_BEGINNODE(pEdge,pSite);
CvVoronoiEdge2D* LinkedEdges[10];
CvVoronoiSite2D* LinkedSites[10];
int multyplicity = _cvNodeMultyplicity(pSite,pEdge,pNode,LinkedEdges,LinkedSites);
if(multyplicity == 2)
{
pLCMInputData->pedge = LinkedEdges[1];
pLCMInputData->psite = CV_TWIN_VORONOISITE2D(LinkedSites[1],LinkedEdges[1]);
return NULL;
}
CvLCMEdge* pLCMEdge_prev = NULL;
CvLCMNode* pLCMNode;
CvLCMData LCMOutputData;
pLCMNode = _cvCreateLCMNode(pLCM);
cvSeqPush((CvSeq*)pLCMNode->contour,&pNode->pt);
_cvAttachLCMEdgeToLCMNode(pLCMNode,pLCMEdge,pLCMEdge_prev,0,1);
for(int i = (int)(pLCMEdge != NULL);i < multyplicity; i++)
{
pEdge = LinkedEdges[i];
pSite = LinkedSites[i];
_CV_INITIALIZE_CVLCMDATA(&LCMOutputData,CV_TWIN_VORONOISITE2D(pSite,pEdge),pEdge,pNode);
pLCMEdge = _cvConstructLCMEdge(pLCM,&LCMOutputData);
_cvAttachLCMEdgeToLCMNode(pLCMNode,pLCMEdge,pLCMEdge_prev,0,0);
}
pLCMEdge_prev->next[(pLCMEdge_prev == (CvLCMEdge*)pLCMNode->first)] = pLCMNode->first;
return pLCMNode;
}//end of _cvConstructLCMSimpleNode
CvLCMEdge* _cvConstructLCMEdge(CvLCM* pLCM,
CvLCMData* pLCMInputData)
{
CvVoronoiEdge2D* pEdge = pLCMInputData->pedge;
CvVoronoiSite2D* pSite = pLCMInputData->psite;
float width = 0;
CvLCMData LCMData;
CvVoronoiNode2D* pNode0,*pNode1;
CvLCMEdge* pLCMEdge = _cvCreateLCMEdge(pLCM);
CvSeqWriter writer;
cvStartAppendToSeq(pLCMEdge->chain,&writer );
pNode0 = pNode1 = pLCMInputData->pnode;
CV_WRITE_SEQ_ELEM(pNode0->pt, writer);
width += pNode0->radius;
for(int counter = 0;
counter < pLCM->VoronoiDiagram->edges->total;
counter++)
{
pNode1 = CV_VORONOIEDGE2D_BEGINNODE(pEdge,pSite);
if(pNode1->radius >= pLCM->maxWidth)
goto CREATECOMPLEXNODE;
CV_WRITE_SEQ_ELEM(pNode1->pt,writer);
width += pNode1->radius;
_CV_INITIALIZE_CVLCMDATA(&LCMData,pSite,pEdge,pNode1);
if(_cvConstructLCMSimpleNode(pLCM,pLCMEdge,&LCMData))
goto LCMEDGEEXIT;
pEdge = LCMData.pedge; pSite = LCMData.psite;
pNode0 = pNode1;
}
return NULL;
CREATECOMPLEXNODE:
_CV_INITIALIZE_CVLCMDATA(&LCMData,pSite,pEdge,pNode0);
CV_WRITE_SEQ_ELEM(LCMData.pnode->pt,writer);
width += LCMData.pnode->radius;
_cvConstructLCMComplexNode(pLCM,pLCMEdge,&LCMData);
LCMEDGEEXIT:
cvEndWriteSeq(&writer);
pLCMEdge->width = width/pLCMEdge->chain->total;
return pLCMEdge;
}//end of _cvConstructLCMEdge
CvLCMNode* _cvTreatExeptionalCase(CvLCM* pLCM,
CvLCMData* pLCMInputData)
{
CvVoronoiEdge2D* pEdge = pLCMInputData->pedge;
CvVoronoiSite2D* pSite = pLCMInputData->psite;
CvVoronoiNode2D* pNode = CV_VORONOIEDGE2D_BEGINNODE(pEdge,pSite);
CvLCMNode* pLCMNode = _cvCreateLCMNode(pLCM);
cvSeqPush((CvSeq*)pLCMNode->contour,&pNode->pt);
return pLCMNode;
}//end of _cvConstructLCMEdge
CV_INLINE
CvLCMNode* _cvCreateLCMNode(CvLCM* pLCM)
{
CvLCMNode* pLCMNode;
cvSetAdd((CvSet*)pLCM->Graph, NULL, (CvSetElem**)&pLCMNode );
pLCMNode->contour = (CvContour*)cvCreateSeq(0, sizeof(CvContour),
sizeof(CvPoint2D32f),pLCM->ContourStorage);
pLCMNode->first = NULL;
return pLCMNode;
}//end of _cvCreateLCMNode
CV_INLINE
CvLCMEdge* _cvCreateLCMEdge(CvLCM* pLCM)
{
CvLCMEdge* pLCMEdge;
cvSetAdd( (CvSet*)(pLCM->Graph->edges), 0, (CvSetElem**)&pLCMEdge );
pLCMEdge->chain = cvCreateSeq(0, sizeof(CvSeq),sizeof(CvPoint2D32f),pLCM->EdgeStorage);
pLCMEdge->next[0] = pLCMEdge->next[1] = NULL;
pLCMEdge->vtx[0] = pLCMEdge->vtx[1] = NULL;
pLCMEdge->index1 = pLCMEdge->index2 = -1;
return pLCMEdge;
}//end of _cvCreateLCMEdge
CV_INLINE
void _cvAttachLCMEdgeToLCMNode(CvLCMNode* LCMNode,
CvLCMEdge* LCMEdge,
CvLCMEdge* &LCMEdge_prev,
int index,
int i)
{
if(!LCMEdge)
return;
if(i==0)
LCMEdge->index1 = index;
else
LCMEdge->index2 = index;
LCMEdge->vtx[i] = (CvGraphVtx*)LCMNode;
if(!LCMEdge_prev)
LCMNode->first = (CvGraphEdge*)LCMEdge;
else
// LCMEdge_prev->next[(LCMEdge_prev == (CvLCMEdge*)LCMNode->first)] = (CvGraphEdge*)LCMEdge;
LCMEdge_prev->next[(LCMEdge_prev->vtx[0] != (CvGraphVtx*)LCMNode)] = (CvGraphEdge*)LCMEdge;
LCMEdge->next[i] = LCMNode->first;
LCMEdge_prev = LCMEdge;
}//end of _cvAttachLCMEdgeToLCMNode
int _cvNodeMultyplicity(CvVoronoiSite2D* pSite,
CvVoronoiEdge2D* pEdge,
CvVoronoiNode2D* pNode,
CvVoronoiEdge2D** LinkedEdges,
CvVoronoiSite2D** LinkedSites)
{
if(!pNode->radius)
return -1;
assert(pNode == CV_VORONOIEDGE2D_BEGINNODE(pEdge,pSite));
int multyplicity = 0;
CvVoronoiEdge2D* pEdge_cur = pEdge;
do
{
if(pEdge_cur->node[0]->radius && pEdge_cur->node[1]->radius)
{
LinkedEdges[multyplicity] = pEdge_cur;
LinkedSites[multyplicity] = pSite;
multyplicity++;
}
pEdge_cur = CV_PREV_VORONOIEDGE2D(pEdge_cur,pSite);
pSite = CV_TWIN_VORONOISITE2D(pSite,pEdge_cur);
}while(pEdge_cur != pEdge);
return multyplicity;
}//end of _cvNodeMultyplicity
CV_INLINE
void _cvPrepareData(CvLCMComplexNodeData* pLCMCCNData,
CvLCMData* pLCMData)
{
pLCMCCNData->site_first = pLCMData->psite;
pLCMCCNData->site_last = CV_TWIN_VORONOISITE2D(pLCMData->psite,pLCMData->pedge);
if(pLCMData->pedge == CV_LAST_VORONOIEDGE2D(pLCMData->psite))
{
pLCMCCNData->edge = CV_PREV_VORONOIEDGE2D(pLCMData->pedge,pLCMData->psite);
pLCMCCNData->edge_node = *pLCMData->pnode;
pLCMCCNData->site_first_pt = pLCMData->psite->node[0]->pt;
pLCMCCNData->site_last_pt = pLCMData->psite->node[0]->pt;
}
else
{
pLCMCCNData->edge = pLCMData->pedge;
pLCMCCNData->edge_node = *pLCMData->pnode;
_cvProjectionPointToSegment(&pLCMCCNData->edge_node.pt,
&pLCMCCNData->site_first->node[0]->pt,
&pLCMCCNData->site_first->node[1]->pt,
&pLCMCCNData->site_first_pt,
NULL);
_cvProjectionPointToSegment(&pLCMCCNData->edge_node.pt,
&pLCMCCNData->site_last->node[0]->pt,
&pLCMCCNData->site_last->node[1]->pt,
&pLCMCCNData->site_last_pt,
NULL);
}
}//end of _cvPrepareData
void _cvProjectionPointToSegment(CvPoint2D32f* PointO,
CvPoint2D32f* PointA,
CvPoint2D32f* PointB,
CvPoint2D32f* PrPoint,
float* dist)
{
float scal_AO_AB, scal_AB_AB;
CvPoint2D32f VectorAB = {PointB->x - PointA->x, PointB->y - PointA->y};
scal_AB_AB = VectorAB.x*VectorAB.x + VectorAB.y*VectorAB.y;
if(scal_AB_AB < LCM_CONST_ZERO)
{
*PrPoint = *PointA;
if(dist)
*dist = (float)sqrt( (double)(PointO->x -PointA->x)*(PointO->x -PointA->x) + (PointO->y - PointA->y)*(PointO->y - PointA->y));
return;
}
CvPoint2D32f VectorAO = {PointO->x - PointA->x, PointO->y - PointA->y};
scal_AO_AB = VectorAO.x*VectorAB.x + VectorAO.y*VectorAB.y;
if(dist)
{
float vector_AO_AB = (float)fabs(VectorAO.x*VectorAB.y - VectorAO.y*VectorAB.x);
*dist = (float)(vector_AO_AB/sqrt((double)scal_AB_AB));
}
float alfa = scal_AO_AB/scal_AB_AB;
PrPoint->x = PointO->x - VectorAO.x + alfa*VectorAB.x;
PrPoint->y = PointO->y - VectorAO.y + alfa*VectorAB.y;
return;
}//end of _cvProjectionPointToSegment

View File

@@ -0,0 +1,320 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#include "cvtypes.h"
#include <float.h>
#include <limits.h>
#include "cv.h"
/* Valery Mosyagin */
//#define TRACKLEVMAR
typedef void (*pointer_LMJac)( const CvMat* src, CvMat* dst );
typedef void (*pointer_LMFunc)( const CvMat* src, CvMat* dst );
/* Optimization using Levenberg-Marquardt */
void cvLevenbergMarquardtOptimization(pointer_LMJac JacobianFunction,
pointer_LMFunc function,
/*pointer_Err error_function,*/
CvMat *X0,CvMat *observRes,CvMat *resultX,
int maxIter,double epsilon)
{
/* This is not sparce method */
/* Make optimization using */
/* func - function to compute */
/* uses function to compute jacobian */
/* Allocate memory */
CvMat *vectX = 0;
CvMat *vectNewX = 0;
CvMat *resFunc = 0;
CvMat *resNewFunc = 0;
CvMat *error = 0;
CvMat *errorNew = 0;
CvMat *Jac = 0;
CvMat *delta = 0;
CvMat *matrJtJ = 0;
CvMat *matrJtJN = 0;
CvMat *matrJt = 0;
CvMat *vectB = 0;
CV_FUNCNAME( "cvLevenbegrMarquardtOptimization" );
__BEGIN__;
if( JacobianFunction == 0 || function == 0 || X0 == 0 || observRes == 0 || resultX == 0 )
{
CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
}
if( !CV_IS_MAT(X0) || !CV_IS_MAT(observRes) || !CV_IS_MAT(resultX) )
{
CV_ERROR( CV_StsUnsupportedFormat, "Some of input parameters must be a matrices" );
}
int numVal;
int numFunc;
double valError;
double valNewError;
numVal = X0->rows;
numFunc = observRes->rows;
/* test input data */
if( X0->cols != 1 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Number of colomn of vector X0 must be 1" );
}
if( observRes->cols != 1 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Number of colomn of vector observed rusult must be 1" );
}
if( resultX->cols != 1 || resultX->rows != numVal )
{
CV_ERROR( CV_StsUnmatchedSizes, "Size of result vector X must be equals to X0" );
}
if( maxIter <= 0 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Number of maximum iteration must be > 0" );
}
if( epsilon < 0 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Epsilon must be >= 0" );
}
/* copy x0 to current value of x */
CV_CALL( vectX = cvCreateMat(numVal, 1, CV_64F) );
CV_CALL( vectNewX = cvCreateMat(numVal, 1, CV_64F) );
CV_CALL( resFunc = cvCreateMat(numFunc,1, CV_64F) );
CV_CALL( resNewFunc = cvCreateMat(numFunc,1, CV_64F) );
CV_CALL( error = cvCreateMat(numFunc,1, CV_64F) );
CV_CALL( errorNew = cvCreateMat(numFunc,1, CV_64F) );
CV_CALL( Jac = cvCreateMat(numFunc,numVal, CV_64F) );
CV_CALL( delta = cvCreateMat(numVal, 1, CV_64F) );
CV_CALL( matrJtJ = cvCreateMat(numVal, numVal, CV_64F) );
CV_CALL( matrJtJN = cvCreateMat(numVal, numVal, CV_64F) );
CV_CALL( matrJt = cvCreateMat(numVal, numFunc,CV_64F) );
CV_CALL( vectB = cvCreateMat(numVal, 1, CV_64F) );
cvCopy(X0,vectX);
/* ========== Main optimization loop ============ */
double change;
int currIter;
double alpha;
change = 1;
currIter = 0;
alpha = 0.001;
do {
/* Compute value of function */
function(vectX,resFunc);
/* Print result of function to file */
/* Compute error */
cvSub(observRes,resFunc,error);
//valError = error_function(observRes,resFunc);
/* Need to use new version of computing error (norm) */
valError = cvNorm(observRes,resFunc);
/* Compute Jacobian for given point vectX */
JacobianFunction(vectX,Jac);
/* Define optimal delta for J'*J*delta=J'*error */
/* compute J'J */
cvMulTransposed(Jac,matrJtJ,1);
cvCopy(matrJtJ,matrJtJN);
/* compute J'*error */
cvTranspose(Jac,matrJt);
cvmMul(matrJt,error,vectB);
/* Solve normal equation for given alpha and Jacobian */
do
{
/* Increase diagonal elements by alpha */
for( int i = 0; i < numVal; i++ )
{
double val;
val = cvmGet(matrJtJ,i,i);
cvmSet(matrJtJN,i,i,(1+alpha)*val);
}
/* Solve system to define delta */
cvSolve(matrJtJN,vectB,delta,CV_SVD);
/* We know delta and we can define new value of vector X */
cvAdd(vectX,delta,vectNewX);
/* Compute result of function for new vector X */
function(vectNewX,resNewFunc);
cvSub(observRes,resNewFunc,errorNew);
valNewError = cvNorm(observRes,resNewFunc);
currIter++;
if( valNewError < valError )
{/* accept new value */
valError = valNewError;
/* Compute relative change of required parameter vectorX. change = norm(curr-prev) / norm(curr) ) */
change = cvNorm(vectX, vectNewX, CV_RELATIVE_L2);
alpha /= 10;
cvCopy(vectNewX,vectX);
break;
}
else
{
alpha *= 10;
}
} while ( currIter < maxIter );
/* new value of X and alpha were accepted */
} while ( change > epsilon && currIter < maxIter );
/* result was computed */
cvCopy(vectX,resultX);
__END__;
cvReleaseMat(&vectX);
cvReleaseMat(&vectNewX);
cvReleaseMat(&resFunc);
cvReleaseMat(&resNewFunc);
cvReleaseMat(&error);
cvReleaseMat(&errorNew);
cvReleaseMat(&Jac);
cvReleaseMat(&delta);
cvReleaseMat(&matrJtJ);
cvReleaseMat(&matrJtJN);
cvReleaseMat(&matrJt);
cvReleaseMat(&vectB);
return;
}
/*------------------------------------------------------------------------------*/
#if 0
//tests
void Jac_Func2(CvMat *vectX,CvMat *Jac)
{
double x = cvmGet(vectX,0,0);
double y = cvmGet(vectX,1,0);
cvmSet(Jac,0,0,2*(x-2));
cvmSet(Jac,0,1,2*(y+3));
cvmSet(Jac,1,0,1);
cvmSet(Jac,1,1,1);
return;
}
void Res_Func2(CvMat *vectX,CvMat *res)
{
double x = cvmGet(vectX,0,0);
double y = cvmGet(vectX,1,0);
cvmSet(res,0,0,(x-2)*(x-2)+(y+3)*(y+3));
cvmSet(res,1,0,x+y);
return;
}
double Err_Func2(CvMat *obs,CvMat *res)
{
CvMat *tmp;
tmp = cvCreateMat(obs->rows,1,CV_64F);
cvSub(obs,res,tmp);
double e;
e = cvNorm(tmp);
return e;
}
void TestOptimX2Y2()
{
CvMat vectX0;
double vectX0_dat[2];
vectX0 = cvMat(2,1,CV_64F,vectX0_dat);
vectX0_dat[0] = 5;
vectX0_dat[1] = -7;
CvMat observRes;
double observRes_dat[2];
observRes = cvMat(2,1,CV_64F,observRes_dat);
observRes_dat[0] = 0;
observRes_dat[1] = -1;
observRes_dat[0] = 0;
observRes_dat[1] = -1.2;
CvMat optimX;
double optimX_dat[2];
optimX = cvMat(2,1,CV_64F,optimX_dat);
LevenbegrMarquardtOptimization( Jac_Func2, Res_Func2, Err_Func2,
&vectX0,&observRes,&optimX,100,0.000001);
return;
}
#endif

View File

@@ -0,0 +1,497 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#include "cvtypes.h"
#include <float.h>
#include <limits.h>
#include "cv.h"
/* Valery Mosyagin */
typedef void (*pointer_LMJac)( const CvMat* src, CvMat* dst );
typedef void (*pointer_LMFunc)( const CvMat* src, CvMat* dst );
void cvLevenbergMarquardtOptimization(pointer_LMJac JacobianFunction,
pointer_LMFunc function,
/*pointer_Err error_function,*/
CvMat *X0,CvMat *observRes,CvMat *resultX,
int maxIter,double epsilon);
void icvReconstructPointsFor3View( CvMat* projMatr1,CvMat* projMatr2,CvMat* projMatr3,
CvMat* projPoints1,CvMat* projPoints2,CvMat* projPoints3,
CvMat* points4D);
/* Jacobian computation for trifocal case */
void icvJacobianFunction_ProjTrifocal(const CvMat *vectX,CvMat *Jacobian)
{
CV_FUNCNAME( "icvJacobianFunction_ProjTrifocal" );
__BEGIN__;
/* Test data for errors */
if( vectX == 0 || Jacobian == 0 )
{
CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
}
if( !CV_IS_MAT(vectX) || !CV_IS_MAT(Jacobian) )
{
CV_ERROR( CV_StsUnsupportedFormat, "Input parameters must be a matrices" );
}
int numPoints;
numPoints = (vectX->rows - 36)/4;
if( numPoints < 1 )//!!! Need to correct this minimal number of points
{
CV_ERROR( CV_StsUnmatchedSizes, "number of points must be more than 0" );
}
if( Jacobian->rows == numPoints*6 || Jacobian->cols != 36+numPoints*4 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Size of Jacobian is not correct it must be 6*numPoints x (36+numPoints*4)" );
}
/* Computed Jacobian in a given point */
/* This is for function with 3 projection matrices */
/* vector X consists of projection matrices and points3D */
/* each 3D points has X,Y,Z,W */
/* each projection matrices has 3x4 coeffs */
/* For N points 4D we have Jacobian 2N x (12*3+4N) */
/* Will store derivates as */
/* Fill Jacobian matrix */
int currProjPoint;
int currMatr;
cvZero(Jacobian);
for( currMatr = 0; currMatr < 3; currMatr++ )
{
double p[12];
for( int i=0;i<12;i++ )
{
p[i] = cvmGet(vectX,currMatr*12+i,0);
}
int currVal = 36;
for( currProjPoint = 0; currProjPoint < numPoints; currProjPoint++ )
{
/* Compute */
double X[4];
X[0] = cvmGet(vectX,currVal++,0);
X[1] = cvmGet(vectX,currVal++,0);
X[2] = cvmGet(vectX,currVal++,0);
X[3] = cvmGet(vectX,currVal++,0);
double piX[3];
piX[0] = X[0]*p[0] + X[1]*p[1] + X[2]*p[2] + X[3]*p[3];
piX[1] = X[0]*p[4] + X[1]*p[5] + X[2]*p[6] + X[3]*p[7];
piX[2] = X[0]*p[8] + X[1]*p[9] + X[2]*p[10] + X[3]*p[11];
int i,j;
/* fill derivate by point */
double tmp3 = 1/(piX[2]*piX[2]);
double tmp1 = -piX[0]*tmp3;
double tmp2 = -piX[1]*tmp3;
for( j = 0; j < 2; j++ )//for x and y
{
for( i = 0; i < 4; i++ )// for X,Y,Z,W
{
cvmSet( Jacobian,
currMatr*numPoints*2+currProjPoint*2+j, 36+currProjPoint*4+i,
(p[j*4+i]*piX[2]-p[8+i]*piX[j]) * tmp3 );
}
}
/* fill derivate by projection matrix */
for( i = 0; i < 4; i++ )
{
/* derivate for x */
cvmSet(Jacobian,currMatr*numPoints*2+currProjPoint*2,currMatr*12+i,X[i]/piX[2]);//x' p1i
cvmSet(Jacobian,currMatr*numPoints*2+currProjPoint*2,currMatr*12+8+i,X[i]*tmp1);//x' p3i
/* derivate for y */
cvmSet(Jacobian,currMatr*numPoints*2+currProjPoint*2+1,currMatr*12+4+i,X[i]/piX[2]);//y' p2i
cvmSet(Jacobian,currMatr*numPoints*2+currProjPoint*2+1,currMatr*12+8+i,X[i]*tmp2);//y' p3i
}
}
}
__END__;
return;
}
void icvFunc_ProjTrifocal(const CvMat *vectX, CvMat *resFunc)
{
/* Computes function in a given point */
/* Computers project points using 3 projection matrices and points 3D */
/* vector X consists of projection matrices and points3D */
/* each projection matrices has 3x4 coeffs */
/* each 3D points has X,Y,Z,W(?) */
/* result of function is projection of N 3D points using 3 projection matrices */
/* projected points store as (projection by matrix P1),(projection by matrix P2),(projection by matrix P3) */
/* each projection is x1,y1,x2,y2,x3,y3,x4,y4 */
/* Compute projection of points */
/* Fill projection matrices */
CV_FUNCNAME( "icvFunc_ProjTrifocal" );
__BEGIN__;
/* Test data for errors */
if( vectX == 0 || resFunc == 0 )
{
CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
}
if( !CV_IS_MAT(vectX) || !CV_IS_MAT(resFunc) )
{
CV_ERROR( CV_StsUnsupportedFormat, "Input parameters must be a matrices" );
}
int numPoints;
numPoints = (vectX->rows - 36)/4;
if( numPoints < 1 )//!!! Need to correct this minimal number of points
{
CV_ERROR( CV_StsUnmatchedSizes, "number of points must be more than 0" );
}
if( resFunc->rows == 2*numPoints*3 || resFunc->cols != 1 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Size of resFunc is not correct it must be 2*numPoints*3 x 1");
}
CvMat projMatrs[3];
double projMatrs_dat[36];
projMatrs[0] = cvMat(3,4,CV_64F,projMatrs_dat);
projMatrs[1] = cvMat(3,4,CV_64F,projMatrs_dat+12);
projMatrs[2] = cvMat(3,4,CV_64F,projMatrs_dat+24);
CvMat point3D;
double point3D_dat[3];
point3D = cvMat(3,1,CV_64F,point3D_dat);
int currMatr;
int currV;
int i,j;
currV=0;
for( currMatr = 0; currMatr < 3; currMatr++ )
{
for( i = 0; i < 3; i++ )
{
for( j = 0;j < 4; j++ )
{
double val = cvmGet(vectX,currV,0);
cvmSet(&projMatrs[currMatr],i,j,val);
currV++;
}
}
}
/* Project points */
int currPoint;
CvMat point4D;
double point4D_dat[4];
point4D = cvMat(4,1,CV_64F,point4D_dat);
for( currPoint = 0; currPoint < numPoints; currPoint++ )
{
/* get curr point */
point4D_dat[0] = cvmGet(vectX,currV++,0);
point4D_dat[1] = cvmGet(vectX,currV++,0);
point4D_dat[2] = cvmGet(vectX,currV++,0);
point4D_dat[3] = cvmGet(vectX,currV++,0);
for( currMatr = 0; currMatr < 3; currMatr++ )
{
/* Compute projection for current point */
cvmMul(&projMatrs[currMatr],&point4D,&point3D);
double z = point3D_dat[2];
cvmSet(resFunc,currMatr*numPoints*2 + currPoint*2, 0,point3D_dat[0]/z);
cvmSet(resFunc,currMatr*numPoints*2 + currPoint*2+1,0,point3D_dat[1]/z);
}
}
__END__;
return;
}
/*----------------------------------------------------------------------------------------*/
void icvOptimizeProjectionTrifocal(CvMat **projMatrs,CvMat **projPoints,
CvMat **resultProjMatrs, CvMat *resultPoints4D)
{
CvMat *optimX = 0;
CvMat *points4D = 0;
CvMat *vectorX0 = 0;
CvMat *observRes = 0;
//CvMat *error = 0;
CV_FUNCNAME( "icvOptimizeProjectionTrifocal" );
__BEGIN__;
/* Test data for errors */
if( projMatrs == 0 || projPoints == 0 || resultProjMatrs == 0 || resultPoints4D == 0)
{
CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
}
if( !CV_IS_MAT(resultPoints4D) )
{
CV_ERROR( CV_StsUnsupportedFormat, "resultPoints4D must be a matrix" );
}
int numPoints;
numPoints = resultPoints4D->cols;
if( numPoints < 1 )
{
CV_ERROR( CV_StsOutOfRange, "Number points of resultPoints4D must be more than 0" );
}
if( resultPoints4D->rows != 4 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Number of coordinates of points4D must be 4" );
}
int i;
for( i = 0; i < 3; i++ )
{
if( projMatrs[i] == 0 )
{
CV_ERROR( CV_StsNullPtr, "Some of projMatrs is a NULL pointer" );
}
if( projPoints[i] == 0 )
{
CV_ERROR( CV_StsNullPtr, "Some of projPoints is a NULL pointer" );
}
if( resultProjMatrs[i] == 0 )
{
CV_ERROR( CV_StsNullPtr, "Some of resultProjMatrs is a NULL pointer" );
}
/* ----------- test for matrix ------------- */
if( !CV_IS_MAT(projMatrs[i]) )
{
CV_ERROR( CV_StsUnsupportedFormat, "Each of projMatrs must be a matrix" );
}
if( !CV_IS_MAT(projPoints[i]) )
{
CV_ERROR( CV_StsUnsupportedFormat, "Each of projPoints must be a matrix" );
}
if( !CV_IS_MAT(resultProjMatrs[i]) )
{
CV_ERROR( CV_StsUnsupportedFormat, "Each of resultProjMatrs must be a matrix" );
}
/* ------------- Test sizes --------------- */
if( projMatrs[i]->rows != 3 || projMatrs[i]->cols != 4 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Size of projMatr must be 3x4" );
}
if( projPoints[i]->rows != 2 || projPoints[i]->cols != numPoints )
{
CV_ERROR( CV_StsUnmatchedSizes, "Size of resultProjMatrs must be 3x4" );
}
if( resultProjMatrs[i]->rows != 3 || resultProjMatrs[i]->cols != 4 )
{
CV_ERROR( CV_StsUnmatchedSizes, "Size of resultProjMatrs must be 3x4" );
}
}
/* Allocate memory for points 4D */
CV_CALL( points4D = cvCreateMat(4,numPoints,CV_64F) );
CV_CALL( vectorX0 = cvCreateMat(36 + numPoints*4,1,CV_64F) );
CV_CALL( observRes = cvCreateMat(2*numPoints*3,1,CV_64F) );
CV_CALL( optimX = cvCreateMat(36+numPoints*4,1,CV_64F) );
//CV_CALL( error = cvCreateMat(numPoints*2*3,1,CV_64F) );
/* Reconstruct points 4D using projected points and projection matrices */
icvReconstructPointsFor3View( projMatrs[0],projMatrs[1],projMatrs[2],
projPoints[0],projPoints[1],projPoints[2],
points4D);
/* Fill observed points on images */
/* result of function is projection of N 3D points using 3 projection matrices */
/* projected points store as (projection by matrix P1),(projection by matrix P2),(projection by matrix P3) */
/* each projection is x1,y1,x2,y2,x3,y3,x4,y4 */
int currMatr;
for( currMatr = 0; currMatr < 3; currMatr++ )
{
for( i = 0; i < numPoints; i++ )
{
cvmSet(observRes,currMatr*numPoints*2+i*2 ,0,cvmGet(projPoints[currMatr],0,i) );/* x */
cvmSet(observRes,currMatr*numPoints*2+i*2+1,0,cvmGet(projPoints[currMatr],1,i) );/* y */
}
}
/* Fill with projection matrices */
for( currMatr = 0; currMatr < 3; currMatr++ )
{
int i;
for( i = 0; i < 12; i++ )
{
cvmSet(vectorX0,currMatr*12+i,0,cvmGet(projMatrs[currMatr],i/4,i%4));
}
}
/* Fill with 4D points */
int currPoint;
for( currPoint = 0; currPoint < numPoints; currPoint++ )
{
cvmSet(vectorX0,36 + currPoint*4 + 0,0,cvmGet(points4D,0,currPoint));
cvmSet(vectorX0,36 + currPoint*4 + 1,0,cvmGet(points4D,1,currPoint));
cvmSet(vectorX0,36 + currPoint*4 + 2,0,cvmGet(points4D,2,currPoint));
cvmSet(vectorX0,36 + currPoint*4 + 3,0,cvmGet(points4D,3,currPoint));
}
/* Allocate memory for result */
cvLevenbergMarquardtOptimization( icvJacobianFunction_ProjTrifocal, icvFunc_ProjTrifocal,
vectorX0,observRes,optimX,100,1e-6);
/* Copy results */
for( currMatr = 0; currMatr < 3; currMatr++ )
{
/* Copy projection matrices */
for(int i=0;i<12;i++)
{
cvmSet(resultProjMatrs[currMatr],i/4,i%4,cvmGet(optimX,currMatr*12+i,0));
}
}
/* Copy 4D points */
for( currPoint = 0; currPoint < numPoints; currPoint++ )
{
cvmSet(resultPoints4D,0,currPoint,cvmGet(optimX,36 + currPoint*4,0));
cvmSet(resultPoints4D,1,currPoint,cvmGet(optimX,36 + currPoint*4+1,0));
cvmSet(resultPoints4D,2,currPoint,cvmGet(optimX,36 + currPoint*4+2,0));
cvmSet(resultPoints4D,3,currPoint,cvmGet(optimX,36 + currPoint*4+3,0));
}
__END__;
/* Free allocated memory */
cvReleaseMat(&optimX);
cvReleaseMat(&points4D);
cvReleaseMat(&vectorX0);
cvReleaseMat(&observRes);
return;
}
/*------------------------------------------------------------------------------*/
/* Create good points using status information */
void icvCreateGoodPoints(CvMat *points,CvMat **goodPoints, CvMat *status)
{
*goodPoints = 0;
CV_FUNCNAME( "icvCreateGoodPoints" );
__BEGIN__;
int numPoints;
numPoints = points->cols;
if( numPoints < 1 )
{
CV_ERROR( CV_StsOutOfRange, "Number of points must be more than 0" );
}
int numCoord;
numCoord = points->rows;
if( numCoord < 1 )
{
CV_ERROR( CV_StsOutOfRange, "Number of points coordinates must be more than 0" );
}
/* Define number of good points */
int goodNum;
int i,j;
goodNum = 0;
for( i = 0; i < numPoints; i++)
{
if( cvmGet(status,0,i) > 0 )
goodNum++;
}
/* Allocate memory for good points */
CV_CALL( *goodPoints = cvCreateMat(numCoord,goodNum,CV_64F) );
for( i = 0; i < numCoord; i++ )
{
int currPoint = 0;
for( j = 0; j < numPoints; j++)
{
if( cvmGet(status,0,j) > 0 )
{
cvmSet(*goodPoints,i,currPoint,cvmGet(points,i,j));
currPoint++;
}
}
}
__END__;
return;
}

View File

@@ -0,0 +1,483 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#if 0
CvStatus
icvFetchLine8uC3R( uchar * src, int src_step,
uchar * dst, int *dst_num, CvSize src_size, CvPoint start, CvPoint end )
{
int i;
int dx = end.x - start.x, dy = end.y - start.y;
int err;
if( !src || !dst || (src_size.width | src_size.height) < 0 ||
src_step < src_size.width * 3 ||
(unsigned) start.x >= (unsigned) src_size.width ||
(unsigned) start.y >= (unsigned) src_size.height ||
(unsigned) end.x >= (unsigned) src_size.width ||
(unsigned) end.y >= (unsigned) src_size.height )
return CV_BADFACTOR_ERR;
if( dx < 0 )
{
dx = -dx;
dy = -dy;
start.x = end.x;
start.y = end.y;
}
src += start.y * src_step + start.x * 3;
i = dy >> 31;
dy = (dy ^ i) - i;
src_step = (src_step ^ i) - i;
if( dx > dy )
{
if( dst_num )
{
if( *dst_num <= dx )
return CV_BADSIZE_ERR;
*dst_num = dx + 1;
}
err = dx;
dx += dx;
dy += dy;
for( i = dx; i >= 0; i -= 2, dst += 3 )
{
int mask = (err -= dy) < 0 ? -1 : 0;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
err += dx & mask;
src += (src_step & mask) + 3;
}
}
else
{
if( dst_num )
{
if( *dst_num <= dy )
return CV_BADSIZE_ERR;
*dst_num = dy + 1;
}
err = dy;
dx += dx;
dy += dy;
for( i = dy; i >= 0; i -= 2, dst += 3 )
{
int mask = (err -= dx) < 0 ? -1 : 0;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
err += dy & mask;
src += src_step + (mask & 3);
}
}
return CV_NO_ERR;
}
CvStatus
icvDrawLine8uC3R( uchar * src, int src_num,
uchar * dst, int dst_step, CvSize dst_size, CvPoint start, CvPoint end )
{
int i;
int dx = end.x - start.x, dy = end.y - start.y;
int err;
if( !src || !dst || (dst_size.width | dst_size.height) < 0 ||
dst_step < dst_size.width * 3 ||
(unsigned) start.x >= (unsigned) dst_size.width ||
(unsigned) start.y >= (unsigned) dst_size.height ||
(unsigned) end.x >= (unsigned) dst_size.width ||
(unsigned) end.y >= (unsigned) dst_size.height )
return CV_BADFACTOR_ERR;
if( dx < 0 )
{
dx = -dx;
dy = -dy;
start.x = end.x;
start.y = end.y;
}
dst += start.y * dst_step + start.x * 3;
i = dy >> 31;
dy = (dy ^ i) - i;
dst_step = (dst_step ^ i) - i;
if( dx > dy )
{
if( (unsigned) (src_num - 1) < (unsigned) dx )
return CV_BADSIZE_ERR;
err = dx;
dx += dx;
dy += dy;
for( i = dx; i >= 0; i -= 2, src += 3 )
{
int mask = (err -= dy) < 0 ? -1 : 0;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
err += dx & mask;
dst += (dst_step & mask) + 3;
}
}
else
{
if( (unsigned) (src_num - 1) < (unsigned) dy )
return CV_BADSIZE_ERR;
err = dy;
dx += dx;
dy += dy;
for( i = dy; i >= 0; i -= 2, src += 3 )
{
int mask = (err -= dx) < 0 ? -1 : 0;
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
err += dy & mask;
dst += dst_step + (mask & 3);
}
}
return CV_NO_ERR;
}
#endif
/*======================================================================================*/
static CvStatus
icvPreWarpImage8uC3R( int numLines, /* number of scanlines */
uchar * src, /* source image */
int src_step, /* line step */
uchar * dst, /* dest buffers */
int *dst_nums, /* lens of buffer */
CvSize src_size, /* image size in pixels */
int *scanlines ) /* scanlines array */
{
int k;
CvPoint start;
CvPoint end;
int curr;
int curr_dst;
CvMat mat;
curr = 0;
curr_dst = 0;
cvInitMatHeader( &mat, src_size.height, src_size.width, CV_8UC3, src, src_step );
for( k = 0; k < numLines; k++ )
{
start.x = scanlines[curr++];
start.y = scanlines[curr++];
end.x = scanlines[curr++];
end.y = scanlines[curr++];
#ifdef _DEBUG
{
CvLineIterator iterator;
assert( cvInitLineIterator( &mat, start, end, &iterator, 8 ) == dst_nums[k] );
}
#endif
cvSampleLine( &mat, start, end, dst + curr_dst, 8 );
curr_dst += dst_nums[k] * 3;
}
return CV_NO_ERR;
}
/*======================================================================================*/
static CvStatus
icvPostWarpImage8uC3R( int numLines, /* number of scanlines */
uchar * src, /* source buffers */
int *src_nums, /* lens of buffers */
uchar * dst, /* dest image */
int dst_step, /* dest image step */
CvSize dst_size, /* dest image size */
int *scanlines ) /* scanline */
{
int i, k;
CvPoint start;
CvPoint end;
int curr;
int src_num;
int curr_src;
CvMat mat;
CvLineIterator iterator;
curr = 0;
curr_src = 0;
cvInitMatHeader( &mat, dst_size.height, dst_size.width, CV_8UC3, dst, dst_step );
for( k = 0; k < numLines; k++ )
{
start.x = scanlines[curr++];
start.y = scanlines[curr++];
end.x = scanlines[curr++];
end.y = scanlines[curr++];
src_num = src_nums[k];
if( cvInitLineIterator( &mat, start, end, &iterator, 8 ) != src_num )
{
assert(0);
return CV_NOTDEFINED_ERR;
}
for( i = 0; i < src_num; i++ )
{
memcpy( iterator.ptr, src + curr_src, 3 );
CV_NEXT_LINE_POINT( iterator );
curr_src += 3;
}
#if 0
err = icvDrawLine8uC3R( src + curr_src, /* sourse buffer */
src_num, /* len of buffer */
dst, /* dest image */
dst_step, /* dest image step */
dst_size, /* dest image size */
start, /* start point */
end ); /* end point */
curr_src += src_num * 3;
#endif
}
return CV_NO_ERR;
}
/*======================================================================================*/
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: icvDeleteMoire8uC3R
// Purpose:
// Function deletes moire - replaces black uncovered pixels with their neighboors.
// Context:
// Parameters:
// img - image data
// img_step - distance between lines in bytes
// img_size - width and height of the image in pixels
// Returns:
// CV_NO_ERR if all Ok or error code
// Notes:
//F*/
static CvStatus
icvDeleteMoire8u( uchar * img, int img_step, CvSize img_size, int cn )
{
int x, y;
uchar *src = img, *dst = img + img_step;
if( !img || img_size.width <= 0 || img_size.height <= 0 || img_step < img_size.width * 3 )
return CV_BADFACTOR_ERR;
img_size.width *= cn;
for( y = 1; y < img_size.height; y++, src = dst, dst += img_step )
{
switch( cn )
{
case 1:
for( x = 0; x < img_size.width; x++ )
{
if( dst[x] == 0 )
dst[x] = src[x];
}
break;
case 3:
for( x = 0; x < img_size.width; x += 3 )
{
if( dst[x] == 0 && dst[x + 1] == 0 && dst[x + 2] == 0 )
{
dst[x] = src[x];
dst[x + 1] = src[x + 1];
dst[x + 2] = src[x + 2];
}
}
break;
default:
assert(0);
break;
}
}
return CV_NO_ERR;
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvDeleteMoire
// Purpose: The functions delete moire on the image after ViewMorphing
// Context:
// Parameters: img - image on which will delete moire
//
// Notes:
//F*/
CV_IMPL void
cvDeleteMoire( IplImage * img )
{
uchar *img_data = 0;
int img_step = 0;
CvSize img_size;
CV_FUNCNAME( "cvDeleteMoire" );
__BEGIN__;
cvGetImageRawData( img, &img_data, &img_step, &img_size );
if( img->nChannels != 1 && img->nChannels != 3 )
CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
if( img->depth != IPL_DEPTH_8U )
CV_ERROR( CV_BadDepth, "Channel depth of source image must be 8." );
CV_CALL( icvDeleteMoire8u( img_data, img_step, img_size, img->nChannels ));
__CLEANUP__;
__END__;
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvPreWarpImage
// Purpose: The functions warp image for next stage of ViewMorphing
// Context:
// Parameters: img - initial image (in the beginning)
//
// Notes:
//F*/
CV_IMPL void
cvPreWarpImage( int numLines, /* number of scanlines */
IplImage * img, /* Source Image */
uchar * dst, /* dest buffers */
int *dst_nums, /* lens of buffer */
int *scanlines /* scanlines array */ )
{
uchar *img_data = 0;
int img_step = 0;
CvSize img_size;
CV_FUNCNAME( "cvPreWarpImage" );
__BEGIN__;
cvGetImageRawData( img, &img_data, &img_step, &img_size );
if( img->nChannels != 3 )
CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
if( img->depth != IPL_DEPTH_8U )
CV_ERROR( CV_BadDepth, "Channel depth of image must be 8." );
CV_CALL( icvPreWarpImage8uC3R( numLines, /* number of scanlines */
img_data, /* source image */
img_step, /* line step */
dst, /* dest buffers */
dst_nums, /* lens of buffer */
img_size, /* image size in pixels */
scanlines /* scanlines array */ ));
__CLEANUP__;
__END__;
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvPostWarpImage
// Purpose: The functions postwarp the image after morphing
// Context:
// Parameters: img - initial image (in the beginning)
//
// Notes:
//F*/
CV_IMPL void
cvPostWarpImage( int numLines, /* number of scanlines */
uchar * src, /* source buffers */
int *src_nums, /* lens of buffers */
IplImage * img, /* dest image */
int *scanlines /* scanline */ )
{
uchar *img_data = 0;
int img_step = 0;
CvSize img_size;
CV_FUNCNAME( "cvPostWarpImage" );
__BEGIN__;
cvGetImageRawData( img, &img_data, &img_step, &img_size );
if( img->nChannels != 3 )
CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
if( img->depth != IPL_DEPTH_8U )
CV_ERROR( CV_BadDepth, "Channel depth of image must be 8." );
CV_CALL( icvPostWarpImage8uC3R( numLines, /* number of scanlines */
src, /* source buffers */
src_nums, /* lens of buffers */
img_data, /* dest image */
img_step, /* dest image step */
img_size, /* dest image size */
scanlines /* scanline */ ));
__CLEANUP__;
__END__;
}
/* End of file */

View File

@@ -0,0 +1,879 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
// temporarily remove it from build
#if 0 && ((_MSC_VER>=1200) || defined __BORLANDC__)
double CvMAT::get( const uchar* ptr, int type, int coi )
{
double t = 0;
assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
switch( CV_MAT_DEPTH(type) )
{
case CV_8U:
t = ((uchar*)ptr)[coi];
break;
case CV_8S:
t = ((char*)ptr)[coi];
break;
case CV_16S:
t = ((short*)ptr)[coi];
break;
case CV_32S:
t = ((int*)ptr)[coi];
break;
case CV_32F:
t = ((float*)ptr)[coi];
break;
case CV_64F:
t = ((double*)ptr)[coi];
break;
}
return t;
}
void CvMAT::set( uchar* ptr, int type, int coi, double d )
{
int i;
assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
switch( CV_MAT_DEPTH(type))
{
case CV_8U:
i = cvRound(d);
((uchar*)ptr)[coi] = CV_CAST_8U(i);
break;
case CV_8S:
i = cvRound(d);
((char*)ptr)[coi] = CV_CAST_8S(i);
break;
case CV_16S:
i = cvRound(d);
((short*)ptr)[coi] = CV_CAST_16S(i);
break;
case CV_32S:
i = cvRound(d);
((int*)ptr)[coi] = CV_CAST_32S(i);
break;
case CV_32F:
((float*)ptr)[coi] = (float)d;
break;
case CV_64F:
((double*)ptr)[coi] = d;
break;
}
}
void CvMAT::set( uchar* ptr, int type, int coi, int i )
{
assert( (unsigned)coi < (unsigned)CV_MAT_CN(type) );
switch( CV_MAT_DEPTH(type))
{
case CV_8U:
((uchar*)ptr)[coi] = CV_CAST_8U(i);
break;
case CV_8S:
((char*)ptr)[coi] = CV_CAST_8S(i);
break;
case CV_16S:
((short*)ptr)[coi] = CV_CAST_16S(i);
break;
case CV_32S:
((int*)ptr)[coi] = i;
break;
case CV_32F:
((float*)ptr)[coi] = (float)i;
break;
case CV_64F:
((double*)ptr)[coi] = (double)i;
break;
}
}
void CvMAT::set( uchar* ptr, int type, double d )
{
int i, cn = CV_MAT_CN(type);
switch( CV_MAT_DEPTH(type))
{
case CV_8U:
i = cvRound(d);
((uchar*)ptr)[0] = CV_CAST_8U(i);
i = cn;
while( --i ) ((uchar*)ptr)[i] = 0;
break;
case CV_8S:
i = cvRound(d);
((char*)ptr)[0] = CV_CAST_8S(i);
i = cn;
while( --i ) ((char*)ptr)[i] = 0;
break;
case CV_16S:
i = cvRound(d);
((short*)ptr)[0] = CV_CAST_16S(i);
i = cn;
while( --i ) ((short*)ptr)[i] = 0;
break;
case CV_32S:
i = cvRound(d);
((int*)ptr)[0] = i;
i = cn;
while( --i ) ((int*)ptr)[i] = 0;
break;
case CV_32F:
((float*)ptr)[0] = (float)d;
i = cn;
while( --i ) ((float*)ptr)[i] = 0;
break;
case CV_64F:
((double*)ptr)[0] = d;
i = cn;
while( --i ) ((double*)ptr)[i] = 0;
break;
}
}
void CvMAT::set( uchar* ptr, int type, int i )
{
int cn = CV_MAT_CN(type);
switch( CV_MAT_DEPTH(type))
{
case CV_8U:
((uchar*)ptr)[0] = CV_CAST_8U(i);
i = cn;
while( --i ) ((uchar*)ptr)[i] = 0;
break;
case CV_8S:
((char*)ptr)[0] = CV_CAST_8S(i);
i = cn;
while( --i ) ((char*)ptr)[i] = 0;
break;
case CV_16S:
((short*)ptr)[0] = CV_CAST_16S(i);
i = cn;
while( --i ) ((short*)ptr)[i] = 0;
break;
case CV_32S:
((int*)ptr)[0] = i;
i = cn;
while( --i ) ((int*)ptr)[i] = 0;
break;
case CV_32F:
((float*)ptr)[0] = (float)i;
i = cn;
while( --i ) ((float*)ptr)[i] = 0;
break;
case CV_64F:
((double*)ptr)[0] = (double)i;
i = cn;
while( --i ) ((double*)ptr)[i] = 0;
break;
}
}
CvMAT::CvMAT( const _CvMAT_T_& mat_t )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = mat_t;
}
CvMAT::CvMAT( const _CvMAT_ADD_& mat_add )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = mat_add;
}
CvMAT::CvMAT( const _CvMAT_ADD_EX_& mat_add )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = mat_add;
}
CvMAT::CvMAT( const _CvMAT_SCALE_& scale_mat )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = scale_mat;
}
CvMAT::CvMAT( const _CvMAT_SCALE_SHIFT_& scale_shift_mat )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = scale_shift_mat;
}
CvMAT::CvMAT( const _CvMAT_MUL_& mmul )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = mmul;
}
CvMAT::CvMAT( const _CvMAT_MUL_ADD_& mmuladd )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = mmuladd;
}
CvMAT::CvMAT( const _CvMAT_INV_& inv_mat )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = inv_mat;
}
CvMAT::CvMAT( const _CvMAT_NOT_& not_mat )
{
type = 0;
data.ptr = 0;
refcount = 0;
*this = not_mat;
}
CvMAT::CvMAT( const _CvMAT_UN_LOGIC_& mat_logic )
{
type = 0;
data.ptr = 0;
refcount = 0;
*this = mat_logic;
}
CvMAT::CvMAT( const _CvMAT_LOGIC_& mat_logic )
{
type = 0;
data.ptr = 0;
refcount = 0;
*this = mat_logic;
}
CvMAT::CvMAT( const _CvMAT_COPY_& mat_copy )
{
CvMAT* src = (CvMAT*)mat_copy.a;
create( src->height, src->width, src->type );
cvCopy( src, this );
}
CvMAT::CvMAT( const _CvMAT_CVT_& mat_cvt )
{
type = 0;
data.ptr = 0;
refcount = 0;
*this = mat_cvt;
}
CvMAT::CvMAT( const _CvMAT_DOT_OP_& dot_op )
{
data.ptr = 0;
type = 0;
refcount = 0;
*this = dot_op;
}
CvMAT::CvMAT( const _CvMAT_SOLVE_& solve_mat )
{
type = 0;
data.ptr = 0;
refcount = 0;
*this = solve_mat;
}
CvMAT::CvMAT( const _CvMAT_CMP_& cmp_mat )
{
type = 0;
data.ptr = 0;
refcount = 0;
*this = cmp_mat;
}
/****************************************************************************************\
* CvMAT::operator = *
\****************************************************************************************/
CvMAT& CvMAT::operator = ( const _CvMAT_T_& mat_t )
{
CvMAT* src = (CvMAT*)&mat_t.a;
if( !data.ptr )
{
create( src->width, src->height, src->type );
}
cvTranspose( src, this );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_ADD_& mat_add )
{
CvMAT* a = mat_add.a;
CvMAT* b = mat_add.b;
if( !data.ptr )
{
create( a->height, a->width, a->type );
}
if( mat_add.beta == 1 )
{
cvAdd( a, b, this );
return *this;
}
if( mat_add.beta == -1 )
{
cvSub( a, b, this );
return *this;
}
if( CV_MAT_DEPTH(a->type) >= CV_32F && CV_MAT_CN(a->type) <= 2 )
cvScaleAdd( b, cvScalar(mat_add.beta), a, this );
else
cvAddWeighted( a, 1, b, mat_add.beta, 0, this );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_ADD_EX_& mat_add )
{
CvMAT* a = mat_add.a;
CvMAT* b = mat_add.b;
if( !data.ptr )
{
create( a->height, a->width, a->type );
}
cvAddWeighted( a, mat_add.alpha, b, mat_add.beta, mat_add.gamma, this );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_SCALE_& scale_mat )
{
CvMAT* src = scale_mat.a;
if( !data.ptr )
{
create( src->height, src->width, src->type );
}
cvConvertScale( src, this, scale_mat.alpha, 0 );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_SCALE_SHIFT_& scale_shift_mat )
{
CvMAT* src = scale_shift_mat.a;
if( !data.ptr )
{
create( src->height, src->width, src->type );
}
cvConvertScale( src, this, scale_shift_mat.alpha, scale_shift_mat.beta );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_MUL_& mmul )
{
CvMAT* a = mmul.a;
CvMAT* b = mmul.b;
int t_a = mmul.t_ab & 1;
int t_b = (mmul.t_ab & 2) != 0;
int m = (&(a->rows))[t_a];
int n = (&(b->rows))[t_b ^ 1];
/* this(m x n) = (a^o1(t))(m x l) * (b^o2(t))(l x n) */
if( !data.ptr )
{
create( m, n, a->type );
}
if( mmul.alpha == 1 )
{
if( mmul.t_ab == 0 )
{
cvMatMulAdd( a, b, 0, this );
return *this;
}
if( a->data.ptr == b->data.ptr && mmul.t_ab < 3 &&
a->rows == b->rows && a->cols == b->cols &&
a->data.ptr != data.ptr )
{
cvMulTransposed( a, this, mmul.t_ab & 1 );
return *this;
}
}
cvGEMM( a, b, mmul.alpha, 0, 0, this, mmul.t_ab );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_MUL_ADD_& mmuladd )
{
CvMAT* a = mmuladd.a;
CvMAT* b = mmuladd.b;
CvMAT* c = mmuladd.c;
int t_a = mmuladd.t_abc & 1;
int t_b = (mmuladd.t_abc & 2) != 0;
int m = (&(a->rows))[t_a];
int n = (&(b->rows))[t_b ^ 1];
/* this(m x n) = (a^o1(t))(m x l) * (b^o2(t))(l x n) */
if( !data.ptr )
{
create( m, n, a->type );
}
if( mmuladd.t_abc == 0 && mmuladd.alpha == 1 && mmuladd.beta == 1 )
cvMatMulAdd( a, b, c, this );
else
cvGEMM( a, b, mmuladd.alpha, c, mmuladd.beta, this, mmuladd.t_abc );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_INV_& inv_mat )
{
CvMAT* src = (CvMAT*)&inv_mat.a;
if( !data.ptr )
{
create( src->height, src->width, src->type );
}
if( inv_mat.method == 0 )
cvInvert( src, this );
else
cvPseudoInv( src, this );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_NOT_& not_mat )
{
CvMAT* src = not_mat.a;
if( !data.ptr )
{
create( src->height, src->width, src->type );
}
cvNot( src, this );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_LOGIC_& mat_logic )
{
CvMAT* a = mat_logic.a;
CvMAT* b = mat_logic.b;
int flags = mat_logic.flags;
_CvMAT_LOGIC_::Op op = mat_logic.op;
if( !data.ptr )
{
create( a->height, a->width, a->type );
}
switch( op )
{
case _CvMAT_LOGIC_::AND:
if( flags == 0 )
cvAnd( a, b, this );
else if( flags == 3 )
{
cvOr( a, b, this );
cvNot( this, this );
}
else if( flags == 1 )
{
if( data.ptr == b->data.ptr )
{
cvNot( b, this );
cvOr( this, a, this );
cvNot( this, this );
}
else
{
cvNot( a, this );
cvAnd( this, b, this );
}
}
else
{
if( data.ptr == a->data.ptr )
{
cvNot( a, this );
cvOr( this, b, this );
cvNot( this, this );
}
else
{
cvNot( b, this );
cvAnd( this, a, this );
}
}
break;
case _CvMAT_LOGIC_::OR:
if( flags == 0 )
cvOr( a, b, this );
else if( flags == 3 )
{
cvAnd( a, b, this );
cvNot( this, this );
}
else if( flags == 1 )
{
if( data.ptr == b->data.ptr )
{
cvNot( b, this );
cvAnd( this, a, this );
cvNot( this, this );
}
else
{
cvNot( a, this );
cvOr( this, b, this );
}
}
else
{
if( data.ptr == a->data.ptr )
{
cvNot( a, this );
cvAnd( this, b, this );
cvNot( this, this );
}
else
{
cvNot( b, this );
cvOr( this, a, this );
}
}
break;
case _CvMAT_LOGIC_::XOR:
cvXor( a, b, this );
if( flags == 1 || flags == 2 )
cvNot( this, this );
break;
}
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_UN_LOGIC_& mat_logic )
{
CvMAT* a = mat_logic.a;
CvScalar scalar = cvScalarAll( mat_logic.alpha );
int flags = mat_logic.flags;
_CvMAT_LOGIC_::Op op = mat_logic.op;
if( !data.ptr )
{
create( a->height, a->width, a->type );
}
switch( op )
{
case _CvMAT_LOGIC_::AND:
if( flags == 0 )
cvAndS( a, scalar, this );
else
{
cvNot( a, this );
cvAndS( this, scalar, this );
}
break;
case _CvMAT_LOGIC_::OR:
if( flags == 0 )
cvOrS( a, scalar, this );
else
{
cvNot( a, this );
cvOrS( this, scalar, this );
}
break;
case _CvMAT_LOGIC_::XOR:
if( flags == 0 )
cvXorS( a, scalar, this );
else
cvXorS( a, ~scalar, this );
break;
}
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_COPY_& mat_copy )
{
CvMAT* src = (CvMAT*)mat_copy.a;
if( !data.ptr )
{
create( src->height, src->width, src->type );
}
if( src != this )
cvCopy( src, this );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_CVT_& mat_cvt )
{
CvMAT* src = (CvMAT*)&mat_cvt.a;
if( !data.ptr )
{
int depth = mat_cvt.newdepth;
create( src->height, src->width, depth < 0 ? src->type :
CV_MAT_CN(src->type)|CV_MAT_DEPTH(depth));
}
cvCvtScale( src, this, mat_cvt.scale, mat_cvt.shift );
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_DOT_OP_& dot_op )
{
CvMAT* a = (CvMAT*)&(dot_op.a);
CvMAT* b = dot_op.b;
if( !data.ptr )
{
create( a->height, a->width, a->type );
}
switch( dot_op.op )
{
case '*':
cvMul( a, b, this, dot_op.alpha );
break;
case '/':
if( b != 0 )
cvDiv( a, b, this, dot_op.alpha );
else
cvDiv( 0, a, this, dot_op.alpha );
break;
case 'm':
if( b != 0 )
cvMin( a, b, this );
else
cvMinS( a, dot_op.alpha, this );
break;
case 'M':
if( b != 0 )
cvMax( a, b, this );
else
cvMaxS( a, dot_op.alpha, this );
break;
case 'a':
if( b != 0 )
cvAbsDiff( a, b, this );
else
cvAbsDiffS( a, this, cvScalar(dot_op.alpha) );
break;
default:
assert(0);
}
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_SOLVE_& solve_mat )
{
CvMAT* a = (CvMAT*)(solve_mat.a);
CvMAT* b = (CvMAT*)(solve_mat.b);
if( !data.ptr )
{
create( a->height, b->width, a->type );
}
if( solve_mat.method == 0 )
cvSolve( a, b, this );
else
{
CvMAT temp;
cvInitMatHeader( &temp, a->cols, a->rows, a->type );
cvCreateData( &temp );
cvPseudoInv( a, &temp );
cvMatMul( &temp, b, this );
}
return *this;
}
CvMAT& CvMAT::operator = ( const _CvMAT_CMP_& mat_cmp )
{
CvMAT* a = mat_cmp.a;
CvMAT* b = mat_cmp.b;
if( !data.ptr )
{
create( a->height, a->width, CV_8UC1 );
}
if( b )
cvCmp( a, b, this, mat_cmp.cmp_op );
else
cvCmpS( a, mat_cmp.alpha, this, mat_cmp.cmp_op );
return *this;
}
/****************************************************************************************\
* CvMAT I/O operations *
\****************************************************************************************/
void CvMAT::write( const char* name, FILE* f, const char* fmt )
{
int i, j, w = width * CV_MAT_CN(type);
FILE* out = f ? f : stdout;
if( name )
fprintf( stdout, "%s(%d x %d) =\n\t", name, rows, cols );
for( i = 0; i < rows; i++ )
{
switch( CV_MAT_DEPTH(type))
{
case CV_8U: if( !fmt )
fmt = "%4d";
for( j = 0; j < w; j++ )
fprintf( out, fmt, ((uchar*)(data.ptr + i*step))[j] );
break;
case CV_8S: if( !fmt )
fmt = "%5d";
for( j = 0; j < w; j++ )
fprintf( out, fmt, ((char*)(data.ptr + i*step))[j] );
break;
case CV_16S: if( !fmt )
fmt = "%7d";
for( j = 0; j < w; j++ )
fprintf( out, fmt, ((short*)(data.ptr + i*step))[j] );
break;
case CV_32S: if( !fmt )
fmt = " %08x";
for( j = 0; j < w; j++ )
fprintf( out, fmt, ((int*)(data.ptr + i*step))[j] );
break;
case CV_32F: if( !fmt )
fmt = "%15g";
for( j = 0; j < w; j++ )
fprintf( out, fmt, ((float*)(data.ptr + i*step))[j] );
break;
case CV_64F: if( !fmt )
fmt = "%15g";
for( j = 0; j < w; j++ )
fprintf( out, fmt, ((double*)(data.ptr + i*step))[j] );
break;
}
fprintf( out, "\n%s", i < rows - 1 ? "\t" : "" );
}
fprintf( out, "\n" );
}
#endif /* _MSC_VER || __BORLANDC__ */
/* End of file. */

View File

@@ -0,0 +1,855 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#define PATH_TO_E 1
#define PATH_TO_SE 2
#define PATH_TO_S 3
#define K_S 2
#define E_S 2
#define C_S .01
#define K_Z 5000
#define K_NM 50000
#define K_B 40
#define NULL_EDGE 0.001f
#define inf DBL_MAX
typedef struct __CvWork
{
double w_east;
double w_southeast;
double w_south;
char path_e;
char path_se;
char path_s;
}_CvWork;
double _cvBendingWork( CvPoint2D32f* B0,
CvPoint2D32f* F0,
CvPoint2D32f* B1,
CvPoint2D32f* F1/*,
CvPoint* K */);
double _cvStretchingWork(CvPoint2D32f* P1,
CvPoint2D32f* P2);
void _cvWorkEast (int i, int j, _CvWork** W, CvPoint2D32f* edges1, CvPoint2D32f* edges2);
void _cvWorkSouthEast(int i, int j, _CvWork** W, CvPoint2D32f* edges1, CvPoint2D32f* edges2);
void _cvWorkSouth (int i, int j, _CvWork** W, CvPoint2D32f* edges1, CvPoint2D32f* edges2);
static CvPoint2D32f null_edge = {0,0};
double _cvStretchingWork(CvPoint2D32f* P1,
CvPoint2D32f* P2)
{
double L1,L2, L_min, dL;
L1 = sqrt( (double)P1->x*P1->x + P1->y*P1->y);
L2 = sqrt( (double)P2->x*P2->x + P2->y*P2->y);
L_min = MIN(L1, L2);
dL = fabs( L1 - L2 );
return K_S * pow( dL, E_S ) / ( L_min + C_S*dL );
}
////////////////////////////////////////////////////////////////////////////////////
double _cvBendingWork( CvPoint2D32f* B0,
CvPoint2D32f* F0,
CvPoint2D32f* B1,
CvPoint2D32f* F1/*,
CvPoint* K*/)
{
CvPoint2D32f Q( CvPoint2D32f q0, CvPoint2D32f q1, CvPoint2D32f q2, double t );
double angle( CvPoint2D32f A, CvPoint2D32f B );
CvPoint2D32f Q0, Q1, Q2;
CvPoint2D32f Q1_nm = { 0, 0 }, Q2_nm = { 0, 0 };
double d0, d1, d2, des, t_zero;
double k_zero, k_nonmon;
CvPoint2D32f center;
double check01, check02;
char check_origin;
double d_angle, d_nm_angle;
/*
if( (B0->x==0) && (B0->y==0) )
{
if( (F0->x==0) && (F0->y==0) )
{
B1->x = -B1->x;
B1->y = -B1->y;
d_angle = acos( (B1->x*F1->x + B1->y*F1->y)/sqrt( (B1->x*B1->x + B1->y*B1->y)*(F1->x*F1->x + F1->y*F1->y) ) );
d_angle = CV_PI - d_angle;
B1->x = -B1->x;
B1->y = -B1->y;
//return d_angle*K_B;
return 100;
}
K->x = -K->x;
K->y = -K->y;
B1->x = -B1->x;
B1->y = -B1->y;
d_angle = acos( (B1->x*F1->x + B1->y*F1->y)/sqrt( (B1->x*B1->x + B1->y*B1->y)*(F1->x*F1->x + F1->y*F1->y) ) );
d_angle = d_angle - acos( (F0->x*K->x + F0->y*K->y)/sqrt( (F0->x*F0->x + F0->y*F0->y)*(K->x*K->x + K->y*K->y) ) );
d_angle = d_angle - CV_PI*0.5;
d_angle = fabs(d_angle);
K->x = -K->x;
K->y = -K->y;
B1->x = -B1->x;
B1->y = -B1->y;
//return d_angle*K_B;
return 100;
}
if( (F0->x==0) && (F0->y==0) )
{
K->x = -K->x;
K->y = -K->y;
B1->x = -B1->x;
B1->y = -B1->y;
d_angle = acos( (B1->x*F1->x + B1->y*F1->y)/sqrt( (B1->x*B1->x + B1->y*B1->y)*(F1->x*F1->x + F1->y*F1->y) ) );
d_angle = d_angle - acos( (B0->x*K->x + B0->y*K->y)/sqrt( (B0->x*B0->x + B0->y*B0->y)*(K->x*K->x + K->y*K->y) ) );
d_angle = d_angle - CV_PI*0.5;
d_angle = fabs(d_angle);
K->x = -K->x;
K->y = -K->y;
B1->x = -B1->x;
B1->y = -B1->y;
//return d_angle*K_B;
return 100;
}
///////////////
if( (B1->x==0) && (B1->y==0) )
{
if( (F1->x==0) && (F1->y==0) )
{
B0->x = -B0->x;
B0->y = -B0->y;
d_angle = acos( (B0->x*F0->x + B0->y*F0->y)/sqrt( (B0->x*B0->x + B0->y*B0->y)*(F0->x*F0->x + F0->y*F0->y) ) );
d_angle = CV_PI - d_angle;
B0->x = -B0->x;
B0->y = -B0->y;
//return d_angle*K_B;
return 100;
}
K->x = -K->x;
K->y = -K->y;
B0->x = -B0->x;
B0->y = -B0->y;
d_angle = acos( (B0->x*F0->x + B0->y*F0->y)/sqrt( (B0->x*B0->x + B0->y*B0->y)*(F0->x*F0->x + F0->y*F0->y) ) );
d_angle = d_angle - acos( (F1->x*K->x + F1->y*K->y)/sqrt( (F1->x*F1->x + F1->y*F1->y)*(K->x*K->x + K->y*K->y) ) );
d_angle = d_angle - CV_PI*0.5;
d_angle = fabs(d_angle);
K->x = -K->x;
K->y = -K->y;
B0->x = -B0->x;
B0->y = -B0->y;
//return d_angle*K_B;
return 100;
}
if( (F1->x==0) && (F1->y==0) )
{
K->x = -K->x;
K->y = -K->y;
B0->x = -B0->x;
B0->y = -B0->y;
d_angle = acos( (B0->x*F0->x + B0->y*F0->y)/sqrt( (B0->x*B0->x + B0->y*B0->y)*(F0->x*F0->x + F0->y*F0->y) ) );
d_angle = d_angle - acos( (B1->x*K->x + B1->y*K->y)/sqrt( (B1->x*B1->x + B1->y*B1->y)*(K->x*K->x + K->y*K->y) ) );
d_angle = d_angle - CV_PI*0.5;
d_angle = fabs(d_angle);
K->x = -K->x;
K->y = -K->y;
B0->x = -B0->x;
B0->y = -B0->y;
//return d_angle*K_B;
return 100;
}
*/
/*
B0->x = -B0->x;
B0->y = -B0->y;
B1->x = -B1->x;
B1->y = -B1->y;
*/
Q0.x = F0->x * (-B0->x) + F0->y * (-B0->y);
Q0.y = F0->x * (-B0->y) - F0->y * (-B0->x);
Q1.x = 0.5f*( (F1->x * (-B0->x) + F1->y * (-B0->y)) + (F0->x * (-B1->x) + F0->y * (-B1->y)) );
Q1.y = 0.5f*( (F1->x * (-B0->y) - F1->y * (-B0->x)) + (F0->x * (-B1->y) - F0->y * (-B1->x)) );
Q2.x = F1->x * (-B1->x) + F1->y * (-B1->y);
Q2.y = F1->x * (-B1->y) - F1->y * (-B1->x);
d0 = Q0.x * Q1.y - Q0.y * Q1.x;
d1 = 0.5f*(Q0.x * Q2.y - Q0.y * Q2.x);
d2 = Q1.x * Q2.y - Q1.y * Q2.x;
// Check angles goes to zero
des = Q1.y*Q1.y - Q0.y*Q2.y;
k_zero = 0;
if( des >= 0 )
{
t_zero = ( Q0.y - Q1.y + sqrt(des) )/( Q0.y - 2*Q1.y + Q2.y );
if( (0 < t_zero) && (t_zero < 1) && ( Q(Q0, Q1, Q2, t_zero).x > 0 ) )
{
k_zero = inf;
}
t_zero = ( Q0.y - Q1.y - sqrt(des) )/( Q0.y - 2*Q1.y + Q2.y );
if( (0 < t_zero) && (t_zero < 1) && ( Q(Q0, Q1, Q2, t_zero).x > 0 ) )
{
k_zero = inf;
}
}
// Check nonmonotonic
des = d1*d1 - d0*d2;
k_nonmon = 0;
if( des >= 0 )
{
t_zero = ( d0 - d1 - sqrt(des) )/( d0 - 2*d1 + d2 );
if( (0 < t_zero) && (t_zero < 1) )
{
k_nonmon = 1;
Q1_nm = Q(Q0, Q1, Q2, t_zero);
}
t_zero = ( d0 - d1 + sqrt(des) )/( d0 - 2*d1 + d2 );
if( (0 < t_zero) && (t_zero < 1) )
{
k_nonmon += 2;
Q2_nm = Q(Q0, Q1, Q2, t_zero);
}
}
// Finde origin lie in Q0Q1Q2
check_origin = 1;
center.x = (Q0.x + Q1.x + Q2.x)/3;
center.y = (Q0.y + Q1.y + Q2.y)/3;
check01 = (center.x - Q0.x)*(Q1.y - Q0.y) + (center.y - Q0.y)*(Q1.x - Q0.x);
check02 = (-Q0.x)*(Q1.y - Q0.y) + (-Q0.y)*(Q1.x - Q0.x);
if( check01*check02 > 0 )
{
check01 = (center.x - Q1.x)*(Q2.y - Q1.y) + (center.y - Q1.y)*(Q2.x - Q1.x);
check02 = (-Q1.x)*(Q2.y - Q1.y) + (-Q1.y)*(Q2.x - Q1.x);
if( check01*check02 > 0 )
{
check01 = (center.x - Q2.x)*(Q0.y - Q2.y) + (center.y - Q2.y)*(Q0.x - Q2.x);
check02 = (-Q2.x)*(Q0.y - Q2.y) + (-Q2.y)*(Q0.x - Q2.x);
if( check01*check02 > 0 )
{
check_origin = 0;
}
}
}
// Calculate angle
d_nm_angle = 0;
d_angle = angle(Q0,Q2);
if( k_nonmon == 0 )
{
if( check_origin == 0 )
{
}
else
{
d_angle = 2*CV_PI - d_angle;
}
}
else
{
if( k_nonmon == 1 )
{
d_nm_angle = angle(Q0,Q1_nm);
if(d_nm_angle > d_angle)
{
d_nm_angle = d_nm_angle - d_angle;
}
}
if( k_nonmon == 2 )
{
d_nm_angle = angle(Q0,Q2_nm);
if(d_nm_angle > d_angle)
{
d_nm_angle = d_nm_angle - d_angle;
}
}
if( k_nonmon == 3 )
{
d_nm_angle = angle(Q0,Q1_nm);
if(d_nm_angle > d_angle)
{
d_nm_angle = d_nm_angle - d_angle;
d_nm_angle = d_nm_angle + angle(Q0, Q2_nm);
}
else
{
d_nm_angle = d_nm_angle + angle(Q2,Q2_nm);
}
}
}
/*
B0->x = -B0->x;
B0->y = -B0->y;
B1->x = -B1->x;
B1->y = -B1->y;
*/
return d_angle*K_B + d_nm_angle*K_NM + k_zero*K_Z;
//return 0;
}
/////////////////////////////////////////////////////////////////////////////////
void _cvWorkEast(int i, int j, _CvWork** W, CvPoint2D32f* edges1, CvPoint2D32f* edges2)
{
double w1,w2;
CvPoint2D32f small_edge;
//W[i,j].w_east
w1 = W[i-1][j].w_east /*+ _cvBendingWork( &edges1[i-2],
&edges1[i-1],
&null_edge ,
&null_edge,
NULL)*/;
small_edge.x = NULL_EDGE*edges1[i-1].x;
small_edge.y = NULL_EDGE*edges1[i-1].y;
w2 = W[i-1][j].w_southeast + _cvBendingWork(&edges1[i-2],
&edges1[i-1],
&edges2[j-1],
/*&null_edge*/&small_edge/*,
&edges2[j]*/);
if(w1<w2)
{
W[i][j].w_east = w1 + _cvStretchingWork( &edges1[i-1], &null_edge );
W[i][j].path_e = PATH_TO_E;
}
else
{
W[i][j].w_east = w2 + _cvStretchingWork( &edges1[i-1], &null_edge );
W[i][j].path_e = PATH_TO_SE;
}
}
////////////////////////////////////////////////////////////////////////////////////
void _cvWorkSouthEast(int i, int j, _CvWork** W, CvPoint2D32f* edges1, CvPoint2D32f* edges2)
{
double w1,w2,w3;
CvPoint2D32f small_edge;
//W[i,j].w_southeast
small_edge.x = NULL_EDGE*edges1[i-2].x;
small_edge.y = NULL_EDGE*edges1[i-2].y;
w1 = W[i-1][j-1].w_east + _cvBendingWork(&edges1[i-2],
&edges1[i-1],
/*&null_edge*/&small_edge,
&edges2[j-1]/*,
&edges2[j-2]*/);
w2 = W[i-1][j-1].w_southeast + _cvBendingWork( &edges1[i-2],
&edges1[i-1],
&edges2[j-2],
&edges2[j-1]/*,
NULL*/);
small_edge.x = NULL_EDGE*edges2[j-2].x;
small_edge.y = NULL_EDGE*edges2[j-2].y;
w3 = W[i-1][j-1].w_south + _cvBendingWork( /*&null_edge*/&small_edge,
&edges1[i-1],
&edges2[j-2],
&edges2[j-1]/*,
&edges1[i-2]*/);
if( w1<w2 )
{
if(w1<w3)
{
W[i][j].w_southeast = w1 + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
W[i][j].path_se = PATH_TO_E;
}
else
{
W[i][j].w_southeast = w3 + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
W[i][j].path_se = 3;
}
}
else
{
if( w2<w3)
{
W[i][j].w_southeast = w2 + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
W[i][j].path_se = PATH_TO_SE;
}
else
{
W[i][j].w_southeast = w3 + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
W[i][j].path_se = 3;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////
void _cvWorkSouth(int i, int j, _CvWork** W, CvPoint2D32f* edges1, CvPoint2D32f* edges2)
{
double w1,w2;
CvPoint2D32f small_edge;
//W[i,j].w_south
small_edge.x = NULL_EDGE*edges2[j-1].x;
small_edge.y = NULL_EDGE*edges2[j-1].y;
w1 = W[i][j-1].w_southeast + _cvBendingWork(&edges1[i-1],
/*&null_edge*/&small_edge,
&edges2[j-2],
&edges2[j-1]/*,
&edges1[i]*/);
w2 = W[i][j-1].w_south /*+ _cvBendingWork( &null_edge ,
&null_edge,
&edges2[j-2],
&edges2[j-1],
NULL)*/;
if( w1<w2 )
{
W[i][j].w_south = w1 + _cvStretchingWork( &null_edge, &edges2[j-1] );
W[i][j].path_s = PATH_TO_SE;
}
else
{
W[i][j].w_south = w2 + _cvStretchingWork( &null_edge, &edges2[j-1] );
W[i][j].path_s = 3;
}
}
//===================================================
CvPoint2D32f Q(CvPoint2D32f q0,CvPoint2D32f q1,CvPoint2D32f q2,double t)
{
CvPoint2D32f q;
q.x = (float)(q0.x*(1-t)*(1-t) + 2*q1.x*t*(1-t) + q2.x*t*t);
q.y = (float)(q0.y*(1-t)*(1-t) + 2*q1.y*t*(1-t) + q2.y*t*t);
return q;
}
double angle(CvPoint2D32f A, CvPoint2D32f B)
{
return acos( (A.x*B.x + A.y*B.y)/sqrt( (double)(A.x*A.x + A.y*A.y)*(B.x*B.x + B.y*B.y) ) );
}
/***************************************************************************************\
*
* This function compute intermediate polygon between contour1 and contour2
*
* Correspondence between points of contours specify by corr
*
* param = [0,1]; 0 correspondence to contour1, 1 - contour2
*
\***************************************************************************************/
CvSeq* icvBlendContours(CvSeq* contour1,
CvSeq* contour2,
CvSeq* corr,
double param,
CvMemStorage* storage)
{
int j;
CvSeqWriter writer01;
CvSeqReader reader01;
int Ni,Nj; // size of contours
int i; // counter
CvPoint* point1; // array of first contour point
CvPoint* point2; // array of second contour point
CvPoint point_output; // intermediate storage of ouput point
int corr_point;
// Create output sequence.
CvSeq* output = cvCreateSeq(0,
sizeof(CvSeq),
sizeof(CvPoint),
storage );
// Find size of contours.
Ni = contour1->total + 1;
Nj = contour2->total + 1;
point1 = (CvPoint* )malloc( Ni*sizeof(CvPoint) );
point2 = (CvPoint* )malloc( Nj*sizeof(CvPoint) );
// Initialize arrays of point
cvCvtSeqToArray( contour1, point1, CV_WHOLE_SEQ );
cvCvtSeqToArray( contour2, point2, CV_WHOLE_SEQ );
// First and last point mast be equal.
point1[Ni-1] = point1[0];
point2[Nj-1] = point2[0];
// Initializes process of writing to sequence.
cvStartAppendToSeq( output, &writer01);
i = Ni-1; //correspondence to points of contour1
for( ; corr; corr = corr->h_next )
{
//Initializes process of sequential reading from sequence
cvStartReadSeq( corr, &reader01, 0 );
for(j=0; j < corr->total; j++)
{
// Read element from sequence.
CV_READ_SEQ_ELEM( corr_point, reader01 );
// Compute point of intermediate polygon.
point_output.x = cvRound(point1[i].x + param*( point2[corr_point].x - point1[i].x ));
point_output.y = cvRound(point1[i].y + param*( point2[corr_point].y - point1[i].y ));
// Write element to sequence.
CV_WRITE_SEQ_ELEM( point_output, writer01 );
}
i--;
}
// Updates sequence header.
cvFlushSeqWriter( &writer01 );
return output;
}
/**************************************************************************************************
*
*
*
*
*
*
*
*
*
*
**************************************************************************************************/
void icvCalcContoursCorrespondence(CvSeq* contour1,
CvSeq* contour2,
CvSeq** corr,
CvMemStorage* storage)
{
int i,j; // counter of cycles
int Ni,Nj; // size of contours
_CvWork** W; // graph for search minimum of work
CvPoint* point1; // array of first contour point
CvPoint* point2; // array of second contour point
CvPoint2D32f* edges1; // array of first contour edge
CvPoint2D32f* edges2; // array of second contour edge
//CvPoint null_edge = {0,0}; //
CvPoint2D32f small_edge;
//double inf; // infinity
CvSeq* corr01;
CvSeqWriter writer;
char path; //
// Find size of contours
Ni = contour1->total + 1;
Nj = contour2->total + 1;
// Create arrays
W = (_CvWork**)malloc(sizeof(_CvWork*)*Ni);
for(i=0; i<Ni; i++)
{
W[i] = (_CvWork*)malloc(sizeof(_CvWork)*Nj);
}
point1 = (CvPoint* )malloc( Ni*sizeof(CvPoint) );
point2 = (CvPoint* )malloc( Nj*sizeof(CvPoint) );
edges1 = (CvPoint2D32f* )malloc( (Ni-1)*sizeof(CvPoint2D32f) );
edges2 = (CvPoint2D32f* )malloc( (Nj-1)*sizeof(CvPoint2D32f) );
// Initialize arrays of point
cvCvtSeqToArray( contour1, point1, CV_WHOLE_SEQ );
cvCvtSeqToArray( contour2, point2, CV_WHOLE_SEQ );
point1[Ni-1] = point1[0];
point2[Nj-1] = point2[0];
for(i=0;i<Ni-1;i++)
{
edges1[i].x = (float)( point1[i+1].x - point1[i].x );
edges1[i].y = (float)( point1[i+1].y - point1[i].y );
};
for(i=0;i<Nj-1;i++)
{
edges2[i].x = (float)( point2[i+1].x - point2[i].x );
edges2[i].y = (float)( point2[i+1].y - point2[i].y );
};
// Find infinity constant
//inf=1;
/////////////
//Find min path in graph
/////////////
W[0][0].w_east = 0;
W[0][0].w_south = 0;
W[0][0].w_southeast = 0;
W[1][1].w_southeast = _cvStretchingWork( &edges1[0], &edges2[0] );
W[1][1].w_east = inf;
W[1][1].w_south = inf;
W[1][1].path_se = PATH_TO_SE;
W[0][1].w_south = _cvStretchingWork( &null_edge, &edges2[0] );
W[0][1].path_s = 3;
W[1][0].w_east = _cvStretchingWork( &edges2[0], &null_edge );
W[1][0].path_e = PATH_TO_E;
for( i=1; i<Ni; i++ )
{
W[i][0].w_south = inf;
W[i][0].w_southeast = inf;
}
for(j=1; j<Nj; j++)
{
W[0][j].w_east = inf;
W[0][j].w_southeast = inf;
}
for(i=2; i<Ni; i++)
{
j=0;/////////
W[i][j].w_east = W[i-1][j].w_east;
W[i][j].w_east = W[i][j].w_east /*+
_cvBendingWork( &edges1[i-2], &edges1[i-1], &null_edge, &null_edge, NULL )*/;
W[i][j].w_east = W[i][j].w_east + _cvStretchingWork( &edges2[i-1], &null_edge );
W[i][j].path_e = PATH_TO_E;
j=1;//////////
W[i][j].w_south = inf;
_cvWorkEast (i, j, W, edges1, edges2);
W[i][j].w_southeast = W[i-1][j-1].w_east;
W[i][j].w_southeast = W[i][j].w_southeast + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
small_edge.x = NULL_EDGE*edges1[i-2].x;
small_edge.y = NULL_EDGE*edges1[i-2].y;
W[i][j].w_southeast = W[i][j].w_southeast +
_cvBendingWork( &edges1[i-2], &edges1[i-1], /*&null_edge*/&small_edge, &edges2[j-1]/*, &edges2[Nj-2]*/);
W[i][j].path_se = PATH_TO_E;
}
for(j=2; j<Nj; j++)
{
i=0;//////////
W[i][j].w_south = W[i][j-1].w_south;
W[i][j].w_south = W[i][j].w_south + _cvStretchingWork( &null_edge, &edges2[j-1] );
W[i][j].w_south = W[i][j].w_south /*+
_cvBendingWork( &null_edge, &null_edge, &edges2[j-2], &edges2[j-1], NULL )*/;
W[i][j].path_s = 3;
i=1;///////////
W[i][j].w_east= inf;
_cvWorkSouth(i, j, W, edges1, edges2);
W[i][j].w_southeast = W[i-1][j-1].w_south;
W[i][j].w_southeast = W[i][j].w_southeast + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
small_edge.x = NULL_EDGE*edges2[j-2].x;
small_edge.y = NULL_EDGE*edges2[j-2].y;
W[i][j].w_southeast = W[i][j].w_southeast +
_cvBendingWork( /*&null_edge*/&small_edge, &edges1[i-1], &edges2[j-2], &edges2[j-1]/*, &edges1[Ni-2]*/);
W[i][j].path_se = 3;
}
for(i=2; i<Ni; i++)
for(j=2; j<Nj; j++)
{
_cvWorkEast (i, j, W, edges1, edges2);
_cvWorkSouthEast(i, j, W, edges1, edges2);
_cvWorkSouth (i, j, W, edges1, edges2);
}
i=Ni-1;j=Nj-1;
*corr = cvCreateSeq(0,
sizeof(CvSeq),
sizeof(int),
storage );
corr01 = *corr;
cvStartAppendToSeq( corr01, &writer );
if( W[i][j].w_east > W[i][j].w_southeast )
{
if( W[i][j].w_southeast > W[i][j].w_south )
{
path = 3;
}
else
{
path = PATH_TO_SE;
}
}
else
{
if( W[i][j].w_east < W[i][j].w_south )
{
path = PATH_TO_E;
}
else
{
path = 3;
}
}
do
{
CV_WRITE_SEQ_ELEM( j, writer );
switch( path )
{
case PATH_TO_E:
path = W[i][j].path_e;
i--;
cvFlushSeqWriter( &writer );
corr01->h_next = cvCreateSeq( 0,
sizeof(CvSeq),
sizeof(int),
storage );
corr01 = corr01->h_next;
cvStartAppendToSeq( corr01, &writer );
break;
case PATH_TO_SE:
path = W[i][j].path_se;
j--; i--;
cvFlushSeqWriter( &writer );
corr01->h_next = cvCreateSeq( 0,
sizeof(CvSeq),
sizeof(int),
storage );
corr01 = corr01->h_next;
cvStartAppendToSeq( corr01, &writer );
break;
case 3:
path = W[i][j].path_s;
j--;
break;
}
} while( (i>=0) && (j>=0) );
cvFlushSeqWriter( &writer );
// Free memory
for(i=1;i<Ni;i++)
{
free(W[i]);
}
free(W);
free(point1);
free(point2);
free(edges1);
free(edges2);
}

View File

@@ -0,0 +1,396 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#include <assert.h>
static CvStatus
icvMorphEpilines8uC3( uchar * first_pix, /* raster epiline from image 1 */
uchar * second_pix, /* raster epiline from image 2 */
uchar * dst_pix, /* raster epiline from dest image */
/* (it's an output parameter) */
float alpha, /* relative position of camera */
int *first, /* first sequence of runs */
int first_runs, /* it's length */
int *second, /* second sequence of runs */
int second_runs, int *first_corr, /* corr data for the 1st seq */
int *second_corr, /* corr data for the 2nd seq */
int dst_len )
{
float alpha1; /* alpha - 1.0 */
int s, s1; /* integer variant of alpha and alpha1 ( 0 <= s,s1 <= 256 ) */
int curr; /* current index in run's array */
float begLine; /* begin of current run */
float endLine; /* end of current run */
float begCorr; /* begin of correspondence destination of run */
float endCorr; /* end of correspondence destination of run */
int begDestLine; /* begin of current destanation of run */
int endDestLine; /* end of current destanation of run */
int begLineIndex;
int endLineIndex;
int indexImg1;
float step = 0;
int n;
memset( dst_pix, 0, dst_len );
alpha1 = (float) (1.0 - alpha);
s = (int) (alpha * 256);
s1 = 256 - s;
/* --------------Create first line------------- */
begLineIndex = first[0];
begLine = (float) begLineIndex;
curr = 0;
for( n = 0; n < first_runs; n++ )
{ /* for each run */
begCorr = (float) first_corr[curr];
curr++;
endCorr = (float) first_corr[curr];
curr++;
endLineIndex = first[curr];
endLine = (float) endLineIndex;
begDestLine = (int) (alpha * begLine + alpha1 * begCorr);
endDestLine = (int) (alpha * endLine + alpha1 * endCorr);
indexImg1 = begDestLine * 3;
step = 0;
if( endDestLine != begDestLine )
step = (endLine - begLine) / ((float) (endDestLine - begDestLine));
if( begCorr != endCorr )
{
for( ; begDestLine < endDestLine; begDestLine++ )
{
/* for each pixel */
begLineIndex = (int) begLine;
begLineIndex *= 3;
/* Blend R */
dst_pix[indexImg1] = (uchar) (((int) (first_pix[begLineIndex]) * s) >> 8);
indexImg1++;
/* Blend G */
dst_pix[indexImg1] = (uchar) (((int) (first_pix[begLineIndex + 1]) * s) >> 8);
indexImg1++;
/* Blend B */
dst_pix[indexImg1] = (uchar) (((int) (first_pix[begLineIndex + 2]) * s) >> 8);
indexImg1++;
begLine += step;
} /* for */
}
else
{
for( ; begDestLine < endDestLine; begDestLine++ )
{
/* for each pixel */
begLineIndex = (int) begLine;
begLineIndex *= 3;
/* Blend R */
dst_pix[indexImg1] = first_pix[begLineIndex];
indexImg1++;
/* Blend G */
dst_pix[indexImg1] = first_pix[begLineIndex + 1];
indexImg1++;
/* Blend B */
dst_pix[indexImg1] = first_pix[begLineIndex + 2];
indexImg1++;
begLine += step;
} /* for */
} /* if */
begLineIndex = endLineIndex;
begLine = endLine;
} /* for each runs in first line */
begLineIndex = second[0];
begLine = (float) begLineIndex;
curr = 0;
/* --------------Create second line------------- */
curr = 0;;
for( n = 0; n < second_runs; n++ )
{ /* for each run */
begCorr = (float) second_corr[curr];
curr++;
endCorr = (float) second_corr[curr];
curr++;
endLineIndex = second[curr];
endLine = (float) endLineIndex;
begDestLine = (int) (alpha1 * begLine + alpha * begCorr);
endDestLine = (int) (alpha1 * endLine + alpha * endCorr);
indexImg1 = begDestLine * 3;
step = 0;
if (endDestLine != begDestLine)
step = (endLine - begLine) / ((float) (endDestLine - begDestLine));
if( begCorr != endCorr )
{
for( ; begDestLine < endDestLine; begDestLine++ )
{
/* for each pixel */
begLineIndex = (int) begLine;
begLineIndex *= 3;
/* Blend R */
dst_pix[indexImg1] =
(uchar) (dst_pix[indexImg1] +
(uchar) (((unsigned int) (second_pix[begLineIndex]) * s1) >> 8));
indexImg1++;
/* Blend G */
dst_pix[indexImg1] =
(uchar) (dst_pix[indexImg1] +
(uchar) (((unsigned int) (second_pix[begLineIndex + 1]) * s1) >>
8));
indexImg1++;
/* Blend B */
dst_pix[indexImg1] =
(uchar) (dst_pix[indexImg1] +
(uchar) (((unsigned int) (second_pix[begLineIndex + 2]) * s1) >>
8));
indexImg1++;
begLine += step;
} /* for */
}
else
{
for( ; begDestLine < endDestLine; begDestLine++ )
{
/* for each pixel */
begLineIndex = (int) begLine;
begLineIndex *= 3;
/* Blend R */
dst_pix[indexImg1] = (uchar) (dst_pix[indexImg1] + second_pix[begLineIndex]);
indexImg1++;
/* Blend G */
dst_pix[indexImg1] =
(uchar) (dst_pix[indexImg1] + second_pix[begLineIndex + 1]);
indexImg1++;
/* Blend B */
dst_pix[indexImg1] =
(uchar) (dst_pix[indexImg1] + second_pix[begLineIndex + 2]);
/*assert(indexImg1 < dst_len); */
indexImg1++;
begLine += step;
} /* for */
} /* if */
begLineIndex = endLineIndex;
begLine = endLine;
} /* for each runs in second line */
return CV_NO_ERR;
} /* icvMorphEpilines8uC3 */
/*======================================================================================*/
static CvStatus
icvMorphEpilines8uC3Multi( int lines, /* number of lines */
uchar * first_pix, /* raster epilines from the first image */
int *first_num, /* numbers of pixel in first line */
uchar * second_pix, /* raster epilines from the second image */
int *second_num, /* numbers of pixel in second line */
uchar * dst_pix, /* raster epiline from the destination image */
/* (it's an output parameter) */
int *dst_num, /* numbers of pixel in output line */
float alpha, /* relative position of camera */
int *first, /* first sequence of runs */
int *first_runs, /* it's length */
int *second, /* second sequence of runs */
int *second_runs, int *first_corr, /* correspond information for the 1st seq */
int *second_corr ) /* correspond information for the 2nd seq */
{
CvStatus error;
int currLine;
int currFirstPix = 0;
//int currFirstNum = 0;
int currSecondPix = 0;
//int currSecondNum = 0;
int currDstPix = 0;
int currFirst = 0;
//int currFirstRuns = 0;
int currSecond = 0;
//int currSecondRuns = 0;
int currFirstCorr = 0;
int currSecondCorr = 0;
if( lines < 1 ||
first_pix == 0 ||
first_num == 0 ||
second_pix == 0 ||
second_num == 0 ||
dst_pix == 0 ||
dst_num == 0 ||
alpha < 0 ||
alpha > 1 ||
first == 0 ||
first_runs == 0 ||
second == 0 || second_runs == 0 || first_corr == 0 || second_corr == 0 )
return CV_BADFACTOR_ERR;
for( currLine = 0; currLine < lines; currLine++ )
{
error = icvMorphEpilines8uC3( &(first_pix[currFirstPix]),
&(second_pix[currSecondPix]),
&(dst_pix[currDstPix]),
alpha,
&(first[currFirst]),
first_runs[currLine],
&(second[currSecond]),
second_runs[currLine],
&(first_corr[currFirstCorr]),
&(second_corr[currSecondCorr]), dst_num[currLine] * 3 );
if( error != CV_NO_ERR )
return CV_NO_ERR;
currFirstPix += first_num[currLine] * 3;
currSecondPix += second_num[currLine] * 3;
currDstPix += dst_num[currLine] * 3;
currFirst += (first_runs[currLine] * 2) + 1;
currSecond += (second_runs[currLine] * 2) + 1;
currFirstCorr += first_runs[currLine] * 2;
currSecondCorr += second_runs[currLine] * 2;
} /* for */
return CV_NO_ERR;
} /* icvMorphEpilines8uC3Multi */
/*======================================================================================*/
CV_IMPL void
cvMorphEpilinesMulti( int lines, /* number of lines */
uchar * first_pix, /* raster epilines from the first image */
int *first_num, /* numbers of pixel in first line */
uchar * second_pix, /* raster epilines from the second image */
int *second_num, /* numbers of pixel in second line */
uchar * dst_pix, /* raster epiline from the destination image */
/* (it's an output parameter) */
int *dst_num, /* numbers of pixel in output line */
float alpha, /* relative position of camera */
int *first, /* first sequence of runs */
int *first_runs, /* it's length */
int *second, /* second sequence of runs */
int *second_runs, int *first_corr, /* correspond information for the 1st seq */
int *second_corr /* correspond information for the 2nd seq */
)
{
CV_FUNCNAME( "cvMorphEpilinesMulti" );
__BEGIN__;
IPPI_CALL( icvMorphEpilines8uC3Multi( lines, /* number of lines */
first_pix, /* raster epilines from the first image */
first_num, /* numbers of pixel in first line */
second_pix, /* raster epilines from the second image */
second_num, /* numbers of pixel in second line */
dst_pix, /* raster epiline from the destination image */
/* (it's an output parameter) */
dst_num, /* numbers of pixel in output line */
alpha, /* relative position of camera */
first, /* first sequence of runs */
first_runs, /* it's length */
second, /* second sequence of runs */
second_runs, first_corr, /* correspond information for the 1st seq */
second_corr /* correspond information for the 2nd seq */
));
__END__;
}

View File

@@ -0,0 +1,168 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#include "_cvvm.h"
/* Valery Mosyagin */
static CvStatus
icvFindRuns( int numLines, /* number of scanlines */
uchar * prewarp_1, /* prewarp image 1 */
uchar * prewarp_2, /* prewarp image 2 */
int *line_lens_1, /* line lengths 1 */
int *line_lens_2, /* line lengths 2 */
int *runs_1, /* result runs 1 */
int *runs_2, /* result runs 2 */
int *num_runs_1, /* numbers of first runs */
int *num_runs_2 )
{
CvStatus err;
err = icvFindRunsInOneImage( numLines, prewarp_1, line_lens_1, runs_1, num_runs_1 );
if( err != CV_NO_ERR )
return err;
err = icvFindRunsInOneImage( numLines, prewarp_2, line_lens_2, runs_2, num_runs_2 );
return err;
}
/*======================================================================================*/
CV_INLINE int
icvGetColor( uchar * valueRGB )
{
int R = *valueRGB;
int G = *(valueRGB + 1);
int B = *(valueRGB + 2);
return ( ((R + G + B) >> 3) & 0xFFFC );
} /* vm_GetColor */
/*======================================================================================*/
CvStatus
icvFindRunsInOneImage( int numLines, /* number of scanlines */
uchar * prewarp, /* prewarp image */
int *line_lens, /* line lengths in pixels */
int *runs, /* result runs */
int *num_runs )
{
int epiLine;
int run_index;
int curr_color;
int index;
int color;
uchar *curr_point;
int num;
run_index = 0;
curr_point = prewarp;
for( epiLine = 0; epiLine < numLines; epiLine++ )
{
curr_color = icvGetColor( curr_point );
runs[run_index++] = 0;
runs[run_index++] = curr_color;
curr_point += 3;
num = 1;
for( index = 1; index < line_lens[epiLine]; index++ )
{
color = icvGetColor( curr_point );
if( color != curr_color )
{
runs[run_index++] = index;
runs[run_index++] = color;
curr_color = color;
num++;
}
curr_point += 3;
}
runs[run_index++] = index;
num_runs[epiLine] = num;
}
return CV_NO_ERR;
}
/*======================================================================================*/
CV_IMPL void
cvFindRuns( int numLines, /* number of scanlines */
uchar * prewarp_1, /* prewarp image 1 */
uchar * prewarp_2, /* prewarp image 2 */
int *line_lens_1, /* line lengths 1 */
int *line_lens_2, /* line lengths 2 */
int *runs_1, /* result runs 1 */
int *runs_2, /* result runs 2 */
int *num_runs_1, /* numbers of first runs */
int *num_runs_2 )
{
CV_FUNCNAME( "cvFindRuns" );
__BEGIN__;
IPPI_CALL( icvFindRuns( numLines, /* number of scanlines */
prewarp_1, /* prewarp image 1 */
prewarp_2, /* prewarp image 2 */
line_lens_1, /* line lengths 1 */
line_lens_2, /* line lengths 2 */
runs_1, /* result runs 1 */
runs_2, /* result runs 2 */
num_runs_1, /* numbers of first runs */
num_runs_2 ));
__CLEANUP__;
__END__;
}

View File

@@ -0,0 +1,585 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
typedef struct Seg
{
ushort y;
ushort l;
ushort r;
ushort Prevl;
ushort Prevr;
short fl;
}
Seg;
#define UP 1
#define DOWN -1
#define PUSH(Y,IL,IR,IPL,IPR,FL) { stack[StIn].y=(ushort)(Y); \
stack[StIn].l=(ushort)(IL); \
stack[StIn].r=(ushort)(IR); \
stack[StIn].Prevl=(ushort)(IPL); \
stack[StIn].Prevr=(ushort)(IPR); \
stack[StIn].fl=(short)(FL); \
StIn++; }
#define POP(Y,IL,IR,IPL,IPR,FL) { StIn--; \
Y=stack[StIn].y; \
IL=stack[StIn].l; \
IR=stack[StIn].r;\
IPL=stack[StIn].Prevl; \
IPR=stack[StIn].Prevr; \
FL=stack[StIn].fl; }
#define DIFF(p1,p2) ((unsigned)((p1)[0] - (p2)[0] + d_lw)<=Interval && \
(unsigned)((p1)[1] - (p2)[1] + d_lw)<=Interval && \
(unsigned)((p1)[2] - (p2)[2] + d_lw)<=Interval)
/*#define DIFF(p1,p2) (CV_IABS((p1)[0] - (p2)[0]) + \
CV_IABS((p1)[1] - (p2)[1]) + \
CV_IABS((p1)[2] - (p2)[2]) <=Interval )*/
static CvStatus
icvSegmFloodFill_Stage1( uchar* pImage, int step,
uchar* pMask, int maskStep,
CvSize /*roi*/, CvPoint seed,
int* newVal, int d_lw, int d_up,
CvConnectedComp * region,
void *pStack )
{
uchar* img = pImage + step * seed.y;
uchar* mask = pMask + maskStep * (seed.y + 1);
unsigned Interval = (unsigned) (d_up + d_lw);
Seg *stack = (Seg*)pStack;
int StIn = 0;
int i, L, R;
int area = 0;
int sum[] = { 0, 0, 0 };
int XMin, XMax, YMin = seed.y, YMax = seed.y;
int val0[3];
L = R = seed.x;
img = pImage + seed.y*step;
mask = pMask + seed.y*maskStep;
mask[L] = 1;
val0[0] = img[seed.x*3];
val0[1] = img[seed.x*3 + 1];
val0[2] = img[seed.x*3 + 2];
while( DIFF( img + (R+1)*3, /*img + R*3*/val0 ) && !mask[R + 1] )
mask[++R] = 2;
while( DIFF( img + (L-1)*3, /*img + L*3*/val0 ) && !mask[L - 1] )
mask[--L] = 2;
XMax = R;
XMin = L;
PUSH( seed.y, L, R, R + 1, R, UP );
while( StIn )
{
int k, YC, PL, PR, flag/*, curstep*/;
POP( YC, L, R, PL, PR, flag );
int data[][3] = { {-flag, L, R}, {flag, L, PL-1}, {flag,PR+1,R}};
if( XMax < R )
XMax = R;
if( XMin > L )
XMin = L;
if( YMax < YC )
YMax = YC;
if( YMin > YC )
YMin = YC;
for( k = 0; k < 3; k++ )
{
flag = data[k][0];
/*curstep = flag * step;*/
img = pImage + (YC + flag) * step;
mask = pMask + (YC + flag) * maskStep;
int left = data[k][1];
int right = data[k][2];
for( i = left; i <= right; i++ )
{
if( !mask[i] && DIFF( img + i*3, /*img - curstep + i*3*/val0 ))
{
int j = i;
mask[i] = 2;
while( !mask[j - 1] && DIFF( img + (j - 1)*3, /*img + j*3*/val0 ))
mask[--j] = 2;
while( !mask[i + 1] &&
(DIFF( img + (i+1)*3, /*img + i*3*/val0 ) ||
(DIFF( img + (i+1)*3, /*img + (i+1)*3 - curstep*/val0) && i < R)))
mask[++i] = 2;
PUSH( YC + flag, j, i, L, R, -flag );
i++;
}
}
}
img = pImage + YC * step;
for( i = L; i <= R; i++ )
{
sum[0] += img[i*3];
sum[1] += img[i*3 + 1];
sum[2] += img[i*3 + 2];
}
area += R - L + 1;
}
region->area = area;
region->rect.x = XMin;
region->rect.y = YMin;
region->rect.width = XMax - XMin + 1;
region->rect.height = YMax - YMin + 1;
region->value = cvScalarAll(0);
{
double inv_area = area ? 1./area : 0;
newVal[0] = cvRound( sum[0] * inv_area );
newVal[1] = cvRound( sum[1] * inv_area );
newVal[2] = cvRound( sum[2] * inv_area );
}
return CV_NO_ERR;
}
#undef PUSH
#undef POP
#undef DIFF
static CvStatus
icvSegmFloodFill_Stage2( uchar* pImage, int step,
uchar* pMask, int maskStep,
CvSize /*roi*/, int* newVal,
CvRect rect )
{
uchar* img = pImage + step * rect.y + rect.x * 3;
uchar* mask = pMask + maskStep * rect.y + rect.x;
uchar uv[] = { (uchar)newVal[0], (uchar)newVal[1], (uchar)newVal[2] };
int x, y;
for( y = 0; y < rect.height; y++, img += step, mask += maskStep )
for( x = 0; x < rect.width; x++ )
if( mask[x] == 2 )
{
mask[x] = 1;
img[x*3] = uv[0];
img[x*3+1] = uv[1];
img[x*3+2] = uv[2];
}
return CV_OK;
}
#if 0
static void color_derv( const CvArr* srcArr, CvArr* dstArr, int thresh )
{
static int tab[] = { 0, 2, 2, 1 };
uchar *src = 0, *dst = 0;
int dst_step, src_step;
int x, y;
CvSize size;
cvGetRawData( srcArr, (uchar**)&src, &src_step, &size );
cvGetRawData( dstArr, (uchar**)&dst, &dst_step, 0 );
memset( dst, 0, size.width*sizeof(dst[0]));
memset( (uchar*)dst + dst_step*(size.height-1), 0, size.width*sizeof(dst[0]));
src += 3;
#define CV_IABS(a) (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0))
for( y = 1; y < size.height - 1; y++ )
{
src += src_step;
dst += dst_step;
uchar* src0 = src;
dst[0] = dst[size.width - 1] = 0;
for( x = 1; x < size.width - 1; x++, src += 3 )
{
/*int d[3];
int ad[3];
int f0, f1;
int val;*/
int m[3];
double val;
//double xx, yy;
int dh[3];
int dv[3];
dh[0] = src[0] - src[-3];
dv[0] = src[0] - src[-src_step];
dh[1] = src[1] - src[-2];
dv[1] = src[1] - src[1-src_step];
dh[2] = src[2] - src[-1];
dv[2] = src[2] - src[2-src_step];
m[0] = dh[0]*dh[0] + dh[1]*dh[1] + dh[2]*dh[2];
m[2] = dh[0]*dv[0] + dh[1]*dv[1] + dh[2]*dv[2];
m[1] = dv[0]*dv[0] + dv[1]*dv[1] + dh[2]*dh[2];
val = (m[0] + m[2]) +
sqrt(((double)((double)m[0] - m[2]))*(m[0] - m[2]) + (4.*m[1])*m[1]);
/*
xx = m[1];
yy = v - m[0];
v /= sqrt(xx*xx + yy*yy) + 1e-7;
xx *= v;
yy *= v;
dx[x] = (short)cvRound(xx);
dy[x] = (short)cvRound(yy);
//dx[x] = (short)cvRound(v);
//dx[x] = dy[x] = (short)v;
d[0] = src[0] - src[-3];
ad[0] = CV_IABS(d[0]);
d[1] = src[1] - src[-2];
ad[1] = CV_IABS(d[1]);
d[2] = src[2] - src[-1];
ad[2] = CV_IABS(d[2]);
f0 = ad[1] > ad[0];
f1 = ad[2] > ad[f0];
val = d[tab[f0*2 + f1]];
d[0] = src[0] - src[-src_step];
ad[0] = CV_IABS(d[0]);
d[1] = src[1] - src[1-src_step];
ad[1] = CV_IABS(d[1]);
d[2] = src[2] - src[2-src_step];
ad[2] = CV_IABS(d[2]);
f0 = ad[1] > ad[0];
f1 = ad[2] > ad[f0];
dst[x] = (uchar)(val + d[tab[f0*2 + f1]] > thresh ? 255 : 0);*/
dst[x] = (uchar)(val > thresh);
}
src = src0;
}
}
#endif
const CvPoint icvCodeDeltas[8] =
{ {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };
static CvSeq*
icvGetComponent( uchar* img, int step, CvRect rect,
CvMemStorage* storage )
{
const char nbd = 4;
int deltas[16];
int x, y;
CvSeq* exterior = 0;
char* ptr;
/* initialize local state */
CV_INIT_3X3_DELTAS( deltas, step, 1 );
memcpy( deltas + 8, deltas, 8 * sizeof( deltas[0] ));
ptr = (char*)(img + step*rect.y);
rect.width += rect.x;
rect.height += rect.y;
for( y = rect.y; y < rect.height; y++, ptr += step )
{
int prev = ptr[rect.x - 1] & -2;
for( x = rect.x; x < rect.width; x++ )
{
int p = ptr[x] & -2;
//assert( exterior || ((p | prev) & -4) == 0 );
if( p != prev )
{
CvSeq *seq = 0;
int is_hole = 0;
CvSeqWriter writer;
char *i0, *i1, *i3, *i4 = 0;
int prev_s = -1, s, s_end;
CvPoint pt = { x, y };
if( !(prev == 0 && p == 2) ) /* if not external contour */
{
/* check hole */
if( p != 0 || prev < 1 )
{
prev = p;
continue;
}
is_hole = 1;
if( !exterior )
{
assert(0);
return 0;
}
}
cvStartWriteSeq( CV_SEQ_CONTOUR | (is_hole ? CV_SEQ_FLAG_HOLE : 0),
sizeof(CvContour), sizeof(CvPoint), storage, &writer );
s_end = s = is_hole ? 0 : 4;
i0 = ptr + x - is_hole;
do
{
s = (s - 1) & 7;
i1 = i0 + deltas[s];
if( (*i1 & -2) != 0 )
break;
}
while( s != s_end );
if( s == s_end ) /* single pixel domain */
{
*i0 = (char) (nbd | -128);
CV_WRITE_SEQ_ELEM( pt, writer );
}
else
{
i3 = i0;
prev_s = s ^ 4;
/* follow border */
for( ;; )
{
s_end = s;
for( ;; )
{
i4 = i3 + deltas[++s];
if( (*i4 & -2) != 0 )
break;
}
s &= 7;
/* check "right" bound */
if( (unsigned) (s - 1) < (unsigned) s_end )
{
*i3 = (char) (nbd | -128);
}
else if( *i3 > 0 )
{
*i3 = nbd;
}
if( s != prev_s )
{
CV_WRITE_SEQ_ELEM( pt, writer );
prev_s = s;
}
pt.x += icvCodeDeltas[s].x;
pt.y += icvCodeDeltas[s].y;
if( i4 == i0 && i3 == i1 )
break;
i3 = i4;
s = (s + 4) & 7;
} /* end of border following loop */
}
seq = cvEndWriteSeq( &writer );
cvContourBoundingRect( seq, 1 );
if( !is_hole )
exterior = seq;
else
{
seq->v_prev = exterior;
seq->h_next = exterior->v_next;
if( seq->h_next )
seq->h_next->h_prev = seq;
exterior->v_next = seq;
}
prev = ptr[x] & -2;
}
}
}
return exterior;
}
CV_IMPL CvSeq*
cvSegmentImage( const CvArr* srcarr, CvArr* dstarr,
double canny_threshold,
double ffill_threshold,
CvMemStorage* storage )
{
CvSeq* root = 0;
CvMat* gray = 0;
CvMat* canny = 0;
//CvMat* temp = 0;
void* stack = 0;
CV_FUNCNAME( "cvSegmentImage" );
__BEGIN__;
CvMat srcstub, *src;
CvMat dststub, *dst;
CvMat* mask;
CvSize size;
CvPoint pt;
int ffill_lw_up = cvRound( fabs(ffill_threshold) );
CvSeq* prev_seq = 0;
CV_CALL( src = cvGetMat( srcarr, &srcstub ));
CV_CALL( dst = cvGetMat( dstarr, &dststub ));
size = cvGetSize( src );
CV_CALL( gray = cvCreateMat( size.height, size.width, CV_8UC1 ));
CV_CALL( canny = cvCreateMat( size.height, size.width, CV_8UC1 ));
//CV_CALL( temp = cvCreateMat( size.height/2, size.width/2, CV_8UC3 ));
CV_CALL( stack = cvAlloc( size.width * size.height * sizeof(Seg)));
cvCvtColor( src, gray, CV_BGR2GRAY );
cvCanny( gray, canny, 0/*canny_threshold*0.4*/, canny_threshold, 3 );
cvThreshold( canny, canny, 1, 1, CV_THRESH_BINARY );
//cvZero( canny );
//color_derv( src, canny, canny_threshold );
//cvPyrDown( src, temp );
//cvPyrUp( temp, dst );
//src = dst;
mask = canny; // a new name for new role
// make a non-zero border.
cvRectangle( mask, cvPoint(0,0), cvPoint(size.width-1,size.height-1), cvScalarAll(1), 1 );
for( pt.y = 0; pt.y < size.height; pt.y++ )
{
for( pt.x = 0; pt.x < size.width; pt.x++ )
{
if( mask->data.ptr[mask->step*pt.y + pt.x] == 0 )
{
CvConnectedComp region;
int avgVal[3] = { 0, 0, 0 };
icvSegmFloodFill_Stage1( src->data.ptr, src->step,
mask->data.ptr, mask->step,
size, pt, avgVal,
ffill_lw_up, ffill_lw_up,
&region, stack );
/*avgVal[0] = (avgVal[0] + 15) & -32;
if( avgVal[0] > 255 )
avgVal[0] = 255;
avgVal[1] = (avgVal[1] + 15) & -32;
if( avgVal[1] > 255 )
avgVal[1] = 255;
avgVal[2] = (avgVal[2] + 15) & -32;
if( avgVal[2] > 255 )
avgVal[2] = 255;*/
if( storage )
{
CvSeq* tmpseq = icvGetComponent( mask->data.ptr, mask->step,
region.rect, storage );
if( tmpseq != 0 )
{
((CvContour*)tmpseq)->color = avgVal[0] + (avgVal[1] << 8) + (avgVal[2] << 16);
tmpseq->h_prev = prev_seq;
if( prev_seq )
prev_seq->h_next = tmpseq;
else
root = tmpseq;
prev_seq = tmpseq;
}
}
icvSegmFloodFill_Stage2( dst->data.ptr, dst->step,
mask->data.ptr, mask->step,
size, avgVal,
region.rect );
}
}
}
__END__;
//cvReleaseMat( &temp );
cvReleaseMat( &gray );
cvReleaseMat( &canny );
cvFree( &stack );
return root;
}
/* End of file. */

View File

@@ -0,0 +1,187 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
CV_IMPL int
icvSubdiv2DCheck( CvSubdiv2D* subdiv )
{
int i, j, total = subdiv->edges->total;
int check_result = 0;
CV_FUNCNAME("icvSubdiv2DCheck");
__BEGIN__;
if( !subdiv )
CV_ERROR_FROM_STATUS( CV_NULLPTR_ERR );
for( i = 0; i < total; i++ )
{
CvQuadEdge2D* edge = (CvQuadEdge2D*)cvGetSetElem(subdiv->edges,i);
if( edge && CV_IS_SET_ELEM( edge ))
{
for( j = 0; j < 4; j++ )
{
CvSubdiv2DEdge e = (CvSubdiv2DEdge)edge + j;
CvSubdiv2DEdge o_next = cvSubdiv2DNextEdge(e);
CvSubdiv2DEdge o_prev = cvSubdiv2DGetEdge(e, CV_PREV_AROUND_ORG );
CvSubdiv2DEdge d_prev = cvSubdiv2DGetEdge(e, CV_PREV_AROUND_DST );
CvSubdiv2DEdge d_next = cvSubdiv2DGetEdge(e, CV_NEXT_AROUND_DST );
// check points
if( cvSubdiv2DEdgeOrg(e) != cvSubdiv2DEdgeOrg(o_next))
EXIT;
if( cvSubdiv2DEdgeOrg(e) != cvSubdiv2DEdgeOrg(o_prev))
EXIT;
if( cvSubdiv2DEdgeDst(e) != cvSubdiv2DEdgeDst(d_next))
EXIT;
if( cvSubdiv2DEdgeDst(e) != cvSubdiv2DEdgeDst(d_prev))
EXIT;
if( j % 2 == 0 )
{
if( cvSubdiv2DEdgeDst(o_next) != cvSubdiv2DEdgeOrg(d_prev))
EXIT;
if( cvSubdiv2DEdgeDst(o_prev) != cvSubdiv2DEdgeOrg(d_next))
EXIT;
if( cvSubdiv2DGetEdge(cvSubdiv2DGetEdge(cvSubdiv2DGetEdge(
e,CV_NEXT_AROUND_LEFT),CV_NEXT_AROUND_LEFT),CV_NEXT_AROUND_LEFT) != e )
EXIT;
if( cvSubdiv2DGetEdge(cvSubdiv2DGetEdge(cvSubdiv2DGetEdge(
e,CV_NEXT_AROUND_RIGHT),CV_NEXT_AROUND_RIGHT),CV_NEXT_AROUND_RIGHT) != e)
EXIT;
}
}
}
}
check_result = 1;
__END__;
return check_result;
}
static void
draw_subdiv_facet( CvSubdiv2D * subdiv, IplImage * dst, IplImage * src, CvSubdiv2DEdge edge )
{
CvSubdiv2DEdge t = edge;
int i, count = 0;
CvPoint local_buf[100];
CvPoint *buf = local_buf;
// count number of edges in facet
do
{
count++;
t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
}
while( t != edge && count < subdiv->quad_edges * 4 );
if( count * sizeof( buf[0] ) > sizeof( local_buf ))
{
buf = (CvPoint *) malloc( count * sizeof( buf[0] ));
}
// gather points
t = edge;
for( i = 0; i < count; i++ )
{
CvSubdiv2DPoint *pt = cvSubdiv2DEdgeOrg( t );
if( !pt )
break;
assert( fabs( pt->pt.x ) < 10000 && fabs( pt->pt.y ) < 10000 );
buf[i] = cvPoint( cvRound( pt->pt.x ), cvRound( pt->pt.y ));
t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
}
if( i == count )
{
CvSubdiv2DPoint *pt = cvSubdiv2DEdgeDst( cvSubdiv2DRotateEdge( edge, 1 ));
CvPoint ip = cvPoint( cvRound( pt->pt.x ), cvRound( pt->pt.y ));
CvScalar color = {{0,0,0,0}};
//printf("count = %d, (%d,%d)\n", ip.x, ip.y );
if( 0 <= ip.x && ip.x < src->width && 0 <= ip.y && ip.y < src->height )
{
uchar *ptr = (uchar*)(src->imageData + ip.y * src->widthStep + ip.x * 3);
color = CV_RGB( ptr[2], ptr[1], ptr[0] );
}
cvFillConvexPoly( dst, buf, count, color );
//draw_subdiv_point( dst, pt->pt, CV_RGB(0,0,0));
}
if( buf != local_buf )
free( buf );
}
CV_IMPL void
icvDrawMosaic( CvSubdiv2D * subdiv, IplImage * src, IplImage * dst )
{
int i, total = subdiv->edges->total;
cvCalcSubdivVoronoi2D( subdiv );
//icvSet( dst, 255 );
for( i = 0; i < total; i++ )
{
CvQuadEdge2D *edge = (CvQuadEdge2D *) cvGetSetElem( subdiv->edges, i );
if( edge && CV_IS_SET_ELEM( edge ))
{
CvSubdiv2DEdge e = (CvSubdiv2DEdge) edge;
// left
draw_subdiv_facet( subdiv, dst, src, cvSubdiv2DRotateEdge( e, 1 ));
// right
draw_subdiv_facet( subdiv, dst, src, cvSubdiv2DRotateEdge( e, 3 ));
}
}
}
/* End of file. */

View File

@@ -0,0 +1,648 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/****************************************************************************************\
Calculation of a texture descriptors from GLCM (Grey Level Co-occurrence Matrix'es)
The code was submitted by Daniel Eaton [danieljameseaton@yahoo.com]
\****************************************************************************************/
#include "_cvaux.h"
#include <math.h>
#include <assert.h>
#define CV_MAX_NUM_GREY_LEVELS_8U 256
struct CvGLCM
{
int matrixSideLength;
int numMatrices;
double*** matrices;
int numLookupTableElements;
int forwardLookupTable[CV_MAX_NUM_GREY_LEVELS_8U];
int reverseLookupTable[CV_MAX_NUM_GREY_LEVELS_8U];
double** descriptors;
int numDescriptors;
int descriptorOptimizationType;
int optimizationType;
};
static void icvCreateGLCM_LookupTable_8u_C1R( const uchar* srcImageData, int srcImageStep,
CvSize srcImageSize, CvGLCM* destGLCM,
int* steps, int numSteps, int* memorySteps );
static void
icvCreateGLCMDescriptors_AllowDoubleNest( CvGLCM* destGLCM, int matrixIndex );
CV_IMPL CvGLCM*
cvCreateGLCM( const IplImage* srcImage,
int stepMagnitude,
const int* srcStepDirections,/* should be static array..
or if not the user should handle de-allocation */
int numStepDirections,
int optimizationType )
{
static const int defaultStepDirections[] = { 0,1, -1,1, -1,0, -1,-1 };
int* memorySteps = 0;
CvGLCM* newGLCM = 0;
int* stepDirections = 0;
CV_FUNCNAME( "cvCreateGLCM" );
__BEGIN__;
uchar* srcImageData = 0;
CvSize srcImageSize;
int srcImageStep;
int stepLoop;
const int maxNumGreyLevels8u = CV_MAX_NUM_GREY_LEVELS_8U;
if( !srcImage )
CV_ERROR( CV_StsNullPtr, "" );
if( srcImage->nChannels != 1 )
CV_ERROR( CV_BadNumChannels, "Number of channels must be 1");
if( srcImage->depth != IPL_DEPTH_8U )
CV_ERROR( CV_BadDepth, "Depth must be equal IPL_DEPTH_8U");
// no Directions provided, use the default ones - 0 deg, 45, 90, 135
if( !srcStepDirections )
{
srcStepDirections = defaultStepDirections;
}
CV_CALL( stepDirections = (int*)cvAlloc( numStepDirections*2*sizeof(stepDirections[0])));
memcpy( stepDirections, srcStepDirections, numStepDirections*2*sizeof(stepDirections[0]));
cvGetImageRawData( srcImage, &srcImageData, &srcImageStep, &srcImageSize );
// roll together Directions and magnitudes together with knowledge of image (step)
CV_CALL( memorySteps = (int*)cvAlloc( numStepDirections*sizeof(memorySteps[0])));
for( stepLoop = 0; stepLoop < numStepDirections; stepLoop++ )
{
stepDirections[stepLoop*2 + 0] *= stepMagnitude;
stepDirections[stepLoop*2 + 1] *= stepMagnitude;
memorySteps[stepLoop] = stepDirections[stepLoop*2 + 0]*srcImageStep +
stepDirections[stepLoop*2 + 1];
}
CV_CALL( newGLCM = (CvGLCM*)cvAlloc(sizeof(newGLCM)));
memset( newGLCM, 0, sizeof(newGLCM) );
newGLCM->matrices = 0;
newGLCM->numMatrices = numStepDirections;
newGLCM->optimizationType = optimizationType;
if( optimizationType <= CV_GLCM_OPTIMIZATION_LUT )
{
int lookupTableLoop, imageColLoop, imageRowLoop, lineOffset = 0;
// if optimization type is set to lut, then make one for the image
if( optimizationType == CV_GLCM_OPTIMIZATION_LUT )
{
for( imageRowLoop = 0; imageRowLoop < srcImageSize.height;
imageRowLoop++, lineOffset += srcImageStep )
{
for( imageColLoop = 0; imageColLoop < srcImageSize.width; imageColLoop++ )
{
newGLCM->forwardLookupTable[srcImageData[lineOffset+imageColLoop]]=1;
}
}
newGLCM->numLookupTableElements = 0;
for( lookupTableLoop = 0; lookupTableLoop < maxNumGreyLevels8u; lookupTableLoop++ )
{
if( newGLCM->forwardLookupTable[ lookupTableLoop ] != 0 )
{
newGLCM->forwardLookupTable[ lookupTableLoop ] =
newGLCM->numLookupTableElements;
newGLCM->reverseLookupTable[ newGLCM->numLookupTableElements ] =
lookupTableLoop;
newGLCM->numLookupTableElements++;
}
}
}
// otherwise make a "LUT" which contains all the gray-levels (for code-reuse)
else if( optimizationType == CV_GLCM_OPTIMIZATION_NONE )
{
for( lookupTableLoop = 0; lookupTableLoop <maxNumGreyLevels8u; lookupTableLoop++ )
{
newGLCM->forwardLookupTable[ lookupTableLoop ] = lookupTableLoop;
newGLCM->reverseLookupTable[ lookupTableLoop ] = lookupTableLoop;
}
newGLCM->numLookupTableElements = maxNumGreyLevels8u;
}
newGLCM->matrixSideLength = newGLCM->numLookupTableElements;
icvCreateGLCM_LookupTable_8u_C1R( srcImageData, srcImageStep, srcImageSize,
newGLCM, stepDirections,
numStepDirections, memorySteps );
}
else if( optimizationType == CV_GLCM_OPTIMIZATION_HISTOGRAM )
{
CV_ERROR( CV_StsBadFlag, "Histogram-based method is not implemented" );
/* newGLCM->numMatrices *= 2;
newGLCM->matrixSideLength = maxNumGreyLevels8u*2;
icvCreateGLCM_Histogram_8uC1R( srcImageStep, srcImageSize, srcImageData,
newGLCM, numStepDirections,
stepDirections, memorySteps );
*/
}
__END__;
cvFree( &memorySteps );
cvFree( &stepDirections );
if( cvGetErrStatus() < 0 )
{
cvFree( &newGLCM );
}
return newGLCM;
}
CV_IMPL void
cvReleaseGLCM( CvGLCM** GLCM, int flag )
{
CV_FUNCNAME( "cvReleaseGLCM" );
__BEGIN__;
int matrixLoop;
if( !GLCM )
CV_ERROR( CV_StsNullPtr, "" );
if( *GLCM )
EXIT; // repeated deallocation: just skip it.
if( (flag == CV_GLCM_GLCM || flag == CV_GLCM_ALL) && (*GLCM)->matrices )
{
for( matrixLoop = 0; matrixLoop < (*GLCM)->numMatrices; matrixLoop++ )
{
if( (*GLCM)->matrices[ matrixLoop ] )
{
cvFree( (*GLCM)->matrices[matrixLoop] );
cvFree( (*GLCM)->matrices + matrixLoop );
}
}
cvFree( &((*GLCM)->matrices) );
}
if( (flag == CV_GLCM_DESC || flag == CV_GLCM_ALL) && (*GLCM)->descriptors )
{
for( matrixLoop = 0; matrixLoop < (*GLCM)->numMatrices; matrixLoop++ )
{
cvFree( (*GLCM)->descriptors + matrixLoop );
}
cvFree( &((*GLCM)->descriptors) );
}
if( flag == CV_GLCM_ALL )
{
cvFree( GLCM );
}
__END__;
}
static void
icvCreateGLCM_LookupTable_8u_C1R( const uchar* srcImageData,
int srcImageStep,
CvSize srcImageSize,
CvGLCM* destGLCM,
int* steps,
int numSteps,
int* memorySteps )
{
int* stepIncrementsCounter = 0;
CV_FUNCNAME( "icvCreateGLCM_LookupTable_8u_C1R" );
__BEGIN__;
int matrixSideLength = destGLCM->matrixSideLength;
int stepLoop, sideLoop1, sideLoop2;
int colLoop, rowLoop, lineOffset = 0;
double*** matrices = 0;
// allocate memory to the matrices
CV_CALL( destGLCM->matrices = (double***)cvAlloc( sizeof(matrices[0])*numSteps ));
matrices = destGLCM->matrices;
for( stepLoop=0; stepLoop<numSteps; stepLoop++ )
{
CV_CALL( matrices[stepLoop] = (double**)cvAlloc( sizeof(matrices[0])*matrixSideLength ));
CV_CALL( matrices[stepLoop][0] = (double*)cvAlloc( sizeof(matrices[0][0])*
matrixSideLength*matrixSideLength ));
memset( matrices[stepLoop][0], 0, matrixSideLength*matrixSideLength*
sizeof(matrices[0][0]) );
for( sideLoop1 = 1; sideLoop1 < matrixSideLength; sideLoop1++ )
{
matrices[stepLoop][sideLoop1] = matrices[stepLoop][sideLoop1-1] + matrixSideLength;
}
}
CV_CALL( stepIncrementsCounter = (int*)cvAlloc( numSteps*sizeof(stepIncrementsCounter[0])));
memset( stepIncrementsCounter, 0, numSteps*sizeof(stepIncrementsCounter[0]) );
// generate GLCM for each step
for( rowLoop=0; rowLoop<srcImageSize.height; rowLoop++, lineOffset+=srcImageStep )
{
for( colLoop=0; colLoop<srcImageSize.width; colLoop++ )
{
int pixelValue1 = destGLCM->forwardLookupTable[srcImageData[lineOffset + colLoop]];
for( stepLoop=0; stepLoop<numSteps; stepLoop++ )
{
int col2, row2;
row2 = rowLoop + steps[stepLoop*2 + 0];
col2 = colLoop + steps[stepLoop*2 + 1];
if( col2>=0 && row2>=0 && col2<srcImageSize.width && row2<srcImageSize.height )
{
int memoryStep = memorySteps[ stepLoop ];
int pixelValue2 = destGLCM->forwardLookupTable[ srcImageData[ lineOffset + colLoop + memoryStep ] ];
// maintain symmetry
matrices[stepLoop][pixelValue1][pixelValue2] ++;
matrices[stepLoop][pixelValue2][pixelValue1] ++;
// incremenet counter of total number of increments
stepIncrementsCounter[stepLoop] += 2;
}
}
}
}
// normalize matrices. each element is a probability of gray value i,j adjacency in direction/magnitude k
for( sideLoop1=0; sideLoop1<matrixSideLength; sideLoop1++ )
{
for( sideLoop2=0; sideLoop2<matrixSideLength; sideLoop2++ )
{
for( stepLoop=0; stepLoop<numSteps; stepLoop++ )
{
matrices[stepLoop][sideLoop1][sideLoop2] /= double(stepIncrementsCounter[stepLoop]);
}
}
}
destGLCM->matrices = matrices;
__END__;
cvFree( &stepIncrementsCounter );
if( cvGetErrStatus() < 0 )
cvReleaseGLCM( &destGLCM, CV_GLCM_GLCM );
}
CV_IMPL void
cvCreateGLCMDescriptors( CvGLCM* destGLCM, int descriptorOptimizationType )
{
CV_FUNCNAME( "cvCreateGLCMDescriptors" );
__BEGIN__;
int matrixLoop;
if( !destGLCM )
CV_ERROR( CV_StsNullPtr, "" );
if( !(destGLCM->matrices) )
CV_ERROR( CV_StsNullPtr, "Matrices are not allocated" );
CV_CALL( cvReleaseGLCM( &destGLCM, CV_GLCM_DESC ));
if( destGLCM->optimizationType != CV_GLCM_OPTIMIZATION_HISTOGRAM )
{
destGLCM->descriptorOptimizationType = destGLCM->numDescriptors = descriptorOptimizationType;
}
else
{
CV_ERROR( CV_StsBadFlag, "Histogram-based method is not implemented" );
// destGLCM->descriptorOptimizationType = destGLCM->numDescriptors = CV_GLCMDESC_OPTIMIZATION_HISTOGRAM;
}
CV_CALL( destGLCM->descriptors = (double**)
cvAlloc( destGLCM->numMatrices*sizeof(destGLCM->descriptors[0])));
for( matrixLoop = 0; matrixLoop < destGLCM->numMatrices; matrixLoop ++ )
{
CV_CALL( destGLCM->descriptors[ matrixLoop ] =
(double*)cvAlloc( destGLCM->numDescriptors*sizeof(destGLCM->descriptors[0][0])));
memset( destGLCM->descriptors[matrixLoop], 0, destGLCM->numDescriptors*sizeof(double) );
switch( destGLCM->descriptorOptimizationType )
{
case CV_GLCMDESC_OPTIMIZATION_ALLOWDOUBLENEST:
icvCreateGLCMDescriptors_AllowDoubleNest( destGLCM, matrixLoop );
break;
default:
CV_ERROR( CV_StsBadFlag,
"descriptorOptimizationType different from CV_GLCMDESC_OPTIMIZATION_ALLOWDOUBLENEST\n"
"is not supported" );
/*
case CV_GLCMDESC_OPTIMIZATION_ALLOWTRIPLENEST:
icvCreateGLCMDescriptors_AllowTripleNest( destGLCM, matrixLoop );
break;
case CV_GLCMDESC_OPTIMIZATION_HISTOGRAM:
if(matrixLoop < destGLCM->numMatrices>>1)
icvCreateGLCMDescriptors_Histogram( destGLCM, matrixLoop);
break;
*/
}
}
__END__;
if( cvGetErrStatus() < 0 )
cvReleaseGLCM( &destGLCM, CV_GLCM_DESC );
}
static void
icvCreateGLCMDescriptors_AllowDoubleNest( CvGLCM* destGLCM, int matrixIndex )
{
int sideLoop1, sideLoop2;
int matrixSideLength = destGLCM->matrixSideLength;
double** matrix = destGLCM->matrices[ matrixIndex ];
double* descriptors = destGLCM->descriptors[ matrixIndex ];
double* marginalProbability =
(double*)cvAlloc( matrixSideLength * sizeof(marginalProbability[0]));
memset( marginalProbability, 0, matrixSideLength * sizeof(double) );
double maximumProbability = 0;
double marginalProbabilityEntropy = 0;
double correlationMean = 0, correlationStdDeviation = 0, correlationProductTerm = 0;
for( sideLoop1=0; sideLoop1<matrixSideLength; sideLoop1++ )
{
int actualSideLoop1 = destGLCM->reverseLookupTable[ sideLoop1 ];
for( sideLoop2=0; sideLoop2<matrixSideLength; sideLoop2++ )
{
double entryValue = matrix[ sideLoop1 ][ sideLoop2 ];
int actualSideLoop2 = destGLCM->reverseLookupTable[ sideLoop2 ];
int sideLoopDifference = actualSideLoop1 - actualSideLoop2;
int sideLoopDifferenceSquared = sideLoopDifference*sideLoopDifference;
marginalProbability[ sideLoop1 ] += entryValue;
correlationMean += actualSideLoop1*entryValue;
maximumProbability = MAX( maximumProbability, entryValue );
if( actualSideLoop2 > actualSideLoop1 )
{
descriptors[ CV_GLCMDESC_CONTRAST ] += sideLoopDifferenceSquared * entryValue;
}
descriptors[ CV_GLCMDESC_HOMOGENITY ] += entryValue / ( 1.0 + sideLoopDifferenceSquared );
if( entryValue > 0 )
{
descriptors[ CV_GLCMDESC_ENTROPY ] += entryValue * log( entryValue );
}
descriptors[ CV_GLCMDESC_ENERGY ] += entryValue*entryValue;
}
if( marginalProbability>0 )
marginalProbabilityEntropy += marginalProbability[ actualSideLoop1 ]*log(marginalProbability[ actualSideLoop1 ]);
}
marginalProbabilityEntropy = -marginalProbabilityEntropy;
descriptors[ CV_GLCMDESC_CONTRAST ] += descriptors[ CV_GLCMDESC_CONTRAST ];
descriptors[ CV_GLCMDESC_ENTROPY ] = -descriptors[ CV_GLCMDESC_ENTROPY ];
descriptors[ CV_GLCMDESC_MAXIMUMPROBABILITY ] = maximumProbability;
double HXY = 0, HXY1 = 0, HXY2 = 0;
HXY = descriptors[ CV_GLCMDESC_ENTROPY ];
for( sideLoop1=0; sideLoop1<matrixSideLength; sideLoop1++ )
{
double sideEntryValueSum = 0;
int actualSideLoop1 = destGLCM->reverseLookupTable[ sideLoop1 ];
for( sideLoop2=0; sideLoop2<matrixSideLength; sideLoop2++ )
{
double entryValue = matrix[ sideLoop1 ][ sideLoop2 ];
sideEntryValueSum += entryValue;
int actualSideLoop2 = destGLCM->reverseLookupTable[ sideLoop2 ];
correlationProductTerm += (actualSideLoop1 - correlationMean) * (actualSideLoop2 - correlationMean) * entryValue;
double clusterTerm = actualSideLoop1 + actualSideLoop2 - correlationMean - correlationMean;
descriptors[ CV_GLCMDESC_CLUSTERTENDENCY ] += clusterTerm * clusterTerm * entryValue;
descriptors[ CV_GLCMDESC_CLUSTERSHADE ] += clusterTerm * clusterTerm * clusterTerm * entryValue;
double HXYValue = marginalProbability[ actualSideLoop1 ] * marginalProbability[ actualSideLoop2 ];
if( HXYValue>0 )
{
double HXYValueLog = log( HXYValue );
HXY1 += entryValue * HXYValueLog;
HXY2 += HXYValue * HXYValueLog;
}
}
correlationStdDeviation += (actualSideLoop1-correlationMean) * (actualSideLoop1-correlationMean) * sideEntryValueSum;
}
HXY1 =- HXY1;
HXY2 =- HXY2;
descriptors[ CV_GLCMDESC_CORRELATIONINFO1 ] = ( HXY - HXY1 ) / ( correlationMean );
descriptors[ CV_GLCMDESC_CORRELATIONINFO2 ] = sqrt( 1.0 - exp( -2.0 * (HXY2 - HXY ) ) );
correlationStdDeviation = sqrt( correlationStdDeviation );
descriptors[ CV_GLCMDESC_CORRELATION ] = correlationProductTerm / (correlationStdDeviation*correlationStdDeviation );
delete [] marginalProbability;
}
CV_IMPL double cvGetGLCMDescriptor( CvGLCM* GLCM, int step, int descriptor )
{
double value = DBL_MAX;
CV_FUNCNAME( "cvGetGLCMDescriptor" );
__BEGIN__;
if( !GLCM )
CV_ERROR( CV_StsNullPtr, "" );
if( !(GLCM->descriptors) )
CV_ERROR( CV_StsNullPtr, "" );
if( (unsigned)step >= (unsigned)(GLCM->numMatrices))
CV_ERROR( CV_StsOutOfRange, "step is not in 0 .. GLCM->numMatrices - 1" );
if( (unsigned)descriptor >= (unsigned)(GLCM->numDescriptors))
CV_ERROR( CV_StsOutOfRange, "descriptor is not in 0 .. GLCM->numDescriptors - 1" );
value = GLCM->descriptors[step][descriptor];
__END__;
return value;
}
CV_IMPL void
cvGetGLCMDescriptorStatistics( CvGLCM* GLCM, int descriptor,
double* _average, double* _standardDeviation )
{
CV_FUNCNAME( "cvGetGLCMDescriptorStatistics" );
if( _average )
*_average = DBL_MAX;
if( _standardDeviation )
*_standardDeviation = DBL_MAX;
__BEGIN__;
int matrixLoop, numMatrices;
double average = 0, squareSum = 0;
if( !GLCM )
CV_ERROR( CV_StsNullPtr, "" );
if( !(GLCM->descriptors))
CV_ERROR( CV_StsNullPtr, "Descriptors are not calculated" );
if( (unsigned)descriptor >= (unsigned)(GLCM->numDescriptors) )
CV_ERROR( CV_StsOutOfRange, "Descriptor index is out of range" );
numMatrices = GLCM->numMatrices;
for( matrixLoop = 0; matrixLoop < numMatrices; matrixLoop++ )
{
double temp = GLCM->descriptors[ matrixLoop ][ descriptor ];
average += temp;
squareSum += temp*temp;
}
average /= numMatrices;
if( _average )
*_average = average;
if( _standardDeviation )
*_standardDeviation = sqrt( (squareSum - average*average*numMatrices)/(numMatrices-1));
__END__;
}
CV_IMPL IplImage*
cvCreateGLCMImage( CvGLCM* GLCM, int step )
{
IplImage* dest = 0;
CV_FUNCNAME( "cvCreateGLCMImage" );
__BEGIN__;
float* destData;
int sideLoop1, sideLoop2;
if( !GLCM )
CV_ERROR( CV_StsNullPtr, "" );
if( !(GLCM->matrices) )
CV_ERROR( CV_StsNullPtr, "Matrices are not allocated" );
if( (unsigned)step >= (unsigned)(GLCM->numMatrices) )
CV_ERROR( CV_StsOutOfRange, "The step index is out of range" );
dest = cvCreateImage( cvSize( GLCM->matrixSideLength, GLCM->matrixSideLength ), IPL_DEPTH_32F, 1 );
destData = (float*)(dest->imageData);
for( sideLoop1 = 0; sideLoop1 < GLCM->matrixSideLength;
sideLoop1++, (float*&)destData += dest->widthStep )
{
for( sideLoop2=0; sideLoop2 < GLCM->matrixSideLength; sideLoop2++ )
{
double matrixValue = GLCM->matrices[step][sideLoop1][sideLoop2];
destData[ sideLoop2 ] = (float)matrixValue;
}
}
__END__;
if( cvGetErrStatus() < 0 )
cvReleaseImage( &dest );
return dest;
}

View File

@@ -0,0 +1,975 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/****************************************************************************************\
Contour-based face feature tracking
The code was created by Tatiana Cherepanova (tata@sl.iae.nsk.su)
\****************************************************************************************/
#include "_cvaux.h"
#include "_cvvectrack.h"
#define _ASSERT assert
#define NUM_FACE_ELEMENTS 3
enum
{
MOUTH = 0,
LEYE = 1,
REYE = 2,
};
#define MAX_LAYERS 64
const double pi = 3.1415926535;
struct CvFaceTracker;
struct CvTrackingRect;
class CvFaceElement;
void ThresholdingParam(IplImage *imgGray, int iNumLayers, int &iMinLevel, int &iMaxLevel, float &step, float& power, int iHistMin /*= HIST_MIN*/);
int ChoiceTrackingFace3(CvFaceTracker* pTF, const int nElements, const CvFaceElement* big_face, CvTrackingRect* face, int& new_energy);
int ChoiceTrackingFace2(CvFaceTracker* pTF, const int nElements, const CvFaceElement* big_face, CvTrackingRect* face, int& new_energy, int noel);
inline int GetEnergy(CvTrackingRect** ppNew, const CvTrackingRect* pPrev, CvPoint* ptTempl, CvRect* rTempl);
inline int GetEnergy2(CvTrackingRect** ppNew, const CvTrackingRect* pPrev, CvPoint* ptTempl, CvRect* rTempl, int* element);
inline double CalculateTransformationLMS3_0( CvPoint* pTemplPoints, CvPoint* pSrcPoints);
inline double CalculateTransformationLMS3( CvPoint* pTemplPoints,
CvPoint* pSrcPoints,
double* pdbAverageScale,
double* pdbAverageRotate,
double* pdbAverageShiftX,
double* pdbAverageShiftY );
struct CvTrackingRect
{
CvRect r;
CvPoint ptCenter;
int iColor;
int iEnergy;
int nRectsInThis;
int nRectsOnLeft;
int nRectsOnRight;
int nRectsOnTop;
int nRectsOnBottom;
CvTrackingRect() { memset(this, 0, sizeof(CvTrackingRect)); };
int Energy(const CvTrackingRect& prev)
{
int prev_color = 0 == prev.iColor ? iColor : prev.iColor;
iEnergy = 1 * pow2(r.width - prev.r.width) +
1 * pow2(r.height - prev.r.height) +
1 * pow2(iColor - prev_color) / 4 +
- 1 * nRectsInThis +
- 0 * nRectsOnTop +
+ 0 * nRectsOnLeft +
+ 0 * nRectsOnRight +
+ 0 * nRectsOnBottom;
return iEnergy;
}
};
struct CvFaceTracker
{
CvTrackingRect face[NUM_FACE_ELEMENTS];
int iTrackingFaceType;
double dbRotateDelta;
double dbRotateAngle;
CvPoint ptRotate;
CvPoint ptTempl[NUM_FACE_ELEMENTS];
CvRect rTempl[NUM_FACE_ELEMENTS];
IplImage* imgGray;
IplImage* imgThresh;
CvMemStorage* mstgContours;
CvFaceTracker()
{
ptRotate.x = 0;
ptRotate.y = 0;
dbRotateDelta = 0;
dbRotateAngle = 0;
iTrackingFaceType = -1;
imgThresh = NULL;
imgGray = NULL;
mstgContours = NULL;
};
~CvFaceTracker()
{
if (NULL != imgGray)
delete imgGray;
if (NULL != imgThresh)
delete imgThresh;
if (NULL != mstgContours)
cvReleaseMemStorage(&mstgContours);
};
int Init(CvRect* pRects, IplImage* imgGray)
{
for (int i = 0; i < NUM_FACE_ELEMENTS; i++)
{
face[i].r = pRects[i];
face[i].ptCenter = Center(face[i].r);
ptTempl[i] = face[i].ptCenter;
rTempl[i] = face[i].r;
}
imgGray = cvCreateImage(cvSize(imgGray->width, imgGray->height), 8, 1);
imgThresh = cvCreateImage(cvSize(imgGray->width, imgGray->height), 8, 1);
mstgContours = cvCreateMemStorage();
if ((NULL == imgGray) ||
(NULL == imgThresh) ||
(NULL == mstgContours))
return FALSE;
return TRUE;
};
int InitNextImage(IplImage* img)
{
CvSize sz = {img->width, img->height};
ReallocImage(&imgGray, sz, 1);
ReallocImage(&imgThresh, sz, 1);
ptRotate = face[MOUTH].ptCenter;
float m[6];
CvMat mat = cvMat( 2, 3, CV_32FC1, m );
if (NULL == imgGray || NULL == imgThresh)
return FALSE;
/*m[0] = (float)cos(-dbRotateAngle*CV_PI/180.);
m[1] = (float)sin(-dbRotateAngle*CV_PI/180.);
m[2] = (float)ptRotate.x;
m[3] = -m[1];
m[4] = m[0];
m[5] = (float)ptRotate.y;*/
cv2DRotationMatrix( cvPointTo32f(ptRotate), -dbRotateAngle, 1., &mat );
cvWarpAffine( img, imgGray, &mat );
if (NULL == mstgContours)
mstgContours = cvCreateMemStorage();
else
cvClearMemStorage(mstgContours);
if (NULL == mstgContours)
return FALSE;
return TRUE;
}
};
class CvFaceElement
{
public:
CvSeq* m_seqRects;
CvMemStorage* m_mstgRects;
CvRect m_rROI;
CvTrackingRect m_trPrev;
inline CvFaceElement()
{
m_seqRects = NULL;
m_mstgRects = NULL;
m_rROI.x = 0;
m_rROI.y = 0;
m_rROI.width = 0;
m_rROI.height = 0;
};
inline int Init(const CvRect& roi, const CvTrackingRect& prev, CvMemStorage* mstg = NULL)
{
m_rROI = roi;
m_trPrev = prev;
if (NULL != mstg)
m_mstgRects = mstg;
if (NULL == m_mstgRects)
return FALSE;
if (NULL == m_seqRects)
m_seqRects = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvTrackingRect), m_mstgRects);
else
cvClearSeq(m_seqRects);
if (NULL == m_seqRects)
return FALSE;
return TRUE;
};
void FindRects(IplImage* img, IplImage* thresh, int nLayers, int dMinSize);
protected:
void FindContours(IplImage* img, IplImage* thresh, int nLayers, int dMinSize);
void MergeRects(int d);
void Energy();
}; //class CvFaceElement
int CV_CDECL CompareEnergy(const void* el1, const void* el2, void*)
{
return ((CvTrackingRect*)el1)->iEnergy - ((CvTrackingRect*)el2)->iEnergy;
}// int CV_CDECL CompareEnergy(const void* el1, const void* el2, void*)
void CvFaceElement::FindRects(IplImage* img, IplImage* thresh, int nLayers, int dMinSize)
{
FindContours(img, thresh, nLayers, dMinSize / 4);
if (0 == m_seqRects->total)
return;
Energy();
cvSeqSort(m_seqRects, CompareEnergy, NULL);
CvTrackingRect* pR = (CvTrackingRect*)cvGetSeqElem(m_seqRects, 0);
if (m_seqRects->total < 32)
{
MergeRects(dMinSize / 8);
Energy();
cvSeqSort(m_seqRects, CompareEnergy, NULL);
}
pR = (CvTrackingRect*)cvGetSeqElem(m_seqRects, 0);
if ((pR->iEnergy > 100 && m_seqRects->total < 32) || (m_seqRects->total < 16))
{
MergeRects(dMinSize / 4);
Energy();
cvSeqSort(m_seqRects, CompareEnergy, NULL);
}
pR = (CvTrackingRect*)cvGetSeqElem(m_seqRects, 0);
if ((pR->iEnergy > 100 && m_seqRects->total < 16) || (pR->iEnergy > 200 && m_seqRects->total < 32))
{
MergeRects(dMinSize / 2);
Energy();
cvSeqSort(m_seqRects, CompareEnergy, NULL);
}
}// void CvFaceElement::FindRects(IplImage* img, IplImage* thresh, int nLayers, int dMinSize)
void CvFaceElement::FindContours(IplImage* img, IplImage* thresh, int nLayers, int dMinSize)
{
CvSeq* seq;
CvRect roi = m_rROI;
Extend(roi, 1);
cvSetImageROI(img, roi);
cvSetImageROI(thresh, roi);
// layers
int colors[MAX_LAYERS] = {0};
int iMinLevel = 0, iMaxLevel = 255;
float step, power;
ThresholdingParam(img, nLayers / 2, iMinLevel, iMaxLevel, step, power, 4);
int iMinLevelPrev = iMinLevel;
int iMaxLevelPrev = iMinLevel;
if (m_trPrev.iColor != 0)
{
iMinLevelPrev = m_trPrev.iColor - nLayers / 2;
iMaxLevelPrev = m_trPrev.iColor + nLayers / 2;
}
if (iMinLevelPrev < iMinLevel)
{
iMaxLevelPrev += iMinLevel - iMinLevelPrev;
iMinLevelPrev = iMinLevel;
}
if (iMaxLevelPrev > iMaxLevel)
{
iMinLevelPrev -= iMaxLevelPrev - iMaxLevel;
if (iMinLevelPrev < iMinLevel)
iMinLevelPrev = iMinLevel;
iMaxLevelPrev = iMaxLevel;
}
int n = nLayers;
n -= (iMaxLevelPrev - iMinLevelPrev + 1) / 2;
step = float(iMinLevelPrev - iMinLevel + iMaxLevel - iMaxLevelPrev) / float(n);
int j = 0;
float level;
for (level = (float)iMinLevel; level < iMinLevelPrev && j < nLayers; level += step, j++)
colors[j] = int(level + 0.5);
for (level = (float)iMinLevelPrev; level < iMaxLevelPrev && j < nLayers; level += 2.0, j++)
colors[j] = int(level + 0.5);
for (level = (float)iMaxLevelPrev; level < iMaxLevel && j < nLayers; level += step, j++)
colors[j] = int(level + 0.5);
//
for (int i = 0; i < nLayers; i++)
{
cvThreshold(img, thresh, colors[i], 255.0, CV_THRESH_BINARY);
if (cvFindContours(thresh, m_mstgRects, &seq, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE))
{
CvTrackingRect cr;
for (CvSeq* external = seq; external; external = external->h_next)
{
cr.r = cvContourBoundingRect(external);
Move(cr.r, roi.x, roi.y);
if (RectInRect(cr.r, m_rROI) && cr.r.width > dMinSize && cr.r.height > dMinSize)
{
cr.ptCenter = Center(cr.r);
cr.iColor = colors[i];
cvSeqPush(m_seqRects, &cr);
}
for (CvSeq* internal = external->v_next; internal; internal = internal->h_next)
{
cr.r = cvContourBoundingRect(internal);
Move(cr.r, roi.x, roi.y);
if (RectInRect(cr.r, m_rROI) && cr.r.width > dMinSize && cr.r.height > dMinSize)
{
cr.ptCenter = Center(cr.r);
cr.iColor = colors[i];
cvSeqPush(m_seqRects, &cr);
}
}
}
cvClearSeq(seq);
}
}
cvResetImageROI(img);
cvResetImageROI(thresh);
}//void CvFaceElement::FindContours(IplImage* img, IplImage* thresh, int nLayers)
void CvFaceElement::MergeRects(int d)
{
int nRects = m_seqRects->total;
CvSeqReader reader, reader2;
cvStartReadSeq( m_seqRects, &reader );
int i, j;
for (i = 0; i < nRects; i++)
{
CvTrackingRect* pRect1 = (CvTrackingRect*)(reader.ptr);
cvStartReadSeq( m_seqRects, &reader2 );
cvSetSeqReaderPos(&reader2, i + 1);
for (j = i + 1; j < nRects; j++)
{
CvTrackingRect* pRect2 = (CvTrackingRect*)(reader2.ptr);
if (abs(pRect1->ptCenter.y - pRect2->ptCenter.y) < d &&
abs(pRect1->r.height - pRect2->r.height) < d)
{
CvTrackingRect rNew;
rNew.iColor = (pRect1->iColor + pRect2->iColor + 1) / 2;
rNew.r.x = min(pRect1->r.x, pRect2->r.x);
rNew.r.y = min(pRect1->r.y, pRect2->r.y);
rNew.r.width = max(pRect1->r.x + pRect1->r.width, pRect2->r.x + pRect2->r.width) - rNew.r.x;
rNew.r.height = min(pRect1->r.y + pRect1->r.height, pRect2->r.y + pRect2->r.height) - rNew.r.y;
if (rNew.r != pRect1->r && rNew.r != pRect2->r)
{
rNew.ptCenter = Center(rNew.r);
cvSeqPush(m_seqRects, &rNew);
}
}
CV_NEXT_SEQ_ELEM( sizeof(CvTrackingRect), reader2 );
}
CV_NEXT_SEQ_ELEM( sizeof(CvTrackingRect), reader );
}
// delete equal rects
for (i = 0; i < m_seqRects->total; i++)
{
CvTrackingRect* pRect1 = (CvTrackingRect*)cvGetSeqElem(m_seqRects, i);
int j_begin = i + 1;
for (j = j_begin; j < m_seqRects->total;)
{
CvTrackingRect* pRect2 = (CvTrackingRect*)cvGetSeqElem(m_seqRects, j);
if (pRect1->r == pRect2->r)
cvSeqRemove(m_seqRects, j);
else
j++;
}
}
}//void CvFaceElement::MergeRects(int d)
void CvFaceElement::Energy()
{
CvSeqReader reader, reader2;
cvStartReadSeq( m_seqRects, &reader );
for (int i = 0; i < m_seqRects->total; i++)
{
CvTrackingRect* pRect = (CvTrackingRect*)(reader.ptr);
// outside and inside rects
cvStartReadSeq( m_seqRects, &reader2 );
for (int j = 0; j < m_seqRects->total; j++)
{
CvTrackingRect* pRect2 = (CvTrackingRect*)(reader2.ptr);
if (i != j)
{
if (RectInRect(pRect2->r, pRect->r))
pRect->nRectsInThis ++;
else if (pRect2->r.y + pRect2->r.height <= pRect->r.y)
pRect->nRectsOnTop ++;
else if (pRect2->r.y >= pRect->r.y + pRect->r.height)
pRect->nRectsOnBottom ++;
else if (pRect2->r.x + pRect2->r.width <= pRect->r.x)
pRect->nRectsOnLeft ++;
else if (pRect2->r.x >= pRect->r.x + pRect->r.width)
pRect->nRectsOnRight ++;
}
CV_NEXT_SEQ_ELEM( sizeof(CvTrackingRect), reader2 );
}
// energy
pRect->Energy(m_trPrev);
CV_NEXT_SEQ_ELEM( sizeof(CvTrackingRect), reader );
}
}//void CvFaceElement::Energy()
CV_IMPL CvFaceTracker*
cvInitFaceTracker(CvFaceTracker* pFaceTracker, const IplImage* imgGray, CvRect* pRects, int nRects)
{
_ASSERT(NULL != imgGray);
_ASSERT(NULL != pRects);
_ASSERT(nRects >= NUM_FACE_ELEMENTS);
if ((NULL == imgGray) ||
(NULL == pRects) ||
(nRects < NUM_FACE_ELEMENTS))
return NULL;
int new_face = FALSE;
CvFaceTracker* pFace = pFaceTracker;
if (NULL == pFace)
{
pFace = new CvFaceTracker;
if (NULL == pFace)
return NULL;
new_face = TRUE;
}
pFace->Init(pRects, (IplImage*)imgGray);
return pFace;
}//CvFaceTracker* InitFaceTracker(IplImage* imgGray, CvRect* pRects, int nRects)
CV_IMPL void
cvReleaseFaceTracker(CvFaceTracker** ppFaceTracker)
{
if (NULL == *ppFaceTracker)
return;
delete *ppFaceTracker;
*ppFaceTracker = NULL;
}//void ReleaseFaceTracker(CvFaceTracker** ppFaceTracker)
CV_IMPL int
cvTrackFace(CvFaceTracker* pFaceTracker, IplImage* imgGray, CvRect* pRects, int nRects, CvPoint* ptRotate, double* dbAngleRotate)
{
_ASSERT(NULL != pFaceTracker);
_ASSERT(NULL != imgGray);
_ASSERT(NULL != pRects && nRects >= NUM_FACE_ELEMENTS);
if ((NULL == pFaceTracker) ||
(NULL == imgGray))
return FALSE;
pFaceTracker->InitNextImage(imgGray);
*ptRotate = pFaceTracker->ptRotate;
*dbAngleRotate = pFaceTracker->dbRotateAngle;
int nElements = 16;
double dx = pFaceTracker->face[LEYE].ptCenter.x - pFaceTracker->face[REYE].ptCenter.x;
double dy = pFaceTracker->face[LEYE].ptCenter.y - pFaceTracker->face[REYE].ptCenter.y;
double d_eyes = sqrt(dx*dx + dy*dy);
int d = cvRound(0.25 * d_eyes);
int dMinSize = d;
int nRestarts = 0;
int elem;
CvFaceElement big_face[NUM_FACE_ELEMENTS];
START:
// init
for (elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
{
CvRect r = pFaceTracker->face[elem].r;
Extend(r, d);
if (r.width < 4*d)
{
r.x -= (4*d - r.width) / 2;
r.width += 4*d - r.width;
}
if (r.height < 3*d)
{
r.y -= (3*d - r.height) / 2;
r.height += 3*d - r.height;
}
if (r.x < 1)
r.x = 1;
if (r.y < 1)
r.y = 1;
if (r.x + r.width > pFaceTracker->imgGray->width - 2)
r.width = pFaceTracker->imgGray->width - 2 - r.x;
if (r.y + r.height > pFaceTracker->imgGray->height - 2)
r.height = pFaceTracker->imgGray->height - 2 - r.y;
if (!big_face[elem].Init(r, pFaceTracker->face[elem], pFaceTracker->mstgContours))
return FALSE;
}
// find contours
for (elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
big_face[elem].FindRects(pFaceTracker->imgGray, pFaceTracker->imgThresh, 32, dMinSize);
// candidats
CvTrackingRect new_face[NUM_FACE_ELEMENTS];
int new_energy = 0;
int found = ChoiceTrackingFace3(pFaceTracker, nElements, big_face, new_face, new_energy);
int restart = FALSE;
int find2 = FALSE;
int noel = -1;
if (found)
{
if (new_energy > 100000 && -1 != pFaceTracker->iTrackingFaceType)
find2 = TRUE;
else if (new_energy > 150000)
{
int elements = 0;
for (int el = 0; el < NUM_FACE_ELEMENTS; el++)
{
if (big_face[el].m_seqRects->total > 16 || (big_face[el].m_seqRects->total > 8 && new_face[el].iEnergy < 100))
elements++;
else
noel = el;
}
if (2 == elements)
find2 = TRUE;
else
restart = TRUE;
}
}
else
{
if (-1 != pFaceTracker->iTrackingFaceType)
find2 = TRUE;
else
restart = TRUE;
}
RESTART:
if (restart)
{
if (nRestarts++ < 2)
{
d = d + d/4;
goto START;
}
}
else if (find2)
{
if (-1 != pFaceTracker->iTrackingFaceType)
noel = pFaceTracker->iTrackingFaceType;
int found2 = ChoiceTrackingFace2(pFaceTracker, nElements, big_face, new_face, new_energy, noel);
if (found2 && new_energy < 100000)
{
pFaceTracker->iTrackingFaceType = noel;
found = TRUE;
}
else
{
restart = TRUE;
goto RESTART;
}
}
if (found)
{
// angle by mouth & eyes
double vx_prev = double(pFaceTracker->face[LEYE].ptCenter.x + pFaceTracker->face[REYE].ptCenter.x) / 2.0 - pFaceTracker->face[MOUTH].ptCenter.x;
double vy_prev = double(pFaceTracker->face[LEYE].ptCenter.y + pFaceTracker->face[REYE].ptCenter.y) / 2.0 - pFaceTracker->face[MOUTH].ptCenter.y;
double vx_prev1 = vx_prev * cos(pFaceTracker->dbRotateDelta) - vy_prev * sin(pFaceTracker->dbRotateDelta);
double vy_prev1 = vx_prev * sin(pFaceTracker->dbRotateDelta) + vy_prev * cos(pFaceTracker->dbRotateDelta);
vx_prev = vx_prev1;
vy_prev = vy_prev1;
for (elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
pFaceTracker->face[elem] = new_face[elem];
double vx = double(pFaceTracker->face[LEYE].ptCenter.x + pFaceTracker->face[REYE].ptCenter.x) / 2.0 - pFaceTracker->face[MOUTH].ptCenter.x;
double vy = double(pFaceTracker->face[LEYE].ptCenter.y + pFaceTracker->face[REYE].ptCenter.y) / 2.0 - pFaceTracker->face[MOUTH].ptCenter.y;
pFaceTracker->dbRotateDelta = 0;
double n1_n2 = (vx * vx + vy * vy) * (vx_prev * vx_prev + vy_prev * vy_prev);
if (n1_n2 != 0)
pFaceTracker->dbRotateDelta = asin((vx * vy_prev - vx_prev * vy) / sqrt(n1_n2));
pFaceTracker->dbRotateAngle -= pFaceTracker->dbRotateDelta;
}
else
{
pFaceTracker->dbRotateDelta = 0;
pFaceTracker->dbRotateAngle = 0;
}
if ((pFaceTracker->dbRotateAngle >= pi/2 && pFaceTracker->dbRotateAngle > 0) ||
(pFaceTracker->dbRotateAngle <= -pi/2 && pFaceTracker->dbRotateAngle < 0))
{
pFaceTracker->dbRotateDelta = 0;
pFaceTracker->dbRotateAngle = 0;
found = FALSE;
}
if (found)
{
for (int i = 0; i < NUM_FACE_ELEMENTS && i < nRects; i++)
pRects[i] = pFaceTracker->face[i].r;
}
return found;
}//int FindFaceTracker(CvFaceTracker* pFaceTracker, IplImage* imgGray, CvRect* pRects, int nRects, CvPoint& ptRotate, double& dbAngleRotate)
void ThresholdingParam(IplImage *imgGray, int iNumLayers, int &iMinLevel, int &iMaxLevel, float &step, float& power, int iHistMin /*= HIST_MIN*/)
{
_ASSERT(imgGray != NULL);
_ASSERT(imgGray->nChannels == 1);
int i, j;
// create histogram
int histImg[256] = {0};
uchar* buffImg = (uchar*)imgGray->imageData;
CvRect rROI = cvGetImageROI(imgGray);
buffImg += rROI.y * imgGray->widthStep + rROI.x;
for (j = 0; j < rROI.height; j++)
{
for (i = 0; i < rROI.width; i++)
histImg[buffImg[i]] ++;
buffImg += imgGray->widthStep;
}
// params
for (i = 0; i < 256; i++)
{
if (histImg[i] > iHistMin)
break;
}
iMinLevel = i;
for (i = 255; i >= 0; i--)
{
if (histImg[i] > iHistMin)
break;
}
iMaxLevel = i;
if (iMaxLevel <= iMinLevel)
{
iMaxLevel = 255;
iMinLevel = 0;
}
// power
double black = 1;
double white = 1;
for (i = iMinLevel; i < (iMinLevel + iMaxLevel) / 2; i++)
black += histImg[i];
for (i = (iMinLevel + iMaxLevel) / 2; i < iMaxLevel; i++)
white += histImg[i];
power = float(black) / float(2 * white);
//
step = float(iMaxLevel - iMinLevel) / float(iNumLayers);
if (step < 1.0)
step = 1.0;
}// void ThresholdingParam(IplImage *imgGray, int iNumLayers, int &iMinLevel, int &iMaxLevel, int &iStep)
int ChoiceTrackingFace3(CvFaceTracker* pTF, const int nElements, const CvFaceElement* big_face, CvTrackingRect* face, int& new_energy)
{
CvTrackingRect* curr_face[NUM_FACE_ELEMENTS] = {NULL};
CvTrackingRect* new_face[NUM_FACE_ELEMENTS] = {NULL};
new_energy = 0x7fffffff;
int curr_energy = 0x7fffffff;
int found = FALSE;
int N = 0;
CvSeqReader reader_m, reader_l, reader_r;
cvStartReadSeq( big_face[MOUTH].m_seqRects, &reader_m );
for (int i_mouth = 0; i_mouth < big_face[MOUTH].m_seqRects->total && i_mouth < nElements; i_mouth++)
{
curr_face[MOUTH] = (CvTrackingRect*)(reader_m.ptr);
cvStartReadSeq( big_face[LEYE].m_seqRects, &reader_l );
for (int i_left = 0; i_left < big_face[LEYE].m_seqRects->total && i_left < nElements; i_left++)
{
curr_face[LEYE] = (CvTrackingRect*)(reader_l.ptr);
if (curr_face[LEYE]->r.y + curr_face[LEYE]->r.height < curr_face[MOUTH]->r.y)
{
cvStartReadSeq( big_face[REYE].m_seqRects, &reader_r );
for (int i_right = 0; i_right < big_face[REYE].m_seqRects->total && i_right < nElements; i_right++)
{
curr_face[REYE] = (CvTrackingRect*)(reader_r.ptr);
if (curr_face[REYE]->r.y + curr_face[REYE]->r.height < curr_face[MOUTH]->r.y &&
curr_face[REYE]->r.x > curr_face[LEYE]->r.x + curr_face[LEYE]->r.width)
{
curr_energy = GetEnergy(curr_face, pTF->face, pTF->ptTempl, pTF->rTempl);
if (curr_energy < new_energy)
{
for (int elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
new_face[elem] = curr_face[elem];
new_energy = curr_energy;
found = TRUE;
}
N++;
}
}
}
}
}
if (found)
{
for (int elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
face[elem] = *(new_face[elem]);
}
return found;
} // int ChoiceTrackingFace3(const CvTrackingRect* tr_face, CvTrackingRect* new_face, int& new_energy)
int ChoiceTrackingFace2(CvFaceTracker* pTF, const int nElements, const CvFaceElement* big_face, CvTrackingRect* face, int& new_energy, int noel)
{
int element[NUM_FACE_ELEMENTS];
for (int i = 0, elem = 0; i < NUM_FACE_ELEMENTS; i++)
{
if (i != noel)
{
element[elem] = i;
elem ++;
}
else
element[2] = i;
}
CvTrackingRect* curr_face[NUM_FACE_ELEMENTS] = {NULL};
CvTrackingRect* new_face[NUM_FACE_ELEMENTS] = {NULL};
new_energy = 0x7fffffff;
int curr_energy = 0x7fffffff;
int found = FALSE;
int N = 0;
CvSeqReader reader0, reader1;
cvStartReadSeq( big_face[element[0]].m_seqRects, &reader0 );
for (int i0 = 0; i0 < big_face[element[0]].m_seqRects->total && i0 < nElements; i0++)
{
curr_face[element[0]] = (CvTrackingRect*)(reader0.ptr);
cvStartReadSeq( big_face[element[1]].m_seqRects, &reader1 );
for (int i1 = 0; i1 < big_face[element[1]].m_seqRects->total && i1 < nElements; i1++)
{
curr_face[element[1]] = (CvTrackingRect*)(reader1.ptr);
curr_energy = GetEnergy2(curr_face, pTF->face, pTF->ptTempl, pTF->rTempl, element);
if (curr_energy < new_energy)
{
for (int elem = 0; elem < NUM_FACE_ELEMENTS; elem++)
new_face[elem] = curr_face[elem];
new_energy = curr_energy;
found = TRUE;
}
N++;
}
}
if (found)
{
face[element[0]] = *(new_face[element[0]]);
face[element[1]] = *(new_face[element[1]]);
// 3 element find by template
CvPoint templ_v01 = {pTF->ptTempl[element[1]].x - pTF->ptTempl[element[0]].x, pTF->ptTempl[element[1]].y - pTF->ptTempl[element[0]].y};
CvPoint templ_v02 = {pTF->ptTempl[element[2]].x - pTF->ptTempl[element[0]].x, pTF->ptTempl[element[2]].y - pTF->ptTempl[element[0]].y};
CvPoint prev_v01 = {pTF->face[element[1]].ptCenter.x - pTF->face[element[0]].ptCenter.x, pTF->face[element[1]].ptCenter.y - pTF->face[element[0]].ptCenter.y};
CvPoint prev_v02 = {pTF->face[element[2]].ptCenter.x - pTF->face[element[0]].ptCenter.x, pTF->face[element[2]].ptCenter.y - pTF->face[element[0]].ptCenter.y};
CvPoint new_v01 = {new_face[element[1]]->ptCenter.x - new_face[element[0]]->ptCenter.x, new_face[element[1]]->ptCenter.y - new_face[element[0]]->ptCenter.y};
double templ_d01 = sqrt((double)templ_v01.x*templ_v01.x + templ_v01.y*templ_v01.y);
double templ_d02 = sqrt((double)templ_v02.x*templ_v02.x + templ_v02.y*templ_v02.y);
double prev_d01 = sqrt((double)prev_v01.x*prev_v01.x + prev_v01.y*prev_v01.y);
double prev_d02 = sqrt((double)prev_v02.x*prev_v02.x + prev_v02.y*prev_v02.y);
double new_d01 = sqrt((double)new_v01.x*new_v01.x + new_v01.y*new_v01.y);
double scale = templ_d01 / new_d01;
double new_d02 = templ_d02 / scale;
double sin_a = double(prev_v01.x * prev_v02.y - prev_v01.y * prev_v02.x) / (prev_d01 * prev_d02);
double cos_a = cos(asin(sin_a));
double x = double(new_v01.x) * cos_a - double(new_v01.y) * sin_a;
double y = double(new_v01.x) * sin_a + double(new_v01.y) * cos_a;
x = x * new_d02 / new_d01;
y = y * new_d02 / new_d01;
CvPoint new_v02 = {int(x + 0.5), int(y + 0.5)};
face[element[2]].iColor = 0;
face[element[2]].iEnergy = 0;
face[element[2]].nRectsInThis = 0;
face[element[2]].nRectsOnBottom = 0;
face[element[2]].nRectsOnLeft = 0;
face[element[2]].nRectsOnRight = 0;
face[element[2]].nRectsOnTop = 0;
face[element[2]].ptCenter.x = new_v02.x + new_face[element[0]]->ptCenter.x;
face[element[2]].ptCenter.y = new_v02.y + new_face[element[0]]->ptCenter.y;
face[element[2]].r.width = int(double(pTF->rTempl[element[2]].width) / (scale) + 0.5);
face[element[2]].r.height = int(double(pTF->rTempl[element[2]].height) / (scale) + 0.5);
face[element[2]].r.x = face[element[2]].ptCenter.x - (face[element[2]].r.width + 1) / 2;
face[element[2]].r.y = face[element[2]].ptCenter.y - (face[element[2]].r.height + 1) / 2;
_ASSERT(face[LEYE].r.x + face[LEYE].r.width <= face[REYE].r.x);
}
return found;
} // int ChoiceTrackingFace3(const CvTrackingRect* tr_face, CvTrackingRect* new_face, int& new_energy)
inline int GetEnergy(CvTrackingRect** ppNew, const CvTrackingRect* pPrev, CvPoint* ptTempl, CvRect* rTempl)
{
int energy = 0;
CvPoint ptNew[NUM_FACE_ELEMENTS];
CvPoint ptPrev[NUM_FACE_ELEMENTS];
for (int i = 0; i < NUM_FACE_ELEMENTS; i++)
{
ptNew[i] = ppNew[i]->ptCenter;
ptPrev[i] = pPrev[i].ptCenter;
energy += ppNew[i]->iEnergy - 2 * ppNew[i]->nRectsInThis;
}
double dx = 0, dy = 0, scale = 1, rotate = 0;
double e_templ = CalculateTransformationLMS3(ptTempl, ptNew, &scale, &rotate, &dx, &dy);
double e_prev = CalculateTransformationLMS3_0(ptPrev, ptNew);
double w_eye = double(ppNew[LEYE]->r.width + ppNew[REYE]->r.width) * scale / 2.0;
double h_eye = double(ppNew[LEYE]->r.height + ppNew[REYE]->r.height) * scale / 2.0;
double w_mouth = double(ppNew[MOUTH]->r.width) * scale;
double h_mouth = double(ppNew[MOUTH]->r.height) * scale;
energy +=
int(512.0 * (e_prev + 16.0 * e_templ)) +
4 * pow2(ppNew[LEYE]->r.width - ppNew[REYE]->r.width) +
4 * pow2(ppNew[LEYE]->r.height - ppNew[REYE]->r.height) +
4 * (int)pow(w_eye - double(rTempl[LEYE].width + rTempl[REYE].width) / 2.0, 2) +
2 * (int)pow(h_eye - double(rTempl[LEYE].height + rTempl[REYE].height) / 2.0, 2) +
1 * (int)pow(w_mouth - double(rTempl[MOUTH].width), 2) +
1 * (int)pow(h_mouth - double(rTempl[MOUTH].height), 2) +
0;
return energy;
}
inline int GetEnergy2(CvTrackingRect** ppNew, const CvTrackingRect* pPrev, CvPoint* ptTempl, CvRect* rTempl, int* element)
{
CvPoint new_v = {ppNew[element[0]]->ptCenter.x - ppNew[element[1]]->ptCenter.x,
ppNew[element[0]]->ptCenter.y - ppNew[element[1]]->ptCenter.y};
CvPoint prev_v = {pPrev[element[0]].ptCenter.x - pPrev[element[1]].ptCenter.x,
pPrev[element[0]].ptCenter.y - pPrev[element[1]].ptCenter.y};
double new_d = sqrt((double)new_v.x*new_v.x + new_v.y*new_v.y);
double prev_d = sqrt((double)prev_v.x*prev_v.x + prev_v.y*prev_v.y);
double dx = ptTempl[element[0]].x - ptTempl[element[1]].x;
double dy = ptTempl[element[0]].y - ptTempl[element[1]].y;
double templ_d = sqrt(dx*dx + dy*dy);
double scale_templ = new_d / templ_d;
double w0 = (double)ppNew[element[0]]->r.width * scale_templ;
double h0 = (double)ppNew[element[0]]->r.height * scale_templ;
double w1 = (double)ppNew[element[1]]->r.width * scale_templ;
double h1 = (double)ppNew[element[1]]->r.height * scale_templ;
int energy = ppNew[element[0]]->iEnergy + ppNew[element[1]]->iEnergy +
- 2 * (ppNew[element[0]]->nRectsInThis - ppNew[element[1]]->nRectsInThis) +
(int)pow(w0 - (double)rTempl[element[0]].width, 2) +
(int)pow(h0 - (double)rTempl[element[0]].height, 2) +
(int)pow(w1 - (double)rTempl[element[1]].width, 2) +
(int)pow(h1 - (double)rTempl[element[1]].height, 2) +
(int)pow(new_d - prev_d, 2) +
0;
return energy;
}
inline double CalculateTransformationLMS3( CvPoint* pTemplPoints,
CvPoint* pSrcPoints,
double* pdbAverageScale,
double* pdbAverageRotate,
double* pdbAverageShiftX,
double* pdbAverageShiftY )
{
// double WS = 0;
double dbAverageScale = 1;
double dbAverageRotate = 0;
double dbAverageShiftX = 0;
double dbAverageShiftY = 0;
double dbLMS = 0;
_ASSERT( NULL != pTemplPoints);
_ASSERT( NULL != pSrcPoints);
double dbXt = double(pTemplPoints[0].x + pTemplPoints[1].x + pTemplPoints[2].x) / 3.0;
double dbYt = double(pTemplPoints[0].y + pTemplPoints[1].y + pTemplPoints[2].y ) / 3.0;
double dbXs = double(pSrcPoints[0].x + pSrcPoints[1].x + pSrcPoints[2].x) / 3.0;
double dbYs = double(pSrcPoints[0].y + pSrcPoints[1].y + pSrcPoints[2].y) / 3.0;
double dbXtXt = double(pow2(pTemplPoints[0].x) + pow2(pTemplPoints[1].x) + pow2(pTemplPoints[2].x)) / 3.0;
double dbYtYt = double(pow2(pTemplPoints[0].y) + pow2(pTemplPoints[1].y) + pow2(pTemplPoints[2].y)) / 3.0;
double dbXsXs = double(pow2(pSrcPoints[0].x) + pow2(pSrcPoints[1].x) + pow2(pSrcPoints[2].x)) / 3.0;
double dbYsYs = double(pow2(pSrcPoints[0].y) + pow2(pSrcPoints[1].y) + pow2(pSrcPoints[2].y)) / 3.0;
double dbXtXs = double(pTemplPoints[0].x * pSrcPoints[0].x +
pTemplPoints[1].x * pSrcPoints[1].x +
pTemplPoints[2].x * pSrcPoints[2].x) / 3.0;
double dbYtYs = double(pTemplPoints[0].y * pSrcPoints[0].y +
pTemplPoints[1].y * pSrcPoints[1].y +
pTemplPoints[2].y * pSrcPoints[2].y) / 3.0;
double dbXtYs = double(pTemplPoints[0].x * pSrcPoints[0].y +
pTemplPoints[1].x * pSrcPoints[1].y +
pTemplPoints[2].x * pSrcPoints[2].y) / 3.0;
double dbYtXs = double(pTemplPoints[0].y * pSrcPoints[0].x +
pTemplPoints[1].y * pSrcPoints[1].x +
pTemplPoints[2].y * pSrcPoints[2].x ) / 3.0;
dbXtXt -= dbXt * dbXt;
dbYtYt -= dbYt * dbYt;
dbXsXs -= dbXs * dbXs;
dbYsYs -= dbYs * dbYs;
dbXtXs -= dbXt * dbXs;
dbYtYs -= dbYt * dbYs;
dbXtYs -= dbXt * dbYs;
dbYtXs -= dbYt * dbXs;
dbAverageRotate = atan2( dbXtYs - dbYtXs, dbXtXs + dbYtYs );
double cosR = cos(dbAverageRotate);
double sinR = sin(dbAverageRotate);
double del = dbXsXs + dbYsYs;
if( del != 0 )
{
dbAverageScale = (double(dbXtXs + dbYtYs) * cosR + double(dbXtYs - dbYtXs) * sinR) / del;
dbLMS = dbXtXt + dbYtYt - ((double)pow(dbXtXs + dbYtYs,2) + (double)pow(dbXtYs - dbYtXs,2)) / del;
}
dbAverageShiftX = double(dbXt) - dbAverageScale * (double(dbXs) * cosR + double(dbYs) * sinR);
dbAverageShiftY = double(dbYt) - dbAverageScale * (double(dbYs) * cosR - double(dbXs) * sinR);
if( pdbAverageScale != NULL ) *pdbAverageScale = dbAverageScale;
if( pdbAverageRotate != NULL ) *pdbAverageRotate = dbAverageRotate;
if( pdbAverageShiftX != NULL ) *pdbAverageShiftX = dbAverageShiftX;
if( pdbAverageShiftY != NULL ) *pdbAverageShiftY = dbAverageShiftY;
_ASSERT(dbLMS >= 0);
return dbLMS;
}
inline double CalculateTransformationLMS3_0( CvPoint* pTemplPoints, CvPoint* pSrcPoints)
{
double dbLMS = 0;
_ASSERT( NULL != pTemplPoints);
_ASSERT( NULL != pSrcPoints);
double dbXt = double(pTemplPoints[0].x + pTemplPoints[1].x + pTemplPoints[2].x) / 3.0;
double dbYt = double(pTemplPoints[0].y + pTemplPoints[1].y + pTemplPoints[2].y ) / 3.0;
double dbXs = double(pSrcPoints[0].x + pSrcPoints[1].x + pSrcPoints[2].x) / 3.0;
double dbYs = double(pSrcPoints[0].y + pSrcPoints[1].y + pSrcPoints[2].y) / 3.0;
double dbXtXt = double(pow2(pTemplPoints[0].x) + pow2(pTemplPoints[1].x) + pow2(pTemplPoints[2].x)) / 3.0;
double dbYtYt = double(pow2(pTemplPoints[0].y) + pow2(pTemplPoints[1].y) + pow2(pTemplPoints[2].y)) / 3.0;
double dbXsXs = double(pow2(pSrcPoints[0].x) + pow2(pSrcPoints[1].x) + pow2(pSrcPoints[2].x)) / 3.0;
double dbYsYs = double(pow2(pSrcPoints[0].y) + pow2(pSrcPoints[1].y) + pow2(pSrcPoints[2].y)) / 3.0;
double dbXtXs = double(pTemplPoints[0].x * pSrcPoints[0].x +
pTemplPoints[1].x * pSrcPoints[1].x +
pTemplPoints[2].x * pSrcPoints[2].x) / 3.0;
double dbYtYs = double(pTemplPoints[0].y * pSrcPoints[0].y +
pTemplPoints[1].y * pSrcPoints[1].y +
pTemplPoints[2].y * pSrcPoints[2].y) / 3.0;
double dbXtYs = double(pTemplPoints[0].x * pSrcPoints[0].y +
pTemplPoints[1].x * pSrcPoints[1].y +
pTemplPoints[2].x * pSrcPoints[2].y) / 3.0;
double dbYtXs = double(pTemplPoints[0].y * pSrcPoints[0].x +
pTemplPoints[1].y * pSrcPoints[1].x +
pTemplPoints[2].y * pSrcPoints[2].x ) / 3.0;
dbXtXt -= dbXt * dbXt;
dbYtYt -= dbYt * dbYt;
dbXsXs -= dbXs * dbXs;
dbYsYs -= dbYs * dbYs;
dbXtXs -= dbXt * dbXs;
dbYtYs -= dbYt * dbYs;
dbXtYs -= dbXt * dbYs;
dbYtXs -= dbYt * dbXs;
double del = dbXsXs + dbYsYs;
if( del != 0 )
dbLMS = dbXtXt + dbYtYt - ((double)pow(dbXtXs + dbYtYs,2) + (double)pow(dbXtYs - dbYtXs,2)) / del;
return dbLMS;
}

View File

@@ -0,0 +1,84 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
CV_IMPL void
cvDeInterlace( const CvArr* framearr, CvArr* fieldEven, CvArr* fieldOdd )
{
CV_FUNCNAME("cvDeInterlace");
__BEGIN__;
CvMat frame_stub, *frame = (CvMat*)framearr;
CvMat even_stub, *even = (CvMat*)fieldEven;
CvMat odd_stub, *odd = (CvMat*)fieldOdd;
CvSize size;
int y;
CV_CALL( frame = cvGetMat( frame, &frame_stub ));
CV_CALL( even = cvGetMat( even, &even_stub ));
CV_CALL( odd = cvGetMat( odd, &odd_stub ));
if( !CV_ARE_TYPES_EQ( frame, even ) || !CV_ARE_TYPES_EQ( frame, odd ))
CV_ERROR( CV_StsUnmatchedFormats, "All the input images must have the same type" );
if( frame->cols != even->cols || frame->cols != odd->cols ||
frame->rows != even->rows*2 || odd->rows != even->rows )
CV_ERROR( CV_StsUnmatchedSizes, "Uncorrelated sizes of the input image and output fields" );
size = cvGetMatSize( even );
size.width *= CV_ELEM_SIZE( even->type );
for( y = 0; y < size.height; y++ )
{
memcpy( even->data.ptr + even->step*y,
frame->data.ptr + frame->step*y*2, size.width );
memcpy( odd->data.ptr + even->step*y,
frame->data.ptr + frame->step*(y*2+1), size.width );
}
__END__;
}
/* End of file. */

View File

@@ -0,0 +1,629 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#if 0
#include <malloc.h>
//#include "decomppoly.h"
#define ZERO_CLOSE 0.00001f
#define ONE_CLOSE 0.99999f
#define CHECK_COLLINEARITY(vec1_x,vec1_y,vec2_x,vec2_y) \
if( vec1_x == 0 ) { \
if( vec1_y * vec2_y > 0 ) { \
return 0; \
} \
} \
else { \
if( vec1_x * vec2_x > 0 ) { \
return 0; \
} \
}
// determines if edge number one lies in counterclockwise
// earlier than edge number two
inline int icvIsFirstEdgeClosier( int x0,
int y0,
int x0_end,
int y0_end,
int x1_end,
int y1_end,
int x2_end,
int y2_end )
{
int mult, mult1, mult2;
int vec0_x, vec0_y;
int vec1_x, vec1_y;
int vec2_x, vec2_y;
vec0_x = x0_end - x0;
vec0_y = y0_end - y0;
vec1_x = x1_end - x0;
vec1_y = y1_end - y0;
vec2_x = x2_end - x0;
vec2_y = y2_end - y0;
mult1 = vec1_x * vec0_y - vec0_x * vec1_y;
mult2 = vec2_x * vec0_y - vec0_x * vec2_y;
if( mult1 == 0 ) {
CHECK_COLLINEARITY( vec0_x, vec0_y, vec1_x, vec1_y );
}
if( mult2 == 0 ) {
CHECK_COLLINEARITY( vec0_x, vec0_y, vec2_x, vec2_y );
}
if( mult1 > 0 && mult2 < 0 ) {
return 1;
}
if( mult1 < 0 && mult2 > 0 ) {
return -1;
}
mult = vec1_x * vec2_y - vec2_x * vec1_y;
if( mult == 0 ) {
CHECK_COLLINEARITY( vec1_x, vec1_y, vec2_x, vec2_y );
}
if( mult1 > 0 )
{
if( mult > 0 ) {
return -1;
}
else {
return 1;
}
} // if( mult1 > 0 )
else
{
if( mult1 != 0 ) {
if( mult > 0 ) {
return 1;
}
else {
return -1;
}
} // if( mult1 != 0 )
else {
if( mult2 > 0 ) {
return -1;
}
else {
return 1;
}
} // if( mult1 != 0 ) else
} // if( mult1 > 0 ) else
} // icvIsFirstEdgeClosier
bool icvEarCutTriangulation( CvPoint* contour,
int num,
int* outEdges,
int* numEdges )
{
int i;
int notFoundFlag = 0;
int begIndex = -1;
int isInternal;
int currentNum = num;
int index1, index2, index3;
int ix0, iy0, ix1, iy1, ix2, iy2;
int x1, y1, x2, y2, x3, y3;
int dx1, dy1, dx2, dy2;
int* pointExist = ( int* )0;
int det, det1, det2;
float t1, t2;
(*numEdges) = 0;
if( num <= 2 ) {
return false;
}
pointExist = ( int* )malloc( num * sizeof( int ) );
for( i = 0; i < num; i ++ ) {
pointExist[i] = 1;
}
for( i = 0; i < num; i ++ ) {
outEdges[ (*numEdges) * 2 ] = i;
if( i != num - 1 ) {
outEdges[ (*numEdges) * 2 + 1 ] = i + 1;
}
else {
outEdges[ (*numEdges) * 2 + 1 ] = 0;
}
(*numEdges) ++;
} // for( i = 0; i < num; i ++ )
// initializing data before while cycle
index1 = 0;
index2 = 1;
index3 = 2;
x1 = contour[ index1 ].x;
y1 = contour[ index1 ].y;
x2 = contour[ index2 ].x;
y2 = contour[ index2 ].y;
x3 = contour[ index3 ].x;
y3 = contour[ index3 ].y;
while( currentNum > 3 )
{
dx1 = x2 - x1;
dy1 = y2 - y1;
dx2 = x3 - x2;
dy2 = y3 - y2;
if( dx1 * dy2 - dx2 * dy1 < 0 ) // convex condition
{
// checking for noncrossing edge
ix1 = x3 - x1;
iy1 = y3 - y1;
isInternal = 1;
for( i = 0; i < num; i ++ )
{
if( i != num - 1 ) {
ix2 = contour[ i + 1 ].x - contour[ i ].x;
iy2 = contour[ i + 1 ].y - contour[ i ].y;
}
else {
ix2 = contour[ 0 ].x - contour[ i ].x;
iy2 = contour[ 0 ].y - contour[ i ].y;
}
ix0 = contour[ i ].x - x1;
iy0 = contour[ i ].y - y1;
det = ix2 * iy1 - ix1 * iy2;
det1 = ix2 * iy0 - ix0 * iy2;
if( det != 0.0f )
{
t1 = ( ( float )( det1 ) ) / det;
if( t1 > ZERO_CLOSE && t1 < ONE_CLOSE )
{
det2 = ix1 * iy0 - ix0 * iy1;
t2 = ( ( float )( det2 ) ) / det;
if( t2 > ZERO_CLOSE && t2 < ONE_CLOSE ) {
isInternal = 0;
}
} // if( t1 > ZERO_CLOSE && t1 < ONE_CLOSE )
} // if( det != 0.0f )
} // for( i = 0; i < (*numEdges); i ++ )
if( isInternal )
{
// this edge is internal
notFoundFlag = 0;
outEdges[ (*numEdges) * 2 ] = index1;
outEdges[ (*numEdges) * 2 + 1 ] = index3;
(*numEdges) ++;
pointExist[ index2 ] = 0;
index2 = index3;
x2 = x3;
y2 = y3;
currentNum --;
if( currentNum >= 3 ) {
do {
index3 ++;
if( index3 == num ) {
index3 = 0;
}
} while( !pointExist[ index3 ] );
x3 = contour[ index3 ].x;
y3 = contour[ index3 ].y;
} // if( currentNum >= 3 )
} // if( isInternal )
else {
// this edge intersects some other initial edges
if( !notFoundFlag ) {
notFoundFlag = 1;
begIndex = index1;
}
index1 = index2;
x1 = x2;
y1 = y2;
index2 = index3;
x2 = x3;
y2 = y3;
do {
index3 ++;
if( index3 == num ) {
index3 = 0;
}
if( index3 == begIndex ) {
if( pointExist ) {
free( pointExist );
}
return false;
}
} while( !pointExist[ index3 ] );
x3 = contour[ index3 ].x;
y3 = contour[ index3 ].y;
} // if( isInternal ) else
} // if( dx1 * dy2 - dx2 * dy1 < 0 )
else
{
if( !notFoundFlag ) {
notFoundFlag = 1;
begIndex = index1;
}
index1 = index2;
x1 = x2;
y1 = y2;
index2 = index3;
x2 = x3;
y2 = y3;
do {
index3 ++;
if( index3 == num ) {
index3 = 0;
}
if( index3 == begIndex ) {
if( pointExist ) {
free( pointExist );
}
return false;
}
} while( !pointExist[ index3 ] );
x3 = contour[ index3 ].x;
y3 = contour[ index3 ].y;
} // if( dx1 * dy2 - dx2 * dy1 < 0 ) else
} // while( currentNum > 3 )
if( pointExist ) {
free( pointExist );
}
return true;
} // icvEarCutTriangulation
inline bool icvFindTwoNeighbourEdges( CvPoint* contour,
int* edges,
int numEdges,
int vtxIdx,
int mainEdgeIdx,
int* leftEdgeIdx,
int* rightEdgeIdx )
{
int i;
int compRes;
int vec0_x, vec0_y;
int x0, y0, x0_end, y0_end;
int x1_left = 0, y1_left = 0, x1_right = 0, y1_right = 0, x2, y2;
(*leftEdgeIdx) = -1;
(*rightEdgeIdx) = -1;
if( edges[ mainEdgeIdx * 2 ] == vtxIdx ) {
x0 = contour[ vtxIdx ].x;
y0 = contour[ vtxIdx ].y;
x0_end = contour[ edges[ mainEdgeIdx * 2 + 1 ] ].x;
y0_end = contour[ edges[ mainEdgeIdx * 2 + 1 ] ].y;
vec0_x = x0_end - x0;
vec0_y = y0_end - y0;
}
else {
//x0 = contour[ edges[ mainEdgeIdx * 2 ] ].x;
//y0 = contour[ edges[ mainEdgeIdx * 2 ] ].y;
//x0_end = contour[ vtxIdx ].x;
//y0_end = contour[ vtxIdx ].y;
x0 = contour[ vtxIdx ].x;
y0 = contour[ vtxIdx ].y;
x0_end = contour[ edges[ mainEdgeIdx * 2 ] ].x;
y0_end = contour[ edges[ mainEdgeIdx * 2 ] ].y;
vec0_x = x0_end - x0;
vec0_y = y0_end - y0;
}
for( i = 0; i < numEdges; i ++ )
{
if( ( i != mainEdgeIdx ) &&
( edges[ i * 2 ] == vtxIdx || edges[ i * 2 + 1 ] == vtxIdx ) )
{
if( (*leftEdgeIdx) == -1 )
{
(*leftEdgeIdx) = (*rightEdgeIdx) = i;
if( edges[ i * 2 ] == vtxIdx ) {
x1_left = x1_right = contour[ edges[ i * 2 + 1 ] ].x;
y1_left = y1_right = contour[ edges[ i * 2 + 1 ] ].y;
}
else {
x1_left = x1_right = contour[ edges[ i * 2 ] ].x;
y1_left = y1_right = contour[ edges[ i * 2 ] ].y;
}
} // if( (*leftEdgeIdx) == -1 )
else
{
if( edges[ i * 2 ] == vtxIdx ) {
x2 = contour[ edges[ i * 2 + 1 ] ].x;
y2 = contour[ edges[ i * 2 + 1 ] ].y;
}
else {
x2 = contour[ edges[ i * 2 ] ].x;
y2 = contour[ edges[ i * 2 ] ].y;
}
compRes = icvIsFirstEdgeClosier( x0,
y0, x0_end, y0_end, x1_left, y1_left, x2, y2 );
if( compRes == 0 ) {
return false;
}
if( compRes == -1 ) {
(*leftEdgeIdx) = i;
x1_left = x2;
y1_left = y2;
} // if( compRes == -1 )
else {
compRes = icvIsFirstEdgeClosier( x0,
y0, x0_end, y0_end, x1_right, y1_right, x2, y2 );
if( compRes == 0 ) {
return false;
}
if( compRes == 1 ) {
(*rightEdgeIdx) = i;
x1_right = x2;
y1_right = y2;
}
} // if( compRes == -1 ) else
} // if( (*leftEdgeIdx) == -1 ) else
} // if( ( i != mainEdgesIdx ) && ...
} // for( i = 0; i < numEdges; i ++ )
return true;
} // icvFindTwoNeighbourEdges
bool icvFindReferences( CvPoint* contour,
int num,
int* outEdges,
int* refer,
int* numEdges )
{
int i;
int currPntIdx;
int leftEdgeIdx, rightEdgeIdx;
if( icvEarCutTriangulation( contour, num, outEdges, numEdges ) )
{
for( i = 0; i < (*numEdges); i ++ )
{
refer[ i * 4 ] = -1;
refer[ i * 4 + 1 ] = -1;
refer[ i * 4 + 2 ] = -1;
refer[ i * 4 + 3 ] = -1;
} // for( i = 0; i < (*numEdges); i ++ )
for( i = 0; i < (*numEdges); i ++ )
{
currPntIdx = outEdges[ i * 2 ];
if( !icvFindTwoNeighbourEdges( contour,
outEdges, (*numEdges), currPntIdx,
i, &leftEdgeIdx, &rightEdgeIdx ) )
{
return false;
} // if( !icvFindTwoNeighbourEdges( contour, ...
else
{
if( outEdges[ leftEdgeIdx * 2 ] == currPntIdx ) {
if( refer[ i * 4 ] == -1 ) {
refer[ i * 4 ] = ( leftEdgeIdx << 2 );
}
}
else {
if( refer[ i * 4 ] == -1 ) {
refer[ i * 4 ] = ( leftEdgeIdx << 2 ) | 2;
}
}
if( outEdges[ rightEdgeIdx * 2 ] == currPntIdx ) {
if( refer[ i * 4 + 1 ] == -1 ) {
refer[ i * 4 + 1 ] = ( rightEdgeIdx << 2 ) | 3;
}
}
else {
if( refer[ i * 4 + 1 ] == -1 ) {
refer[ i * 4 + 1 ] = ( rightEdgeIdx << 2 ) | 1;
}
}
} // if( !icvFindTwoNeighbourEdges( contour, ... ) else
currPntIdx = outEdges[ i * 2 + 1 ];
if( i == 18 ) {
i = i;
}
if( !icvFindTwoNeighbourEdges( contour,
outEdges, (*numEdges), currPntIdx,
i, &leftEdgeIdx, &rightEdgeIdx ) )
{
return false;
} // if( !icvFindTwoNeighbourEdges( contour, ...
else
{
if( outEdges[ leftEdgeIdx * 2 ] == currPntIdx ) {
if( refer[ i * 4 + 3 ] == -1 ) {
refer[ i * 4 + 3 ] = ( leftEdgeIdx << 2 );
}
}
else {
if( refer[ i * 4 + 3 ] == -1 ) {
refer[ i * 4 + 3 ] = ( leftEdgeIdx << 2 ) | 2;
}
}
if( outEdges[ rightEdgeIdx * 2 ] == currPntIdx ) {
if( refer[ i * 4 + 2 ] == -1 ) {
refer[ i * 4 + 2 ] = ( rightEdgeIdx << 2 ) | 3;
}
}
else {
if( refer[ i * 4 + 2 ] == -1 ) {
refer[ i * 4 + 2 ] = ( rightEdgeIdx << 2 ) | 1;
}
}
} // if( !icvFindTwoNeighbourEdges( contour, ... ) else
} // for( i = 0; i < (*numEdges); i ++ )
} // if( icvEarCutTriangulation( contour, num, outEdges, numEdges ) )
else {
return false;
} // if( icvEarCutTriangulation( contour, num, outEdges, ... ) else
return true;
} // icvFindReferences
void cvDecompPoly( CvContour* cont,
CvSubdiv2D** subdiv,
CvMemStorage* storage )
{
int* memory;
CvPoint* contour;
int* outEdges;
int* refer;
CvSubdiv2DPoint** pntsPtrs;
CvQuadEdge2D** edgesPtrs;
int numVtx;
int numEdges;
int i;
CvSeqReader reader;
CvPoint2D32f pnt;
CvQuadEdge2D* quadEdge;
numVtx = cont -> total;
if( numVtx < 3 ) {
return;
}
*subdiv = ( CvSubdiv2D* )0;
memory = ( int* )malloc( sizeof( int ) * ( numVtx * 2
+ numVtx * numVtx * 2 * 5 )
+ sizeof( CvQuadEdge2D* ) * ( numVtx * numVtx )
+ sizeof( CvSubdiv2DPoint* ) * ( numVtx * 2 ) );
contour = ( CvPoint* )memory;
outEdges = ( int* )( contour + numVtx );
refer = outEdges + numVtx * numVtx * 2;
edgesPtrs = ( CvQuadEdge2D** )( refer + numVtx * numVtx * 4 );
pntsPtrs = ( CvSubdiv2DPoint** )( edgesPtrs + numVtx * numVtx );
cvStartReadSeq( ( CvSeq* )cont, &reader, 0 );
for( i = 0; i < numVtx; i ++ )
{
CV_READ_SEQ_ELEM( (contour[ i ]), reader );
} // for( i = 0; i < numVtx; i ++ )
if( !icvFindReferences( contour, numVtx, outEdges, refer, &numEdges ) )
{
free( memory );
return;
} // if( !icvFindReferences( contour, numVtx, outEdges, refer, ...
*subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D,
sizeof( CvSubdiv2D ),
sizeof( CvSubdiv2DPoint ),
sizeof( CvQuadEdge2D ),
storage );
for( i = 0; i < numVtx; i ++ )
{
pnt.x = ( float )contour[ i ].x;
pnt.y = ( float )contour[ i ].y;
pntsPtrs[ i ] = cvSubdiv2DAddPoint( *subdiv, pnt, 0 );
} // for( i = 0; i < numVtx; i ++ )
for( i = 0; i < numEdges; i ++ )
{
edgesPtrs[ i ] = ( CvQuadEdge2D* )
( cvSubdiv2DMakeEdge( *subdiv ) & 0xfffffffc );
} // for( i = 0; i < numEdges; i ++ )
for( i = 0; i < numEdges; i ++ )
{
quadEdge = edgesPtrs[ i ];
quadEdge -> next[ 0 ] =
( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 ] >> 2 ] )
| ( refer[ i * 4 ] & 3 );
quadEdge -> next[ 1 ] =
( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 1 ] >> 2 ] )
| ( refer[ i * 4 + 1 ] & 3 );
quadEdge -> next[ 2 ] =
( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 2 ] >> 2 ] )
| ( refer[ i * 4 + 2 ] & 3 );
quadEdge -> next[ 3 ] =
( ( CvSubdiv2DEdge )edgesPtrs[ refer[ i * 4 + 3 ] >> 2 ] )
| ( refer[ i * 4 + 3 ] & 3 );
quadEdge -> pt[ 0 ] = pntsPtrs[ outEdges[ i * 2 ] ];
quadEdge -> pt[ 1 ] = ( CvSubdiv2DPoint* )0;
quadEdge -> pt[ 2 ] = pntsPtrs[ outEdges[ i * 2 + 1 ] ];
quadEdge -> pt[ 3 ] = ( CvSubdiv2DPoint* )0;
} // for( i = 0; i < numEdges; i ++ )
(*subdiv) -> topleft.x = ( float )cont -> rect.x;
(*subdiv) -> topleft.y = ( float )cont -> rect.y;
(*subdiv) -> bottomright.x =
( float )( cont -> rect.x + cont -> rect.width );
(*subdiv) -> bottomright.y =
( float )( cont -> rect.y + cont -> rect.height );
free( memory );
return;
} // cvDecompPoly
#endif
// End of file decomppoly.cpp

View File

@@ -0,0 +1 @@
// this file is empty but needed for libtool

View File

@@ -0,0 +1,268 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#ifdef WIN32 /* make sure it builds under Linux whenever it is included into Makefile.am or not. */
//void icvCutContour( CvSeq* current, IplImage* image );
CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image );
//create lists of segments of all contours from image
CvSeq* cvExtractSingleEdges( IplImage* image, //bw image - it's content will be destroyed by cvFindContours
CvMemStorage* storage )
{
CvMemStorage* tmp_storage = cvCreateChildMemStorage( storage );
CvSeq* contours = 0;
cvFindContours( image, tmp_storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
cvZero( image );
//iterate through contours
//iterate through tree
CvSeq* current = contours;
int number = 0;
int level = 1;
CvSeq* output = 0;
CvSeq* tail_seq = 0;
//actually this loop can iterates through tree,
//but still we use CV_RETR_LIST it is not useful
while( current )
{
number++;
//get vertical list of segments for one contour
CvSeq* new_seq = icvCutContourRaster( current, storage, image );
//add this vertical list to horisontal list
if( new_seq )
{
if( tail_seq )
{
tail_seq->h_next = new_seq;
new_seq->h_prev = tail_seq;
tail_seq = new_seq;
}
else
{
output = tail_seq = new_seq;
}
}
//iteration through tree
if( current->v_next )
{
//goto child
current = current->v_next;
level++;
}
else
{
//go parent
while( !current->h_next )
{
current = current->v_prev;
level--;
if( !level ) break;
}
if( current ) //go brother
current = current->h_next;
}
}
//free temporary memstorage with initial contours
cvReleaseMemStorage( &tmp_storage );
return output;
}
//makes vertical list of segments for 1 contour
CvSeq* icvCutContourRaster( CvSeq* current, CvMemStorage* storage, IplImage* image /*tmp image*/)
{
//iplSet(image, 0 ); // this can cause double edges if two contours have common edge
// for example if object is circle with 1 pixel width
// to remove such problem - remove this iplSet
//approx contour by single edges
CvSeqReader reader;
CvSeqWriter writer;
int writing = 0;
cvStartReadSeq( current, &reader, 0 );
//below line just to avoid warning
cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer );
CvSeq* output = 0;
CvSeq* tail = 0;
//first pass through contour - compute number of branches at every point
int i;
for( i = 0; i < current->total; i++ )
{
CvPoint cur;
CV_READ_SEQ_ELEM( cur, reader );
//mark point
((uchar*)image->imageData)[image->widthStep * cur.y + cur.x]++;
assert( ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] != 255 );
}
//second pass - create separate edges
for( i = 0; i < current->total; i++ )
{
CvPoint cur;
CV_READ_SEQ_ELEM( cur, reader );
//get pixel at this point
uchar flag = image->imageData[image->widthStep * cur.y + cur.x];
if( flag != 255 && flag < 3) //
{
if(!writing)
{
cvStartWriteSeq( current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer );
writing = 1 ;
}
//mark point
if( flag < 3 ) ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x] = 255;
//add it to another seq
CV_WRITE_SEQ_ELEM( cur, writer );
}
else
{
//exclude this point from contour
if( writing )
{
CvSeq* newseq = cvEndWriteSeq( &writer );
writing = 0;
if( tail )
{
tail->v_next = newseq;
newseq->v_prev = tail;
tail = newseq;
}
else
{
output = tail = newseq;
}
}
}
}
if( writing ) //if were not self intersections
{
CvSeq* newseq = cvEndWriteSeq( &writer );
writing = 0;
if( tail )
{
tail->v_next = newseq;
newseq->v_prev = tail;
tail = newseq;
}
else
{
output = tail = newseq;
}
}
return output;
}
/*void icvCutContour( CvSeq* current, IplImage* image )
{
//approx contour by single edges
CvSeqReader reader;
CvSeqReader rev_reader;
cvStartReadSeq( current, &reader, 0 );
int64* cur_pt = (int64*)reader.ptr;
int64* prev_pt = (int64*)reader.prev_elem;
//search for point a in aba position
for( int i = 0; i < current->total; i++ )
{
CV_NEXT_SEQ_ELEM( sizeof(int64), reader );
//compare current reader pos element with old previous
if( prev_pt[0] == ((int64*)reader.ptr)[0] )
{
//return to prev pos
CV_PREV_SEQ_ELEM( sizeof(int64), reader );
//this point is end of edge
//start going both directions and collect edge
cvStartReadSeq( current, &rev_reader, 1 );
int pos = cvGetSeqReaderPos( &reader );
cvSetSeqReaderPos( &rev_reader, pos );
//walk in both directions
while(1);
}
int64* cur_pt = (int64*)reader.ptr;
int64* prev_pt = (int64*)reader.prev_elem;
}
}
*/
#endif /* WIN32 */

View File

@@ -0,0 +1,20 @@
TARGET := cvaux
BINTYPE := DLL
SRC_ROOT := ../../cvaux/src
INC_ROOT := ../../cvaux/include
CXCORE_INC := ../../cxcore/include
CV_INC := ../../cv/include
CV_SRC := ../../cv/src
SRC_DIRS := . ./vs ../include ../../cxcore/include ../../cv/include
CXXFLAGS := -D"CVAPI_EXPORTS" -I"$(INC_ROOT)" -I"$(SRC_ROOT)" \
-I"$(CXCORE_INC)" -I"$(CV_INC)" -I"$(CV_SRC)"
INCS := cvaux.h cvaux.hpp cvmat.hpp cvvidsurv.hpp cvface.h cvfacedetection.h \
cvfacetemplate.h _cvaux.h _cvfacedetection.h _cvvectrack.h _cvvm.h \
cv.h cv.hpp cvcompat.h cvtypes.h $(CV_SRC)/_cvmatrix.h \
cxcore.h cxcore.hpp cxerror.h cxmisc.h cxtypes.h cvver.h
LIBS := -lcxcore$(DBG) -lcv$(DBG)
include ../../_make/make_module_gnu.mak

View File

@@ -0,0 +1,60 @@
TARGET = cvaux
BINTYPE = DLL
ROOT = ..\..
PCH = _cvaux.h
PCH_STARTER = precomp
OBJS = \
$(OBJPATH)/camshift.obj $(OBJPATH)/cv3dtracker.obj $(OBJPATH)/cvaux.obj \
$(OBJPATH)/cvauxutils.obj $(OBJPATH)/cvbgfg_acmmm2003.obj $(OBJPATH)/cvbgfg_common.obj \
$(OBJPATH)/cvbgfg_gaussmix.obj $(OBJPATH)/cvcalibfilter.obj $(OBJPATH)/cvclique.obj \
$(OBJPATH)/cvcorrespond.obj $(OBJPATH)/cvcorrimages.obj $(OBJPATH)/cvcreatehandmask.obj \
$(OBJPATH)/cvdpstereo.obj $(OBJPATH)/cveigenobjects.obj $(OBJPATH)/cvepilines.obj \
$(OBJPATH)/cvface.obj $(OBJPATH)/cvfacedetection.obj $(OBJPATH)/cvfacetemplate.obj \
$(OBJPATH)/cvfindface.obj $(OBJPATH)/cvfindhandregion.obj $(OBJPATH)/cvhmm.obj \
$(OBJPATH)/cvhmm1d.obj $(OBJPATH)/cvhmmobs.obj $(OBJPATH)/cvlcm.obj \
$(OBJPATH)/cvlee.obj $(OBJPATH)/cvlevmar.obj $(OBJPATH)/cvlevmarprojbandle.obj \
$(OBJPATH)/cvlevmartrif.obj $(OBJPATH)/cvlines.obj $(OBJPATH)/cvlmeds.obj \
$(OBJPATH)/cvmat.obj $(OBJPATH)/cvmorphcontours.obj $(OBJPATH)/cvmorphing.obj \
$(OBJPATH)/cvprewarp.obj $(OBJPATH)/cvscanlines.obj $(OBJPATH)/cvsegment.obj \
$(OBJPATH)/cvsubdiv2.obj $(OBJPATH)/cvtexture.obj $(OBJPATH)/cvtrifocal.obj \
$(OBJPATH)/cvvecfacetracking.obj $(OBJPATH)/cvvideo.obj $(OBJPATH)/decomppoly.obj \
$(OBJPATH)/enmin.obj $(OBJPATH)/extendededges.obj \
$(OBJPATH)/bgfg_estimation.obj $(OBJPATH)/blobtrackanalysis.obj \
$(OBJPATH)/blobtrackanalysishist.obj $(OBJPATH)/blobtrackanalysisior.obj \
$(OBJPATH)/blobtrackanalysistrackdist.obj $(OBJPATH)/blobtrackgen1.obj \
$(OBJPATH)/blobtrackgenyml.obj $(OBJPATH)/blobtrackingauto.obj \
$(OBJPATH)/blobtrackingcc.obj $(OBJPATH)/blobtrackingccwithcr.obj \
$(OBJPATH)/blobtrackingkalman.obj $(OBJPATH)/blobtrackinglist.obj \
$(OBJPATH)/blobtrackingmsfg.obj $(OBJPATH)/blobtrackingmsfgs.obj \
$(OBJPATH)/blobtrackpostprockalman.obj $(OBJPATH)/blobtrackpostproclinear.obj \
$(OBJPATH)/blobtrackpostproclist.obj $(OBJPATH)/enteringblobdetection.obj \
$(OBJPATH)/enteringblobdetectionreal.obj $(OBJPATH)/testseq.obj
INCS = ../include/cvaux.h ../include/cvaux.hpp ../include/cvmat.hpp \
../include/cvvidsurv.hpp ./cvface.h ./cvfacedetection.h \
./cvfacetemplate.h ./_cvaux.h ./_cvfacedetection.h \
./_cvvectrack.h ./_cvvm.h $(ROOT)/cv/include/cv.h \
$(ROOT)/cv/include/cv.hpp $(ROOT)/cv/include/cvcompat.h \
$(ROOT)/cv/include/cvtypes.h $(ROOT)/cv/src/_cvmatrix.h \
$(ROOT)/cxcore/include/cxcore.h $(ROOT)/cxcore/include/cxcore.hpp \
$(ROOT)/cxcore/include/cxerror.h $(ROOT)/cxcore/include/cxmisc.h \
$(ROOT)/cxcore/include/cxtypes.h $(ROOT)/cxcore/include/cvver.h
CXXFLAGS_PROJ = /I"." /I"../include" /I"$(ROOT)/cv/include" /I"$(ROOT)/cv/src" /I"$(ROOT)/cxcore/include"
LIBS_PROJ = $(LIBPATH)"$(ROOT)/lib" cxcore$(DBG)$(OUT_P_SUFFIX).lib cv$(DBG)$(OUT_P_SUFFIX).lib
!if "$(MS)" == "bc"
SRCPATH = .;.\vs
!endif
!include $(ROOT)/_make/make_module_$(MS).mak
!if "$(MS)"=="ms"
# Hack: include all the files from vs subdirectory as well
{.\vs}.cpp{$(OBJPATH)}.obj:
@-mkdir $(OBJPATH) 2> nul
@$(CXX) $(CXXFLAGS)$@ $<
!endif

View File

@@ -0,0 +1,42 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"

View File

@@ -0,0 +1,15 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by cvaux.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,204 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
//Function cvCreateBGStatModel creates and returns initialized BG model
// parameters:
// first_frame - frame from video sequence
// model_type type of BG model (CV_BG_MODEL_MOG, CV_BG_MODEL_FGD,…)
// parameters - (optional) if NULL the default parameters of the algorithm will be used
CvBGStatModel* cvCreateBGStatModel( IplImage* first_frame, int model_type, void* params )
{
CvBGStatModel* bg_model = NULL;
if( model_type == CV_BG_MODEL_FGD || model_type == CV_BG_MODEL_FGD_SIMPLE )
bg_model = cvCreateFGDStatModel( first_frame, (CvFGDStatModelParams*)params );
else if( model_type == CV_BG_MODEL_MOG )
bg_model = cvCreateGaussianBGModel( first_frame, (CvGaussBGStatModelParams*)params );
return bg_model;
}
/* FOREGROUND DETECTOR INTERFACE */
class CvFGDetectorBase:public CvFGDetector
{
protected:
CvBGStatModel* m_pFG;
int m_FGType;
void* m_pFGParam; /* foreground params */
CvFGDStatModelParams m_ParamFGD;
CvGaussBGStatModelParams m_ParamMOG;
char* m_SaveName;
char* m_LoadName;
public:
virtual void SaveState(CvFileStorage* )
{
if( m_FGType == CV_BG_MODEL_FGD || m_FGType == CV_BG_MODEL_FGD_SIMPLE )
{
if( m_SaveName ) /* File name is not empty */
{
//cvSaveStatModel(m_SaveName, (CvFGDStatModel*)m_pFG);
}
}
};
virtual void LoadState(CvFileStorage* , CvFileNode* )
{
if( m_FGType == CV_BG_MODEL_FGD || m_FGType == CV_BG_MODEL_FGD_SIMPLE )
{
if( m_LoadName ) /* File name is not empty */
{
//cvRestoreStatModel(m_LoadName, (CvFGDStatModel*)m_pFG);
}
}
};
CvFGDetectorBase(int type, void* param)
{
m_pFG = NULL;
m_FGType = type;
m_pFGParam = param;
if( m_FGType == CV_BG_MODEL_FGD || m_FGType == CV_BG_MODEL_FGD_SIMPLE )
{
if(m_pFGParam)
{
m_ParamFGD = *(CvFGDStatModelParams*)m_pFGParam;
}
else
{
m_ParamFGD.Lc = CV_BGFG_FGD_LC;
m_ParamFGD.N1c = CV_BGFG_FGD_N1C;
m_ParamFGD.N2c = CV_BGFG_FGD_N2C;
m_ParamFGD.Lcc = CV_BGFG_FGD_LCC;
m_ParamFGD.N1cc = CV_BGFG_FGD_N1CC;
m_ParamFGD.N2cc = CV_BGFG_FGD_N2CC;
m_ParamFGD.delta = CV_BGFG_FGD_DELTA;
m_ParamFGD.alpha1 = CV_BGFG_FGD_ALPHA_1;
m_ParamFGD.alpha2 = CV_BGFG_FGD_ALPHA_2;
m_ParamFGD.alpha3 = CV_BGFG_FGD_ALPHA_3;
m_ParamFGD.T = CV_BGFG_FGD_T;
m_ParamFGD.minArea = CV_BGFG_FGD_MINAREA;
m_ParamFGD.is_obj_without_holes = 1;
m_ParamFGD.perform_morphing = 1;
}
AddParam("LC",&m_ParamFGD.Lc);
AddParam("alpha1",&m_ParamFGD.alpha1);
AddParam("alpha2",&m_ParamFGD.alpha2);
AddParam("alpha3",&m_ParamFGD.alpha3);
AddParam("N1c",&m_ParamFGD.N1c);
AddParam("N2c",&m_ParamFGD.N2c);
AddParam("N1cc",&m_ParamFGD.N1cc);
AddParam("N2cc",&m_ParamFGD.N2cc);
m_SaveName = 0;
m_LoadName = 0;
AddParam("SaveName",&m_SaveName);
AddParam("LoadName",&m_LoadName);
AddParam("ObjWithoutHoles",&m_ParamFGD.is_obj_without_holes);
AddParam("Morphology",&m_ParamFGD.perform_morphing);
}
else if( m_FGType == CV_BG_MODEL_MOG )
{
if(m_pFGParam)
{
m_ParamMOG = *(CvGaussBGStatModelParams*)m_pFGParam;
}
else
{
m_ParamMOG.win_size = CV_BGFG_MOG_WINDOW_SIZE;
m_ParamMOG.bg_threshold = CV_BGFG_MOG_BACKGROUND_THRESHOLD;
m_ParamMOG.std_threshold = CV_BGFG_MOG_STD_THRESHOLD;
m_ParamMOG.weight_init = CV_BGFG_MOG_WEIGHT_INIT;
m_ParamMOG.variance_init = CV_BGFG_MOG_SIGMA_INIT*CV_BGFG_MOG_SIGMA_INIT;
m_ParamMOG.minArea = CV_BGFG_MOG_MINAREA;
m_ParamMOG.n_gauss = CV_BGFG_MOG_NGAUSSIANS;
}
AddParam("NG",&m_ParamMOG.n_gauss);
}
};
~CvFGDetectorBase()
{
if(m_pFG)cvReleaseBGStatModel( &m_pFG );
}
void ParamUpdate()
{
if(m_pFG)cvReleaseBGStatModel( &m_pFG );
}
inline IplImage* GetMask()
{
return m_pFG?m_pFG->foreground:NULL;
};
/* process current image */
virtual void Process(IplImage* pImg)
{
if(m_pFG == NULL)
{
void* param = m_pFGParam;
if( m_FGType == CV_BG_MODEL_FGD || m_FGType == CV_BG_MODEL_FGD_SIMPLE )
{
param = &m_ParamFGD;
}
else if( m_FGType == CV_BG_MODEL_MOG )
{
param = &m_ParamMOG;
}
m_pFG = cvCreateBGStatModel(
pImg,
m_FGType,
param);
LoadState(0, 0);
}
else
{
cvUpdateBGStatModel( pImg, m_pFG );
}
};
/* release foreground detector */
virtual void Release()
{
SaveState(0);
if(m_pFG)cvReleaseBGStatModel( &m_pFG );
};
};
CvFGDetector* cvCreateFGDetectorBase(int type, void *param)
{
return (CvFGDetector*) new CvFGDetectorBase(type, param);
}

View File

@@ -0,0 +1,127 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/*======================= FILTER LIST SHELL =====================*/
typedef struct DefTrackAnalyser
{
CvBlob blob;
CvBlobTrackAnalysisOne* pFilter;
int m_LastFrame;
int state;
} DefTrackAnalyser;
class CvBlobTrackAnalysisList : public CvBlobTrackAnalysis
{
protected:
CvBlobTrackAnalysisOne* (*m_CreateAnalysis)();
CvBlobSeq m_TrackAnalyserList;
int m_Frame;
public:
CvBlobTrackAnalysisList(CvBlobTrackAnalysisOne* (*create)()):m_TrackAnalyserList(sizeof(DefTrackAnalyser))
{
m_Frame = 0;
m_CreateAnalysis = create;
}
~CvBlobTrackAnalysisList()
{
int i;
for(i=m_TrackAnalyserList.GetBlobNum();i>0;--i)
{
DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlob(i-1);
pF->pFilter->Release();
}
};
virtual void AddBlob(CvBlob* pBlob)
{
DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlobByID(CV_BLOB_ID(pBlob));
if(pF == NULL)
{ /* create new filter */
DefTrackAnalyser F;
F.state = 0;
F.blob = pBlob[0];
F.m_LastFrame = m_Frame;
F.pFilter = m_CreateAnalysis();
m_TrackAnalyserList.AddBlob((CvBlob*)&F);
pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlobByID(CV_BLOB_ID(pBlob));
}
assert(pF);
pF->blob = pBlob[0];
pF->m_LastFrame = m_Frame;
};
virtual void Process(IplImage* pImg, IplImage* pFG)
{
int i;
for(i=m_TrackAnalyserList.GetBlobNum();i>0;--i)
{
DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlob(i-1);
if(pF->m_LastFrame == m_Frame)
{/* process */
int ID = CV_BLOB_ID(pF);
pF->state = pF->pFilter->Process(&(pF->blob), pImg, pFG);
CV_BLOB_ID(pF) = ID;
}
else
{/* delete blob filter */
pF->pFilter->Release();
m_TrackAnalyserList.DelBlob(i-1);
}
}/* next blob */
m_Frame++;
};
float GetState(int BlobID)
{
DefTrackAnalyser* pF = (DefTrackAnalyser*)m_TrackAnalyserList.GetBlobByID(BlobID);
return pF?pF->state:0.f;
};
void Release(){delete this;};
}; /* CvBlobTrackAnalysisList */
CvBlobTrackAnalysis* cvCreateBlobTrackAnalysisList(CvBlobTrackAnalysisOne* (*create)())
{
return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisList(create);
}
/* ======================== Analyser modules ============================= */

View File

@@ -0,0 +1,161 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/*======================= FILTER LIST SHELL =====================*/
#define MAX_ANS 16
#define MAX_DESC 1024
class CvBlobTrackAnalysisIOR : public CvBlobTrackAnalysis
{
protected:
struct DefAn
{
char* pName;
CvBlobTrackAnalysis* pAn;
} m_Ans[MAX_ANS];
int m_AnNum;
char m_Desc[MAX_DESC];
public:
CvBlobTrackAnalysisIOR()
{
m_AnNum = 0;
}
~CvBlobTrackAnalysisIOR()
{
};
virtual void AddBlob(CvBlob* pBlob)
{
int i;
for(i=0;i<m_AnNum;++i)
{
m_Ans[i].pAn->AddBlob(pBlob);
}/* next analizer */
};
virtual void Process(IplImage* pImg, IplImage* pFG)
{
int i;
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(i=0;i<m_AnNum;++i)
{
m_Ans[i].pAn->Process(pImg, pFG);
}/* next analizer */
};
float GetState(int BlobID)
{
int state = 0;
int i;
for(i=0;i<m_AnNum;++i)
{
state |= (m_Ans[i].pAn->GetState(BlobID) > 0.5);
}/* next analizer */
return (float)state;
};
virtual char* GetStateDesc(int BlobID)
{
int rest = MAX_DESC-1;
int i;
m_Desc[0] = 0;
for(i=0;i<m_AnNum;++i)
{
char* str = m_Ans[i].pAn->GetStateDesc(BlobID);
if(str && strlen(m_Ans[i].pName) + strlen(str)+4 < (size_t)rest)
{
strcat(m_Desc,m_Ans[i].pName);
strcat(m_Desc,": ");
strcat(m_Desc,str);
strcat(m_Desc,"\n");
rest = MAX_DESC - (int)strlen(m_Desc) - 1;
}
}/* next analizer */
if(m_Desc[0]!=0)return m_Desc;
return NULL;
};
virtual void SetFileName(char* /*DataBaseName*/)
{
};
int AddAnalizer(CvBlobTrackAnalysis* pA, char* pName)
{
if(m_AnNum<MAX_ANS)
{
//int i;
m_Ans[m_AnNum].pName = pName;
m_Ans[m_AnNum].pAn = pA;
TransferParamsFromChild(m_Ans[m_AnNum].pAn, pName);
m_AnNum++;
return 1;
}
else
{
printf("Can not add track analizer %s! (not more that %d analizers)\n",pName,MAX_ANS);
return 0;
}
}
void Release()
{
int i;
for(i=0;i<m_AnNum;++i)
{
m_Ans[i].pAn->Release();
}/* next analizer */
delete this;
};
}; /* CvBlobTrackAnalysisIOR */
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisIOR()
{
CvBlobTrackAnalysisIOR* pIOR = new CvBlobTrackAnalysisIOR();
CvBlobTrackAnalysis* pA = NULL;
pA = cvCreateModuleBlobTrackAnalysisHistPVS();
pIOR->AddAnalizer(pA, "HIST");
//pA = (CvBlobTrackAnalysis*)cvCreateModuleBlobTrackAnalysisHeightScale();
//pIOR->AddAnalizer(pA, "SCALE");
return (CvBlobTrackAnalysis*)pIOR;
}/* cvCreateCvBlobTrackAnalysisIOR */
/* ======================== Analyser modules ============================= */

View File

@@ -0,0 +1,561 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
typedef struct DefTrackPoint
{
float x,y,r,vx,vy,v;
} DefTrackPoint;
class DefTrackRec
{
private:
int ID;
public:
DefTrackRec(int id = 0,int BlobSize = sizeof(DefTrackPoint))
{
ID = id;
m_pMem = cvCreateMemStorage();
m_pSeq = cvCreateSeq(0,sizeof(CvSeq),BlobSize,m_pMem);
}
~DefTrackRec()
{
cvReleaseMemStorage(&m_pMem);
};
inline DefTrackPoint* GetPoint(int PointIndex)
{
return (DefTrackPoint*)cvGetSeqElem(m_pSeq,PointIndex);
};
inline void DelPoint(int PointIndex)
{
cvSeqRemove(m_pSeq,PointIndex);
};
inline void Clear()
{
cvClearSeq(m_pSeq);
};
inline void AddPoint(float x, float y, float r)
{
DefTrackPoint p = {x,y,r,0};
int Num = GetPointNum();
if(Num > 0)
{
DefTrackPoint* pPrev = GetPoint(Num-1);
float Alpha = 0.8f;
float dx = x-pPrev->x;
float dy = y-pPrev->y;
p.vx = Alpha*dx+(1-Alpha)*pPrev->vx;
p.vy = Alpha*dy+(1-Alpha)*pPrev->vy;
p.v = Alpha*dx+(1-Alpha)*pPrev->v;
}
AddPoint(&p);
}
inline void AddPoint(DefTrackPoint* pB)
{/* add point and recal last velocities */
int wnd=3;
int Num;
int i;
cvSeqPush(m_pSeq,pB);
Num = GetPointNum();
for(i=MAX(0,Num-wnd-1);i<Num;++i)
{/* next updating point */
DefTrackPoint* p = GetPoint(i);
int j0 = i - wnd;
int j1 = i + wnd;
if(j0<0) j0 = 0;
if(j1>=Num)j1=Num-1;
if(j1>j0)
{
float dt = (float)(j1-j0);
DefTrackPoint* p0 = GetPoint(j0);
DefTrackPoint* p1 = GetPoint(j1);
p->vx = (p1->x - p0->x) / dt;
p->vy = (p1->y - p0->y) / dt;
p->v = (float)sqrt(p->vx*p->vx+p->vy*p->vy);
}
}/* next updating point */
#if 0
if(0)
{ /* debug */
int i;
printf("Blob %d: ",ID);
for(i=0;i<GetPointNum();++i)
{
DefTrackPoint* p = GetPoint(i);
printf(",(%.2f,%.2f,%f.2)",p->vx,p->vy,p->v);
}
printf("\n");
}
#endif
};
inline int GetPointNum()
{
return m_pSeq->total;
};
private:
CvMemStorage* m_pMem;
CvSeq* m_pSeq;
};
/* fill array pIdxPairs by pair of index of correspondent blobs */
/* return number of pairs */
/* pIdxPairs must have size not less that 2*(pSeqNum+pSeqTNum) */
/* pTmp is pointer to memory which size is pSeqNum*pSeqTNum*16 */
typedef struct DefMatch
{
int Idx; /* prev best blob index */
int IdxT; /* prev best template blob index */
double D; /* blob to blob distance sum */
}DefMatch;
static int cvTrackMatch(DefTrackRec* pSeq, int MaxLen, DefTrackRec* pSeqT, int* pIdxPairs, void* pTmp)
{
int NumPair = 0;
DefMatch* pMT = (DefMatch*)pTmp;
int Num = pSeq->GetPointNum();
int NumT = pSeqT->GetPointNum();
int i,it;
int i0=0; /* last point in the track sequence */
if(MaxLen > 0 && Num > MaxLen)
{/* set new point seq len and new last point in this seq */
Num = MaxLen;
i0 = pSeq->GetPointNum() - Num;
}
for(i=0;i<Num;++i)
{ /* for eacj point row */
for(it=0;it<NumT;++it)
{ /* for each point templet column */
DefTrackPoint* pB = pSeq->GetPoint(i+i0);
DefTrackPoint* pBT = pSeqT->GetPoint(it);
DefMatch* pMT_cur = pMT + i*NumT + it;
double dx = pB->x-pBT->x;
double dy = pB->y-pBT->y;
double D = dx*dx+dy*dy;
int DI[3][2] = {{-1,-1},{-1,0},{0,-1}};
int iDI;
pMT_cur->D = D;
pMT_cur->Idx = -1;
pMT_cur->IdxT = 0;
if(i==0) continue;
for(iDI=0;iDI<3;++iDI)
{
int i_prev = i+DI[iDI][0];
int it_prev = it+DI[iDI][1];
if(i_prev >= 0 && it_prev>=0)
{
double D_cur = D+pMT[NumT*i_prev+it_prev].D;
if(pMT_cur->D > D_cur || (pMT_cur->Idx<0) )
{/* set new best local way */
pMT_cur->D = D_cur;
pMT_cur->Idx = i_prev;
pMT_cur->IdxT = it_prev;
}
}
}/* check next direction */
}/* fill next colum from table */
}/*fill next row */
{ /* back tracking */
/* find best end in template */
int it_best = 0;
DefMatch* pMT_best = pMT + (Num-1)*NumT;
i = Num-1; /* set current i to last position */
for(it=1;it<NumT;++it)
{
DefMatch* pMT_new = pMT + it + i*NumT;
if(pMT_best->D > pMT_new->D)
{
pMT_best->D = pMT_new->D;
it_best = it;
}
}/* find best end template point */
/* back tracking whole sequence */
for(it = it_best;i>=0 && it>=0;)
{
DefMatch* pMT_new = pMT + it + i*NumT;
pIdxPairs[2*NumPair] = i+i0;
pIdxPairs[2*NumPair+1] = it;
NumPair++;
it = pMT_new->IdxT;
i = pMT_new->Idx;
}
}/* end back tracing */
return NumPair;
}/* cvTrackMatch */
typedef struct DefTrackForDist
{
CvBlob blob;
DefTrackRec* pTrack;
int LastFrame;
float state;
/* for debug */
int close;
} DefTrackForDist;
class CvBlobTrackAnalysisTrackDist : public CvBlobTrackAnalysis
{
/*---------------- internal functions --------------------*/
private:
char* m_pDebugAVIName; /* for debuf purpose */
//CvVideoWriter* m_pDebugAVI; /* for debuf purpose */
IplImage* m_pDebugImg; /* for debuf purpose */
char m_DataFileName[1024];
CvBlobSeq m_Tracks;
CvBlobSeq m_TrackDataBase;
int m_Frame;
void* m_pTempData;
int m_TempDataSize;
int m_TraceLen;
float m_AbnormalThreshold;
float m_PosThreshold;
float m_VelThreshold;
inline void* ReallocTempData(int Size)
{
if(Size <= m_TempDataSize && m_pTempData) return m_pTempData;
cvFree(&m_pTempData);
m_TempDataSize = 0;
m_pTempData = cvAlloc(Size);
if(m_pTempData) m_TempDataSize = Size;
return m_pTempData;
}/* ReallocTempData */
public:
CvBlobTrackAnalysisTrackDist():m_Tracks(sizeof(DefTrackForDist)),m_TrackDataBase(sizeof(DefTrackForDist))
{
m_pDebugImg = 0;
//m_pDebugAVI = 0;
m_Frame = 0;
m_pTempData = NULL;
m_TempDataSize = 0;
m_pDebugAVIName = NULL;
AddParam("DebugAVI",&m_pDebugAVIName);
CommentParam("DebugAVI","Name of AVI file to save images from debug window");
m_TraceLen = 50;
AddParam("TraceLen",&m_TraceLen);
CommentParam("TraceLen","Length (in frames) of trajectory part that is used for comparison");
m_AbnormalThreshold = 0.02f;
AddParam("AbnormalThreshold",&m_AbnormalThreshold);
CommentParam("AbnormalThreshold","If trajectory is equal with less then <AbnormalThreshold*DataBaseTrackNum> tracks then trajectory is abnormal");
m_PosThreshold = 1.25;
AddParam("PosThreshold",&m_PosThreshold);
CommentParam("PosThreshold","Minimal allowd distance in blob width that is allowed");
m_VelThreshold = 0.5;
AddParam("VelThreshold",&m_VelThreshold);
CommentParam("VelThreshold","Minimal allowed relative difference between blob speed");
}/* constructor */
~CvBlobTrackAnalysisTrackDist()
{
int i;
for(i=m_Tracks.GetBlobNum();i>0;--i)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlob(i-1);
delete pF->pTrack;
}
if(m_pDebugImg) cvReleaseImage(&m_pDebugImg);
//if(m_pDebugAVI) cvReleaseVideoWriter(&m_pDebugAVI);
}/* destructor */
/*----------------- interface --------------------*/
virtual void AddBlob(CvBlob* pBlob)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlobByID(CV_BLOB_ID(pBlob));
if(pF == NULL)
{ /* create new TRack record */
DefTrackForDist F;
F.state = 0;
F.blob = pBlob[0];
F.LastFrame = m_Frame;
F.pTrack = new DefTrackRec(CV_BLOB_ID(pBlob));
m_Tracks.AddBlob((CvBlob*)&F);
pF = (DefTrackForDist*)m_Tracks.GetBlobByID(CV_BLOB_ID(pBlob));
}
assert(pF);
assert(pF->pTrack);
pF->pTrack->AddPoint(pBlob->x,pBlob->y,pBlob->w*0.5f);
pF->blob = pBlob[0];
pF->LastFrame = m_Frame;
};
virtual void Process(IplImage* pImg, IplImage* /*pFG*/)
{
int i;
double MinTv = pImg->width/1440.0; /* minimal threshold for speed difference */
double MinTv2 = MinTv*MinTv;
for(i=m_Tracks.GetBlobNum();i>0;--i)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlob(i-1);
pF->state = 0;
if(pF->LastFrame == m_Frame || pF->LastFrame+1 == m_Frame)
{/* process one blob trajectory */
int NumEq = 0;
int it;
for(it=m_TrackDataBase.GetBlobNum();it>0;--it)
{/* check template */
DefTrackForDist* pFT = (DefTrackForDist*)m_TrackDataBase.GetBlob(it-1);
int Num = pF->pTrack->GetPointNum();
int NumT = pFT->pTrack->GetPointNum();
int* pPairIdx = (int*)ReallocTempData(sizeof(int)*2*(Num+NumT)+sizeof(DefMatch)*Num*NumT);
void* pTmpData = pPairIdx+2*(Num+NumT);
int PairNum = 0;
int k;
int Equal = 1;
int UseVel = 0;
int UsePos = 0;
if(i==it) continue;
/* match track */
PairNum = cvTrackMatch( pF->pTrack, m_TraceLen, pFT->pTrack, pPairIdx, pTmpData );
Equal = MAX(1,cvRound(PairNum*0.1));
UseVel = 3*pF->pTrack->GetPointNum() > m_TraceLen;
UsePos = 10*pF->pTrack->GetPointNum() > m_TraceLen;
{ /* check continues */
float D;
int DI = pPairIdx[0*2+0]-pPairIdx[(PairNum-1)*2+0];
int DIt = pPairIdx[0*2+1]-pPairIdx[(PairNum-1)*2+1];
if(UseVel && DI != 0)
{
D = (float)(DI-DIt)/(float)DI;
if(fabs(D)>m_VelThreshold)Equal=0;
if(fabs(D)>m_VelThreshold*0.5)Equal/=2;
}
}/* check continues */
for(k=0;Equal>0 && k<PairNum;++k)
{/* compare with threshold */
int j = pPairIdx[k*2+0];
int jt = pPairIdx[k*2+1];
DefTrackPoint* pB = pF->pTrack->GetPoint(j);
DefTrackPoint* pBT = pFT->pTrack->GetPoint(jt);
double dx = pB->x-pBT->x;
double dy = pB->y-pBT->y;
double dvx = pB->vx - pBT->vx;
double dvy = pB->vy - pBT->vy;
//double dv = pB->v - pBT->v;
double D = dx*dx+dy*dy;
double Td = pBT->r*m_PosThreshold;
double dv2 = dvx*dvx+dvy*dvy;
double Tv2 = (pBT->vx*pBT->vx+pBT->vy*pBT->vy)*m_VelThreshold*m_VelThreshold;
double Tvm = pBT->v*m_VelThreshold;
if(Tv2 < MinTv2) Tv2 = MinTv2;
if(Tvm < MinTv) Tvm = MinTv;
/* check trajectory position */
if(UsePos && D > Td*Td)
{
Equal--;
}
else
/* check trajectory velacity */
/* don't consider tails of trajectory becasue its unnstable for velosity calculation */
if(UseVel && j>5 && jt>5 && dv2 > Tv2 )
{
Equal--;
}
}/* compare with threshold */
if(Equal>0)
{
NumEq++;
pFT->close++;
}
}/* next template */
{ /* calc state */
float T = m_TrackDataBase.GetBlobNum() * m_AbnormalThreshold; /* calc threshold */
if(T>0)
{
pF->state = (T - NumEq)/(T*0.2f) + 0.5f;
}
if(pF->state<0)pF->state=0;
if(pF->state>1)pF->state=1;
/*if(0)if(pF->state>0)
{// if abnormal blob
printf("Abnormal blob(%d) %d < %f, state=%f\n",CV_BLOB_ID(pF),NumEq,T, pF->state);
}*/
}/* calc state */
}/* process one blob trajectory */
else
{/* move track to trcaks data base */
m_TrackDataBase.AddBlob((CvBlob*)pF);
m_Tracks.DelBlob(i-1);
}
}/* next blob */
if(m_Wnd)
{/* debug output */
int i;
if(m_pDebugImg==NULL)
m_pDebugImg = cvCloneImage(pImg);
else
cvCopyImage(pImg, m_pDebugImg);
for(i=m_TrackDataBase.GetBlobNum();i>0;--i)
{/* draw all elements from trackdata base */
int j;
DefTrackForDist* pF = (DefTrackForDist*)m_TrackDataBase.GetBlob(i-1);
CvScalar color = CV_RGB(0,0,0);
if(!pF->close) continue;
if(pF->close)
{
color = CV_RGB(0,0,255);
}
else
{
color = CV_RGB(0,0,128);
}
for(j=pF->pTrack->GetPointNum();j>0;j--)
{
DefTrackPoint* pB = pF->pTrack->GetPoint(j-1);
int r = 0;//MAX(cvRound(pB->r),1);
cvCircle(m_pDebugImg, cvPoint(cvRound(pB->x),cvRound(pB->y)), r, color);
}
pF->close = 0;
}/* draw all elements from trackdata base */
for(i=m_Tracks.GetBlobNum();i>0;--i)
{/* draw all elements for all trajectories */
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlob(i-1);
int j;
int c = cvRound(pF->state*255);
CvScalar color = CV_RGB(c,255-c,0);
CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pF));
int x = cvRound(CV_BLOB_RX(pF)), y = cvRound(CV_BLOB_RY(pF));
CvSize s = cvSize(MAX(1,x), MAX(1,y));
cvEllipse( m_pDebugImg,
p,
s,
0, 0, 360,
CV_RGB(c,255-c,0), cvRound(1+(0*c)/255) );
for(j=pF->pTrack->GetPointNum();j>0;j--)
{
DefTrackPoint* pB = pF->pTrack->GetPoint(j-1);
if(pF->pTrack->GetPointNum()-j > m_TraceLen) break;
cvCircle(m_pDebugImg, cvPoint(cvRound(pB->x),cvRound(pB->y)), 0, color);
}
pF->close = 0;
}/* draw all elements for all trajectories */
//cvNamedWindow("Tracks",0);
//cvShowImage("Tracks", m_pDebugImg);
}/* debug output */
#if 0
if(m_pDebugImg && m_pDebugAVIName)
{
if(m_pDebugAVI==NULL)
{/* create avi file for writing */
m_pDebugAVI = cvCreateVideoWriter(
m_pDebugAVIName,
CV_FOURCC('x','v','i','d'),
25,
cvSize(m_pDebugImg->width,m_pDebugImg->height));
if(m_pDebugAVI == NULL)
{
printf("WARNING!!! Can not create AVI file %s for writing\n",m_pDebugAVIName);
}
}/* create avi file for writing */
if(m_pDebugAVI)cvWriteFrame( m_pDebugAVI, m_pDebugImg );
}/* write debug window to AVI file */
#endif
m_Frame++;
};
float GetState(int BlobID)
{
DefTrackForDist* pF = (DefTrackForDist*)m_Tracks.GetBlobByID(BlobID);
return pF?pF->state:0.0f;
};
/* return 0 if trajectory is normal
return >0 if trajectory abnormal */
virtual char* GetStateDesc(int BlobID)
{
if(GetState(BlobID)>0.5) return "abnormal";
return NULL;
}
virtual void SetFileName(char* DataBaseName)
{
m_DataFileName[0] = 0;
if(DataBaseName)
{
strncpy(m_DataFileName,DataBaseName,1000);
strcat(m_DataFileName, ".yml");
}
};
virtual void Release(){ delete this; };
};
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisTrackDist()
{return (CvBlobTrackAnalysis*) new CvBlobTrackAnalysisTrackDist;}

View File

@@ -0,0 +1,171 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
typedef struct DefBlobTrack
{
CvBlob blob;
CvBlobSeq* pSeq;
int FrameBegin;
int FrameLast;
int Saved; /* flag */
}DefBlobTrack;
static void SaveTrack(DefBlobTrack* pTrack, char* pFileName, int norm = 0)
{/* save blob track */
int j;
FILE* out = NULL;
CvBlobSeq* pS = pTrack->pSeq;
CvBlob* pB0 = pS?pS->GetBlob(0):NULL;
if(pFileName == NULL) return;
if(pTrack == NULL) return;
out = fopen(pFileName,"at");
if(out == NULL)
{
printf("Warning! Can not open %s file for track output\n",pFileName);
return;
}
fprintf(out,"%d",pTrack->FrameBegin);
if(pS)for(j=0;j<pS->GetBlobNum();++j)
{
CvBlob* pB = pS->GetBlob(j);
fprintf(out,", %.1f, %.1f", CV_BLOB_X(pB),CV_BLOB_Y(pB));
if(CV_BLOB_WX(pB0)>0)
fprintf(out,", %.2f",CV_BLOB_WX(pB)/(norm?CV_BLOB_WX(pB0):1));
if(CV_BLOB_WY(pB0)>0)
fprintf(out,", %.2f",CV_BLOB_WY(pB)/(norm?CV_BLOB_WY(pB0):1));
}
fprintf(out,"\n");
fclose(out);
pTrack->Saved = 1;
}/* save blob track */
class CvBlobTrackGen1:public CvBlobTrackGen
{
public:
CvBlobTrackGen1(int BlobSizeNorm = 0):m_TrackList(sizeof(DefBlobTrack))
{
m_BlobSizeNorm = BlobSizeNorm;
m_Frame = 0;
m_pFileName = NULL;
};
~CvBlobTrackGen1()
{
int i;
for(i=m_TrackList.GetBlobNum();i>0;--i)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i-1);
if(!pTrack->Saved)
{/* save track */
SaveTrack(pTrack, m_pFileName, m_BlobSizeNorm);
}/* save track */
/* delete sequence */
delete pTrack->pSeq;
pTrack->pSeq = NULL;
}/* check next track */
}/* destructor */
void SetFileName(char* pFileName){m_pFileName = pFileName;};
void AddBlob(CvBlob* pBlob)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
if(pTrack==NULL)
{/* add new track */
DefBlobTrack Track;
Track.blob = pBlob[0];
Track.FrameBegin = m_Frame;
Track.pSeq = new CvBlobSeq;
Track.Saved = 0;
m_TrackList.AddBlob((CvBlob*)&Track);
pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
}/* add new track */
assert(pTrack);
pTrack->FrameLast = m_Frame;
assert(pTrack->pSeq);
pTrack->pSeq->AddBlob(pBlob);
};
void Process(IplImage* /*pImg*/ = NULL, IplImage* /*pFG*/ = NULL)
{
int i;
for(i=m_TrackList.GetBlobNum();i>0;--i)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i-1);
if(pTrack->FrameLast < m_Frame && !pTrack->Saved)
{/* save track */
SaveTrack(pTrack, m_pFileName, m_BlobSizeNorm);
if(pTrack->Saved)
{ /* delete sequence */
delete pTrack->pSeq;
pTrack->pSeq = NULL;
m_TrackList.DelBlob(i-1);
}
}/* save track */
}/* check next track */
m_Frame++;
}
void Release()
{
delete this;
}
protected:
int m_Frame;
char* m_pFileName;
CvBlobSeq m_TrackList;
int m_BlobSizeNorm;
}; /* class CvBlobTrackGen1 */
CvBlobTrackGen* cvCreateModuleBlobTrackGen1()
{
return (CvBlobTrackGen*) new CvBlobTrackGen1(0);
}

View File

@@ -0,0 +1,202 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
typedef struct DefBlobTrack
{
CvBlob blob;
CvBlobSeq* pSeq;
int FrameBegin;
int FrameLast;
int Saved; /* flag */
}DefBlobTrack;
class CvBlobTrackGenYML:public CvBlobTrackGen
{
protected:
int m_Frame;
char* m_pFileName;
CvBlobSeq m_TrackList;
CvSize m_Size;
void SaveAll()
{
int ObjNum = m_TrackList.GetBlobNum();
int i;
char video_name[1024];
char* struct_name = NULL;
CvFileStorage* storage = cvOpenFileStorage(m_pFileName,NULL,CV_STORAGE_WRITE_TEXT);
if(storage==NULL)
{
printf("WARNING!!! Can not open %s file for trajectories writing",m_pFileName);
}
for(i=0;i<1024 && m_pFileName[i]!='.' && m_pFileName[i]!=0;++i)video_name[i]=m_pFileName[i];
video_name[i] = 0;
for(;i>0;i--)
{
if(video_name[i-1] == '\\') break;
if(video_name[i-1] == '/') break;
if(video_name[i-1] == ':') break;
}
struct_name = video_name + i;
cvStartWriteStruct(storage, struct_name, CV_NODE_SEQ);
for(i=0;i<ObjNum;++i)
{
char obj_name[1024];
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i);
if(pTrack==NULL) continue;
sprintf(obj_name,"%s_obj%d",struct_name,i);
cvStartWriteStruct(storage, NULL, CV_NODE_MAP);
cvWriteInt(storage, "FrameBegin", pTrack->FrameBegin);
cvWriteString(storage, "VideoObj", obj_name);
cvEndWriteStruct( storage );
pTrack->Saved = 1;
}
cvEndWriteStruct( storage );
for(i=0;i<ObjNum;++i)
{
char obj_name[1024];
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i);
CvBlobSeq* pSeq = pTrack->pSeq;
sprintf(obj_name,"%s_obj%d",struct_name,i);
cvStartWriteStruct(storage, obj_name, CV_NODE_MAP);
{ /* write pos */
int j;
CvPoint2D32f p;
cvStartWriteStruct(storage, "Pos", CV_NODE_SEQ|CV_NODE_FLOW);
for(j=0;j<pSeq->GetBlobNum();++j)
{
CvBlob* pB = pSeq->GetBlob(j);
p.x = pB->x/(m_Size.width-1);
p.y = pB->y/(m_Size.height-1);
cvWriteRawData(storage, &p, 1 ,"ff");
}
cvEndWriteStruct( storage );
}
{ /* write size */
int j;
CvPoint2D32f p;
cvStartWriteStruct(storage, "Size", CV_NODE_SEQ|CV_NODE_FLOW);
for(j=0;j<pSeq->GetBlobNum();++j)
{
CvBlob* pB = pSeq->GetBlob(j);
p.x = pB->w/(m_Size.width-1);
p.y = pB->h/(m_Size.height-1);
cvWriteRawData(storage, &p, 1 ,"ff");
}
cvEndWriteStruct( storage );
}
cvEndWriteStruct( storage );
}
cvReleaseFileStorage(&storage);
}/* Save All */
public:
CvBlobTrackGenYML():m_TrackList(sizeof(DefBlobTrack))
{
m_Frame = 0;
m_pFileName = NULL;
m_Size = cvSize(2,2);
};
~CvBlobTrackGenYML()
{
int i;
SaveAll();
for(i=m_TrackList.GetBlobNum();i>0;--i)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i-1);
/* delete sequence */
delete pTrack->pSeq;
pTrack->pSeq = NULL;
}/* check next track */
}/* destructor */
void SetFileName(char* pFileName){m_pFileName = pFileName;};
void AddBlob(CvBlob* pBlob)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
if(pTrack==NULL)
{/* add new track */
DefBlobTrack Track;
Track.blob = pBlob[0];
Track.FrameBegin = m_Frame;
Track.pSeq = new CvBlobSeq;
Track.Saved = 0;
m_TrackList.AddBlob((CvBlob*)&Track);
pTrack = (DefBlobTrack*)m_TrackList.GetBlobByID(CV_BLOB_ID(pBlob));
}/* add new track */
assert(pTrack);
pTrack->FrameLast = m_Frame;
assert(pTrack->pSeq);
pTrack->pSeq->AddBlob(pBlob);
};
void Process(IplImage* pImg = NULL, IplImage* /*pFG*/ = NULL)
{
int i;
m_Size = cvSize(pImg->width,pImg->height);
for(i=m_TrackList.GetBlobNum();i>0;--i)
{
DefBlobTrack* pTrack = (DefBlobTrack*)m_TrackList.GetBlob(i-1);
if(pTrack->FrameLast < m_Frame && !pTrack->Saved)
{/* save track */
SaveAll();
}/* save track */
}/* check next track */
m_Frame++;
}
void Release()
{
delete this;
}
}; /* class CvBlobTrackGenYML */
CvBlobTrackGen* cvCreateModuleBlobTrackGenYML()
{
return (CvBlobTrackGen*) new CvBlobTrackGenYML;
}

View File

@@ -0,0 +1,456 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/*
This file contain simple implementation of BlobTrackerAuto virtual interface
This module just connected other low level 3 modules
(foreground estimator + BlobDetector + BlobTracker)
and some simple code to detect "lost tracking"
The track is lost when integral of foreground mask image by blob area has low value
*/
#include "_cvaux.h"
#include <time.h>
/* list of Blob Detection modules */
CvBlobDetector* cvCreateBlobDetectorSimple();
/* get frequency for each module time working estimation */
static double FREQ = 1000*cvGetTickFrequency();
#if 1
#define COUNTNUM 100
#define TIME_BEGIN() \
{\
static double _TimeSum = 0;\
static int _Count = 0;\
static int _CountBlob = 0;\
int64 _TickCount = cvGetTickCount();\
#define TIME_END(_name_,_BlobNum_) \
_Count++;\
_CountBlob+=_BlobNum_;\
_TimeSum += (cvGetTickCount()-_TickCount)/FREQ;\
if(m_TimesFile)if(_Count%COUNTNUM==0)\
{ \
FILE* out = fopen(m_TimesFile,"at");\
if(out)\
{\
fprintf(out,"ForFrame Frame: %d %s %f on %f blobs\n",_Count,_name_, _TimeSum/COUNTNUM,((float)_CountBlob)/COUNTNUM);\
if(_CountBlob>0)fprintf(out,"ForBlob Frame: %d %s - %f\n",_Count,_name_, _TimeSum/_CountBlob);\
fclose(out);\
}\
_TimeSum = 0;\
_CountBlob = 0;\
}\
}
#else
#define TIME_BEGIN()
#define TIME_END(_name_)
#endif
/* special extended blob structure for auto blob tracking */
typedef struct CvBlobTrackAuto
{
CvBlob blob;
int BadFrames;
}CvBlobTrackAuto;
class CvBlobTrackerAuto1: public CvBlobTrackerAuto
{
public:
CvBlobTrackerAuto1(CvBlobTrackerAutoParam1* param);
~CvBlobTrackerAuto1();
CvBlob* GetBlob(int index){return m_BlobList.GetBlob(index);};
CvBlob* GetBlobByID(int ID){return m_BlobList.GetBlobByID(ID);};
int GetBlobNum(){return m_BlobList.GetBlobNum();};
virtual IplImage* GetFGMask(){return m_pFGMask;};
float GetState(int BlobID){return m_pBTA?m_pBTA->GetState(BlobID):0;};
char* GetStateDesc(int BlobID){return m_pBTA?m_pBTA->GetStateDesc(BlobID):NULL;};
/* return 0 if trajectory is normal
return >0 if trajectory abnormal */
void Process(IplImage* pImg, IplImage* pMask = NULL);
void Release(){delete this;};
private:
IplImage* m_pFGMask;
int m_FGTrainFrames;
CvFGDetector* m_pFG; /* pointer to foreground mask detector modelu */
CvBlobTracker* m_pBT; /* pointer to Blob tracker module */
int m_BTDel;
int m_BTReal;
CvBlobDetector* m_pBD; /* pointer to Blob detector module */
int m_BDDel;
CvBlobTrackGen* m_pBTGen;
CvBlobTrackPostProc* m_pBTPostProc;
int m_UsePPData;
CvBlobTrackAnalysis* m_pBTA; /* blob trajectory analyser */
CvBlobSeq m_BlobList;
int m_FrameCount;
int m_NextBlobID;
char* m_TimesFile;
public:
virtual void SaveState(CvFileStorage* fs)
{
cvWriteInt(fs,"FrameCount",m_FrameCount);
cvWriteInt(fs,"NextBlobID",m_NextBlobID);
m_BlobList.Write(fs,"BlobList");
};
virtual void LoadState(CvFileStorage* fs, CvFileNode* node)
{
CvFileNode* BlobListNode = cvGetFileNodeByName(fs,node,"BlobList");
m_FrameCount = cvReadIntByName(fs,node, "FrameCount", m_FrameCount);
m_NextBlobID = cvReadIntByName(fs,node, "NextBlobID", m_NextBlobID);
if(BlobListNode)
{
m_BlobList.Load(fs,BlobListNode);
}
};
};
/* Auto Blob tracker creater (sole interface function for this file) */
CvBlobTrackerAuto* cvCreateBlobTrackerAuto1(CvBlobTrackerAutoParam1* param)
{
return (CvBlobTrackerAuto*)new CvBlobTrackerAuto1(param);
}
/* Constructor of auto blob tracker*/
CvBlobTrackerAuto1::CvBlobTrackerAuto1(CvBlobTrackerAutoParam1* param):m_BlobList(sizeof(CvBlobTrackAuto))
{
m_BlobList.AddFormat("i");
m_TimesFile = NULL;
AddParam("TimesFile",&m_TimesFile);
m_NextBlobID = 0;
m_pFGMask = NULL;
m_FrameCount = 0;
m_FGTrainFrames = param?param->FGTrainFrames:0;
m_pFG = param?param->pFG:0;
m_BDDel = 0;
m_pBD = param?param->pBD:NULL;
m_BTDel = 0;
m_pBT = param?param->pBT:NULL;;
m_BTReal = m_pBT?m_pBT->IsModuleName("BlobTrackerReal"):0;
m_pBTGen = param?param->pBTGen:NULL;
m_pBTA = param?param->pBTA:NULL;
m_pBTPostProc = param?param->pBTPP:NULL;
m_UsePPData = param?param->UsePPData:0;
/* create default sub modules */
if(m_pBD==NULL)
{
m_pBD = cvCreateBlobDetectorSimple();
m_BDDel = 1;
}
if(m_pBT==NULL)
{
m_pBT = cvCreateBlobTrackerMS();
m_BTDel = 1;
}
}/* CvBlobTrackerAuto1::CvBlobTrackerAuto1 */
/* Destructor of auto blob tracker */
CvBlobTrackerAuto1::~CvBlobTrackerAuto1()
{
if(m_BDDel)m_pBD->Release();
if(m_BTDel)m_pBT->Release();
}/* Destructor of auto blob tracker */
void CvBlobTrackerAuto1::Process(IplImage* pImg, IplImage* pMask)
{
int CurBlobNum = 0;
int i;
IplImage* pFG = pMask;
/* increase frame counter */
m_FrameCount++;
if(m_TimesFile)
{
static int64 TickCount = cvGetTickCount();
static double TimeSum = 0;
static int Count = 0;
Count++;
if(Count%100==0)
{
time_t ltime;
time( &ltime );
FILE* out = fopen(m_TimesFile,"at");
double Time;
TickCount = cvGetTickCount()-TickCount;
Time = TickCount/FREQ;
if(out){fprintf(out,"- %sFrame: %d ALL_TIME - %f\n",ctime( &ltime ),Count,Time/1000);fclose(out);}
TimeSum = 0;
TickCount = cvGetTickCount();
}
}
/* update BG model */
TIME_BEGIN()
if(m_pFG)
{/* if FG detector is needed */
m_pFG->Process(pImg);
pFG = m_pFG->GetMask();
}/* if FG detector is needed */
TIME_END("FGDetector",-1)
m_pFGMask = pFG; /* for external use */
/*if(m_pFG && m_pFG->GetParam("DebugWnd") == 1)
{// debug foreground result
IplImage *pFG = m_pFG->GetMask();
if(pFG)
{
cvNamedWindow("FG",0);
cvShowImage("FG", pFG);
}
}*/
/* track blobs */
TIME_BEGIN()
if(m_pBT)
{
int i;
m_pBT->Process(pImg, pFG);
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* update data of tracked blob list */
CvBlob* pB = m_BlobList.GetBlob(i-1);
int BlobID = CV_BLOB_ID(pB);
int i = m_pBT->GetBlobIndexByID(BlobID);
m_pBT->ProcessBlob(i, pB, pImg, pFG);
pB->ID = BlobID;
}
CurBlobNum = m_pBT->GetBlobNum();
}
TIME_END("BlobTracker",CurBlobNum)
/* this part should be removed */
if(m_BTReal && m_pBT)
{/* update blob list (detect new blob for real blob tracker )*/
int i;
for(i=m_pBT->GetBlobNum();i>0;--i)
{/* update data of tracked blob list */
CvBlob* pB = m_pBT->GetBlob(i-1);
if(pB && m_BlobList.GetBlobByID(CV_BLOB_ID(pB)) == NULL )
{
CvBlobTrackAuto NewB;
NewB.blob = pB[0];
NewB.BadFrames = 0;
m_BlobList.AddBlob((CvBlob*)&NewB);
}
}/* next blob */
/*delete blobs */
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* update data of tracked blob list */
CvBlob* pB = m_BlobList.GetBlob(i-1);
if(pB && m_pBT->GetBlobByID(CV_BLOB_ID(pB)) == NULL )
{
m_BlobList.DelBlob(i-1);
}
}/* next blob */
}/* update blob list */
TIME_BEGIN()
if(m_pBTPostProc)
{/* post processing module */
int i;
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* update data of tracked blob list */
CvBlob* pB = m_BlobList.GetBlob(i-1);
m_pBTPostProc->AddBlob(pB);
}
m_pBTPostProc->Process();
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* update data of tracked blob list */
CvBlob* pB = m_BlobList.GetBlob(i-1);
int BlobID = CV_BLOB_ID(pB);
CvBlob* pBN = m_pBTPostProc->GetBlobByID(BlobID);
if(pBN && m_UsePPData && pBN->w >= CV_BLOB_MINW && pBN->h >= CV_BLOB_MINH)
{ /* set new data for tracker */
m_pBT->SetBlobByID(BlobID, pBN );
}
if(pBN)
{/* update blob list by result from postprocessing */
pB[0] = pBN[0];
}
}
}/* post processing module */
TIME_END("PostProcessing",CurBlobNum)
/* Blob deleter (experimental and simple)*/
TIME_BEGIN()
if(pFG)
{/* Blob deleter */
int i;
if(!m_BTReal)for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* check all blobs from list */
CvBlobTrackAuto* pB = (CvBlobTrackAuto*)(m_BlobList.GetBlob(i-1));
int Good = 0;
int w=pFG->width;
int h=pFG->height;
CvRect r = CV_BLOB_RECT(pB);
CvMat mat;
double aver = 0;
double area = CV_BLOB_WX(pB)*CV_BLOB_WY(pB);
if(r.x < 0){r.width += r.x;r.x = 0;}
if(r.y < 0){r.height += r.y;r.y = 0;}
if(r.x+r.width>=w){r.width = w-r.x-1;}
if(r.y+r.height>=h){r.height = h-r.y-1;}
if(r.width > 4 && r.height > 4 && r.x < w && r.y < h &&
r.x >=0 && r.y >=0 &&
r.x+r.width < w && r.y+r.height < h && area > 0)
{
aver = cvSum(cvGetSubRect(pFG,&mat,r)).val[0] / area;
/* if mask in blob area exists then its blob OK*/
if(aver > 0.1*255)Good = 1;
}
else
{
pB->BadFrames+=2;
}
if(Good)
{
pB->BadFrames = 0;
}
else
{
pB->BadFrames++;
}
}/* next blob */
/* check error count */
for(i=0;i<m_BlobList.GetBlobNum();++i)
{
CvBlobTrackAuto* pB = (CvBlobTrackAuto*)m_BlobList.GetBlob(i);
if(pB->BadFrames>3)
{/* delete such object */
/* from tracker */
m_pBT->DelBlobByID(CV_BLOB_ID(pB));
/* from local list */
m_BlobList.DelBlob(i);
i--;
}
}/* check error count for next blob */
}/* Blob deleter */
TIME_END("BlobDeleter",m_BlobList.GetBlobNum())
/* Update blobs */
TIME_BEGIN()
if(m_pBT)
m_pBT->Update(pImg, pFG);
TIME_END("BlobTrackerUpdate",CurBlobNum)
/* detect new blob */
TIME_BEGIN()
if(!m_BTReal && m_pBD && pFG && (m_FrameCount > m_FGTrainFrames) )
{/* detect new blob */
static CvBlobSeq NewBlobList;
CvBlobTrackAuto NewB;
NewBlobList.Clear();
if(m_pBD->DetectNewBlob(pImg, pFG, &NewBlobList, &m_BlobList))
{/* add new blob to tracker and blob list */
int i;
IplImage* pMask = pFG;
/*if(0)if(NewBlobList.GetBlobNum()>0 && pFG )
{// erode FG mask (only for FG_0 and MS1||MS2)
pMask = cvCloneImage(pFG);
cvErode(pFG,pMask,NULL,2);
}*/
for(i=0;i<NewBlobList.GetBlobNum();++i)
{
CvBlob* pBN = NewBlobList.GetBlob(i);
pBN->ID = m_NextBlobID;
if(pBN && pBN->w >= CV_BLOB_MINW && pBN->h >= CV_BLOB_MINH)
{
CvBlob* pB = m_pBT->AddBlob(pBN, pImg, pMask );
if(pB)
{
NewB.blob = pB[0];
NewB.BadFrames = 0;
m_BlobList.AddBlob((CvBlob*)&NewB);
m_NextBlobID++;
}
}
}/* add next blob from list of detected blob */
if(pMask != pFG) cvReleaseImage(&pMask);
}/* create and add new blobs and trackers */
}/* detect new blob */
TIME_END("BlobDetector",-1)
TIME_BEGIN()
if(m_pBTGen)
{/* run tracj generator */
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* update data of tracked blob list */
CvBlob* pB = m_BlobList.GetBlob(i-1);
m_pBTGen->AddBlob(pB);
}
m_pBTGen->Process(pImg, pFG);
}/* run tracj generator */
TIME_END("TrajectoryGeneration",-1)
TIME_BEGIN()
if(m_pBTA)
{/* trajectory analysis module */
int i;
for(i=m_BlobList.GetBlobNum();i>0;i--)
m_pBTA->AddBlob(m_BlobList.GetBlob(i-1));
m_pBTA->Process(pImg, pFG);
}/* trajectory analysis module */
TIME_END("TrackAnalysis",m_BlobList.GetBlobNum())
}/* CvBlobTrackerAuto1::Process */

View File

@@ -0,0 +1,529 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
static float CalcAverageMask(CvBlob* pBlob, IplImage* pImgFG )
{/* calc summ of mask */
double Area, Aver = 0;
CvRect r;
CvMat mat;
if(pImgFG==NULL) return 0;
r.x = cvRound(pBlob->x - pBlob->w*0.5);
r.y = cvRound(pBlob->y - pBlob->h*0.5);
r.width = cvRound(pBlob->w);
r.height = cvRound(pBlob->h);
Area = r.width*r.height;
if(r.x<0){r.width += r.x;r.x = 0;}
if(r.y<0){r.height += r.y;r.y = 0;}
if((r.x+r.width)>=pImgFG->width){r.width=pImgFG->width-r.x-1;}
if((r.y+r.height)>=pImgFG->height){r.height=pImgFG->height-r.y-1;}
if(r.width>0 && r.height>0)
{
double Sum = cvSum(cvGetSubRect(pImgFG,&mat,r)).val[0]/255.0;
assert(Area>0);
Aver = Sum/Area;
}
return (float)Aver;
}/* calc summ of mask */
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */
typedef struct DefBlobTracker
{
CvBlob blob;
CvBlobTrackPredictor* pPredictor;
CvBlob BlobPredict;
int Collision;
CvBlobSeq* pBlobHyp;
float AverFG;
}DefBlobTracker;
void cvFindBlobsByCCClasters(IplImage* pFG, CvBlobSeq* pBlobs, CvMemStorage* storage);
class CvBlobTrackerCC : public CvBlobTracker
{
private:
float m_AlphaSize;
float m_AlphaPos;
float m_Alpha;
int m_Collision;
int m_ConfidenceType;
char* m_ConfidenceTypeStr;
CvBlobSeq m_BlobList;
CvBlobSeq m_BlobListNew;
// int m_LastID;
CvMemStorage* m_pMem;
int m_ClearHyp;
IplImage* m_pImg;
IplImage* m_pImgFG;
public:
CvBlobTrackerCC():m_BlobList(sizeof(DefBlobTracker))
{
// m_LastID = 0;
m_ClearHyp = 0;
m_pMem = cvCreateMemStorage();
m_Collision = 1; /* if 1 then collistion will be detected and processed */
AddParam("Collision",&m_Collision);
CommentParam("Collision", "if 1 then collision cases are processed in special way");
m_AlphaSize = 0.02f;
AddParam("AlphaSize",&m_AlphaSize);
CommentParam("AlphaSize", "Size update speed (0..1)");
m_AlphaPos = 1.0f;
AddParam("AlphaPos",&m_AlphaPos);
CommentParam("AlphaPos", "Pos update speed (0..1)");
m_Alpha = 0.001f;
AddParam("Alpha", &m_Alpha);
CommentParam("Alpha","Coefficient for model histogramm updating (0 - hist is not upated)");
m_ConfidenceType=0;
m_ConfidenceTypeStr = "NearestBlob";
AddParam("ConfidenceType", &m_ConfidenceTypeStr);
CommentParam("ConfidenceType","Type of calculated Confidence (NearestBlob, AverFG, BC)");
SetModuleName("CC");
};
~CvBlobTrackerCC()
{
if(m_pMem)cvReleaseMemStorage(&m_pMem);
};
/* blob functions*/
virtual int GetBlobNum() {return m_BlobList.GetBlobNum();};
virtual CvBlob* GetBlob(int BlobIndex){return m_BlobList.GetBlob(BlobIndex);};
virtual void SetBlob(int BlobIndex, CvBlob* pBlob)
{
CvBlob* pB = m_BlobList.GetBlob(BlobIndex);
if(pB) pB[0] = pBlob[0];
};
virtual CvBlob* GetBlobByID(int BlobID){return m_BlobList.GetBlobByID(BlobID);};
virtual void DelBlob(int BlobIndex)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
if(pBT==NULL) return;
if(pBT->pPredictor)
{
pBT->pPredictor->Release();
}
else
{
printf("WARNING!!! Invalid Predictor in CC tracker");
}
delete pBT->pBlobHyp;
m_BlobList.DelBlob(BlobIndex);
};
#if 0
virtual void DelBlobByID(int BlobID)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlobByID(BlobID);
pBT->pPredictor->Release();
delete pBT->pBlobHyp;
m_BlobList.DelBlobByID(BlobID);
};
#endif
virtual void Release(){delete this;};
/* Add new blob to track it and assign to this blob personal ID */
/* pBlob - pinter to structure with blob parameters (ID is ignored)*/
/* pImg - current image */
/* pImgFG - current foreground mask */
/* return pointer to new added blob */
virtual CvBlob* AddBlob(CvBlob* pB, IplImage* /*pImg*/, IplImage* pImgFG = NULL )
{
assert(pImgFG); /* this tracker use only foreground mask */
DefBlobTracker NewB;
NewB.blob = pB[0];
// CV_BLOB_ID(&NewB) = m_LastID;
NewB.pBlobHyp = new CvBlobSeq;
NewB.pPredictor = cvCreateModuleBlobTrackPredictKalman(); /* module for predict position */
NewB.pPredictor->Update(pB);
NewB.AverFG = pImgFG?CalcAverageMask(pB,pImgFG):0;
m_BlobList.AddBlob((CvBlob*)&NewB);
return m_BlobList.GetBlob(m_BlobList.GetBlobNum()-1);
};
virtual void Process(IplImage* pImg, IplImage* pImgFG = NULL)
{
CvSeq* cnts;
CvSeq* cnt;
int i;
m_pImg = pImg;
m_pImgFG = pImgFG;
if(m_BlobList.GetBlobNum() <= 0 ) return;
/* clear blob list for new blobs */
m_BlobListNew.Clear();
assert(m_pMem);
cvClearMemStorage(m_pMem);
assert(pImgFG);
/* find CC */
#if 0
{// by contur clastring
cvFindBlobsByCCClasters(pImgFG, &m_BlobListNew, m_pMem);
}
#else
{/* one contour - one blob */
IplImage* pBin = cvCloneImage(pImgFG);
assert(pBin);
cvThreshold(pBin,pBin,128,255,CV_THRESH_BINARY);
cvFindContours(pBin, m_pMem, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);
/* process each contours*/
for(cnt = cnts;cnt;cnt=cnt->h_next)
{
CvBlob NewBlob;
/* image moments */
double M00,X,Y,XX,YY;
CvMoments m;
CvRect r = ((CvContour*)cnt)->rect;
CvMat mat;
if(r.height < 3 || r.width < 3) continue;
cvMoments( cvGetSubRect(pImgFG,&mat,r), &m, 0 );
M00 = cvGetSpatialMoment( &m, 0, 0 );
if(M00 <= 0 ) continue;
X = cvGetSpatialMoment( &m, 1, 0 )/M00;
Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
NewBlob = cvBlob(r.x+(float)X,r.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
m_BlobListNew.AddBlob(&NewBlob);
}/* next contour */
cvReleaseImage(&pBin);
}
#endif
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* predict new blob position */
CvBlob* pB=NULL;
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(i-1);
/* update predictor by previouse value of blob*/
pBT->pPredictor->Update(&(pBT->blob));
/* predict current position */
pB = pBT->pPredictor->Predict();
if(pB)
{
pBT->BlobPredict = pB[0];
}
else
{
pBT->BlobPredict = pBT->blob;
}
}/* predict new blob position */
if(m_Collision)
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* predict collision */
int Collision = 0;
int j;
DefBlobTracker* pF = (DefBlobTracker*)m_BlobList.GetBlob(i-1);
for(j=m_BlobList.GetBlobNum();j>0;--j)
{/* predict collision */
CvBlob* pB1;
CvBlob* pB2;
DefBlobTracker* pF2 = (DefBlobTracker*)m_BlobList.GetBlob(j-1);
if(i==j) continue;
pB1 = &pF->BlobPredict;
pB2 = &pF2->BlobPredict;
if( fabs(pB1->x-pB2->x)<0.6*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.6*(pB1->h+pB2->h) ) Collision = 1;
pB1 = &pF->blob;
pB2 = &pF2->blob;
if( fabs(pB1->x-pB2->x)<0.6*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.6*(pB1->h+pB2->h) ) Collision = 1;
if(Collision) break;
}/* check next blob to cross current*/
pF->Collision = Collision;
}/* predict collision */
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* find a neighbour on cur frame for each blob from prev frame */
CvBlob* pB = m_BlobList.GetBlob(i-1);
DefBlobTracker* pBT = (DefBlobTracker*)pB;
//int BlobID = CV_BLOB_ID(pB);
//CvBlob* pBBest = NULL;
//double DistBest = -1;
//int j;
if(pBT->pBlobHyp->GetBlobNum()>0)
{/* track all hypothesis */
int h,hN = pBT->pBlobHyp->GetBlobNum();
for(h=0;h<hN;++h)
{
int j, jN = m_BlobListNew.GetBlobNum();
CvBlob* pB = pBT->pBlobHyp->GetBlob(h);
int BlobID = CV_BLOB_ID(pB);
CvBlob* pBBest = NULL;
double DistBest = -1;
for(j=0;j<jN;j++)
{/* find best CC */
double Dist = -1;
CvBlob* pBNew = m_BlobListNew.GetBlob(j);
double dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
double dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
if(dx > 2*CV_BLOB_WX(pB) || dy > 2*CV_BLOB_WY(pB)) continue;
Dist = sqrt(dx*dx+dy*dy);
if(Dist < DistBest || pBBest == NULL)
{
DistBest = Dist;
pBBest = pBNew;
}
}/* find best CC */
if(pBBest)
{
pB[0] = pBBest[0];
CV_BLOB_ID(pB) = BlobID;
}
else
{ /* delete this hypothesis */
pBT->pBlobHyp->DelBlob(h);
h--;
hN--;
}
}/* next hyp*/
}/* track all hypothesis */
}/* track next blob */
m_ClearHyp = 1;
}/* Process */
virtual void ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
{
int ID = pBlob->ID;
CvBlob* pB = m_BlobList.GetBlob(BlobIndex);
DefBlobTracker* pBT = (DefBlobTracker*)pB;
//CvBlob* pBBest = NULL;
//double DistBest = -1;
int BlobID;
if(pB==NULL) return;
BlobID = pB->ID;
if(m_Collision && pBT->Collision)
{/* tracking in collision */
pB[0]=pBT->BlobPredict;
CV_BLOB_ID(pB)=BlobID;
}/* tracking in collision */
else
{/* not collision tracking */
CvBlob* pBBest = GetNearestBlob(pB);
if(pBBest)
{
float w = pBlob->w*(1-m_AlphaSize)+m_AlphaSize*pBBest->w;
float h = pBlob->h*(1-m_AlphaSize)+m_AlphaSize*pBBest->h;
float x = pBlob->x*(1-m_AlphaPos)+m_AlphaPos*pBBest->x;
float y = pBlob->y*(1-m_AlphaPos)+m_AlphaPos*pBBest->y;
pB->w = w;
pB->h = h;
pB->x = x;
pB->y = y;
CV_BLOB_ID(pB) = BlobID;
}
}/* not collision tracking */
pBlob[0] = pB[0];
pBlob->ID = ID;
};
virtual double GetConfidence(int BlobIndex, CvBlob* pBlob, IplImage* /*pImg*/, IplImage* pImgFG = NULL)
{
/* define koefficients in exp by exp(-XT*K)=VT */
static double _KS = -log(0.1)/pow(0.5,2); /* XT = 1, VT = 0.1 - when size is Larger in 2 times Confidence is smoller in 10 times */
static double _KP = -log(0.1)/pow(m_pImg->width*0.02,2); /* XT = 0.02*ImgWidth, VT = 0.1*/
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
float dx,dy,dw,dh;
float dp2,ds2;
double W = 1;
CvBlob* pBC = GetNearestBlob(pBlob);
if(pBC == NULL ) return 0;
dx = pBC->x-pBlob->x;
dy = pBC->y-pBlob->y;
dw = (pBC->w-pBlob->w)/pBC->w;
dh = (pBC->h-pBlob->h)/pBC->h;
dp2 = dx*dx+dy*dy;
ds2 = dw*dw+dh*dh;
if(!pBT->Collision)
{ /* Confidence for size by nearest blob */
W*=exp(-_KS*ds2);
}
if(m_ConfidenceType==0 && !pBT->Collision)
{ /* confinence by nearest blob */
W*=exp(-_KP*dp2);
}
if(m_ConfidenceType==1 && pBT->AverFG>0)
{/* calc summ of mask */
float Aver = CalcAverageMask(pBlob, pImgFG );
if(Aver < pBT->AverFG)
{
float diff = 1+0.9f*(Aver-pBT->AverFG)/pBT->AverFG;
if(diff < 0.1f) diff = 0.1f;
W *= diff;
}
}/* calc summ of mask */
if(m_ConfidenceType==2)
{/* calc BCoeff */
float S = 0.2f;
float Aver = CalcAverageMask(pBlob, pImgFG );
double B = sqrt(Aver*pBT->AverFG)+sqrt((1-Aver)*(1-pBT->AverFG));
W *= exp((B-1)/(2*S));
}/* calc summ of mask */
return W;
};
virtual void UpdateBlob(int BlobIndex, CvBlob* /*pBlob*/, IplImage* /*pImg*/, IplImage* pImgFG = NULL)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
if(pImgFG==NULL || pBT==NULL) return;
if(!pBT->Collision)
{
//pBT->AverFG = pBT->AverFG * (1-m_Alpha) + m_Alpha * CalcAverageMask(pBlob,pImgFG);
}
};
virtual void ParamUpdate()
{
char* pCT[3] = {"NearestBlob","AverFG","BC"};
int i;
CvBlobTracker::ParamUpdate();
for(i=0;i<3;++i)
{
if(cv_stricmp(m_ConfidenceTypeStr,pCT[i])==0)
{
m_ConfidenceType = i;
}
}
SetParamStr("ConfidenceType",pCT[m_ConfidenceType]);
}
/* =============== MULTI HYPOTHESIS INTERFACE ================== */
/* return number of position hyposetis of currently tracked blob */
virtual int GetBlobHypNum(int BlobIdx)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIdx);
assert(pBT->pBlobHyp);
return pBT->pBlobHyp->GetBlobNum();
};/* CvBlobtrackerList::GetBlobHypNum() */
/* return pointer to specified blob hypothesis by index blob */
virtual CvBlob* GetBlobHyp(int BlobIndex, int hypothesis)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
assert(pBT->pBlobHyp);
return pBT->pBlobHyp->GetBlob(hypothesis);
};/* CvBlobtrackerList::GetBlobHyp() */
/* Set new parameters for specified (by index) blob hyp (can be called several times for each hyp )*/
virtual void SetBlobHyp(int BlobIndex, CvBlob* pBlob)
{
if(m_ClearHyp)
{/* clear all hypothesis */
int b, bN = m_BlobList.GetBlobNum();
for(b=0;b<bN;++b)
{
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(b);
assert(pBT->pBlobHyp);
pBT->pBlobHyp->Clear();
}
m_ClearHyp = 0;
}
{/* add hypothesis */
DefBlobTracker* pBT = (DefBlobTracker*)m_BlobList.GetBlob(BlobIndex);
assert(pBT->pBlobHyp);
pBT->pBlobHyp->AddBlob(pBlob);
}
};
private:
CvBlob* GetNearestBlob(CvBlob* pB)
{
//DefBlobTracker* pBT = (DefBlobTracker*)pB;
CvBlob* pBBest = NULL;
double DistBest = -1;
int j,BlobID;
if(pB==NULL) return NULL;
BlobID = pB->ID;
for(j=m_BlobListNew.GetBlobNum();j>0;--j)
{/* find best CC */
double Dist = -1;
CvBlob* pBNew = m_BlobListNew.GetBlob(j-1);
double dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
double dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
if(dx > 2*CV_BLOB_WX(pB) || dy > 2*CV_BLOB_WY(pB)) continue;
Dist = sqrt(dx*dx+dy*dy);
if(Dist < DistBest || pBBest == NULL)
{
DistBest = Dist;
pBBest = pBNew;
}
}/* find best CC */
return pBBest;
}; /* GetNearestBlob */
};
CvBlobTracker* cvCreateBlobTrackerCC()
{
return (CvBlobTracker*) new CvBlobTrackerCC;
}
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */

View File

@@ -0,0 +1,451 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */
typedef struct DefBlobTrackerCR
{
CvBlob blob;
CvBlobTrackPredictor* pPredictor;
CvBlob BlobPredict;
CvBlob BlobPrev;
int Collision;
CvBlobSeq* pBlobHyp;
CvBlobTrackerOne* pResolver;
}DefBlobTrackerCR;
void cvFindBlobsByCCClasters(IplImage* pFG, CvBlobSeq* pBlobs, CvMemStorage* storage);
class CvBlobTrackerCCCR : public CvBlobTracker
{
private:
float m_AlphaSize;
int m_Collision;
CvBlobSeq m_BlobList;
CvBlobSeq m_BlobListNew;
CvMemStorage* m_pMem;
CvBlobTrackerOne* (*m_CreateCR)();
char m_ModuleName[1024];
public:
CvBlobTrackerCCCR(CvBlobTrackerOne* (*CreateCR)(), char* CRName):m_BlobList(sizeof(DefBlobTrackerCR))
{
m_CreateCR = CreateCR;
m_pMem = cvCreateMemStorage();
m_Collision = 1; /* if 1 then collistion will be detected and processed */
m_AlphaSize = 0.05f;
AddParam("AlphaSize",&m_AlphaSize);
CommentParam("AlphaSize", "Size update speed (0..1)");
strcpy(m_ModuleName, "CC");
if(CRName)strcat(m_ModuleName,CRName);
SetModuleName(m_ModuleName);
{
CvBlobTrackerOne* pM = m_CreateCR();
TransferParamsFromChild(pM,NULL);
pM->Release();
}
SetParam("SizeVar",0);
};
~CvBlobTrackerCCCR()
{
if(m_pMem)cvReleaseMemStorage(&m_pMem);
};
/* blob functions*/
virtual int GetBlobNum() {return m_BlobList.GetBlobNum();};
virtual CvBlob* GetBlob(int BlobIndex){return m_BlobList.GetBlob(BlobIndex);};
virtual void SetBlob(int BlobIndex, CvBlob* pBlob)
{
CvBlob* pB = m_BlobList.GetBlob(BlobIndex);
if(pB) pB[0] = pBlob[0];
};
virtual CvBlob* GetBlobByID(int BlobID){return m_BlobList.GetBlobByID(BlobID);};
virtual void DelBlob(int BlobIndex)
{
DefBlobTrackerCR* pBT = (DefBlobTrackerCR*)m_BlobList.GetBlob(BlobIndex);
if(pBT->pResolver)pBT->pResolver->Release();
if(pBT->pPredictor)pBT->pPredictor->Release();
delete pBT->pBlobHyp;
m_BlobList.DelBlob(BlobIndex);
};
virtual void DelBlobByID(int BlobID)
{
DefBlobTrackerCR* pBT = (DefBlobTrackerCR*)m_BlobList.GetBlobByID(BlobID);
if(pBT->pResolver)pBT->pResolver->Release();
if(pBT->pPredictor)pBT->pPredictor->Release();
delete pBT->pBlobHyp;
m_BlobList.DelBlobByID(BlobID);
};
virtual void Release(){delete this;};
/* Add new blob to track it and assign to this blob personal ID */
/* pBlob - pinter to structure with blob parameters (ID is ignored)*/
/* pImg - current image */
/* pImgFG - current foreground mask */
/* return pointer to new added blob */
virtual CvBlob* AddBlob(CvBlob* pB, IplImage* pImg, IplImage* pImgFG = NULL )
{
DefBlobTrackerCR NewB;
NewB.blob = pB[0];
NewB.pBlobHyp = new CvBlobSeq;
NewB.pPredictor = cvCreateModuleBlobTrackPredictKalman(); /* module for predict position */
NewB.pPredictor->SetParam("DataNoisePos",0.001);
NewB.pPredictor->ParamUpdate();
NewB.pResolver = NULL;
if(m_CreateCR)
{
NewB.pResolver = m_CreateCR();
TransferParamsToChild(NewB.pResolver,NULL);
NewB.pResolver->Init(pB, pImg, pImgFG);
}
m_BlobList.AddBlob((CvBlob*)&NewB);
return m_BlobList.GetBlob(m_BlobList.GetBlobNum()-1);
};
virtual void Process(IplImage* pImg, IplImage* pImgFG = NULL)
{
CvSeq* cnts;
CvSeq* cnt;
int i;
//CvMat* pMC = NULL;
if(m_BlobList.GetBlobNum() <= 0 ) return;
/* clear blob list for new blobs */
m_BlobListNew.Clear();
assert(m_pMem);
cvClearMemStorage(m_pMem);
assert(pImgFG);
{/* one contour - one blob */
IplImage* pBin = cvCloneImage(pImgFG);
assert(pBin);
cvThreshold(pBin,pBin,128,255,CV_THRESH_BINARY);
cvFindContours(pBin, m_pMem, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);
/* process each contours*/
for(cnt = cnts;cnt;cnt=cnt->h_next)
{
CvBlob NewBlob;
/* image moments */
double M00,X,Y,XX,YY;
CvMoments m;
CvRect r = ((CvContour*)cnt)->rect;
CvMat mat;
if(r.height < 3 || r.width < 3) continue;
cvMoments( cvGetSubRect(pImgFG,&mat,r), &m, 0 );
M00 = cvGetSpatialMoment( &m, 0, 0 );
if(M00 <= 0 ) continue;
X = cvGetSpatialMoment( &m, 1, 0 )/M00;
Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
NewBlob = cvBlob(r.x+(float)X,r.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
m_BlobListNew.AddBlob(&NewBlob);
}/* next contour */
cvReleaseImage(&pBin);
}
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* predict new blob position */
CvBlob* pB = NULL;
DefBlobTrackerCR* pBT = (DefBlobTrackerCR*)m_BlobList.GetBlob(i-1);
/*update predictor */
pBT->pPredictor->Update(&(pBT->blob));
pB = pBT->pPredictor->Predict();
if(pB)
{
pBT->BlobPredict = pB[0];
}
pBT->BlobPrev = pBT->blob;
}/* predict new blob position */
if(m_BlobList.GetBlobNum()>0 && m_BlobListNew.GetBlobNum()>0)
{/* resolve new blob to old */
int i,j;
int NOld = m_BlobList.GetBlobNum();
int NNew = m_BlobListNew.GetBlobNum();
for(i=0;i<NOld;i++)
{/* set 0 collision and clear all hyp */
DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i);
pF->Collision = 0;
pF->pBlobHyp->Clear();
}/* set 0 collision */
/* create correspondance records */
for(j=0;j<NNew;++j)
{
CvBlob* pB1 = m_BlobListNew.GetBlob(j);
DefBlobTrackerCR* pFLast = NULL;
for(i=0;i<NOld;i++)
{/* check intersection */
int Intersection = 0;
DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i);
CvBlob* pB2 = &(pF->BlobPredict);
if( fabs(pB1->x-pB2->x)<0.5*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.5*(pB1->h+pB2->h) ) Intersection = 1;
if(Intersection)
{
if(pFLast)
{
pF->Collision = pFLast->Collision = 1;
}
pFLast = pF;
pF->pBlobHyp->AddBlob(pB1);
}
}/* check intersection */
}/* check next new blob */
}/* resolve new blob to old */
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* track each blob */
CvBlob* pB = m_BlobList.GetBlob(i-1);
DefBlobTrackerCR* pBT = (DefBlobTrackerCR*)pB;
int BlobID = CV_BLOB_ID(pB);
//CvBlob* pBBest = NULL;
//double DistBest = -1;
int j;
if(pBT->pResolver)
{
pBT->pResolver->SetCollision(pBT->Collision);
}
if(pBT->Collision)
{/* tracking in collision */
if(pBT->pResolver)
{
pB[0] = pBT->pResolver->Process(&(pBT->BlobPredict),pImg, pImgFG)[0];
}
}/* tracking in collision */
else
{/* not collision tracking */
CvBlob NewCC = pBT->BlobPredict;
if(pBT->pBlobHyp->GetBlobNum()==1)
{/* one blob to one CC */
NewCC = pBT->pBlobHyp->GetBlob(0)[0];
}
else
{/* one blob several CC */
CvBlob* pBBest = NULL;
double DistBest = -1;
double CMax = 0;
for(j=pBT->pBlobHyp->GetBlobNum();j>0;--j)
{/* find best CC */
CvBlob* pBNew = pBT->pBlobHyp->GetBlob(j-1);
if(pBT->pResolver)
{/* choose CC by confidence */
// double dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
// double dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
double C = pBT->pResolver->GetConfidence(pBNew,pImg, pImgFG);
if(C > CMax || pBBest == NULL)
{
CMax = C;
pBBest = pBNew;
}
}
else
{ /* chose CC by distance */
double dx = fabs(CV_BLOB_X(pB)-CV_BLOB_X(pBNew));
double dy = fabs(CV_BLOB_Y(pB)-CV_BLOB_Y(pBNew));
double Dist = sqrt(dx*dx+dy*dy);
if(Dist < DistBest || pBBest == NULL)
{
DistBest = Dist;
pBBest = pBNew;
}
}
}/* find best CC */
if(pBBest)
NewCC = pBBest[0];
}/* one blob several CC */
pB->x = NewCC.x;
pB->y = NewCC.y;
pB->w = (m_AlphaSize)*NewCC.w+(1-m_AlphaSize)*pB->w;
pB->h = (m_AlphaSize)*NewCC.h+(1-m_AlphaSize)*pB->h;
pBT->pResolver->SkipProcess(&(pBT->BlobPredict),pImg, pImgFG);
}/* not collision tracking */
pBT->pResolver->Update(pB, pImg, pImgFG);
CV_BLOB_ID(pB)=BlobID;
}/* track next blob */
if(m_Wnd)
{
IplImage* pI = cvCloneImage(pImg);
int i;
for(i=m_BlobListNew.GetBlobNum();i>0;--i)
{/* draw each new CC */
CvBlob* pB = m_BlobListNew.GetBlob(i-1);
CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB));
CvSize s = cvSize(MAX(1,x), MAX(1,y));
//int c = 255;
cvEllipse( pI,
p,
s,
0, 0, 360,
CV_RGB(255,255,0), 1 );
}
for(i=m_BlobList.GetBlobNum();i>0;--i)
{/* draw each new CC */
DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(i-1);
CvBlob* pB = &(pF->BlobPredict);
CvPoint p = cvPointFrom32f(CV_BLOB_CENTER(pB));
int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB));
CvSize s = cvSize(MAX(1,x), MAX(1,y));
cvEllipse( pI,
p,
s,
0, 0, 360,
CV_RGB(0,0,255), 1 );
pB = &(pF->blob);
p = cvPointFrom32f(CV_BLOB_CENTER(pB));
x = cvRound(CV_BLOB_RX(pB)); y = cvRound(CV_BLOB_RY(pB));
s = cvSize(MAX(1,x), MAX(1,y));
cvEllipse( pI,
p,
s,
0, 0, 360,
CV_RGB(0,255,0), 1 );
}
//cvNamedWindow("CCwithCR",0);
//cvShowImage("CCwithCR",pI);
cvReleaseImage(&pI);
}
}/* Process */
virtual void SaveState(CvFileStorage* fs)
{
int b,bN = m_BlobList.GetBlobNum();
cvWriteInt(fs,"BlobNum",m_BlobList.GetBlobNum());
cvStartWriteStruct(fs,"BlobList",CV_NODE_SEQ);
for(b=0;b<bN;++b)
{
DefBlobTrackerCR* pF = (DefBlobTrackerCR*)m_BlobList.GetBlob(b);
cvStartWriteStruct(fs,NULL,CV_NODE_MAP);
cvWriteInt(fs,"ID",CV_BLOB_ID(pF));
cvStartWriteStruct(fs,"Blob",CV_NODE_SEQ|CV_NODE_FLOW);
cvWriteRawData(fs,&(pF->blob),1,"ffffi");
cvEndWriteStruct(fs);
cvStartWriteStruct(fs,"BlobPredict",CV_NODE_SEQ|CV_NODE_FLOW);
cvWriteRawData(fs,&(pF->BlobPredict),1,"ffffi");
cvEndWriteStruct(fs);
cvStartWriteStruct(fs,"BlobPrev",CV_NODE_SEQ|CV_NODE_FLOW);
cvWriteRawData(fs,&(pF->BlobPrev),1,"ffffi");
cvEndWriteStruct(fs);
pF->pBlobHyp->Write(fs,"BlobHyp");
cvWriteInt(fs,"Collision",pF->Collision);
cvStartWriteStruct(fs,"Predictor",CV_NODE_MAP);
pF->pPredictor->SaveState(fs);
cvEndWriteStruct(fs);
cvStartWriteStruct(fs,"Resolver",CV_NODE_MAP);
pF->pResolver->SaveState(fs);
cvEndWriteStruct(fs);
cvEndWriteStruct(fs);
}
cvEndWriteStruct(fs);
}/* SaveState*/
virtual void LoadState(CvFileStorage* fs, CvFileNode* node)
{
int b,bN = cvReadIntByName(fs,node,"BlobNum",0);
CvFileNode* pBlobListNode = cvGetFileNodeByName(fs,node,"BlobList");
if(!CV_NODE_IS_SEQ(pBlobListNode->tag)) return;
bN = pBlobListNode->data.seq->total;
for(b=0;b<bN;++b)
{
DefBlobTrackerCR* pF = NULL;
CvBlob Blob;
CvFileNode* pSeqNode = NULL;
CvFileNode* pBlobNode = (CvFileNode*)cvGetSeqElem(pBlobListNode->data.seq,b);
assert(pBlobNode);
Blob.ID = cvReadIntByName(fs,pBlobNode,"ID",0);
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "Blob");
if(CV_NODE_IS_SEQ(pSeqNode->tag))
cvReadRawData( fs, pSeqNode, &Blob, "ffffi" );
AddBlob(&Blob,NULL,NULL);
pF = (DefBlobTrackerCR*)m_BlobList.GetBlobByID(Blob.ID);
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "BlobPredict");
if(CV_NODE_IS_SEQ(pSeqNode->tag))
cvReadRawData( fs, pSeqNode, &pF->BlobPredict, "ffffi" );
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "BlobPrev");
if(CV_NODE_IS_SEQ(pSeqNode->tag))
cvReadRawData( fs, pSeqNode, &pF->BlobPrev, "ffffi" );
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "BlobHyp");
if(pSeqNode)
pF->pBlobHyp->Load(fs,pSeqNode);
pF->Collision = cvReadIntByName(fs, pBlobNode,"Collision",pF->Collision);
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "Predictor");
if(pSeqNode)
pF->pPredictor->LoadState(fs,pSeqNode);
pSeqNode = cvGetFileNodeByName(fs, pBlobNode, "Resolver");
if(pSeqNode)
pF->pResolver->LoadState(fs,pSeqNode);
}/* read next blob */
}/* CCwithCR LoadState */
//void SetCollision(int Collision){m_Collision = Collision;};
};
CvBlobTrackerOne* cvCreateBlobTrackerOneMSPF();
CvBlobTracker* cvCreateBlobTrackerCCMSPF()
{
return (CvBlobTracker*) new CvBlobTrackerCCCR(cvCreateBlobTrackerOneMSPF,"MSPF");
}
/*============== BLOB TRACKERCC CLASS DECLARATION =============== */

View File

@@ -0,0 +1,163 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/*======================= KALMAN FILTER AS TRACKER =========================*/
/* state vector is (x,y,w,h,dx,dy,dw,dh)*/
/* mesurment is (x,y,w,h) */
/* dinamic matrix A */
const float A8[] = { 1, 0, 0, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 1,
0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 1};
/* measurement matrix H */
const float H8[] = { 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0};
/* matices for zero size velosity */
/* dinamic matrix A */
const float A6[] = { 1, 0, 0, 0, 1, 0,
0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 1};
/* measurement matrix H */
const float H6[] = { 1, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0};
#define STATE_NUM 6
#define A A6
#define H H6
class CvBlobTrackerOneKalman:public CvBlobTrackerOne
{
private:
CvBlob m_Blob;
CvKalman* m_pKalman;
int m_Frame;
public:
CvBlobTrackerOneKalman()
{
m_Frame = 0;
m_pKalman = cvCreateKalman(STATE_NUM,4);
memcpy( m_pKalman->transition_matrix->data.fl, A, sizeof(A));
memcpy( m_pKalman->measurement_matrix->data.fl, H, sizeof(H));
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(1e-5) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(1e-1) );
// CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) *= (float)pow(20,2);
// CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) *= (float)pow(20,2);
cvSetIdentity( m_pKalman->error_cov_post, cvRealScalar(1));
cvZero(m_pKalman->state_post);
cvZero(m_pKalman->state_pre);
}
~CvBlobTrackerOneKalman()
{
cvReleaseKalman(&m_pKalman);
}
virtual void Init(CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
{
m_Blob = pBlob[0];
m_pKalman->state_post->data.fl[0] = CV_BLOB_X(pBlob);
m_pKalman->state_post->data.fl[1] = CV_BLOB_Y(pBlob);
m_pKalman->state_post->data.fl[2] = CV_BLOB_WX(pBlob);
m_pKalman->state_post->data.fl[3] = CV_BLOB_WY(pBlob);
}
virtual CvBlob* Process(CvBlob* pBlob, IplImage* /*pImg*/, IplImage* /*pImgFG*/ = NULL)
{
CvBlob* pBlobRes = &m_Blob;
float Z[4];
CvMat Zmat = cvMat(4,1,CV_32F,Z);
m_Blob = pBlob[0];
if(m_Frame < 2)
{/* first call */
m_pKalman->state_post->data.fl[0+4] = CV_BLOB_X(pBlob)-m_pKalman->state_post->data.fl[0];
m_pKalman->state_post->data.fl[1+4] = CV_BLOB_Y(pBlob)-m_pKalman->state_post->data.fl[1];
if(m_pKalman->DP>6)
{
m_pKalman->state_post->data.fl[2+4] = CV_BLOB_WX(pBlob)-m_pKalman->state_post->data.fl[2];
m_pKalman->state_post->data.fl[3+4] = CV_BLOB_WY(pBlob)-m_pKalman->state_post->data.fl[3];
}
m_pKalman->state_post->data.fl[0] = CV_BLOB_X(pBlob);
m_pKalman->state_post->data.fl[1] = CV_BLOB_Y(pBlob);
m_pKalman->state_post->data.fl[2] = CV_BLOB_WX(pBlob);
m_pKalman->state_post->data.fl[3] = CV_BLOB_WY(pBlob);
memcpy(m_pKalman->state_pre->data.fl,m_pKalman->state_post->data.fl,sizeof(float)*STATE_NUM);
}
else
{/* another call */
Z[0] = CV_BLOB_X(pBlob);
Z[1] = CV_BLOB_Y(pBlob);
Z[2] = CV_BLOB_WX(pBlob);
Z[3] = CV_BLOB_WY(pBlob);
cvKalmanCorrect(m_pKalman,&Zmat);
cvKalmanPredict(m_pKalman,0);
cvMatMulAdd(m_pKalman->measurement_matrix, m_pKalman->state_pre, NULL, &Zmat);
CV_BLOB_X(pBlobRes) = Z[0];
CV_BLOB_Y(pBlobRes) = Z[1];
CV_BLOB_WX(pBlobRes) = Z[2];
CV_BLOB_WY(pBlobRes) = Z[3];
}
m_Frame++;
return pBlobRes;
}
virtual void Release()
{
delete this;
}
}; /* class CvBlobTrackerOneKalman */
static CvBlobTrackerOne* cvCreateModuleBlobTrackerOneKalman()
{
return (CvBlobTrackerOne*) new CvBlobTrackerOneKalman;
}
CvBlobTracker* cvCreateBlobTrackerKalman()
{
return cvCreateBlobTrackerList(cvCreateModuleBlobTrackerOneKalman);
}

View File

@@ -0,0 +1,524 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#define PIX_HIST_BIN_NUM_1 3 //number of bins for classification (not used now)
#define PIX_HIST_BIN_NUM_2 5 //number of bins for statistic collection
#define PIX_HIST_ALPHA 0.01f //alpha-coefficient for running avarage procedure
#define PIX_HIST_DELTA 2 //maximal difference between descriptors(RGB)
#define PIX_HIST_COL_QUANTS 64 //quantization level in rgb-space
#define PIX_HIST_DELTA_IN_PIX_VAL (PIX_HIST_DELTA * 256 / PIX_HIST_COL_QUANTS) //allowed difference in rgb-space
//structures for background statistics estimation
typedef struct CvPixHistBin{
float bin_val;
uchar cols[3];
}CvPixHistBin;
typedef struct CvPixHist{
CvPixHistBin bins[PIX_HIST_BIN_NUM_2];
}CvPixHist;
//class for background statistics estimation
class CvBGEstimPixHist
{
private:
CvPixHist* m_PixHists;
int m_width;
int m_height;
//function for update color histogram for one pixel
void update_hist_elem(int x, int y, uchar* cols )
{
//find closest bin
int dist = 0, min_dist = 2147483647, indx = -1;
for( int k = 0; k < PIX_HIST_BIN_NUM_2; k++ ){
uchar* hist_cols = m_PixHists[y*m_width+x].bins[k].cols;
m_PixHists[y*m_width+x].bins[k].bin_val *= (1-PIX_HIST_ALPHA);
int l;
for( l = 0; l < 3; l++ ){
int val = abs( hist_cols[l] - cols[l] );
if( val > PIX_HIST_DELTA_IN_PIX_VAL ) break;
dist += val;
}
if( l == 3 && dist < min_dist ){
min_dist = dist;
indx = k;
}
}
if( indx < 0 ){//N2th elem in the table is replaced by a new features
indx = PIX_HIST_BIN_NUM_2 - 1;
m_PixHists[y*m_width+x].bins[indx].bin_val = PIX_HIST_ALPHA;
for(int l = 0; l < 3; l++ ){
m_PixHists[y*m_width+x].bins[indx].cols[l] = cols[l];
}
}
else {
//add vote!
m_PixHists[y*m_width+x].bins[indx].bin_val += PIX_HIST_ALPHA;
}
//re-sort bins by BIN_VAL
{
int k;
for(k = 0; k < indx; k++ ){
if( m_PixHists[y*m_width+x].bins[k].bin_val <= m_PixHists[y*m_width+x].bins[indx].bin_val ){
CvPixHistBin tmp1, tmp2 = m_PixHists[y*m_width+x].bins[indx];
//shift elements
for(int l = k; l <= indx; l++ ){
tmp1 = m_PixHists[y*m_width+x].bins[l];
m_PixHists[y*m_width+x].bins[l] = tmp2;
tmp2 = tmp1;
}
break;
}
}
}
}//void update_hist(...)
//function for calculation difference between histograms
float get_hist_diff(int x1, int y1, int x2, int y2)
{
float dist = 0;
for( int i = 0; i < 3; i++ ){
dist += labs(m_PixHists[y1*m_width+x1].bins[0].cols[i] -
m_PixHists[y2*m_width+x2].bins[0].cols[i]);
}
return dist;
}
public:
IplImage* bg_image;
CvBGEstimPixHist(CvSize img_size)
{
m_PixHists = (CvPixHist*)cvAlloc(img_size.width*img_size.height*sizeof(CvPixHist));
memset( m_PixHists, 0, img_size.width*img_size.height*sizeof(CvPixHist) );
m_width = img_size.width;
m_height = img_size.height;
bg_image = cvCreateImage(img_size, IPL_DEPTH_8U, 3 );
}/* constructor */
~CvBGEstimPixHist()
{
cvReleaseImage(&bg_image);
cvFree(&m_PixHists);
}/* destructor */
//function for update histograms and bg_image
void update_hists( IplImage* pImg )
{
for( int i = 0; i < pImg->height; i++ ){
for( int j = 0; j < pImg->width; j++ ){
update_hist_elem( j, i, ((uchar*)(pImg->imageData))+i*pImg->widthStep+3*j );
((uchar*)(bg_image->imageData))[i*bg_image->widthStep+3*j] = m_PixHists[i*m_width+j].bins[0].cols[0];
((uchar*)(bg_image->imageData))[i*bg_image->widthStep+3*j+1] = m_PixHists[i*m_width+j].bins[0].cols[1];
((uchar*)(bg_image->imageData))[i*bg_image->widthStep+3*j+2] = m_PixHists[i*m_width+j].bins[0].cols[2];
}
}
//cvNamedWindow("RoadMap2",0);
//cvShowImage("RoadMap2", bg_image);
}
};/* CvBGEstimPixHist */
/*======================= TRACKER LIST SHELL =====================*/
typedef struct DefBlobTrackerL
{
CvBlob blob;
CvBlobTrackerOne* pTracker;
int Frame;
int Collision;
CvBlobTrackPredictor* pPredictor;
CvBlob BlobPredict;
CvBlobSeq* pBlobHyp;
} DefBlobTrackerL;
class CvBlobTrackerList : public CvBlobTracker
{
private:
CvBlobTrackerOne* (*m_Create)();
CvBlobSeq m_BlobTrackerList;
// int m_LastID;
int m_Collision;
int m_ClearHyp;
float m_BGImageUsing;
CvBGEstimPixHist* m_pBGImage;
IplImage* m_pImgFG;
IplImage* m_pImgReg; /* mask for multiblob confidence calculation */
public:
CvBlobTrackerList(CvBlobTrackerOne* (*create)()):m_BlobTrackerList(sizeof(DefBlobTrackerL))
{
//int i;
CvBlobTrackerOne* pM = create();
// m_LastID = 0;
m_Create = create;
m_ClearHyp = 0;
m_pImgFG = 0;
m_pImgReg = NULL;
TransferParamsFromChild(pM,NULL);
pM->Release();
m_Collision = 1; /* if 1 then collistion will be detected and processed */
AddParam("Collision",&m_Collision);
CommentParam("Collision", "if 1 then collision cases are processed in special way");
m_pBGImage = NULL;
m_BGImageUsing = 50;
AddParam("BGImageUsing", &m_BGImageUsing);
CommentParam("BGImageUsing","Weight of using BG image in update hist model (0 - BG dies not use 1 - use)");
}
~CvBlobTrackerList()
{
int i;
if(m_pBGImage) delete m_pBGImage;
if(m_pImgFG) cvReleaseImage(&m_pImgFG);
if(m_pImgReg) cvReleaseImage(&m_pImgReg);
for(i=m_BlobTrackerList.GetBlobNum();i>0;--i)
{
m_BlobTrackerList.DelBlob(i-1);
}
};
CvBlob* AddBlob(CvBlob* pBlob, IplImage* pImg, IplImage* pImgFG )
{/* create new tracker */
DefBlobTrackerL F;
F.blob = pBlob[0];
// F.blob.ID = m_LastID++;
F.pTracker = m_Create();
F.pPredictor = cvCreateModuleBlobTrackPredictKalman();
F.pBlobHyp = new CvBlobSeq;
F.Frame = 0;
TransferParamsToChild(F.pTracker,NULL);
F.pTracker->Init(pBlob,pImg, pImgFG);
m_BlobTrackerList.AddBlob((CvBlob*)&F);
return m_BlobTrackerList.GetBlob(m_BlobTrackerList.GetBlobNum()-1);
};
void DelBlob(int BlobIndex)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
if(pF == NULL) return;
pF->pTracker->Release();
pF->pPredictor->Release();
delete pF->pBlobHyp;
m_BlobTrackerList.DelBlob(BlobIndex);
}
void DelBlobByID(int BlobID)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlobByID(BlobID);
if(pF == NULL) return;
pF->pTracker->Release();
pF->pPredictor->Release();
delete pF->pBlobHyp;
m_BlobTrackerList.DelBlobByID(BlobID);
}
virtual void Process(IplImage* pImg, IplImage* pImgFG = NULL)
{
int i;
if(pImgFG)
{
if(m_pImgFG) cvCopyImage(pImgFG,m_pImgFG);
else m_pImgFG = cvCloneImage(pImgFG);
}
if(m_pBGImage==NULL && m_BGImageUsing>0)
{
m_pBGImage = new CvBGEstimPixHist(cvSize(pImg->width,pImg->height));
}
if(m_Collision)
for(i=m_BlobTrackerList.GetBlobNum();i>0;--i)
{/* update predictor */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
pF->pPredictor->Update((CvBlob*)pF);
}/* update predictor */
if(m_pBGImage && m_pImgFG)
{/* wheighting mask mask */
int x,y,yN=pImg->height,xN=pImg->width;
IplImage* pImgBG = NULL;
m_pBGImage->update_hists(pImg);
pImgBG = m_pBGImage->bg_image;
for(y=0;y<yN;++y)
{
unsigned char* pI = (unsigned char*)pImg->imageData + y*pImg->widthStep;
unsigned char* pBG = (unsigned char*)pImgBG->imageData + y*pImgBG->widthStep;
unsigned char* pFG = (unsigned char*)m_pImgFG->imageData +y*m_pImgFG->widthStep;
for(x=0;x<xN;++x)
{
if(pFG[x])
{
int D1 = (int)(pI[3*x+0])-(int)(pBG[3*x+0]);
int D2 = (int)(pI[3*x+1])-(int)(pBG[3*x+1]);
int D3 = (int)(pI[3*x+2])-(int)(pBG[3*x+2]);
int DD = D1*D1+D2*D2+D3*D3;
double D = sqrt((float)DD);
double DW = 25;
double W = 1/(exp(-4*(D-m_BGImageUsing)/DW)+1);
pFG[x] = (uchar)cvRound(W*255);
}
}/* next mask pixel */
}/* next mask line */
/*if(m_Wnd)
{
cvNamedWindow("BlobList_FGWeight",0);
cvShowImage("BlobList_FGWeight",m_pImgFG);
}*/
}/* wheighting mask mask */
for(i=m_BlobTrackerList.GetBlobNum();i>0;--i)
{/* predict position */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
CvBlob* pB = pF->pPredictor->Predict();
if(pB)
{
pF->BlobPredict = pB[0];
pF->BlobPredict.w = pF->blob.w;
pF->BlobPredict.h = pF->blob.h;
}
}/* predict position */
if(m_Collision)
for(i=m_BlobTrackerList.GetBlobNum();i>0;--i)
{/* predict collision */
int Collision = 0;
int j;
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
for(j=m_BlobTrackerList.GetBlobNum();j>0;--j)
{/* predict collision */
CvBlob* pB1;
CvBlob* pB2;
DefBlobTrackerL* pF2 = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(j-1);
if(i==j) continue;
pB1 = &pF->BlobPredict;
pB2 = &pF2->BlobPredict;
if( fabs(pB1->x-pB2->x)<0.5*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.5*(pB1->h+pB2->h) ) Collision = 1;
pB1 = &pF->blob;
pB2 = &pF2->blob;
if( fabs(pB1->x-pB2->x)<0.5*(pB1->w+pB2->w) &&
fabs(pB1->y-pB2->y)<0.5*(pB1->h+pB2->h) ) Collision = 1;
if(Collision) break;
}/* check next blob to cross current*/
pF->Collision = Collision;
pF->pTracker->SetCollision(Collision);
}/* predict collision */
for(i=m_BlobTrackerList.GetBlobNum();i>0;--i)
{/* track each blob */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
if(pF->pBlobHyp->GetBlobNum()>0)
{/* track all hypothesis */
int h,hN = pF->pBlobHyp->GetBlobNum();
for(h=0;h<hN;++h)
{
CvBlob* pB = pF->pBlobHyp->GetBlob(h);
CvBlob* pNewBlob = pF->pTracker->Process(pB,pImg,m_pImgFG);
int BlobID = CV_BLOB_ID(pB);
if(pNewBlob)
{
pB[0] = pNewBlob[0];
pB->w = MAX(CV_BLOB_MINW,pNewBlob->w);
pB->h = MAX(CV_BLOB_MINH,pNewBlob->h);
CV_BLOB_ID(pB) = BlobID;
}
}/* next hyp*/
}/* track all hypothesis */
pF->Frame++;
}/* next blob */
#if 0
for(i=m_BlobTrackerList.GetBlobNum();i>0;--i)
{/* update predictor */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
if((m_Collision && !pF->Collision) || !m_Collision)
{
pF->pPredictor->Update((CvBlob*)pF);
}
else
{/* pravilnyp putem idete tovarischy!!! */
pF->pPredictor->Update(&(pF->BlobPredict));
}
}/* update predictor */
#endif
m_ClearHyp = 1;
};
/* Process on blob (for multi hypothesis tracing) */
virtual void ProcessBlob(int BlobIndex, CvBlob* pBlob, IplImage* pImg, IplImage* /*pImgFG*/ = NULL)
{
int ID = pBlob->ID;
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
CvBlob* pNewBlob = pF->pTracker->Process(pBlob?pBlob:&(pF->blob),pImg,m_pImgFG);
if(pNewBlob)
{
pF->blob = pNewBlob[0];
pF->blob.w = MAX(CV_BLOB_MINW,pNewBlob->w);
pF->blob.h = MAX(CV_BLOB_MINH,pNewBlob->h);
pBlob[0] = pF->blob;
}
pBlob->ID = ID;
};
virtual double GetConfidence(int BlobIndex, CvBlob* pBlob, IplImage* pImg, IplImage* pImgFG = NULL)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
if(pF==NULL) return 0;
if(pF->pTracker==NULL) return 0;
return pF->pTracker->GetConfidence(pBlob?pBlob:(&pF->blob), pImg, pImgFG, NULL);
};
virtual double GetConfidenceList(CvBlobSeq* pBlobList, IplImage* pImg, IplImage* pImgFG = NULL)
{
double W = 1;
int b,bN = pBlobList->GetBlobNum();
if(m_pImgReg == NULL)
{
m_pImgReg = cvCreateImage(cvSize(pImg->width,pImg->height),IPL_DEPTH_8U,1);
}
assert(pImg);
cvSet(m_pImgReg,cvScalar(255));
for(b=0;b<bN;++b)
{
CvBlob* pB = pBlobList->GetBlob(b);
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlobByID(pB->ID);
if(pF==NULL || pF->pTracker==NULL) continue;
W *= pF->pTracker->GetConfidence(pB, pImg, pImgFG, m_pImgReg );
cvEllipse(
m_pImgReg,
cvPoint(cvRound(pB->x*256),cvRound(pB->y*256)), cvSize(cvRound(pB->w*128),cvRound(pB->h*128)),
0, 0, 360,
cvScalar(0), CV_FILLED, 8, 8 );
// cvNamedWindow("REG",0);
// cvShowImage("REG",m_pImgReg);
// cvWaitKey(0);
}
return W;
};
virtual void UpdateBlob(int BlobIndex, CvBlob* pBlob, IplImage* pImg, IplImage* /*pImgFG*/ = NULL)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
if(pF)
{
pF->pTracker->Update(pBlob?pBlob:&(pF->blob),pImg,m_pImgFG);
}
};
int GetBlobNum(){return m_BlobTrackerList.GetBlobNum();};
CvBlob* GetBlob(int index){return m_BlobTrackerList.GetBlob(index);};
void SetBlob(int BlobIndex, CvBlob* pBlob)
{
CvBlob* pB = m_BlobTrackerList.GetBlob(BlobIndex);
if(pB)
{
pB[0] = pBlob[0];
pB->w = MAX(CV_BLOB_MINW, pBlob->w);
pB->h = MAX(CV_BLOB_MINH, pBlob->h);
}
}
void Release(){delete this;};
/* additional functionality */
CvBlob* GetBlobByID(int BlobID){return m_BlobTrackerList.GetBlobByID(BlobID);}
/* =============== MULTI HYPOTHESIS INTERFACE ================== */
/* return number of position hyposetis of currently tracked blob */
virtual int GetBlobHypNum(int BlobIdx)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIdx);
assert(pF->pBlobHyp);
return pF->pBlobHyp->GetBlobNum();
};/* CvBlobtrackerList::GetBlobHypNum() */
/* return pointer to specified blob hypothesis by index blob */
virtual CvBlob* GetBlobHyp(int BlobIndex, int hypothesis)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
assert(pF->pBlobHyp);
return pF->pBlobHyp->GetBlob(hypothesis);
};/* CvBlobtrackerList::GetBlobHyp() */
/* Set new parameters for specified (by index) blob hyp (can be called several times for each hyp )*/
virtual void SetBlobHyp(int BlobIndex, CvBlob* pBlob)
{
if(m_ClearHyp)
{/* clear all hypothesis */
int b, bN = m_BlobTrackerList.GetBlobNum();
for(b=0;b<bN;++b)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(b);
assert(pF->pBlobHyp);
pF->pBlobHyp->Clear();
}
m_ClearHyp = 0;
}
{/* add hypothesis */
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(BlobIndex);
assert(pF->pBlobHyp);
pF->pBlobHyp->AddBlob(pBlob);
}
}; /*CvBlobtrackerList::SetBlobHyp*/
private:
public:
void ParamUpdate()
{
int i;
for(i=m_BlobTrackerList.GetBlobNum();i>0;--i)
{
DefBlobTrackerL* pF = (DefBlobTrackerL*)m_BlobTrackerList.GetBlob(i-1);
TransferParamsToChild(pF->pTracker);
pF->pTracker->ParamUpdate();
}
}
}; /* CvBlobTrackerList */
CvBlobTracker* cvCreateBlobTrackerList(CvBlobTrackerOne* (*create)())
{
return (CvBlobTracker*) new CvBlobTrackerList(create);
}

View File

@@ -0,0 +1,420 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
#define SCALE_BASE 1.1
#define SCALE_RANGE 2
#define SCALE_NUM (2*SCALE_RANGE+1)
typedef float DefHistType;
#define DefHistTypeMat CV_32F
#define HIST_INDEX(_pData) (((_pData)[0]>>m_ByteShift) + (((_pData)[1]>>(m_ByteShift))<<m_BinBit)+((pImgData[2]>>m_ByteShift)<<(m_BinBit*2)))
void calcKernelEpanechnikov(CvMat* pK)
{/* allocate kernel for histogramm creation */
int x,y;
int w = pK->width;
int h = pK->height;
float x0 = 0.5f*(w-1);
float y0 = 0.5f*(h-1);
for(y=0;y<h;++y)for(x=0;x<w;++x)
{
// float r2 = ((x-x0)*(x-x0)/(x0*x0)+(y-y0)*(y-y0)/(y0*y0));
float r2 = ((x-x0)*(x-x0)+(y-y0)*(y-y0))/((x0*x0)+(y0*y0));
CV_MAT_ELEM(pK[0],DefHistType, y, x) = (DefHistType)((r2<1)?(1-r2):0);
}
}/* allocate kernel for histogramm creation */
class CvBlobTrackerOneMSFGS:public CvBlobTrackerOne
{
private:
/* parameters */
float m_FGWeight;
float m_Alpha;
CvSize m_ObjSize;
CvMat* m_KernelHistModel;
CvMat* m_KernelHistCandidate;
CvSize m_KernelMeanShiftSize;
CvMat* m_KernelMeanShiftK[SCALE_NUM];
CvMat* m_KernelMeanShiftG[SCALE_NUM];
CvMat* m_Weights;
int m_BinBit;
int m_ByteShift;
int m_BinNum;
int m_Dim;
int m_BinNumTotal;
CvMat* m_HistModel;
float m_HistModelVolume;
CvMat* m_HistCandidate;
float m_HistCandidateVolume;
CvMat* m_HistTemp;
CvBlob m_Blob;
void ReAllocHist(int Dim, int BinBit)
{
m_BinBit = BinBit;
m_ByteShift = 8-BinBit;
m_Dim = Dim;
m_BinNum = (1<<BinBit);
m_BinNumTotal = cvRound(pow((double)m_BinNum,(double)m_Dim));
if(m_HistModel) cvReleaseMat(&m_HistModel);
if(m_HistCandidate) cvReleaseMat(&m_HistCandidate);
if(m_HistTemp) cvReleaseMat(&m_HistTemp);
m_HistCandidate = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
m_HistModel = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
m_HistTemp = cvCreateMat(1, m_BinNumTotal, DefHistTypeMat);
cvZero(m_HistCandidate);
cvZero(m_HistModel);
m_HistModelVolume = 0.0f;
m_HistCandidateVolume = 0.0f;
}
void ReAllocKernel(int w, int h, float sigma=0.4)
{
double ScaleToObj = sigma*1.39;
int kernel_width = cvRound(w/ScaleToObj);
int kernel_height = cvRound(h/ScaleToObj);
int x,y,s;
assert(w>0);
assert(h>0);
m_ObjSize = cvSize(w,h);
m_KernelMeanShiftSize = cvSize(kernel_width,kernel_height);
/* create kernels for histogramm calculation */
if(m_KernelHistModel) cvReleaseMat(&m_KernelHistModel);
m_KernelHistModel = cvCreateMat(h, w, DefHistTypeMat);
calcKernelEpanechnikov(m_KernelHistModel);
if(m_KernelHistCandidate) cvReleaseMat(&m_KernelHistCandidate);
m_KernelHistCandidate = cvCreateMat(kernel_height, kernel_width, DefHistTypeMat);
calcKernelEpanechnikov(m_KernelHistCandidate);
if(m_Weights) cvReleaseMat(&m_Weights);
m_Weights = cvCreateMat(kernel_height, kernel_width, CV_32F);
for(s=-SCALE_RANGE;s<=SCALE_RANGE;++s)
{/* allocate kernwl for meanshifts in space and scale */
int si = s+SCALE_RANGE;
double cur_sigma = sigma * pow(SCALE_BASE,s);
double cur_sigma2 = cur_sigma*cur_sigma;
double x0 = 0.5*(kernel_width-1);
double y0 = 0.5*(kernel_height-1);
if(m_KernelMeanShiftK[si]) cvReleaseMat(&m_KernelMeanShiftK[si]);
if(m_KernelMeanShiftG[si]) cvReleaseMat(&m_KernelMeanShiftG[si]);
m_KernelMeanShiftK[si] = cvCreateMat(kernel_height, kernel_width, DefHistTypeMat);
m_KernelMeanShiftG[si] = cvCreateMat(kernel_height, kernel_width, DefHistTypeMat);
for(y=0;y<kernel_height;++y)
{
DefHistType* pK = (DefHistType*)CV_MAT_ELEM_PTR_FAST( m_KernelMeanShiftK[si][0], y, 0, sizeof(DefHistType) );
DefHistType* pG = (DefHistType*)CV_MAT_ELEM_PTR_FAST( m_KernelMeanShiftG[si][0], y, 0, sizeof(DefHistType) );
for(x=0;x<kernel_width;++x)
{
double r2 = ((x-x0)*(x-x0)/(x0*x0)+(y-y0)*(y-y0)/(y0*y0));
double sigma12 = cur_sigma2 / 2.56;
double sigma22 = cur_sigma2 * 2.56;
pK[x] = (DefHistType)(Gaussian2D(r2, sigma12)/sigma12 - Gaussian2D(r2, sigma22)/sigma22);
pG[x] = (DefHistType)(Gaussian2D(r2, cur_sigma2/1.6) - Gaussian2D(r2, cur_sigma2*1.6));
}
}/* next line */
}
}/* ReallocKernel*/
inline double Gaussian2D(double x, double sigma2)
{
return (exp(-x/(2*sigma2)) / (2*3.1415926535897932384626433832795*sigma2) );
}
void calcHist(IplImage* pImg, IplImage* pMask, CvPoint Center, CvMat* pKernel, CvMat* pHist, DefHistType* pHistVolume)
{
int w = pKernel->width;
int h = pKernel->height;
DefHistType Volume = 0;
int x0 = Center.x - w/2;
int y0 = Center.y - h/2;
int x,y;
//cvZero(pHist);
cvSet(pHist,cvScalar(1.0/m_BinNumTotal)); /* no zero bins, all bins have very small value*/
Volume = 1;
if(m_Dim == 3)
{
for(y=0;y<h;++y)
{
unsigned char* pImgData = NULL;
unsigned char* pMaskData = NULL;
DefHistType* pKernelData = NULL;
if((y0+y)>=pImg->height) continue;
if((y0+y)<0)continue;
pImgData = &CV_IMAGE_ELEM(pImg,unsigned char,y+y0,x0*3);
pMaskData = pMask?(&CV_IMAGE_ELEM(pMask,unsigned char,y+y0,x0)):NULL;
pKernelData = (DefHistType*)CV_MAT_ELEM_PTR_FAST(pKernel[0],y,0,sizeof(DefHistType));
for(x=0;x<w;++x,pImgData+=3)
{
if((x0+x)>=pImg->width) continue;
if((x0+x)<0)continue;
if(pMaskData==NULL || pMaskData[x]>128)
{
DefHistType K = pKernelData[x];
int index = HIST_INDEX(pImgData);
assert(index >= 0 && index < pHist->cols);
Volume += K;
((DefHistType*)(pHist->data.ptr))[index] += K;
}/* only masked pixels */
}/* next column */
}/* next row */
}/* if m_Dim == 3 */
if(pHistVolume)pHistVolume[0] = Volume;
};/*calcHist*/
double calcBhattacharyya()
{
cvMul(m_HistCandidate,m_HistModel,m_HistTemp);
cvPow(m_HistTemp,m_HistTemp,0.5);
return cvSum(m_HistTemp).val[0] / sqrt(m_HistCandidateVolume*m_HistModelVolume);
} /* calcBhattacharyyaCoefficient */
void calcWeights(IplImage* pImg, IplImage* pImgFG, CvPoint Center)
{
cvZero(m_Weights);
/* calc new pos */
if(m_Dim == 3)
{
int x0 = Center.x - m_KernelMeanShiftSize.width/2;
int y0 = Center.y - m_KernelMeanShiftSize.height/2;
int x,y;
assert(m_Weights->width == m_KernelMeanShiftSize.width);
assert(m_Weights->height == m_KernelMeanShiftSize.height);
/*calc shift vector */
for(y=0;y<m_KernelMeanShiftSize.height;++y)
{
unsigned char* pImgData = NULL;
unsigned char* pMaskData = NULL;
float* pWData = NULL;
if(y+y0 < 0 || y+y0 >= pImg->height) continue;
pImgData = &CV_IMAGE_ELEM(pImg,unsigned char,y+y0,x0*3);
pMaskData = pImgFG?(&CV_IMAGE_ELEM(pImgFG,unsigned char,y+y0,x0)):NULL;
pWData = (float*)CV_MAT_ELEM_PTR_FAST(m_Weights[0],y,0,sizeof(float));
for(x=0;x<m_KernelMeanShiftSize.width;++x,pImgData+=3)
{
double V = 0;
double HM = 0;
double HC = 0;
int index;
if(x+x0 < 0 || x+x0 >= pImg->width) continue;
index = HIST_INDEX(pImgData);
assert(index >= 0 && index < m_BinNumTotal);
if(m_HistModelVolume>0)
HM = ((DefHistType*)m_HistModel->data.ptr)[index]/m_HistModelVolume;
if(m_HistCandidateVolume>0)
HC = ((DefHistType*)m_HistCandidate->data.ptr)[index]/m_HistCandidateVolume;
V = (HC>0)?sqrt(HM / HC):0;
V += m_FGWeight*(pMaskData?((pMaskData[x]/255.0f)):0);
pWData[x] = (float)MIN(V,100000);
}/* next column */
}/* next row */
}/* if m_Dim == 3 */
}/* calcWeights */
public:
CvBlobTrackerOneMSFGS()
{
int i;
m_FGWeight = 0;
m_Alpha = 0.0;
/* add several parameters for external use */
AddParam("FGWeight", &m_FGWeight);
CommentParam("FGWeight","Weight of FG mask using (0 - mask will not be used for tracking)");
AddParam("Alpha", &m_Alpha);
CommentParam("Alpha","Coefficient for model histogramm updating (0 - hist is not upated)");
m_BinBit=0;
m_Dim = 0;
m_HistModel = NULL;
m_HistCandidate = NULL;
m_HistTemp = NULL;
m_KernelHistModel = NULL;
m_KernelHistCandidate = NULL;
m_Weights = NULL;
for(i=0;i<SCALE_NUM;++i)
{
m_KernelMeanShiftK[i] = NULL;
m_KernelMeanShiftG[i] = NULL;
}
ReAllocHist(3,5); /* 3D hist, each dim has 2^5 bins*/
}
~CvBlobTrackerOneMSFGS()
{
int i;
if(m_HistModel) cvReleaseMat(&m_HistModel);
if(m_HistCandidate) cvReleaseMat(&m_HistCandidate);
if(m_HistTemp) cvReleaseMat(&m_HistTemp);
if(m_KernelHistModel) cvReleaseMat(&m_KernelHistModel);
for(i=0;i<SCALE_NUM;++i)
{
if(m_KernelMeanShiftK[i]) cvReleaseMat(&m_KernelMeanShiftK[i]);
if(m_KernelMeanShiftG[i]) cvReleaseMat(&m_KernelMeanShiftG[i]);
}
}
/* interface */
virtual void Init(CvBlob* pBlobInit, IplImage* pImg, IplImage* pImgFG = NULL)
{
int w = cvRound(CV_BLOB_WX(pBlobInit));
int h = cvRound(CV_BLOB_WY(pBlobInit));
if(w<3)w=3;
if(h<3)h=3;
if(w>pImg->width)w=pImg->width;
if(h>pImg->height)h=pImg->height;
ReAllocKernel(w,h);
calcHist(pImg, pImgFG, cvPointFrom32f(CV_BLOB_CENTER(pBlobInit)), m_KernelHistModel, m_HistModel, &m_HistModelVolume);
m_Blob = pBlobInit[0];
};
virtual CvBlob* Process(CvBlob* pBlobPrev, IplImage* pImg, IplImage* pImgFG = NULL)
{
int iter;
if(pBlobPrev)
{
m_Blob = pBlobPrev[0];
}
for(iter=0;iter<10;++iter)
{
// float newx=0,newy=0,sum=0;
float dx=0,dy=0,sum=0;
int x,y,si;
CvPoint Center = cvPoint(cvRound(m_Blob.x),cvRound(m_Blob.y));
CvSize Size = cvSize(cvRound(m_Blob.w),cvRound(m_Blob.h));
if(m_ObjSize.width != Size.width || m_ObjSize.height != Size.height)
{ /* realloc kernels */
ReAllocKernel(Size.width,Size.height);
} /* realloc kernels */
/* mean shift in coordinate space */
calcHist(pImg, NULL, Center, m_KernelHistCandidate, m_HistCandidate, &m_HistCandidateVolume);
calcWeights(pImg, pImgFG, Center);
for(si=1;si<(SCALE_NUM-1);++si)
{
CvMat* pKernel = m_KernelMeanShiftK[si];
float sdx = 0, sdy=0, ssum=0;
int s = si-SCALE_RANGE;
float factor = (1.0f-( float(s)/float(SCALE_RANGE) )*( float(s)/float(SCALE_RANGE) ));
for(y=0;y<m_KernelMeanShiftSize.height;++y)
for(x=0;x<m_KernelMeanShiftSize.width;++x)
{
float W = *(float*)CV_MAT_ELEM_PTR_FAST(m_Weights[0],y,x,sizeof(float));
float K = *(float*)CV_MAT_ELEM_PTR_FAST(pKernel[0],y,x,sizeof(float));
float KW = K*W;
ssum += (float)fabs(KW);
sdx += KW*(x-m_KernelMeanShiftSize.width*0.5f);
sdy += KW*(y-m_KernelMeanShiftSize.height*0.5f);
}/* next pixel */
dx += sdx * factor;
dy += sdy * factor;
sum += ssum * factor;
}/* next scale */
if(sum > 0)
{
dx /= sum;
dy /= sum;
}
m_Blob.x += dx;
m_Blob.y += dy;
{ /* mean shift in scale space */
float news = 0;
float sum = 0;
float scale;
Center = cvPoint(cvRound(m_Blob.x),cvRound(m_Blob.y));
calcHist(pImg, NULL, Center, m_KernelHistCandidate, m_HistCandidate, &m_HistCandidateVolume);
calcWeights(pImg, pImgFG, Center);
//cvSet(m_Weights,cvScalar(1));
for(si=0; si<SCALE_NUM; si++)
{
double W = cvDotProduct(m_Weights, m_KernelMeanShiftG[si]);;
int s = si-SCALE_RANGE;
sum += (float)fabs(W);
news += (float)(s*W);
}
if(sum>0)
{
news /= sum;
}
scale = (float)pow((double)SCALE_BASE,(double)news);
m_Blob.w *= scale;
m_Blob.h *= scale;
} /* mean shift in scale space */
/* check fo finish */
if(fabs(dx)<0.1 && fabs(dy)<0.1) break;
}/* next iteration */
if(m_Alpha>0)
{/* update hist */
double Vol, WM, WC;
CvPoint Center = cvPoint(cvRound(m_Blob.x),cvRound(m_Blob.y));
calcHist(pImg, pImgFG, Center, m_KernelHistModel, m_HistCandidate, &m_HistCandidateVolume);
Vol = 0.5*(m_HistModelVolume + m_HistCandidateVolume);
WM = Vol*(1-m_Alpha)/m_HistModelVolume;
WC = Vol*(m_Alpha)/m_HistCandidateVolume;
cvAddWeighted(m_HistModel, WM, m_HistCandidate,WC,0,m_HistModel);
m_HistModelVolume = (float)cvSum(m_HistModel).val[0];
}/* update hist */
return &m_Blob;
}; /* Process */
virtual void Release(){delete this;};
}; /*CvBlobTrackerOneMSFGS*/
CvBlobTrackerOne* cvCreateBlobTrackerOneMSFGS()
{
return (CvBlobTrackerOne*) new CvBlobTrackerOneMSFGS;
}
CvBlobTracker* cvCreateBlobTrackerMSFGS()
{
return cvCreateBlobTrackerList(cvCreateBlobTrackerOneMSFGS);
}

View File

@@ -0,0 +1,303 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/*======================= KALMAN FILTER =========================*/
/* state vector is (x,y,w,h,dx,dy,dw,dh)*/
/* mesurment is (x,y,w,h) */
/* dinamic matrix A */
const float A8[] = { 1, 0, 0, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 1,
0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 1};
/* measurement matrix H */
const float H8[] = { 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0, 0};
/* matices for zero size velosity */
/* dinamic matrix A */
const float A6[] = { 1, 0, 0, 0, 1, 0,
0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 1};
/* measurement matrix H */
const float H6[] = { 1, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0};
#define STATE_NUM 6
#define A A6
#define H H6
class CvBlobTrackPostProcKalman:public CvBlobTrackPostProcOne
{
private:
CvBlob m_Blob;
CvKalman* m_pKalman;
int m_Frame;
float m_ModelNoise;
float m_DataNoisePos;
float m_DataNoiseSize;
public:
CvBlobTrackPostProcKalman();
~CvBlobTrackPostProcKalman();
CvBlob* Process(CvBlob* pBlob);
void Release();
virtual void ParamUpdate();
}; /* class CvBlobTrackPostProcKalman */
CvBlobTrackPostProcKalman::CvBlobTrackPostProcKalman()
{
m_ModelNoise = 1e-6f;
m_DataNoisePos = 1e-6f;
m_DataNoiseSize = 1e-1f;
#if STATE_NUM>6
m_DataNoiseSize *= (float)pow(20.,2.);
#else
m_DataNoiseSize /= (float)pow(20.,2.);
#endif
AddParam("ModelNoise",&m_ModelNoise);
AddParam("DataNoisePos",&m_DataNoisePos);
AddParam("DataNoiseSize",&m_DataNoiseSize);
m_Frame = 0;
m_pKalman = cvCreateKalman(STATE_NUM,4);
memcpy( m_pKalman->transition_matrix->data.fl, A, sizeof(A));
memcpy( m_pKalman->measurement_matrix->data.fl, H, sizeof(H));
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(m_ModelNoise) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(m_DataNoisePos) );
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) = m_DataNoiseSize;
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) = m_DataNoiseSize;
cvSetIdentity( m_pKalman->error_cov_post, cvRealScalar(1));
cvZero(m_pKalman->state_post);
cvZero(m_pKalman->state_pre);
}
CvBlobTrackPostProcKalman::~CvBlobTrackPostProcKalman()
{
cvReleaseKalman(&m_pKalman);
}
void CvBlobTrackPostProcKalman::ParamUpdate()
{
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(m_ModelNoise) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(m_DataNoisePos) );
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) = m_DataNoiseSize;
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) = m_DataNoiseSize;
}
CvBlob* CvBlobTrackPostProcKalman::Process(CvBlob* pBlob)
{
CvBlob* pBlobRes = &m_Blob;
float Z[4];
CvMat Zmat = cvMat(4,1,CV_32F,Z);
m_Blob = pBlob[0];
if(m_Frame < 2)
{/* first call */
m_pKalman->state_post->data.fl[0+4] = CV_BLOB_X(pBlob)-m_pKalman->state_post->data.fl[0];
m_pKalman->state_post->data.fl[1+4] = CV_BLOB_Y(pBlob)-m_pKalman->state_post->data.fl[1];
if(m_pKalman->DP>6)
{
m_pKalman->state_post->data.fl[2+4] = CV_BLOB_WX(pBlob)-m_pKalman->state_post->data.fl[2];
m_pKalman->state_post->data.fl[3+4] = CV_BLOB_WY(pBlob)-m_pKalman->state_post->data.fl[3];
}
m_pKalman->state_post->data.fl[0] = CV_BLOB_X(pBlob);
m_pKalman->state_post->data.fl[1] = CV_BLOB_Y(pBlob);
m_pKalman->state_post->data.fl[2] = CV_BLOB_WX(pBlob);
m_pKalman->state_post->data.fl[3] = CV_BLOB_WY(pBlob);
}
else
{/* another call */
cvKalmanPredict(m_pKalman,0);
Z[0] = CV_BLOB_X(pBlob);
Z[1] = CV_BLOB_Y(pBlob);
Z[2] = CV_BLOB_WX(pBlob);
Z[3] = CV_BLOB_WY(pBlob);
cvKalmanCorrect(m_pKalman,&Zmat);
cvMatMulAdd(m_pKalman->measurement_matrix, m_pKalman->state_post, NULL, &Zmat);
CV_BLOB_X(pBlobRes) = Z[0];
CV_BLOB_Y(pBlobRes) = Z[1];
// CV_BLOB_WX(pBlobRes) = Z[2];
// CV_BLOB_WY(pBlobRes) = Z[3];
}
m_Frame++;
return pBlobRes;
}
void CvBlobTrackPostProcKalman::Release()
{
delete this;
}
CvBlobTrackPostProcOne* cvCreateModuleBlobTrackPostProcKalmanOne()
{
return (CvBlobTrackPostProcOne*) new CvBlobTrackPostProcKalman;
}
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcKalman()
{
return cvCreateBlobTrackPostProcList(cvCreateModuleBlobTrackPostProcKalmanOne);
}
/*======================= KALMAN FILTER =========================*/
/*======================= KALMAN PREDICTOR =========================*/
class CvBlobTrackPredictKalman:public CvBlobTrackPredictor
{
private:
CvBlob m_BlobPredict;
CvKalman* m_pKalman;
int m_Frame;
float m_ModelNoise;
float m_DataNoisePos;
float m_DataNoiseSize;
public:
CvBlobTrackPredictKalman();
~CvBlobTrackPredictKalman();
CvBlob* Predict();
void Update(CvBlob* pBlob);
virtual void ParamUpdate();
void Release()
{
delete this;
}
}; /* class CvBlobTrackPredictKalman */
void CvBlobTrackPredictKalman::ParamUpdate()
{
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(m_ModelNoise) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(m_DataNoisePos) );
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) = m_DataNoiseSize;
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) = m_DataNoiseSize;
}
CvBlobTrackPredictKalman::CvBlobTrackPredictKalman()
{
m_ModelNoise = 1e-6f;
m_DataNoisePos = 1e-6f;
m_DataNoiseSize = 1e-1f;
#if STATE_NUM>6
m_DataNoiseSize *= (float)pow(20.,2.);
#else
m_DataNoiseSize /= (float)pow(20.,2.);
#endif
AddParam("ModelNoise",&m_ModelNoise);
AddParam("DataNoisePos",&m_DataNoisePos);
AddParam("DataNoiseSize",&m_DataNoiseSize);
m_Frame = 0;
m_pKalman = cvCreateKalman(STATE_NUM,4);
memcpy( m_pKalman->transition_matrix->data.fl, A, sizeof(A));
memcpy( m_pKalman->measurement_matrix->data.fl, H, sizeof(H));
cvSetIdentity( m_pKalman->process_noise_cov, cvRealScalar(m_ModelNoise) );
cvSetIdentity( m_pKalman->measurement_noise_cov, cvRealScalar(m_DataNoisePos) );
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 2,2) = m_DataNoiseSize;
CV_MAT_ELEM(*m_pKalman->measurement_noise_cov, float, 3,3) = m_DataNoiseSize;
cvSetIdentity( m_pKalman->error_cov_post, cvRealScalar(1));
cvZero(m_pKalman->state_post);
cvZero(m_pKalman->state_pre);
}
CvBlobTrackPredictKalman::~CvBlobTrackPredictKalman()
{
cvReleaseKalman(&m_pKalman);
}
CvBlob* CvBlobTrackPredictKalman::Predict()
{
if(m_Frame >= 2)
{
cvKalmanPredict(m_pKalman,0);
m_BlobPredict.x = m_pKalman->state_pre->data.fl[0];
m_BlobPredict.y = m_pKalman->state_pre->data.fl[1];
m_BlobPredict.w = m_pKalman->state_pre->data.fl[2];
m_BlobPredict.h = m_pKalman->state_pre->data.fl[3];
}
return &m_BlobPredict;
}
void CvBlobTrackPredictKalman::Update(CvBlob* pBlob)
{
float Z[4];
CvMat Zmat = cvMat(4,1,CV_32F,Z);
m_BlobPredict = pBlob[0];
if(m_Frame < 2)
{/* first call */
m_pKalman->state_post->data.fl[0+4] = CV_BLOB_X(pBlob)-m_pKalman->state_post->data.fl[0];
m_pKalman->state_post->data.fl[1+4] = CV_BLOB_Y(pBlob)-m_pKalman->state_post->data.fl[1];
if(m_pKalman->DP>6)
{
m_pKalman->state_post->data.fl[2+4] = CV_BLOB_WX(pBlob)-m_pKalman->state_post->data.fl[2];
m_pKalman->state_post->data.fl[3+4] = CV_BLOB_WY(pBlob)-m_pKalman->state_post->data.fl[3];
}
m_pKalman->state_post->data.fl[0] = CV_BLOB_X(pBlob);
m_pKalman->state_post->data.fl[1] = CV_BLOB_Y(pBlob);
m_pKalman->state_post->data.fl[2] = CV_BLOB_WX(pBlob);
m_pKalman->state_post->data.fl[3] = CV_BLOB_WY(pBlob);
}
else
{/* another call */
Z[0] = CV_BLOB_X(pBlob);
Z[1] = CV_BLOB_Y(pBlob);
Z[2] = CV_BLOB_WX(pBlob);
Z[3] = CV_BLOB_WY(pBlob);
cvKalmanCorrect(m_pKalman,&Zmat);
}
cvKalmanPredict(m_pKalman,0);
m_Frame++;
}/* update */
CvBlobTrackPredictor* cvCreateModuleBlobTrackPredictKalman()
{
return (CvBlobTrackPredictor*) new CvBlobTrackPredictKalman;
}
/*======================= KALMAN PREDICTOR =========================*/

View File

@@ -0,0 +1,119 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/*======================= TIME AVERAGING FILTER =========================*/
#define TIME_WND 5
class CvBlobTrackPostProcTimeAver:public CvBlobTrackPostProcOne
{
protected:
CvBlob m_Blob;
CvBlob m_pBlobs[TIME_WND];
float m_Weights[TIME_WND];
int m_Frame;
public:
CvBlobTrackPostProcTimeAver( int KernelType = 0)
{
int i;
m_Frame = 0;
for(i=0;i<TIME_WND;++i)
{
m_Weights[i] = 1;
if(KernelType == 1)
{
m_Weights[i] = (float)exp((-2.3*i)/(TIME_WND-1)); /* last weight is 0.1 of first weight */
}
}
};
~CvBlobTrackPostProcTimeAver(){};
CvBlob* Process(CvBlob* pBlob)
{
float WSum = 0;
int i;
int index = m_Frame % TIME_WND;
int size = MIN((m_Frame+1), TIME_WND);
m_pBlobs[index] = pBlob[0];
m_Blob.x = m_Blob.y = m_Blob.w = m_Blob.h = 0;
for(i=0;i<size;++i)
{
float W = m_Weights[i];
int index = (m_Frame - i + TIME_WND) % TIME_WND;
m_Blob.x += W*m_pBlobs[index].x;
m_Blob.y += W*m_pBlobs[index].y;
m_Blob.w += W*m_pBlobs[index].w;
m_Blob.h += W*m_pBlobs[index].h;
WSum += W;
}
assert(WSum>0);
m_Blob.x /= WSum;
m_Blob.y /= WSum;
m_Blob.w /= WSum;
m_Blob.h /= WSum;
m_Frame++;
return &m_Blob;
};
void Release()
{
delete this;
}
}; /* class CvBlobTrackPostProcTimeAver */
CvBlobTrackPostProcOne* cvCreateModuleBlobTrackPostProcTimeAverRectOne()
{
return (CvBlobTrackPostProcOne*) new CvBlobTrackPostProcTimeAver(0);
}
CvBlobTrackPostProcOne* cvCreateModuleBlobTrackPostProcTimeAverExpOne()
{
return (CvBlobTrackPostProcOne*) new CvBlobTrackPostProcTimeAver(1);
}
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcTimeAverRect()
{
return cvCreateBlobTrackPostProcList(cvCreateModuleBlobTrackPostProcTimeAverRectOne);
}
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcTimeAverExp()
{
return cvCreateBlobTrackPostProcList(cvCreateModuleBlobTrackPostProcTimeAverExpOne);
}
/*======================= KALMAN FILTER =========================*/

View File

@@ -0,0 +1,125 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cvaux.h"
/*======================= FILTER LIST SHELL =====================*/
typedef struct DefBlobFilter
{
CvBlob blob;
CvBlobTrackPostProcOne* pFilter;
int m_LastFrame;
} DefBlobFilter;
class CvBlobTrackPostProcList : public CvBlobTrackPostProc
{
protected:
CvBlobTrackPostProcOne* (*m_CreatePostProc)();
CvBlobSeq m_BlobFilterList;
int m_Frame;
public:
CvBlobTrackPostProcList(CvBlobTrackPostProcOne* (*create)()):m_BlobFilterList(sizeof(DefBlobFilter))
{
m_Frame = 0;
m_CreatePostProc = create;
CvBlobTrackPostProcOne* pM = create();
TransferParamsFromChild(pM,NULL);
pM->Release();
}
~CvBlobTrackPostProcList()
{
int i;
for(i=m_BlobFilterList.GetBlobNum();i>0;--i)
{
DefBlobFilter* pF = (DefBlobFilter*)m_BlobFilterList.GetBlob(i-1);
pF->pFilter->Release();
}
};
virtual void AddBlob(CvBlob* pBlob)
{
DefBlobFilter* pF = (DefBlobFilter*)m_BlobFilterList.GetBlobByID(CV_BLOB_ID(pBlob));
if(pF == NULL)
{ /* create new filter */
DefBlobFilter F;
F.blob = pBlob[0];
F.m_LastFrame = m_Frame;
F.pFilter = m_CreatePostProc();
TransferParamsToChild(F.pFilter,NULL);
m_BlobFilterList.AddBlob((CvBlob*)&F);
pF = (DefBlobFilter*)m_BlobFilterList.GetBlobByID(CV_BLOB_ID(pBlob));
}
assert(pF);
pF->blob = pBlob[0];
pF->m_LastFrame = m_Frame;
};
virtual void Process()
{
int i;
for(i=m_BlobFilterList.GetBlobNum();i>0;--i)
{
DefBlobFilter* pF = (DefBlobFilter*)m_BlobFilterList.GetBlob(i-1);
if(pF->m_LastFrame == m_Frame)
{/* process */
int ID = CV_BLOB_ID(pF);
pF->blob = *(pF->pFilter->Process(&(pF->blob)));
CV_BLOB_ID(pF) = ID;
}
else
{/* delete blob filter */
pF->pFilter->Release();
m_BlobFilterList.DelBlob(i-1);
}
}/* next blob */
m_Frame++;
};
int GetBlobNum(){return m_BlobFilterList.GetBlobNum();};
CvBlob* GetBlob(int index){return m_BlobFilterList.GetBlob(index);};
void Release(){delete this;};
/* additional functionality */
CvBlob* GetBlobByID(int BlobID){return m_BlobFilterList.GetBlobByID(BlobID);}
}; /* CvBlobTrackPostProcList */
CvBlobTrackPostProc* cvCreateBlobTrackPostProcList(CvBlobTrackPostProcOne* (*create)())
{
return (CvBlobTrackPostProc*) new CvBlobTrackPostProcList(create);
}
/*======================= FILTER LIST SHELL =====================*/

View File

@@ -0,0 +1,991 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/*
This file contain implementation of virtual interface of CvBlobDetector
this implementation based on simple algorithm
new blob is detected when several successive frames contains connected componets
which have uniform motion with not high speed.
Also separation from border and already tracked blobs are considered.
*/
//#define USE_OBJECT_DETECTOR
#include "_cvaux.h"
static int CompareContour(const void* a, const void* b, void* )
{
float dx,dy;
float h,w,ht,wt;
CvPoint2D32f pa,pb;
CvRect ra,rb;
CvSeq* pCA = *(CvSeq**)a;
CvSeq* pCB = *(CvSeq**)b;
ra = ((CvContour*)pCA)->rect;
rb = ((CvContour*)pCB)->rect;
pa.x = ra.x + ra.width*0.5f;
pa.y = ra.y + ra.height*0.5f;
pb.x = rb.x + rb.width*0.5f;
pb.y = rb.y + rb.height*0.5f;
w = (ra.width+rb.width)*0.5f;
h = (ra.height+rb.height)*0.5f;
dx = (float)(fabs(pa.x - pb.x)-w);
dy = (float)(fabs(pa.y - pb.y)-h);
//wt = MAX(ra.width,rb.width)*0.1f;
wt = 0;
ht = MAX(ra.height,rb.height)*0.3f;
if(dx < wt && dy < ht) return 1;
return 0;
}
void cvFindBlobsByCCClasters(IplImage* pFG, CvBlobSeq* pBlobs, CvMemStorage* storage)
{/* create contours */
IplImage* pIB = NULL;
CvSeq* cnt = NULL;
CvSeq* cnt_list = cvCreateSeq(0,sizeof(CvSeq),sizeof(CvSeq*), storage );
CvSeq* clasters = NULL;
int claster_cur, claster_num;
pIB = cvCloneImage(pFG);
cvThreshold(pIB,pIB,128,255,CV_THRESH_BINARY);
cvFindContours(pIB,storage, &cnt, sizeof(CvContour), CV_RETR_EXTERNAL);
cvReleaseImage(&pIB);
/* create cnt_list*/
/* process each contours*/
for(;cnt;cnt=cnt->h_next)
{
cvSeqPush( cnt_list, &cnt);
}
claster_num = cvSeqPartition( cnt_list, storage, &clasters, CompareContour, NULL );
for(claster_cur=0;claster_cur<claster_num;++claster_cur)
{
int cnt_cur;
CvBlob NewBlob;
double M00,X,Y,XX,YY; /* image moments */
CvMoments m;
CvRect rect_res = cvRect(-1,-1,-1,-1);
CvMat mat;
for(cnt_cur=0;cnt_cur<clasters->total;++cnt_cur)
{
CvRect rect;
CvSeq* cnt;
int k = *(int*)cvGetSeqElem( clasters, cnt_cur );
if(k!=claster_cur) continue;
cnt = *(CvSeq**)cvGetSeqElem( cnt_list, cnt_cur );
rect = ((CvContour*)cnt)->rect;
if(rect_res.height<0)
{
rect_res = rect;
}
else
{/* unite rects */
int x0,x1,y0,y1;
x0 = MIN(rect_res.x,rect.x);
y0 = MIN(rect_res.y,rect.y);
x1 = MAX(rect_res.x+rect_res.width,rect.x+rect.width);
y1 = MAX(rect_res.y+rect_res.height,rect.y+rect.height);
rect_res.x = x0;
rect_res.y = y0;
rect_res.width = x1-x0;
rect_res.height = y1-y0;
}
}
if(rect_res.height < 1 || rect_res.width < 1)
{
X = 0;
Y = 0;
XX = 0;
YY = 0;
}
else
{
cvMoments( cvGetSubRect(pFG,&mat,rect_res), &m, 0 );
M00 = cvGetSpatialMoment( &m, 0, 0 );
if(M00 <= 0 ) continue;
X = cvGetSpatialMoment( &m, 1, 0 )/M00;
Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
}
NewBlob = cvBlob(rect_res.x+(float)X,rect_res.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
pBlobs->AddBlob(&NewBlob);
}/* next cluster */
#if 0
{// debug info
IplImage* pI = cvCreateImage(cvSize(pFG->width,pFG->height),IPL_DEPTH_8U,3);
cvZero(pI);
for(claster_cur=0;claster_cur<claster_num;++claster_cur)
{
int cnt_cur;
CvScalar color = CV_RGB(rand()%256,rand()%256,rand()%256);
for(cnt_cur=0;cnt_cur<clasters->total;++cnt_cur)
{
CvSeq* cnt;
int k = *(int*)cvGetSeqElem( clasters, cnt_cur );
if(k!=claster_cur) continue;
cnt = *(CvSeq**)cvGetSeqElem( cnt_list, cnt_cur );
cvDrawContours( pI, cnt, color, color, 0, 1, 8);
}
CvBlob* pB = pBlobs->GetBlob(claster_cur);
int x = cvRound(CV_BLOB_RX(pB)), y = cvRound(CV_BLOB_RY(pB));
cvEllipse( pI,
cvPointFrom32f(CV_BLOB_CENTER(pB)),
cvSize(MAX(1,x), MAX(1,y)),
0, 0, 360,
color, 1 );
}
cvNamedWindow( "Clusters", 0);
cvShowImage( "Clusters",pI );
cvReleaseImage(&pI);
}/* debug info */
#endif
}/* cvFindBlobsByCCClasters */
/* simple blob detector */
/* numer of successive frame to analyse */
#define EBD_FRAME_NUM 5
class CvBlobDetectorSimple:public CvBlobDetector
{
public:
CvBlobDetectorSimple();
~CvBlobDetectorSimple();
int DetectNewBlob(IplImage* pImg, IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList);
void Release(){delete this;};
protected:
IplImage* m_pMaskBlobNew;
IplImage* m_pMaskBlobExist;
/* lists of connected components detected on previouse frames */
CvBlobSeq* m_pBlobLists[EBD_FRAME_NUM];
};
/* Blob detector creator (sole interface function for this file) */
CvBlobDetector* cvCreateBlobDetectorSimple(){return new CvBlobDetectorSimple;};
/* Constructor of BlobDetector */
CvBlobDetectorSimple::CvBlobDetectorSimple()
{
int i = 0;
m_pMaskBlobNew = NULL;
m_pMaskBlobExist = NULL;
for(i=0;i<EBD_FRAME_NUM;++i)m_pBlobLists[i] = NULL;
}
/* destructor of BlobDetector*/
CvBlobDetectorSimple::~CvBlobDetectorSimple()
{
int i;
if(m_pMaskBlobExist) cvReleaseImage(&m_pMaskBlobExist);
if(m_pMaskBlobNew) cvReleaseImage(&m_pMaskBlobNew);
for(i=0;i<EBD_FRAME_NUM;++i)delete m_pBlobLists[i];
}/* cvReleaseBlobDetector */
/* cvDetectNewBlobs return 1 and fill blob pNewBlob by blob parameters if new blob is detected */
int CvBlobDetectorSimple::DetectNewBlob(IplImage* /*pImg*/, IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList)
{
int res = 0;
CvSize S = cvSize(pFGMask->width,pFGMask->height);
if(m_pMaskBlobNew == NULL ) m_pMaskBlobNew = cvCreateImage(S,IPL_DEPTH_8U,1);
if(m_pMaskBlobExist == NULL ) m_pMaskBlobExist = cvCreateImage(S,IPL_DEPTH_8U,1);
/* shift blob list */
{
int i;
if(m_pBlobLists[0]) delete m_pBlobLists[0];
for(i=1;i<EBD_FRAME_NUM;++i)m_pBlobLists[i-1]=m_pBlobLists[i];
m_pBlobLists[EBD_FRAME_NUM-1] = new CvBlobSeq;
}/* shift blob list */
/* create exist blob mask */
cvCopy(pFGMask, m_pMaskBlobNew);
/* create contours and add new blobs to blob list */
{/* create blobs */
CvBlobSeq Blobs;
CvMemStorage* storage = cvCreateMemStorage();
#if 1
{/* glue contours */
cvFindBlobsByCCClasters(m_pMaskBlobNew, &Blobs, storage );
}/* glue contours */
#else
{ /**/
IplImage* pIB = cvCloneImage(m_pMaskBlobNew);
CvSeq* cnts = NULL;
CvSeq* cnt = NULL;
cvThreshold(pIB,pIB,128,255,CV_THRESH_BINARY);
cvFindContours(pIB,storage, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);
/* process each contours*/
for(cnt = cnts;cnt;cnt=cnt->h_next)
{
CvBlob NewBlob;
/* image moments */
double M00,X,Y,XX,YY;
CvMoments m;
CvRect r = ((CvContour*)cnt)->rect;
CvMat mat;
if(r.height < S.height*0.02 || r.width < S.width*0.02) continue;
cvMoments( cvGetSubRect(m_pMaskBlobNew,&mat,r), &m, 0 );
M00 = cvGetSpatialMoment( &m, 0, 0 );
if(M00 <= 0 ) continue;
X = cvGetSpatialMoment( &m, 1, 0 )/M00;
Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
NewBlob = cvBlob(r.x+(float)X,r.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
Blobs.AddBlob(&NewBlob);
}/* next contour */
cvReleaseImage(&pIB);
}/* one contour - one blob */
#endif
{/* Delete small and intersected blobs */
int i;
for(i=Blobs.GetBlobNum();i>0;i--)
{
CvBlob* pB = Blobs.GetBlob(i-1);
if(pB->h < S.height*0.02 || pB->w < S.width*0.02)
{
Blobs.DelBlob(i-1);
continue;
}
if(pOldBlobList)
{
int j;
for(j=pOldBlobList->GetBlobNum();j>0;j--)
{
CvBlob* pBOld = pOldBlobList->GetBlob(j-1);
if((fabs(pBOld->x-pB->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pB))) &&
(fabs(pBOld->y-pB->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pB))))
{/* intersection is present, delete blob from list*/
Blobs.DelBlob(i-1);
break;
}
}/* checl next old blob */
}/*if pOldBlobList */
}/* check next blob */
}/* Delete small and intersected blobs */
{/* bubble sort blobs by size */
int N = Blobs.GetBlobNum();
int i,j;
for(i=1;i<N;++i)
{
for(j=i;j>0;--j)
{
CvBlob temp;
float AreaP, AreaN;
CvBlob* pP = Blobs.GetBlob(j-1);
CvBlob* pN = Blobs.GetBlob(j);
AreaP = CV_BLOB_WX(pP)*CV_BLOB_WY(pP);
AreaN = CV_BLOB_WX(pN)*CV_BLOB_WY(pN);
if(AreaN < AreaP)break;
temp = pN[0];
pN[0] = pP[0];
pP[0] = temp;
}
}
/* copy only first 10 blobs */
for(i=0;i<MIN(N,10);++i)
{
m_pBlobLists[EBD_FRAME_NUM-1]->AddBlob(Blobs.GetBlob(i));
}
}/* sort blobs by size */
cvReleaseMemStorage(&storage);
}/* create Blobs */
/* analize blob list to find best blob trajectory */
{/* analize blob list to find best blob trajectory */
int Count = 0;
int pBLIndex[EBD_FRAME_NUM];
int pBL_BEST[EBD_FRAME_NUM];
int i;
int finish = 0;
double BestError = -1;
int Good = 1;
for(i=0;i<EBD_FRAME_NUM;++i)
{
pBLIndex[i] = 0;
pBL_BEST[i] = 0;
}
/* check configuration exist */
for(i=0;Good && (i<EBD_FRAME_NUM);++i)
if(m_pBlobLists[i] == NULL || m_pBlobLists[i]->GetBlobNum() == 0)
Good = 0;
if(Good)
do{/* for each configuration */
CvBlob* pBL[EBD_FRAME_NUM];
int Good = 1;
double Error = 0;
CvBlob* pBNew = m_pBlobLists[EBD_FRAME_NUM-1]->GetBlob(pBLIndex[EBD_FRAME_NUM-1]);
for(i=0;i<EBD_FRAME_NUM;++i)pBL[i] = m_pBlobLists[i]->GetBlob(pBLIndex[i]);
Count++;
/* check intersection last blob with existed */
if(Good && pOldBlobList)
{ /* check intersection last blob with existed */
int k;
for(k=pOldBlobList->GetBlobNum();k>0;--k)
{
CvBlob* pBOld = pOldBlobList->GetBlob(k-1);
if((fabs(pBOld->x-pBNew->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pBNew))) &&
(fabs(pBOld->y-pBNew->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pBNew))))
Good = 0;
}
}/* check intersection last blob with existed */
/* check distance to image border */
if(Good)
{ /* check distance to image border */
CvBlob* pB = pBNew;
float dx = MIN(pB->x,S.width-pB->x)/CV_BLOB_RX(pB);
float dy = MIN(pB->y,S.height-pB->y)/CV_BLOB_RY(pB);
if(dx < 1.1 || dy < 1.1) Good = 0;
}/* check distance to image border */
/* check uniform moveing */
if(Good)
{/* check uniform moveing */
int N = EBD_FRAME_NUM;
float sum[2] = {0,0};
float jsum[2] = {0,0};
float a[2],b[2]; /* estimated parameters of moving x(t) = a*t+b*/
int j;
for(j=0;j<N;++j)
{
float x = pBL[j]->x;
float y = pBL[j]->y;
sum[0] += x;
jsum[0] += j*x;
sum[1] += y;
jsum[1] += j*y;
}
a[0] = 6*((1-N)*sum[0]+2*jsum[0])/(N*(N*N-1));
b[0] = -2*((1-2*N)*sum[0]+3*jsum[0])/(N*(N+1));
a[1] = 6*((1-N)*sum[1]+2*jsum[1])/(N*(N*N-1));
b[1] = -2*((1-2*N)*sum[1]+3*jsum[1])/(N*(N+1));
for(j=0;j<N;++j)
{
Error +=
pow(a[0]*j+b[0]-pBL[j]->x,2)+
pow(a[1]*j+b[1]-pBL[j]->y,2);
}
Error = sqrt(Error/N);
if( Error > S.width*0.01 ||
fabs(a[0])>S.width*0.1 ||
fabs(a[1])>S.height*0.1)
Good = 0;
}/* check configuration */
/* new best trajectory */
if(Good && (BestError == -1 || BestError > Error))
{/* new best trajectory */
for(i=0;i<EBD_FRAME_NUM;++i)
{
pBL_BEST[i] = pBLIndex[i];
}
BestError = Error;
}/* new best trajectory */
/* set next configuration */
for(i=0;i<EBD_FRAME_NUM;++i)
{
pBLIndex[i]++;
if(pBLIndex[i] != m_pBlobLists[i]->GetBlobNum()) break;
pBLIndex[i]=0;
}/* next time shift */
if(i==EBD_FRAME_NUM)finish=1;
}while(!finish); /* check next time configuration of connected components */
#if 0
{/**/
printf("BlobDetector configurations = %d [",Count);
int i;
for(i=0;i<EBD_FRAME_NUM;++i)
{
printf("%d,",m_pBlobLists[i]?m_pBlobLists[i]->GetBlobNum():0);
}
printf("]\n");
}
#endif
if(BestError != -1)
{/* put new blob to output and delete from blob list */
CvBlob* pNewBlob = m_pBlobLists[EBD_FRAME_NUM-1]->GetBlob(pBL_BEST[EBD_FRAME_NUM-1]);
pNewBlobList->AddBlob(pNewBlob);
for(i=0;i<EBD_FRAME_NUM;++i)
{/* remove blob from each list */
m_pBlobLists[i]->DelBlob(pBL_BEST[i]);
}/* remove blob from each list */
res = 1;
}/* put new blob to output and delete from blob list */
}/* analize blod list to find best blob trajectory */
return res;
}/* cvDetectNewBlob */
/* simple blob detector2 */
/* numer of successive frame to analyse */
#define SEQ_SIZE_MAX 30
#define SEQ_NUM 1000
typedef struct
{
int size;
CvBlob* pBlobs[SEQ_SIZE_MAX];
} DefSeq;
class CvBlobDetectorCC:public CvBlobDetector
{
public:
CvBlobDetectorCC();
~CvBlobDetectorCC();
int DetectNewBlob(IplImage* pImg, IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList);
void Release(){delete this;};
virtual void ParamUpdate()
{
if(SEQ_SIZE<1)SEQ_SIZE=1;
if(SEQ_SIZE>SEQ_SIZE_MAX)SEQ_SIZE=SEQ_SIZE_MAX;
#ifdef USE_OBJECT_DETECTOR
if( m_param_split_detector_file_name )
{
m_split_detector = new CvObjectDetector();
if( !m_split_detector->Load( m_param_split_detector_file_name ) )
{
delete m_split_detector;
m_split_detector = 0;
}
else
{
m_min_window_size = m_split_detector->GetMinWindowSize();
m_max_border = m_split_detector->GetMaxBorderSize();
}
}
#endif
}
private:
/* lists of connected components detected on previouse frames */
CvBlobSeq* m_pBlobLists[SEQ_SIZE_MAX];
DefSeq m_TrackSeq[SEQ_NUM];
int m_TrackNum;
float m_HMin;
float m_WMin;
float m_MinDistToBorder;
int m_Clastering;
int SEQ_SIZE;
/* if not 0 then the detector is loaded from the specified file
and it is applied for splitting blobs which actually correspond
to groups of objects */
char* m_param_split_detector_file_name;
float m_param_roi_scale;
int m_param_only_roi;
CvObjectDetector* m_split_detector;
CvSize m_min_window_size;
int m_max_border;
CvBlobSeq m_detected_blob_seq;
CvSeq* m_roi_seq;
CvBlobSeq m_debug_blob_seq;
};
/* Blob detector creator (sole interface function for this file) */
CvBlobDetector* cvCreateBlobDetectorCC(){return new CvBlobDetectorCC;}
/* Constructor of BlobDetector */
CvBlobDetectorCC::CvBlobDetectorCC() :
m_split_detector(0),
m_detected_blob_seq(sizeof(CvDetectedBlob)),
m_roi_seq(0),
m_debug_blob_seq(sizeof(CvDetectedBlob))
{
/*CvDrawShape shapes[] =
{
{ CvDrawShape::RECT, {{255,255,255}} },
{ CvDrawShape::RECT, {{0,0,255}} },
{ CvDrawShape::ELLIPSE, {{0,255,0}} }
};
int num_shapes = sizeof(shapes) / sizeof(shapes[0]);*/
int i = 0;
SEQ_SIZE = 10;
AddParam("Latency",&SEQ_SIZE);
for(i=0;i<SEQ_SIZE_MAX;++i)m_pBlobLists[i] = NULL;
for(i=0;i<SEQ_NUM;++i)m_TrackSeq[i].size = 0;
m_TrackNum = 0;
m_HMin = 0.02f;
m_WMin = 0.01f;
AddParam("HMin",&m_HMin);
AddParam("WMin",&m_WMin);
m_MinDistToBorder = 1.1f;
AddParam("MinDistToBorder",&m_MinDistToBorder);
CommentParam("MinDistToBorder","Minimal allowed distance from blob center to image border in blob sizes");
m_Clastering=1;
AddParam("Clastering",&m_Clastering);
CommentParam("Clastering","Minimal allowed distance from blob center to image border in blob sizes");
m_param_split_detector_file_name = 0;
#ifdef USE_OBJECT_DETECTOR
AddParam("Detector", &m_param_split_detector_file_name);
CommentParam("Detector", "Detector file name");
#endif
m_param_roi_scale = 1.5F;
AddParam("ROIScale", &m_param_roi_scale);
CommentParam("ROIScale", "Determines the size of search window around a blob");
m_param_only_roi = 1;
AddParam("OnlyROI", &m_param_only_roi);
CommentParam("OnlyROI", "Shows the whole debug image (0) or only ROIs where the detector was applied (1)");
m_min_window_size = cvSize(0,0);
m_max_border = 0;
m_roi_seq = cvCreateSeq( 0, sizeof(*m_roi_seq), sizeof(CvRect), cvCreateMemStorage() );
SetModuleName("BD_CC");
}
/* destructor of BlobDetector*/
CvBlobDetectorCC::~CvBlobDetectorCC()
{
int i;
for(i=0;i<SEQ_SIZE_MAX;++i)
{
if(m_pBlobLists[i])
delete m_pBlobLists[i];
}
if( m_roi_seq )
{
cvReleaseMemStorage( &m_roi_seq->storage );
m_roi_seq = 0;
}
//cvDestroyWindow( "EnteringBlobDetectionDebug" );
}/* cvReleaseBlobDetector */
/* cvDetectNewBlobs return 1 and fill blob pNewBlob by blob parameters if new blob is detected */
int CvBlobDetectorCC::DetectNewBlob(IplImage* /*pImg*/, IplImage* pFGMask, CvBlobSeq* pNewBlobList, CvBlobSeq* pOldBlobList)
{
int res = 0;
CvSize S = cvSize(pFGMask->width,pFGMask->height);
/* shift blob list */
{
int i;
if(m_pBlobLists[SEQ_SIZE-1]) delete m_pBlobLists[SEQ_SIZE-1];
for(i=SEQ_SIZE-1;i>0;--i)m_pBlobLists[i]=m_pBlobLists[i-1];
m_pBlobLists[0] = new CvBlobSeq;
}/* shift blob list */
/* create contours and add new blobs to blob list */
{/* create blobs */
CvBlobSeq Blobs;
CvMemStorage* storage = cvCreateMemStorage();
if(m_Clastering)
{/* glue contours */
cvFindBlobsByCCClasters(pFGMask, &Blobs, storage );
}/* glue contours */
else
{ /**/
IplImage* pIB = cvCloneImage(pFGMask);
CvSeq* cnts = NULL;
CvSeq* cnt = NULL;
cvThreshold(pIB,pIB,128,255,CV_THRESH_BINARY);
cvFindContours(pIB,storage, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);
/* process each contours*/
for(cnt = cnts;cnt;cnt=cnt->h_next)
{
CvBlob NewBlob;
/* image moments */
double M00,X,Y,XX,YY;
CvMoments m;
CvRect r = ((CvContour*)cnt)->rect;
CvMat mat;
if(r.height < S.height*m_HMin || r.width < S.width*m_WMin) continue;
cvMoments( cvGetSubRect(pFGMask,&mat,r), &m, 0 );
M00 = cvGetSpatialMoment( &m, 0, 0 );
if(M00 <= 0 ) continue;
X = cvGetSpatialMoment( &m, 1, 0 )/M00;
Y = cvGetSpatialMoment( &m, 0, 1 )/M00;
XX = (cvGetSpatialMoment( &m, 2, 0 )/M00) - X*X;
YY = (cvGetSpatialMoment( &m, 0, 2 )/M00) - Y*Y;
NewBlob = cvBlob(r.x+(float)X,r.y+(float)Y,(float)(4*sqrt(XX)),(float)(4*sqrt(YY)));
Blobs.AddBlob(&NewBlob);
}/* next contour */
cvReleaseImage(&pIB);
}/* one contour - one blob */
{/* Delete small and intersected blobs */
int i;
for(i=Blobs.GetBlobNum();i>0;i--)
{
CvBlob* pB = Blobs.GetBlob(i-1);
if(pB->h < S.height*m_HMin || pB->w < S.width*m_WMin)
{
Blobs.DelBlob(i-1);
continue;
}
if(pOldBlobList)
{
int j;
for(j=pOldBlobList->GetBlobNum();j>0;j--)
{
CvBlob* pBOld = pOldBlobList->GetBlob(j-1);
if((fabs(pBOld->x-pB->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pB))) &&
(fabs(pBOld->y-pB->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pB))))
{/* intersection is present, delete blob from list*/
Blobs.DelBlob(i-1);
break;
}
}/* checl next old blob */
}/*if pOldBlobList */
}/* check next blob */
}/* Delete small and intersected blobs */
{/* bubble sort blobs by size */
int N = Blobs.GetBlobNum();
int i,j;
for(i=1;i<N;++i)
{
for(j=i;j>0;--j)
{
CvBlob temp;
float AreaP, AreaN;
CvBlob* pP = Blobs.GetBlob(j-1);
CvBlob* pN = Blobs.GetBlob(j);
AreaP = CV_BLOB_WX(pP)*CV_BLOB_WY(pP);
AreaN = CV_BLOB_WX(pN)*CV_BLOB_WY(pN);
if(AreaN < AreaP)break;
temp = pN[0];
pN[0] = pP[0];
pP[0] = temp;
}
}
/* copy only first 10 blobs */
for(i=0;i<MIN(N,10);++i)
{
m_pBlobLists[0]->AddBlob(Blobs.GetBlob(i));
}
}/* sort blobs by size */
cvReleaseMemStorage(&storage);
}/* create Blobs */
{/* shift each track */
int j;
for(j=0;j<m_TrackNum;++j)
{
int i;
DefSeq* pTrack = m_TrackSeq+j;
for(i=SEQ_SIZE-1;i>0;--i)pTrack->pBlobs[i]=pTrack->pBlobs[i-1];
pTrack->pBlobs[0] = NULL;
if(pTrack->size == SEQ_SIZE)pTrack->size--;
}
}/* shift each track */
/* analize blob list to find best blob trajectory */
{/* analize blob list to find best blob trajectory */
double BestError = -1;
int BestTrack = -1;;
CvBlobSeq* pNewBlobs = m_pBlobLists[0];
int i;
int NewTrackNum = 0;
for(i=pNewBlobs->GetBlobNum();i>0;--i)
{
CvBlob* pBNew = pNewBlobs->GetBlob(i-1);
int j;
int AsignedTrack = 0;
for(j=0;j<m_TrackNum;++j)
{
double dx,dy;
DefSeq* pTrack = m_TrackSeq+j;
CvBlob* pLastBlob = pTrack->size>0?pTrack->pBlobs[1]:NULL;
if(pLastBlob == NULL) continue;
dx = fabs(CV_BLOB_X(pLastBlob)-CV_BLOB_X(pBNew));
dy = fabs(CV_BLOB_Y(pLastBlob)-CV_BLOB_Y(pBNew));
if(dx > 2*CV_BLOB_WX(pLastBlob) || dy > 2*CV_BLOB_WY(pLastBlob)) continue;
AsignedTrack++;
if(pTrack->pBlobs[0]==NULL)
{/*fill existed track */
pTrack->pBlobs[0] = pBNew;
pTrack->size++;
}
else if((m_TrackNum+NewTrackNum)<SEQ_NUM)
{ /* duplicate existed track */
m_TrackSeq[m_TrackNum+NewTrackNum] = pTrack[0];
m_TrackSeq[m_TrackNum+NewTrackNum].pBlobs[0] = pBNew;
NewTrackNum++;
}
}/* next track */
if(AsignedTrack==0 && (m_TrackNum+NewTrackNum)<SEQ_NUM )
{/* init new track */
m_TrackSeq[m_TrackNum+NewTrackNum].size = 1;
m_TrackSeq[m_TrackNum+NewTrackNum].pBlobs[0] = pBNew;
NewTrackNum++;
}
}/* next new blob */
m_TrackNum += NewTrackNum;
/* check each track */
for(i=0;i<m_TrackNum;++i)
{
int Good = 1;
DefSeq* pTrack = m_TrackSeq+i;
CvBlob* pBNew = pTrack->pBlobs[0];
if(pTrack->size != SEQ_SIZE) continue;
if(pBNew == NULL ) continue;
/* check intersection last blob with existed */
if(Good && pOldBlobList)
{ /* check intersection last blob with existed */
int k;
for(k=pOldBlobList->GetBlobNum();k>0;--k)
{
CvBlob* pBOld = pOldBlobList->GetBlob(k-1);
if((fabs(pBOld->x-pBNew->x) < (CV_BLOB_RX(pBOld)+CV_BLOB_RX(pBNew))) &&
(fabs(pBOld->y-pBNew->y) < (CV_BLOB_RY(pBOld)+CV_BLOB_RY(pBNew))))
Good = 0;
}
}/* check intersection last blob with existed */
/* check distance to image border */
if(Good)
{ /* check distance to image border */
float dx = MIN(pBNew->x,S.width-pBNew->x)/CV_BLOB_RX(pBNew);
float dy = MIN(pBNew->y,S.height-pBNew->y)/CV_BLOB_RY(pBNew);
if(dx < m_MinDistToBorder || dy < m_MinDistToBorder) Good = 0;
}/* check distance to image border */
/* check uniform moveing */
if(Good)
{/* check uniform moveing */
double Error = 0;
int N = pTrack->size;
CvBlob** pBL = pTrack->pBlobs;
float sum[2] = {0,0};
float jsum[2] = {0,0};
float a[2],b[2]; /* estimated parameters of moving x(t) = a*t+b*/
int j;
for(j=0;j<N;++j)
{
float x = pBL[j]->x;
float y = pBL[j]->y;
sum[0] += x;
jsum[0] += j*x;
sum[1] += y;
jsum[1] += j*y;
}
a[0] = 6*((1-N)*sum[0]+2*jsum[0])/(N*(N*N-1));
b[0] = -2*((1-2*N)*sum[0]+3*jsum[0])/(N*(N+1));
a[1] = 6*((1-N)*sum[1]+2*jsum[1])/(N*(N*N-1));
b[1] = -2*((1-2*N)*sum[1]+3*jsum[1])/(N*(N+1));
for(j=0;j<N;++j)
{
Error +=
pow(a[0]*j+b[0]-pBL[j]->x,2)+
pow(a[1]*j+b[1]-pBL[j]->y,2);
}
Error = sqrt(Error/N);
if( Error > S.width*0.01 ||
fabs(a[0])>S.width*0.1 ||
fabs(a[1])>S.height*0.1)
Good = 0;
/* new best trajectory */
if(Good && (BestError == -1 || BestError > Error))
{/* new best trajectory */
BestTrack = i;
BestError = Error;
}/* new best trajectory */
}/* check uniform moveing */
}/* next track */
#if 0
{/**/
printf("BlobDetector configurations = %d [",m_TrackNum);
int i;
for(i=0;i<SEQ_SIZE;++i)
{
printf("%d,",m_pBlobLists[i]?m_pBlobLists[i]->GetBlobNum():0);
}
printf("]\n");
}
#endif
if(BestTrack >= 0)
{/* put new blob to output and delete from blob list */
assert(m_TrackSeq[BestTrack].size == SEQ_SIZE);
assert(m_TrackSeq[BestTrack].pBlobs[0]);
pNewBlobList->AddBlob(m_TrackSeq[BestTrack].pBlobs[0]);
m_TrackSeq[BestTrack].pBlobs[0] = NULL;
m_TrackSeq[BestTrack].size--;
res = 1;
}/* put new blob to output and mark in blob list to delete*/
}/* analize blod list to find best blob trajectory */
{/* delete bad tracks */
int i;
for(i=m_TrackNum-1;i>=0;--i)
{/* delete bad tracks */
if(m_TrackSeq[i].pBlobs[0]) continue;
if(m_TrackNum>0)
m_TrackSeq[i] = m_TrackSeq[--m_TrackNum];
}/* delete bad tracks */
}
#ifdef USE_OBJECT_DETECTOR
if( m_split_detector && pNewBlobList->GetBlobNum() > 0 )
{
int num_new_blobs = pNewBlobList->GetBlobNum();
int i = 0;
if( m_roi_seq ) cvClearSeq( m_roi_seq );
m_debug_blob_seq.Clear();
for( i = 0; i < num_new_blobs; ++i )
{
CvBlob* b = pNewBlobList->GetBlob(i);
CvMat roi_stub;
CvMat* roi_mat = 0;
CvMat* scaled_roi_mat = 0;
CvDetectedBlob d_b = cvDetectedBlob( CV_BLOB_X(b), CV_BLOB_Y(b), CV_BLOB_WX(b), CV_BLOB_WY(b), 0 );
m_debug_blob_seq.AddBlob(&d_b);
float scale = m_param_roi_scale * m_min_window_size.height / CV_BLOB_WY(b);
float b_width = MAX(CV_BLOB_WX(b), m_min_window_size.width / scale)
+ (m_param_roi_scale - 1.0F) * (m_min_window_size.width / scale)
+ 2.0F * m_max_border / scale;
float b_height = CV_BLOB_WY(b) * m_param_roi_scale + 2.0F * m_max_border / scale;
CvRect roi = cvRectIntersection( cvRect( cvFloor(CV_BLOB_X(b) - 0.5F*b_width),
cvFloor(CV_BLOB_Y(b) - 0.5F*b_height),
cvCeil(b_width), cvCeil(b_height) ),
cvRect( 0, 0, pImg->width, pImg->height ) );
if( roi.width <= 0 || roi.height <= 0 )
continue;
if( m_roi_seq ) cvSeqPush( m_roi_seq, &roi );
roi_mat = cvGetSubRect( pImg, &roi_stub, roi );
scaled_roi_mat = cvCreateMat( cvCeil(scale*roi.height), cvCeil(scale*roi.width), CV_8UC3 );
cvResize( roi_mat, scaled_roi_mat );
m_detected_blob_seq.Clear();
m_split_detector->Detect( scaled_roi_mat, &m_detected_blob_seq );
cvReleaseMat( &scaled_roi_mat );
for( int k = 0; k < m_detected_blob_seq.GetBlobNum(); ++k )
{
CvDetectedBlob* b = (CvDetectedBlob*) m_detected_blob_seq.GetBlob(k);
/* scale and shift each detected blob back to the original image coordinates */
CV_BLOB_X(b) = CV_BLOB_X(b) / scale + roi.x;
CV_BLOB_Y(b) = CV_BLOB_Y(b) / scale + roi.y;
CV_BLOB_WX(b) /= scale;
CV_BLOB_WY(b) /= scale;
CvDetectedBlob d_b = cvDetectedBlob( CV_BLOB_X(b), CV_BLOB_Y(b), CV_BLOB_WX(b), CV_BLOB_WY(b), 1,
b->response );
m_debug_blob_seq.AddBlob(&d_b);
}
if( m_detected_blob_seq.GetBlobNum() > 1 )
{
/*
* Split blob
* The original blob is replaced by the first detected blob,
* remaining detected blobs are added to the end of the sequence
*/
CvBlob* first_b = m_detected_blob_seq.GetBlob(0);
CV_BLOB_X(b) = CV_BLOB_X(first_b); CV_BLOB_Y(b) = CV_BLOB_Y(first_b);
CV_BLOB_WX(b) = CV_BLOB_WX(first_b); CV_BLOB_WY(b) = CV_BLOB_WY(first_b);
for( int j = 1; j < m_detected_blob_seq.GetBlobNum(); ++j )
{
CvBlob* detected_b = m_detected_blob_seq.GetBlob(j);
pNewBlobList->AddBlob(detected_b);
}
}
} /* for each new blob */
for( i = 0; i < pNewBlobList->GetBlobNum(); ++i )
{
CvBlob* b = pNewBlobList->GetBlob(i);
CvDetectedBlob d_b = cvDetectedBlob( CV_BLOB_X(b), CV_BLOB_Y(b), CV_BLOB_WX(b), CV_BLOB_WY(b), 2 );
m_debug_blob_seq.AddBlob(&d_b);
}
} // if( m_split_detector )
#endif
return res;
}/* cvDetectNewBlob */

View File

@@ -0,0 +1,158 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
/*
This file contain implementation of virtual interface of CvBlobDetector
this implementation based on simple algorithm
new blob is detected when several successive frames contains connected componets
which have uniform motion with not high speed.
Also separation from border and already tracked blobs are considered.
*/
#include "_cvaux.h"
/* blob detector based on real data (groundtruth data)*/
class CvBlobDetectorReal:public CvBlobDetector
{
protected:
CvTestSeq* m_pTestSeq;
CvBlobSeq m_DetectedBlobs;
CvMemStorage* m_pMem;
public:
CvBlobDetectorReal(CvTestSeq* pTestSeq)
{
m_pTestSeq = pTestSeq;
m_pMem = cvCreateMemStorage(0);
}
/* destructor of BlobDetector*/
~CvBlobDetectorReal()
{
if(m_pMem) cvReleaseMemStorage(&m_pMem);
}/* cvReleaseBlobDetector */
/* cvDetectNewBlobs return 1 and fill blob pNewBlob by blob parameters if new blob is detected */
int DetectNewBlob(IplImage* /*pImg*/, IplImage* /*pFGMask*/, CvBlobSeq* pNewBlobList, CvBlobSeq* /*pOldBlobList*/)
{
int i;
int TestObjNum;
IplImage* pMask = NULL;
IplImage* pMaskCopy = NULL;
CvSeq* cnts = NULL;
if(m_pTestSeq==NULL) return 0;
TestObjNum = cvTestSeqGetObjectNum(m_pTestSeq);
pMask = cvTestSeqGetFGMask(m_pTestSeq);
if(pMask == NULL) return 0;
pMaskCopy = cvCloneImage(pMask);
assert(pMaskCopy);
cvClearMemStorage(m_pMem);
cvFindContours( pMaskCopy, m_pMem, &cnts, sizeof(CvContour), CV_RETR_EXTERNAL);
cvReleaseImage(&pMaskCopy);
for(i=0;i<TestObjNum;++i)
{/* check each object */
CvPoint2D32f RealPos;
CvPoint2D32f RealSize;
int RealPosFlag = cvTestSeqGetObjectPos(m_pTestSeq,i,&RealPos);
int RealSizeFlag = cvTestSeqGetObjectSize(m_pTestSeq,i,&RealSize);
if(!RealPosFlag) continue;
if(m_DetectedBlobs.GetBlobByID(i)) continue;
if(RealSizeFlag)
{ /* real size is know */
float W2 = RealSize.x * 0.5f;
float H2 = RealSize.y * 0.5f;
if( RealPos.x > W2 && RealPos.x < (pMask->width-W2) &&
RealPos.y > H2 && RealPos.y < (pMask->height-H2) )
{ /* yes !! we found new blob, Let's add it to list */
CvBlob NewBlob;
NewBlob.x = RealPos.x;
NewBlob.y = RealPos.y;
NewBlob.w = RealSize.x;
NewBlob.h = RealSize.y;
NewBlob.ID = i;
m_DetectedBlobs.AddBlob(&NewBlob);
pNewBlobList->AddBlob(&NewBlob);
}
}/* real size is know */
else
{
CvSeq* cnt;
if(m_DetectedBlobs.GetBlobByID(i)) continue;
for(cnt=cnts;cnt;cnt=cnt->h_next)
{
//CvBlob* pNewBlob = NULL;
CvBlob NewBlob;
CvRect r = cvBoundingRect( cnt );
float x = RealPos.x - r.x;
float y = RealPos.y - r.y;
if(x<0 || x > r.width || y < 0 || y > r.height ) continue;
if( r.x <= 1 ||
r.y <= 1 ||
r.x + r.width >= pMask->width - 2 ||
r.y + r.height >= pMask->height - 2 ) continue;
/* yes !! we found new blob, Let's add it to list */
NewBlob.x = RealPos.x;
NewBlob.y = RealPos.y;
NewBlob.w = (float)r.width;
NewBlob.h = (float)r.height;
NewBlob.ID = i;
m_DetectedBlobs.AddBlob(&NewBlob);
pNewBlobList->AddBlob(&NewBlob);
}
}/* check new blob entrance */
}/* check next object */
return pNewBlobList->GetBlobNum();
}/* cvDetectNewBlob */
void Release(){delete this;};
};
/* Blob detector creator */
CvBlobDetector* cvCreateBlobDetectorReal(CvTestSeq* pTestSeq){return new CvBlobDetectorReal(pTestSeq);}