diff --git a/Przyklad/.dep.inc b/Przyklad/.dep.inc new file mode 100644 index 0000000..4560e55 --- /dev/null +++ b/Przyklad/.dep.inc @@ -0,0 +1,5 @@ +# This code depends on make tool being used +DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES})) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/Przyklad/build/Debug/GNU-Linux-x86/main.o.d b/Przyklad/build/Debug/GNU-Linux-x86/main.o.d new file mode 100644 index 0000000..fd85132 --- /dev/null +++ b/Przyklad/build/Debug/GNU-Linux-x86/main.o.d @@ -0,0 +1 @@ +build/Debug/GNU-Linux-x86/main.o: main.cpp diff --git a/Przyklad/dist/Debug/GNU-Linux-x86/przyklad b/Przyklad/dist/Debug/GNU-Linux-x86/przyklad new file mode 100755 index 0000000..1e19a13 Binary files /dev/null and b/Przyklad/dist/Debug/GNU-Linux-x86/przyklad differ diff --git a/Przyklad/nbproject/Makefile-Debug.mk b/Przyklad/nbproject/Makefile-Debug.mk index 44f9777..46b33fd 100644 --- a/Przyklad/nbproject/Makefile-Debug.mk +++ b/Przyklad/nbproject/Makefile-Debug.mk @@ -42,8 +42,8 @@ OBJECTFILES= \ CFLAGS=pkg-config --cflags --libs opencv # CC Compiler Flags -CCFLAGS=`pkg-config --cflags --libs opencv` -CXXFLAGS=`pkg-config --cflags --libs opencv` +CCFLAGS=`pkg-config --cflags --libs opencv` -lX11 +CXXFLAGS=`pkg-config --cflags --libs opencv` -lX11 # Fortran Compiler Flags FFLAGS= @@ -56,16 +56,16 @@ LDLIBSOPTIONS= # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer: ${OBJECTFILES} +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad: ${OBJECTFILES} ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} - ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer ${OBJECTFILES} ${LDLIBSOPTIONS} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad ${OBJECTFILES} ${LDLIBSOPTIONS} ${OBJECTDIR}/main.o: main.cpp ${MKDIR} -p ${OBJECTDIR} ${RM} $@.d - $(COMPILE.cc) -g `pkg-config --cflags --libs opencv` -MMD -MP -MF $@.d -o ${OBJECTDIR}/main.o main.cpp + $(COMPILE.cc) -g `pkg-config --cflags --libs opencv` -lX11 -MMD -MP -MF $@.d -o ${OBJECTDIR}/main.o main.cpp # Subprojects .build-subprojects: @@ -73,7 +73,7 @@ ${OBJECTDIR}/main.o: main.cpp # Clean Targets .clean-conf: ${CLEAN_SUBPROJECTS} ${RM} -r ${CND_BUILDDIR}/${CND_CONF} - ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer + ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad # Subprojects .clean-subprojects: diff --git a/Przyklad/nbproject/Makefile-Release.mk b/Przyklad/nbproject/Makefile-Release.mk index 6303314..bca5ce6 100644 --- a/Przyklad/nbproject/Makefile-Release.mk +++ b/Przyklad/nbproject/Makefile-Release.mk @@ -56,11 +56,11 @@ LDLIBSOPTIONS= # Build Targets .build-conf: ${BUILD_SUBPROJECTS} - "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad -${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer: ${OBJECTFILES} +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad: ${OBJECTFILES} ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} - ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer ${OBJECTFILES} ${LDLIBSOPTIONS} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad ${OBJECTFILES} ${LDLIBSOPTIONS} ${OBJECTDIR}/main.o: main.cpp ${MKDIR} -p ${OBJECTDIR} @@ -73,7 +73,7 @@ ${OBJECTDIR}/main.o: main.cpp # Clean Targets .clean-conf: ${CLEAN_SUBPROJECTS} ${RM} -r ${CND_BUILDDIR}/${CND_CONF} - ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer + ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad # Subprojects .clean-subprojects: diff --git a/Przyklad/nbproject/Makefile-impl.mk b/Przyklad/nbproject/Makefile-impl.mk index 963d09a..adfed7d 100644 --- a/Przyklad/nbproject/Makefile-impl.mk +++ b/Przyklad/nbproject/Makefile-impl.mk @@ -24,7 +24,7 @@ CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} # Project Name -PROJECTNAME=Modal-HandPointer +PROJECTNAME=Przyklad # Active Configuration DEFAULTCONF=Debug diff --git a/Przyklad/nbproject/Makefile-variables.mk b/Przyklad/nbproject/Makefile-variables.mk index 533abee..e484060 100644 --- a/Przyklad/nbproject/Makefile-variables.mk +++ b/Przyklad/nbproject/Makefile-variables.mk @@ -9,19 +9,19 @@ CND_DISTDIR=dist # Debug configuration CND_PLATFORM_Debug=GNU-Linux-x86 CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux-x86 -CND_ARTIFACT_NAME_Debug=modal-handpointer -CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux-x86/modal-handpointer +CND_ARTIFACT_NAME_Debug=przyklad +CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux-x86/przyklad CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux-x86/package -CND_PACKAGE_NAME_Debug=modal-handpointer.tar -CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/modal-handpointer.tar +CND_PACKAGE_NAME_Debug=przyklad.tar +CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/przyklad.tar # Release configuration CND_PLATFORM_Release=GNU-Linux-x86 CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux-x86 -CND_ARTIFACT_NAME_Release=modal-handpointer -CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/modal-handpointer +CND_ARTIFACT_NAME_Release=przyklad +CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/przyklad CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux-x86/package -CND_PACKAGE_NAME_Release=modal-handpointer.tar -CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/modal-handpointer.tar +CND_PACKAGE_NAME_Release=przyklad.tar +CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/przyklad.tar # # include compiler specific variables # diff --git a/Przyklad/nbproject/Package-Debug.bash b/Przyklad/nbproject/Package-Debug.bash index dc5b354..6c19df5 100644 --- a/Przyklad/nbproject/Package-Debug.bash +++ b/Przyklad/nbproject/Package-Debug.bash @@ -12,9 +12,9 @@ CND_DISTDIR=dist CND_BUILDDIR=build NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer -OUTPUT_BASENAME=modal-handpointer -PACKAGE_TOP_DIR=modal-handpointer/ +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad +OUTPUT_BASENAME=przyklad +PACKAGE_TOP_DIR=przyklad/ # Functions function checkReturnCode @@ -59,15 +59,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/modal-handpointer/bin" +makeDirectory "${NBTMPDIR}/przyklad/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/modal-handpointer.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/przyklad.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/modal-handpointer.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/przyklad.tar * checkReturnCode # Cleanup diff --git a/Przyklad/nbproject/Package-Release.bash b/Przyklad/nbproject/Package-Release.bash index e30113a..58f473b 100644 --- a/Przyklad/nbproject/Package-Release.bash +++ b/Przyklad/nbproject/Package-Release.bash @@ -12,9 +12,9 @@ CND_DISTDIR=dist CND_BUILDDIR=build NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging TMPDIRNAME=tmp-packaging -OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/modal-handpointer -OUTPUT_BASENAME=modal-handpointer -PACKAGE_TOP_DIR=modal-handpointer/ +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/przyklad +OUTPUT_BASENAME=przyklad +PACKAGE_TOP_DIR=przyklad/ # Functions function checkReturnCode @@ -59,15 +59,15 @@ mkdir -p ${NBTMPDIR} # Copy files and create directories and links cd "${TOP}" -makeDirectory "${NBTMPDIR}/modal-handpointer/bin" +makeDirectory "${NBTMPDIR}/przyklad/bin" copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 # Generate tar file cd "${TOP}" -rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/modal-handpointer.tar +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/przyklad.tar cd ${NBTMPDIR} -tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/modal-handpointer.tar * +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/przyklad.tar * checkReturnCode # Cleanup diff --git a/Przyklad/nbproject/configurations.xml b/Przyklad/nbproject/configurations.xml index 18aabcd..fdc82b7 100644 --- a/Przyklad/nbproject/configurations.xml +++ b/Przyklad/nbproject/configurations.xml @@ -41,7 +41,7 @@ pkg-config --cflags --libs opencv - `pkg-config --cflags --libs opencv` + `pkg-config --cflags --libs opencv` -lX11 diff --git a/Przyklad/main.cpp b/Przyklad/src/HandPointer/HandPointer.cpp.cpp similarity index 100% rename from Przyklad/main.cpp rename to Przyklad/src/HandPointer/HandPointer.cpp.cpp diff --git a/mariusz/.dep.inc b/mariusz/.dep.inc new file mode 100644 index 0000000..4560e55 --- /dev/null +++ b/mariusz/.dep.inc @@ -0,0 +1,5 @@ +# This code depends on make tool being used +DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES})) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/mariusz/Makefile b/mariusz/Makefile new file mode 100644 index 0000000..05de621 --- /dev/null +++ b/mariusz/Makefile @@ -0,0 +1,128 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_PLATFORM_${CONF} platform name (current configuration) +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# build tests +build-tests: .build-tests-post + +.build-tests-pre: +# Add your pre 'build-tests' code here... + +.build-tests-post: .build-tests-impl +# Add your post 'build-tests' code here... + + +# run tests +test: .test-post + +.test-pre: build-tests +# Add your pre 'test' code here... + +.test-post: .test-impl +# Add your post 'test' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/mariusz/build/Debug/GNU-Linux-x86/Mouse.o.d b/mariusz/build/Debug/GNU-Linux-x86/Mouse.o.d new file mode 100644 index 0000000..2b0e22d --- /dev/null +++ b/mariusz/build/Debug/GNU-Linux-x86/Mouse.o.d @@ -0,0 +1,3 @@ +build/Debug/GNU-Linux-x86/Mouse.o: Mouse.cpp Mouse.hpp + +Mouse.hpp: diff --git a/mariusz/build/Debug/GNU-Linux-x86/main.o.d b/mariusz/build/Debug/GNU-Linux-x86/main.o.d new file mode 100644 index 0000000..fd85132 --- /dev/null +++ b/mariusz/build/Debug/GNU-Linux-x86/main.o.d @@ -0,0 +1 @@ +build/Debug/GNU-Linux-x86/main.o: main.cpp diff --git a/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/HandPointer.cpp.o.d b/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/HandPointer.cpp.o.d new file mode 100644 index 0000000..dbdb541 --- /dev/null +++ b/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/HandPointer.cpp.o.d @@ -0,0 +1,4 @@ +build/Debug/GNU-Linux-x86/src/HandPointer/HandPointer.cpp.o: \ + src/HandPointer/HandPointer.cpp.cpp src/HandPointer/Mouse.hpp + +src/HandPointer/Mouse.hpp: diff --git a/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/HandPointer.o.d b/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/HandPointer.o.d new file mode 100644 index 0000000..901bb98 --- /dev/null +++ b/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/HandPointer.o.d @@ -0,0 +1,7 @@ +build/Debug/GNU-Linux-x86/src/HandPointer/HandPointer.o: \ + src/HandPointer/HandPointer.cpp include/cvBlob/cvblob.h \ + src/HandPointer/Mouse.hpp + +include/cvBlob/cvblob.h: + +src/HandPointer/Mouse.hpp: diff --git a/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/Mouse.o.d b/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/Mouse.o.d new file mode 100644 index 0000000..e51be53 --- /dev/null +++ b/mariusz/build/Debug/GNU-Linux-x86/src/HandPointer/Mouse.o.d @@ -0,0 +1,4 @@ +build/Debug/GNU-Linux-x86/src/HandPointer/Mouse.o: \ + src/HandPointer/Mouse.cpp src/HandPointer/Mouse.hpp + +src/HandPointer/Mouse.hpp: diff --git a/mariusz/dist/Debug/GNU-Linux-x86/mariusz b/mariusz/dist/Debug/GNU-Linux-x86/mariusz new file mode 100755 index 0000000..3409dcc Binary files /dev/null and b/mariusz/dist/Debug/GNU-Linux-x86/mariusz differ diff --git a/mariusz/dist/Debug/GNU-Linux-x86/przyklad b/mariusz/dist/Debug/GNU-Linux-x86/przyklad new file mode 100755 index 0000000..88763c5 Binary files /dev/null and b/mariusz/dist/Debug/GNU-Linux-x86/przyklad differ diff --git a/mariusz/include/cvBlob/CMakeLists.txt b/mariusz/include/cvBlob/CMakeLists.txt new file mode 100644 index 0000000..939f96b --- /dev/null +++ b/mariusz/include/cvBlob/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright (C) 2007 by Cristóbal Carnero Liñán +# grendel.ccl@gmail.com +# +# This file is part of cvBlob. +# +# cvBlob is free software: you can redistribute it and/or modify +# it under the terms of the Lesser GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cvBlob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# Lesser GNU General Public License for more details. +# +# You should have received a copy of the Lesser GNU General Public License +# along with cvBlob. If not, see . +# + +find_package(OpenCV REQUIRED) + +set(cvBlob_CVBLOB cvblob.cpp + cvlabel.cpp + cvaux.cpp + cvcontour.cpp + cvtrack.cpp + cvcolor.cpp +) + +set_source_files_properties(${cvBlob_SRC} + PROPERTIES + COMPILE_FLAGS "-O3" +) + +add_library(cvblob SHARED ${cvBlob_CVBLOB}) + +target_link_libraries(cvblob ${OpenCV_LIBS}) + +install(FILES cvblob.h DESTINATION include) + +install(TARGETS cvblob + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/mariusz/include/cvBlob/cvaux.cpp b/mariusz/include/cvBlob/cvaux.cpp new file mode 100644 index 0000000..0404c88 --- /dev/null +++ b/mariusz/include/cvBlob/cvaux.cpp @@ -0,0 +1,79 @@ +// Copyright (C) 2007 by Cristóbal Carnero Liñán +// grendel.ccl@gmail.com +// +// This file is part of cvBlob. +// +// cvBlob is free software: you can redistribute it and/or modify +// it under the terms of the Lesser GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// cvBlob is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Lesser GNU General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License +// along with cvBlob. If not, see . +// + +#include + +#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__))) +#include +#else +#include +#endif + +#include "cvblob.h" + +namespace cvb +{ + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry1 + + double cvDotProductPoints(CvPoint const &a, CvPoint const &b, CvPoint const &c) + { + double abx = b.x-a.x; + double aby = b.y-a.y; + double bcx = c.x-b.x; + double bcy = c.y-b.y; + + return abx*bcx + aby*bcy; + } + + double cvCrossProductPoints(CvPoint const &a, CvPoint const &b, CvPoint const &c) + { + double abx = b.x-a.x; + double aby = b.y-a.y; + double acx = c.x-a.x; + double acy = c.y-a.y; + + return abx*acy - aby*acx; + } + + double cvDistancePointPoint(CvPoint const &a, CvPoint const &b) + { + double abx = a.x-b.x; + double aby = a.y-b.y; + + return sqrt(abx*abx + aby*aby); + } + + double cvDistanceLinePoint(CvPoint const &a, CvPoint const &b, CvPoint const &c, bool isSegment) + { + if (isSegment) + { + double dot1 = cvDotProductPoints(a, b, c); + if (dot1>0) return cvDistancePointPoint(b, c); + + double dot2 = cvDotProductPoints(b, a, c); + if(dot2>0) return cvDistancePointPoint(a, c); + } + + return fabs(cvCrossProductPoints(a,b,c)/cvDistancePointPoint(a,b)); + } + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +} diff --git a/mariusz/include/cvBlob/cvblob.cpp b/mariusz/include/cvBlob/cvblob.cpp new file mode 100644 index 0000000..19b40e5 --- /dev/null +++ b/mariusz/include/cvBlob/cvblob.cpp @@ -0,0 +1,344 @@ +// Copyright (C) 2007 by Cristóbal Carnero Liñán +// grendel.ccl@gmail.com +// +// This file is part of cvBlob. +// +// cvBlob is free software: you can redistribute it and/or modify +// it under the terms of the Lesser GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// cvBlob is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Lesser GNU General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License +// along with cvBlob. If not, see . +// + +#include +#include +using namespace std; + +#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__))) +#include +#include +#else +#include +#include +#endif + +#include "cvblob.h" + +namespace cvb +{ + + CvLabel cvLargestBlob(const CvBlobs &blobs) + { + CvLabel label=0; + unsigned int maxArea=0; + + for (CvBlobs::const_iterator it=blobs.begin();it!=blobs.end();++it) + { + CvBlob *blob=(*it).second; + + if (blob->area > maxArea) + { + label=blob->label; + maxArea=blob->area; + } + } + + return label; + } + + void cvFilterByArea(CvBlobs &blobs, unsigned int minArea, unsigned int maxArea) + { + CvBlobs::iterator it=blobs.begin(); + while(it!=blobs.end()) + { + CvBlob *blob=(*it).second; + if ((blob->areaarea>maxArea)) + { + cvReleaseBlob(blob); + + CvBlobs::iterator tmp=it; + ++it; + blobs.erase(tmp); + } + else + ++it; + } + } + + void cvFilterByLabel(CvBlobs &blobs, CvLabel label) + { + CvBlobs::iterator it=blobs.begin(); + while(it!=blobs.end()) + { + CvBlob *blob=(*it).second; + if (blob->label!=label) + { + delete blob; + CvBlobs::iterator tmp=it; + ++it; + blobs.erase(tmp); + } + else + ++it; + } + } + + /*void cvCentralMoments(CvBlob *blob, const IplImage *img) + { + CV_FUNCNAME("cvCentralMoments"); + __CV_BEGIN__; + if (!blob->centralMoments) + { + CV_ASSERT(img&&(img->depth==IPL_DEPTH_LABEL)&&(img->nChannels==1)); + + //cvCentroid(blob); // Here? + + blob->u11=blob->u20=blob->u02=0.; + + // Only in the bounding box + int stepIn = img->widthStep / (img->depth / 8); + int img_width = img->width; + int img_height = img->height; + int img_offset = 0; + if(0 != img->roi) + { + img_width = img->roi->width; + img_height = img->roi->height; + img_offset = img->roi->xOffset + (img->roi->yOffset * stepIn); + } + + CvLabel *imgData=(CvLabel *)img->imageData + (blob->miny * stepIn) + img_offset; + for (unsigned int r=blob->miny; + rmaxy; + r++,imgData+=stepIn) + for (unsigned int c=blob->minx;cmaxx;c++) + if (imgData[c]==blob->label) + { + double tx=(c-blob->centroid.x); + double ty=(r-blob->centroid.y); + blob->u11+=tx*ty; + blob->u20+=tx*tx; + blob->u02+=ty*ty; + } + + blob->centralMoments = true; + } + __CV_END__; + }*/ + + void cvRenderBlob(const IplImage *imgLabel, CvBlob *blob, IplImage *imgSource, IplImage *imgDest, unsigned short mode, CvScalar const &color, double alpha) + { + CV_FUNCNAME("cvRenderBlob"); + __CV_BEGIN__; + + CV_ASSERT(imgLabel&&(imgLabel->depth==IPL_DEPTH_LABEL)&&(imgLabel->nChannels==1)); + CV_ASSERT(imgDest&&(imgDest->depth==IPL_DEPTH_8U)&&(imgDest->nChannels==3)); + + if (mode&CV_BLOB_RENDER_COLOR) + { + int stepLbl = imgLabel->widthStep/(imgLabel->depth/8); + int stepSrc = imgSource->widthStep/(imgSource->depth/8); + int stepDst = imgDest->widthStep/(imgDest->depth/8); + int imgLabel_width = imgLabel->width; + int imgLabel_height = imgLabel->height; + int imgLabel_offset = 0; + int imgSource_width = imgSource->width; + int imgSource_height = imgSource->height; + int imgSource_offset = 0; + int imgDest_width = imgDest->width; + int imgDest_height = imgDest->height; + int imgDest_offset = 0; + if(imgLabel->roi) + { + imgLabel_width = imgLabel->roi->width; + imgLabel_height = imgLabel->roi->height; + imgLabel_offset = (imgLabel->nChannels * imgLabel->roi->xOffset) + (imgLabel->roi->yOffset * stepLbl); + } + if(imgSource->roi) + { + imgSource_width = imgSource->roi->width; + imgSource_height = imgSource->roi->height; + imgSource_offset = (imgSource->nChannels * imgSource->roi->xOffset) + (imgSource->roi->yOffset * stepSrc); + } + if(imgDest->roi) + { + imgDest_width = imgDest->roi->width; + imgDest_height = imgDest->roi->height; + imgDest_offset = (imgDest->nChannels * imgDest->roi->xOffset) + (imgDest->roi->yOffset * stepDst); + } + + CvLabel *labels = (CvLabel *)imgLabel->imageData + imgLabel_offset + (blob->miny * stepLbl); + unsigned char *source = (unsigned char *)imgSource->imageData + imgSource_offset + (blob->miny * stepSrc); + unsigned char *imgData = (unsigned char *)imgDest->imageData + imgDest_offset + (blob->miny * stepDst); + + for (unsigned int r=blob->miny; rmaxy; r++, labels+=stepLbl, source+=stepSrc, imgData+=stepDst) + for (unsigned int c=blob->minx; cmaxx; c++) + { + if (labels[c]==blob->label) + { + imgData[imgDest->nChannels*c+0] = (unsigned char)((1.-alpha)*source[imgSource->nChannels*c+0]+alpha*color.val[0]); + imgData[imgDest->nChannels*c+1] = (unsigned char)((1.-alpha)*source[imgSource->nChannels*c+1]+alpha*color.val[1]); + imgData[imgDest->nChannels*c+2] = (unsigned char)((1.-alpha)*source[imgSource->nChannels*c+2]+alpha*color.val[2]); + } + } + } + + if (mode) + { + if (mode&CV_BLOB_RENDER_TO_LOG) + { + std::clog << "Blob " << blob->label << std::endl; + std::clog << " - Bounding box: (" << blob->minx << ", " << blob->miny << ") - (" << blob->maxx << ", " << blob->maxy << ")" << std::endl; + std::clog << " - Bounding box area: " << (1 + blob->maxx - blob->minx) * (1 + blob->maxy - blob->miny) << std::endl; + std::clog << " - Area: " << blob->area << std::endl; + std::clog << " - Centroid: (" << blob->centroid.x << ", " << blob->centroid.y << ")" << std::endl; + std::clog << std::endl; + } + + if (mode&CV_BLOB_RENDER_TO_STD) + { + std::cout << "Blob " << blob->label << std::endl; + std::cout << " - Bounding box: (" << blob->minx << ", " << blob->miny << ") - (" << blob->maxx << ", " << blob->maxy << ")" << std::endl; + std::cout << " - Bounding box area: " << (1 + blob->maxx - blob->minx) * (1 + blob->maxy - blob->miny) << std::endl; + std::cout << " - Area: " << blob->area << std::endl; + std::cout << " - Centroid: (" << blob->centroid.x << ", " << blob->centroid.y << ")" << std::endl; + std::cout << std::endl; + } + + if (mode&CV_BLOB_RENDER_BOUNDING_BOX) + cvRectangle(imgDest, cvPoint(blob->minx, blob->miny), cvPoint(blob->maxx-1, blob->maxy-1), CV_RGB(255., 0., 0.)); + + if (mode&CV_BLOB_RENDER_ANGLE) + { + double angle = cvAngle(blob); + + double x1,y1,x2,y2; + double lengthLine = MAX(blob->maxx-blob->minx, blob->maxy-blob->miny)/2.; + + x1=blob->centroid.x-lengthLine*cos(angle); + y1=blob->centroid.y-lengthLine*sin(angle); + x2=blob->centroid.x+lengthLine*cos(angle); + y2=blob->centroid.y+lengthLine*sin(angle); + cvLine(imgDest,cvPoint(int(x1),int(y1)),cvPoint(int(x2),int(y2)),CV_RGB(0.,255.,0.)); + } + + if (mode&CV_BLOB_RENDER_CENTROID) + { + cvLine(imgDest,cvPoint(int(blob->centroid.x)-3,int(blob->centroid.y)),cvPoint(int(blob->centroid.x)+3,int(blob->centroid.y)),CV_RGB(0.,0.,255.)); + cvLine(imgDest,cvPoint(int(blob->centroid.x),int(blob->centroid.y)-3),cvPoint(int(blob->centroid.x),int(blob->centroid.y)+3),CV_RGB(0.,0.,255.)); + } + } + + __CV_END__; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////// + // Based on http://en.wikipedia.org/wiki/HSL_and_HSV + + /// \def _HSV2RGB_(H, S, V, R, G, B) + /// \brief Color translation between HSV and RGB. +#define _HSV2RGB_(H, S, V, R, G, B) \ + { \ + double _h = H/60.; \ + int _hf = (int)floor(_h); \ + int _hi = ((int)_h)%6; \ + double _f = _h - _hf; \ + \ + double _p = V * (1. - S); \ + double _q = V * (1. - _f * S); \ + double _t = V * (1. - (1. - _f) * S); \ + \ + switch (_hi) \ + { \ + case 0: \ + R = 255.*V; G = 255.*_t; B = 255.*_p; \ + break; \ + case 1: \ + R = 255.*_q; G = 255.*V; B = 255.*_p; \ + break; \ + case 2: \ + R = 255.*_p; G = 255.*V; B = 255.*_t; \ + break; \ + case 3: \ + R = 255.*_p; G = 255.*_q; B = 255.*V; \ + break; \ + case 4: \ + R = 255.*_t; G = 255.*_p; B = 255.*V; \ + break; \ + case 5: \ + R = 255.*V; G = 255.*_p; B = 255.*_q; \ + break; \ + } \ + } + /////////////////////////////////////////////////////////////////////////////////////////////////// + + typedef std::map Palete; + + void cvRenderBlobs(const IplImage *imgLabel, CvBlobs &blobs, IplImage *imgSource, IplImage *imgDest, unsigned short mode, double alpha) + { + CV_FUNCNAME("cvRenderBlobs"); + __CV_BEGIN__; + { + + CV_ASSERT(imgLabel&&(imgLabel->depth==IPL_DEPTH_LABEL)&&(imgLabel->nChannels==1)); + CV_ASSERT(imgDest&&(imgDest->depth==IPL_DEPTH_8U)&&(imgDest->nChannels==3)); + + Palete pal; + if (mode&CV_BLOB_RENDER_COLOR) + { + + unsigned int colorCount = 0; + for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it) + { + CvLabel label = (*it).second->label; + + double r, g, b; + + _HSV2RGB_((double)((colorCount*77)%360), .5, 1., r, g, b); + colorCount++; + + pal[label] = CV_RGB(r, g, b); + } + } + + for (CvBlobs::iterator it=blobs.begin(); it!=blobs.end(); ++it) + cvRenderBlob(imgLabel, (*it).second, imgSource, imgDest, mode, pal[(*it).second->label], alpha); + + } + __CV_END__; + } + + // Returns radians + double cvAngle(CvBlob *blob) + { + CV_FUNCNAME("cvAngle"); + __CV_BEGIN__; + + return .5*atan2(2.*blob->u11,(blob->u20-blob->u02)); + + __CV_END__; + } + + void cvSaveImageBlob(const char *filename, IplImage *img, CvBlob const *blob) + { + CvRect roi = cvGetImageROI(img); + cvSetImageROItoBlob(img, blob); + cvSaveImage(filename, img); + cvSetImageROI(img, roi); + } + +} + +ostream& operator<< (ostream& output, const cvb::CvBlob& b) +{ + output << b.label << ": " << b.area << ", (" << b.centroid.x << ", " << b.centroid.y << "), [(" << b.minx << ", " << b.miny << ") - (" << b.maxx << ", " << b.maxy << ")]"; + + return output; +} diff --git a/mariusz/include/cvBlob/cvblob.h b/mariusz/include/cvBlob/cvblob.h new file mode 100644 index 0000000..c3d8e07 --- /dev/null +++ b/mariusz/include/cvBlob/cvblob.h @@ -0,0 +1,587 @@ +// Copyright (C) 2007 by Cristóbal Carnero Liñán +// grendel.ccl@gmail.com +// +// This file is part of cvBlob. +// +// cvBlob is free software: you can redistribute it and/or modify +// it under the terms of the Lesser GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Lesser GNU General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License +// along with cvBlob. If not, see . +// + +/// \file cvblob.h +/// \brief OpenCV Blob header file. + +#ifdef SWIG +%module cvblob +%{ +#include "cvblob.h" +%} +#endif + +#ifndef CVBLOB_H +#define CVBLOB_H + +#include +#include +#include +#include +#include + +#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__))) +#include +#else +#include +#endif + +#ifndef __CV_BEGIN__ +#define __CV_BEGIN__ __BEGIN__ +#endif +#ifndef __CV_END__ +#define __CV_END__ __END__ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + namespace cvb + { + + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Contours + + // Chain code: + // 7 0 1 + // 6 2 + // 5 4 3 +#define CV_CHAINCODE_UP 0 ///< Up. +#define CV_CHAINCODE_UP_RIGHT 1 ///< Up and right. +#define CV_CHAINCODE_RIGHT 2 ///< Right. +#define CV_CHAINCODE_DOWN_RIGHT 3 ///< Down and right. +#define CV_CHAINCODE_DOWN 4 ///< Down. +#define CV_CHAINCODE_DOWN_LEFT 5 ///< Down and left. +#define CV_CHAINCODE_LEFT 6 ///< Left. +#define CV_CHAINCODE_UP_LEFT 7 ///< Up and left. + + /// \brief Move vectors of chain codes. + /// \see CV_CHAINCODE_UP + /// \see CV_CHAINCODE_UP_LEFT + /// \see CV_CHAINCODE_LEFT + /// \see CV_CHAINCODE_DOWN_LEFT + /// \see CV_CHAINCODE_DOWN + /// \see CV_CHAINCODE_DOWN_RIGHT + /// \see CV_CHAINCODE_RIGHT + /// \see CV_CHAINCODE_UP_RIGHT + const char cvChainCodeMoves[8][2] = { { 0, -1}, + { 1, -1}, + { 1, 0}, + { 1, 1}, + { 0, 1}, + {-1, 1}, + {-1, 0}, + {-1, -1} + }; + + /// \brief Direction. + /// \see CV_CHAINCODE_UP + /// \see CV_CHAINCODE_UP_LEFT + /// \see CV_CHAINCODE_LEFT + /// \see CV_CHAINCODE_DOWN_LEFT + /// \see CV_CHAINCODE_DOWN + /// \see CV_CHAINCODE_DOWN_RIGHT + /// \see CV_CHAINCODE_RIGHT + /// \see CV_CHAINCODE_UP_RIGHT + typedef unsigned char CvChainCode; + + /// \brief Chain code. + /// \see CvChainCode + typedef std::list CvChainCodes; + + /// \brief Chain code contour. + /// \see CvChainCodes + struct CvContourChainCode + { + CvPoint startingPoint; ///< Point where contour begin. + CvChainCodes chainCode; ///< Polygon description based on chain codes. + }; + + typedef std::list CvContoursChainCode; ///< List of contours (chain codes type). + + /// \brief Polygon based contour. + typedef std::vector CvContourPolygon; + + /// \fn void cvRenderContourChainCode(CvContourChainCode const *contour, IplImage const *img, CvScalar const &color=CV_RGB(255, 255, 255)) + /// \brief Draw a contour. + /// \param contour Chain code contour. + /// \param img Image to draw on. + /// \param color Color to draw (default, white). + /// \see CvContourChainCode + void cvRenderContourChainCode(CvContourChainCode const *contour, IplImage const *img, CvScalar const &color=CV_RGB(255, 255, 255)); + + /// \fn CvContourPolygon *cvConvertChainCodesToPolygon(CvContourChainCode const *cc) + /// \brief Convert a chain code contour to a polygon. + /// \param cc Chain code contour. + /// \return A polygon. + /// \see CvContourChainCode + /// \see CvContourPolygon + CvContourPolygon *cvConvertChainCodesToPolygon(CvContourChainCode const *cc); + + /// \fn void cvRenderContourPolygon(CvContourPolygon const *contour, IplImage *img, CvScalar const &color=CV_RGB(255, 255, 255)) + /// \brief Draw a polygon. + /// \param contour Polygon contour. + /// \param img Image to draw on. + /// \param color Color to draw (default, white). + /// \see CvContourPolygon + void cvRenderContourPolygon(CvContourPolygon const *contour, IplImage *img, CvScalar const &color=CV_RGB(255, 255, 255)); + + /// \fn double cvContourPolygonArea(CvContourPolygon const *p) + /// \brief Calculates area of a polygonal contour. + /// \param p Contour (polygon type). + /// \return Area of the contour. + double cvContourPolygonArea(CvContourPolygon const *p); + + /// \fn double cvContourChainCodePerimeter(CvContourChainCode const *c) + /// \brief Calculates perimeter of a chain code contour. + /// \param c Contour (chain code type). + /// \return Perimeter of the contour. + double cvContourChainCodePerimeter(CvContourChainCode const *c); + + /// \fn double cvContourPolygonPerimeter(CvContourPolygon const *p) + /// \brief Calculates perimeter of a polygonal contour. + /// \param p Contour (polygon type). + /// \return Perimeter of the contour. + double cvContourPolygonPerimeter(CvContourPolygon const *p); + + /// \fn double cvContourPolygonCircularity(const CvContourPolygon *p) + /// \brief Calculates the circularity of a polygon (compactness measure). + /// \param p Contour (polygon type). + /// \return Circularity: a non-negative value, where 0 correspond with a circumference. + double cvContourPolygonCircularity(const CvContourPolygon *p); + + /// \fn CvContourPolygon *cvSimplifyPolygon(CvContourPolygon const *p, double const delta=1.) + /// \brief Simplify a polygon reducing the number of vertex according the distance "delta". + /// Uses a version of the Ramer-Douglas-Peucker algorithm (http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm). + /// \param p Contour (polygon type). + /// \param delta Minimun distance. + /// \return A simplify version of the original polygon. + CvContourPolygon *cvSimplifyPolygon(CvContourPolygon const *p, double const delta=1.); + + /// \fn CvContourPolygon *cvPolygonContourConvexHull(CvContourPolygon const *p) + /// \brief Calculates convex hull of a contour. + /// Uses the Melkman Algorithm. Code based on the version in http://w3.impa.br/~rdcastan/Cgeometry/. + /// \param p Contour (polygon type). + /// \return Convex hull. + CvContourPolygon *cvPolygonContourConvexHull(CvContourPolygon const *p); + + /// \fn void cvWriteContourPolygonCSV(const CvContourPolygon& p, const std::string& filename) + /// \brief Write a contour to a CSV (Comma-separated values) file. + /// \param p Polygon contour. + /// \param filename File name. + void cvWriteContourPolygonCSV(const CvContourPolygon& p, const std::string& filename); + + /// \fn void cvWriteContourPolygonSVG(const CvContourPolygon& p, const std::string& filename, const CvScalar& stroke=cvScalar(0,0,0), const CvScalar& fill=cvScalar(255,255,255)) + /// \brief Write a contour to a SVG file (http://en.wikipedia.org/wiki/Scalable_Vector_Graphics). + /// \param p Polygon contour. + /// \param filename File name. + /// \param stroke Stroke color (black by default). + /// \param fill Fill color (white by default). + void cvWriteContourPolygonSVG(const CvContourPolygon& p, const std::string& filename, const CvScalar& stroke=cvScalar(0,0,0), const CvScalar& fill=cvScalar(255,255,255)); + + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Blobs + + /// \brief Type of label. + /// \see IPL_DEPTH_LABEL + typedef unsigned int CvLabel; + //typedef unsigned char CvLabel; + + /// \def IPL_DEPTH_LABEL + /// \brief Size of a label in bits. + /// \see CvLabel +#define IPL_DEPTH_LABEL (sizeof(cvb::CvLabel)*8) + + /// \def CV_BLOB_MAX_LABEL + /// \brief Max label number. + /// \see CvLabel. +#define CV_BLOB_MAX_LABEL std::numeric_limits::max() + + /// \brief Type of identification numbers. + typedef unsigned int CvID; + + /// \brief Struct that contain information about one blob. + struct CvBlob + { + CvLabel label; ///< Label assigned to the blob. + + union + { + unsigned int area; ///< Area (moment 00). + unsigned int m00; ///< Moment 00 (area). + }; + + unsigned int minx; ///< X min. + unsigned int maxx; ///< X max. + unsigned int miny; ///< Y min. + unsigned int maxy; ///< y max. + + CvPoint2D64f centroid; ///< Centroid. + + double m10; ///< Moment 10. + double m01; ///< Moment 01. + double m11; ///< Moment 11. + double m20; ///< Moment 20. + double m02; ///< Moment 02. + + double u11; ///< Central moment 11. + double u20; ///< Central moment 20. + double u02; ///< Central moment 02. + + double n11; ///< Normalized central moment 11. + double n20; ///< Normalized central moment 20. + double n02; ///< Normalized central moment 02. + + double p1; ///< Hu moment 1. + double p2; ///< Hu moment 2. + + CvContourChainCode contour; ///< Contour. + CvContoursChainCode internalContours; ///< Internal contours. + }; + + /// \var typedef std::map CvBlobs + /// \brief List of blobs. + /// A map is used to access each blob from its label number. + /// \see CvLabel + /// \see CvBlob + typedef std::map CvBlobs; + + /// \var typedef std::pair CvLabelBlob + /// \brief Pair (label, blob). + /// \see CvLabel + /// \see CvBlob + typedef std::pair CvLabelBlob; + + /// \fn unsigned int cvLabel (IplImage const *img, IplImage *imgOut, CvBlobs &blobs); + /// \brief Label the connected parts of a binary image. + /// Algorithm based on paper "A linear-time component-labeling algorithm using contour tracing technique" of Fu Chang, Chun-Jen Chen and Chi-Jen Lu. + /// \param img Input binary image (depth=IPL_DEPTH_8U and num. channels=1). + /// \param imgOut Output image (depth=IPL_DEPTH_LABEL and num. channels=1). + /// \param blobs List of blobs. + /// \return Number of pixels that has been labeled. + unsigned int cvLabel (IplImage const *img, IplImage *imgOut, CvBlobs &blobs); + + //IplImage *cvFilterLabel(IplImage *imgIn, CvLabel label); + + /// \fn void cvFilterLabels(IplImage *imgIn, IplImage *imgOut, const CvBlobs &blobs) + /// \brief Draw a binary image with the blobs that have been given. + /// \param imgIn Input image (depth=IPL_DEPTH_LABEL and num. channels=1). + /// \param imgOut Output binary image (depth=IPL_DEPTH_8U and num. channels=1). + /// \param blobs List of blobs to be drawn. + /// \see cvLabel + void cvFilterLabels(IplImage *imgIn, IplImage *imgOut, const CvBlobs &blobs); + + /// \fn CvLabel cvGetLabel(IplImage const *img, unsigned int x, unsigned int y) + /// \brief Get the label value from a labeled image. + /// \param img Label image. + /// \param x X coordenate. + /// \param y Y coordenate. + /// \return Label value. + /// \see CvLabel + CvLabel cvGetLabel(IplImage const *img, unsigned int x, unsigned int y); + + /// \fn inline void cvReleaseBlob(CvBlob *blob) + /// \brief Clear a blob structure. + /// \param blob Blob. + /// \see CvBlob + inline void cvReleaseBlob(CvBlob *blob) + { + if (blob) + { + for (CvContoursChainCode::iterator jt=blob->internalContours.begin(); jt!=blob->internalContours.end(); ++jt) + { + CvContourChainCode *contour = *jt; + if (contour) + delete contour; + } + blob->internalContours.clear(); + + delete blob; + } + } + + /// \fn inline void cvReleaseBlobs(CvBlobs &blobs) + /// \brief Clear blobs structure. + /// \param blobs List of blobs. + /// \see CvBlobs + inline void cvReleaseBlobs(CvBlobs &blobs) + { + for (CvBlobs::iterator it=blobs.begin(); it!=blobs.end(); ++it) + { + cvReleaseBlob((*it).second); + } + blobs.clear(); + } + + /// \fn CvLabel cvLargestBlob(const CvBlobs &blobs) + /// \brief Find largest blob (biggest area). + /// \param blobs List of blobs. + /// \return Label of the largest blob or 0 if there are no blobs. + /// \see cvLabel + CvLabel cvLargestBlob(const CvBlobs &blobs); + + inline CvLabel cvGreaterBlob(const CvBlobs &blobs) + { + return cvLargestBlob(blobs); + } + + /// \fn void cvFilterByArea(CvBlobs &blobs, unsigned int minArea, unsigned int maxArea) + /// \brief Filter blobs by area. + /// Those blobs whose areas are not in range will be erased from the input list of blobs. + /// \param blobs List of blobs. + /// \param minArea Minimun area. + /// \param maxArea Maximun area. + void cvFilterByArea(CvBlobs &blobs, unsigned int minArea, unsigned int maxArea); + + /// \fn void cvFilterByLabel(CvBlobs &blobs, CvLabel label) + /// \brief Filter blobs by label. + /// Delete all blobs except those with label l. + /// \param blobs List of blobs. + /// \param label Label to leave. + void cvFilterByLabel(CvBlobs &blobs, CvLabel label); + + /// \fn inline CvPoint2D64f cvCentroid(CvBlob *blob) + /// \brief Calculates centroid. + /// Centroid will be returned and stored in the blob structure. + /// \param blob Blob whose centroid will be calculated. + /// \return Centroid. + /// \see CvBlob + inline CvPoint2D64f cvCentroid(CvBlob *blob) + { + return blob->centroid=cvPoint2D64f(blob->m10/blob->area, blob->m01/blob->area); + } + + /// \fn double cvAngle(CvBlob *blob) + /// \brief Calculates angle orientation of a blob. + /// \param blob Blob. + /// \return Angle orientation in radians. + /// \see CvBlob + double cvAngle(CvBlob *blob); + + /// \fn cvSaveImageBlob(const char *filename, IplImage *img, CvBlob const *blob) + /// \brief Save the image of a blob to a file. + /// The function uses an image (that can be the original pre-processed image or a processed one, or even the result of cvRenderBlobs, for example) and a blob structure. + /// Then the function saves a copy of the part of the image where the blob is. + /// \param filename Name of the file. + /// \param img Image. + /// \param blob Blob. + /// \see CvBlob + /// \see cvRenderBlob + void cvSaveImageBlob(const char *filename, IplImage *img, CvBlob const *blob); + +#define CV_BLOB_RENDER_COLOR 0x0001 ///< Render each blog with a different color. \see cvRenderBlobs +#define CV_BLOB_RENDER_CENTROID 0x0002 ///< Render centroid. \see cvRenderBlobs +#define CV_BLOB_RENDER_BOUNDING_BOX 0x0004 ///< Render bounding box. \see cvRenderBlobs +#define CV_BLOB_RENDER_ANGLE 0x0008 ///< Render angle. \see cvRenderBlobs +#define CV_BLOB_RENDER_TO_LOG 0x0010 ///< Print blob data to log out. \see cvRenderBlobs +#define CV_BLOB_RENDER_TO_STD 0x0020 ///< Print blob data to std out. \see cvRenderBlobs + + /// \fn void cvRenderBlob(const IplImage *imgLabel, CvBlob *blob, IplImage *imgSource, IplImage *imgDest, unsigned short mode=0x000f, CvScalar const &color=CV_RGB(255, 255, 255), double alpha=1.) + /// \brief Draws or prints information about a blob. + /// \param imgLabel Label image (depth=IPL_DEPTH_LABEL and num. channels=1). + /// \param blob Blob. + /// \param imgSource Input image (depth=IPL_DEPTH_8U and num. channels=3). + /// \param imgDest Output image (depth=IPL_DEPTH_8U and num. channels=3). + /// \param mode Render mode. By default is CV_BLOB_RENDER_COLOR|CV_BLOB_RENDER_CENTROID|CV_BLOB_RENDER_BOUNDING_BOX|CV_BLOB_RENDER_ANGLE. + /// \param color Color to render (if CV_BLOB_RENDER_COLOR is used). + /// \param alpha If mode CV_BLOB_RENDER_COLOR is used. 1.0 indicates opaque and 0.0 translucent (1.0 by default). + /// \see CV_BLOB_RENDER_COLOR + /// \see CV_BLOB_RENDER_CENTROID + /// \see CV_BLOB_RENDER_BOUNDING_BOX + /// \see CV_BLOB_RENDER_ANGLE + /// \see CV_BLOB_RENDER_TO_LOG + /// \see CV_BLOB_RENDER_TO_STD + void cvRenderBlob(const IplImage *imgLabel, CvBlob *blob, IplImage *imgSource, IplImage *imgDest, unsigned short mode=0x000f, CvScalar const &color=CV_RGB(255, 255, 255), double alpha=1.); + + /// \fn void cvRenderBlobs(const IplImage *imgLabel, CvBlobs &blobs, IplImage *imgSource, IplImage *imgDest, unsigned short mode=0x000f, double alpha=1.) + /// \brief Draws or prints information about blobs. + /// \param imgLabel Label image (depth=IPL_DEPTH_LABEL and num. channels=1). + /// \param blobs List of blobs. + /// \param imgSource Input image (depth=IPL_DEPTH_8U and num. channels=3). + /// \param imgDest Output image (depth=IPL_DEPTH_8U and num. channels=3). + /// \param mode Render mode. By default is CV_BLOB_RENDER_COLOR|CV_BLOB_RENDER_CENTROID|CV_BLOB_RENDER_BOUNDING_BOX|CV_BLOB_RENDER_ANGLE. + /// \param alpha If mode CV_BLOB_RENDER_COLOR is used. 1.0 indicates opaque and 0.0 translucent (1.0 by default). + /// \see CV_BLOB_RENDER_COLOR + /// \see CV_BLOB_RENDER_CENTROID + /// \see CV_BLOB_RENDER_BOUNDING_BOX + /// \see CV_BLOB_RENDER_ANGLE + /// \see CV_BLOB_RENDER_TO_LOG + /// \see CV_BLOB_RENDER_TO_STD + void cvRenderBlobs(const IplImage *imgLabel, CvBlobs &blobs, IplImage *imgSource, IplImage *imgDest, unsigned short mode=0x000f, double alpha=1.); + + /// \fn void cvSetImageROItoBlob(IplImage *img, CvBlob const *blob) + /// \brief Set the ROI of an image to the bounding box of a blob. + /// \param img Image. + /// \param blob Blob. + /// \see CvBlob + inline void cvSetImageROItoBlob(IplImage *img, CvBlob const *blob) + { + cvSetImageROI(img, cvRect(blob->minx, blob->miny, blob->maxx-blob->minx, blob->maxy-blob->miny)); + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Color + + /// \fn CvScalar cvBlobMeanColor(CvBlob const *blob, IplImage const *imgLabel, IplImage const *img) + /// \brief Calculates mean color of a blob in an image. + /// \param blob Blob. + /// \param imgLabel Image of labels. + /// \param img Original image. + /// \return Average color. + CvScalar cvBlobMeanColor(CvBlob const *blob, IplImage const *imgLabel, IplImage const *img); + + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Aux + + /// \fn double cvDotProductPoints(CvPoint const &a, CvPoint const &b, CvPoint const &c) + /// \brief Dot product of the vectors ab and bc. + /// \param a First point. + /// \param b Middle point. + /// \param c Last point. + /// \return Dot product of ab and bc. + double cvDotProductPoints(CvPoint const &a, CvPoint const &b, CvPoint const &c); + + /// \fn double cvCrossProductPoints(CvPoint const &a, CvPoint const &b, CvPoint const &c) + /// \brief Cross product of the vectors ab and bc. + /// \param a Point. + /// \param b Point. + /// \param c Point. + /// \return Cross product of ab and bc. + double cvCrossProductPoints(CvPoint const &a, CvPoint const &b, CvPoint const &c); + + /// \fn double cvDistancePointPoint(CvPoint const &a, CvPoint const &b) + /// \brief Distance between two points. + /// \param a Point. + /// \param b Point. + /// \return Distance. + double cvDistancePointPoint(CvPoint const &a, CvPoint const &b); + + /// \fn double cvDistanceLinePoint(CvPoint const &a, CvPoint const &b, CvPoint const &c, bool isSegment=true) + /// \brief Distance between line ab and point c. + /// \param a First point of the segment. + /// \param b Second point of the segment. + /// \param c Point. + /// \param isSegment If false then the distance will be calculated from the line defined by the points a and b, to the point c. + /// \return Distance between ab and c. + double cvDistanceLinePoint(CvPoint const &a, CvPoint const &b, CvPoint const &c, bool isSegment=true); + + //////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Tracking + + /// \brief Struct that contain information about one track. + /// \see CvID + /// \see CvLabel + struct CvTrack + { + CvID id; ///< Track identification number. + + CvLabel label; ///< Label assigned to the blob related to this track. + + unsigned int minx; ///< X min. + unsigned int maxx; ///< X max. + unsigned int miny; ///< Y min. + unsigned int maxy; ///< y max. + + CvPoint2D64f centroid; ///< Centroid. + + unsigned int lifetime; ///< Indicates how much frames the object has been in scene. + unsigned int active; ///< Indicates number of frames that has been active from last inactive period. + unsigned int inactive; ///< Indicates number of frames that has been missing. + }; + + /// \var typedef std::map CvTracks + /// \brief List of tracks. + /// \see CvID + /// \see CvTrack + typedef std::map CvTracks; + + /// \var typedef std::pair CvIDTrack + /// \brief Pair (identification number, track). + /// \see CvID + /// \see CvTrack + typedef std::pair CvIDTrack; + + /// \fn inline void cvReleaseTracks(CvTracks &tracks) + /// \brief Clear tracks structure. + /// \param tracks List of tracks. + /// \see CvTracks + inline void cvReleaseTracks(CvTracks &tracks) + { + for (CvTracks::iterator it=tracks.begin(); it!=tracks.end(); it++) + { + CvTrack *track = (*it).second; + if (track) delete track; + } + + tracks.clear(); + } + + /// \fn cvUpdateTracks(CvBlobs const &b, CvTracks &t, const double thDistance, const unsigned int thInactive, const unsigned int thActive=0) + /// \brief Updates list of tracks based on current blobs. + /// Tracking based on: + /// A. Senior, A. Hampapur, Y-L Tian, L. Brown, S. Pankanti, R. Bolle. Appearance Models for + /// Occlusion Handling. Second International workshop on Performance Evaluation of Tracking and + /// Surveillance Systems & CVPR'01. December, 2001. + /// (http://www.research.ibm.com/peoplevision/PETS2001.pdf) + /// \param b List of blobs. + /// \param t List of tracks. + /// \param thDistance Max distance to determine when a track and a blob match. + /// \param thInactive Max number of frames a track can be inactive. + /// \param thActive If a track becomes inactive but it has been active less than thActive frames, the track will be deleted. + /// \see CvBlobs + /// \see Tracks + void cvUpdateTracks(CvBlobs const &b, CvTracks &t, const double thDistance, const unsigned int thInactive, const unsigned int thActive=0); + +#define CV_TRACK_RENDER_ID 0x0001 ///< Print the ID of each track in the image. \see cvRenderTracks +#define CV_TRACK_RENDER_BOUNDING_BOX 0x0002 ///< Draw bounding box of each track in the image. \see cvRenderTracks +#define CV_TRACK_RENDER_TO_LOG 0x0010 ///< Print track info to log out. \see cvRenderTracks +#define CV_TRACK_RENDER_TO_STD 0x0020 ///< Print track info to log out. \see cvRenderTracks + + /// \fn void cvRenderTracks(CvTracks const tracks, IplImage *imgSource, IplImage *imgDest, unsigned short mode=0x00ff, CvFont *font=NULL) + /// \brief Prints tracks information. + /// \param tracks List of tracks. + /// \param imgSource Input image (depth=IPL_DEPTH_8U and num. channels=3). + /// \param imgDest Output image (depth=IPL_DEPTH_8U and num. channels=3). + /// \param mode Render mode. By default is CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX. + /// \param font OpenCV font for print on the image. + /// \see CV_TRACK_RENDER_ID + /// \see CV_TRACK_RENDER_BOUNDING_BOX + /// \see CV_TRACK_RENDER_TO_LOG + /// \see CV_TRACK_RENDER_TO_STD + void cvRenderTracks(CvTracks const tracks, IplImage *imgSource, IplImage *imgDest, unsigned short mode=0x000f, CvFont *font=NULL); + } +#ifdef __cplusplus +} +#endif + +/// \fn std::ostream& operator<< (std::ostream& output, const cvb::CvBlob& b) +/// \brief Overload operator "<<" for printing blob structure. +/// \return Stream. +std::ostream& operator<< (std::ostream& output, const cvb::CvBlob& b); + +/// \fn std::ostream& operator<< (std::ostream& output, const cvb::CvContourPolygon& p) +/// \brief Overload operator "<<" for printing polygons in CSV format. +/// \return Stream. +std::ostream& operator<< (std::ostream& output, const cvb::CvContourPolygon& p); + +/// \fn std::ostream& operator<< (std::ostream& output, const cvb::CvTrack& t) +/// \brief Overload operator "<<" for printing track structure. +/// \return Stream. +std::ostream& operator<< (std::ostream& output, const cvb::CvTrack& t); +#endif diff --git a/mariusz/include/cvBlob/cvcolor.cpp b/mariusz/include/cvBlob/cvcolor.cpp new file mode 100644 index 0000000..fda20d4 --- /dev/null +++ b/mariusz/include/cvBlob/cvcolor.cpp @@ -0,0 +1,104 @@ +// Copyright (C) 2007 by Cristóbal Carnero Liñán +// grendel.ccl@gmail.com +// +// This file is part of cvBlob. +// +// cvBlob is free software: you can redistribute it and/or modify +// it under the terms of the Lesser GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// cvBlob is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Lesser GNU General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License +// along with cvBlob. If not, see . +// + +#include +#include +using namespace std; + +#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__))) +#include +#else +#include +#endif + +#include "cvblob.h" + +namespace cvb +{ + + CvScalar cvBlobMeanColor(CvBlob const *blob, IplImage const *imgLabel, IplImage const *img) + { + CV_FUNCNAME("cvBlobMeanColor"); + __CV_BEGIN__; + { + CV_ASSERT(imgLabel&&(imgLabel->depth==IPL_DEPTH_LABEL)&&(imgLabel->nChannels==1)); + CV_ASSERT(img&&(img->depth==IPL_DEPTH_8U)&&(img->nChannels==3)); + + int stepLbl = imgLabel->widthStep/(imgLabel->depth/8); + int stepImg = img->widthStep/(img->depth/8); + int imgLabel_width = imgLabel->width; + int imgLabel_height = imgLabel->height; + int imgLabel_offset = 0; + int img_width = img->width; + int img_height = img->height; + int img_offset = 0; + if(imgLabel->roi) + { + imgLabel_width = imgLabel->roi->width; + imgLabel_height = imgLabel->roi->height; + imgLabel_offset = (imgLabel->nChannels * imgLabel->roi->xOffset) + (imgLabel->roi->yOffset * stepLbl); + } + if(img->roi) + { + img_width = img->roi->width; + img_height = img->roi->height; + img_offset = (img->nChannels * img->roi->xOffset) + (img->roi->yOffset * stepImg); + } + + CvLabel *labels = (CvLabel *)imgLabel->imageData + imgLabel_offset; + unsigned char *imgData = (unsigned char *)img->imageData + img_offset; + + double mb = 0; + double mg = 0; + double mr = 0; + double pixels = (double)blob->area; + + for (unsigned int r=0; r<(unsigned int)imgLabel_height; r++, labels+=stepLbl, imgData+=stepImg) + for (unsigned int c=0; c<(unsigned int)imgLabel_width; c++) + { + if (labels[c]==blob->label) + { + mb += ((double)imgData[img->nChannels*c+0])/pixels; // B + mg += ((double)imgData[img->nChannels*c+1])/pixels; // G + mr += ((double)imgData[img->nChannels*c+2])/pixels; // R + } + } + + /*double mb = 0; + double mg = 0; + double mr = 0; + double pixels = (double)blob->area; + for (unsigned int y=0; yheight; y++) + for (unsigned int x=0; xwidth; x++) + { + if (cvGetLabel(imgLabel, x, y)==blob->label) + { + CvScalar color = cvGet2D(img, y, x); + mb += color.val[0]/pixels; + mg += color.val[1]/pixels; + mr += color.val[2]/pixels; + } + }*/ + + return cvScalar(mr, mg, mb); + } + __CV_END__; + } + +} diff --git a/mariusz/include/cvBlob/cvcontour.cpp b/mariusz/include/cvBlob/cvcontour.cpp new file mode 100644 index 0000000..71b514d --- /dev/null +++ b/mariusz/include/cvBlob/cvcontour.cpp @@ -0,0 +1,436 @@ +// Copyright (C) 2007 by Cristóbal Carnero Liñán +// grendel.ccl@gmail.com +// +// This file is part of cvBlob. +// +// cvBlob is free software: you can redistribute it and/or modify +// it under the terms of the Lesser GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// cvBlob is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Lesser GNU General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License +// along with cvBlob. If not, see . +// + +#include + +#define _USE_MATH_DEFINES +#include + +#include +#include +#include +#include +using namespace std; + +#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__))) +#include +#else +#include +#endif + +#include "cvblob.h" + +#ifdef M_PI +const double pi = M_PI; +#else +const double pi = std::atan(1.)*4.; +#endif // M_PI + +namespace cvb +{ + + void cvRenderContourChainCode(CvContourChainCode const *contour, IplImage const *img, CvScalar const &color) + { + CV_FUNCNAME("cvRenderContourChainCode"); + __CV_BEGIN__; + { + CV_ASSERT(img&&(img->depth==IPL_DEPTH_8U)&&(img->nChannels==3)); + + int stepDst = img->widthStep/(img->depth/8); + int img_width = img->width; + int img_height = img->height; + int img_offset = 0; + + if(img->roi) + { + img_width = img->roi->width; + img_height = img->roi->height; + img_offset = (img->nChannels * img->roi->xOffset) + (img->roi->yOffset * stepDst); + } + + unsigned char *imgData = (unsigned char *)img->imageData + img_offset; + + unsigned int x = contour->startingPoint.x; + unsigned int y = contour->startingPoint.y; + + for (CvChainCodes::const_iterator it=contour->chainCode.begin(); it!=contour->chainCode.end(); ++it) + { + imgData[img->nChannels*x+img->widthStep*y+0] = (unsigned char)(color.val[0]); // Blue + imgData[img->nChannels*x+img->widthStep*y+1] = (unsigned char)(color.val[1]); // Green + imgData[img->nChannels*x+img->widthStep*y+2] = (unsigned char)(color.val[2]); // Red + + x += cvChainCodeMoves[*it][0]; + y += cvChainCodeMoves[*it][1]; + } + } + __CV_END__; + } + + CvContourPolygon *cvConvertChainCodesToPolygon(CvContourChainCode const *cc) + { + CV_FUNCNAME("cvConvertChainCodesToPolygon"); + __CV_BEGIN__; + { + CV_ASSERT(cc!=NULL); + + CvContourPolygon *contour = new CvContourPolygon; + + unsigned int x = cc->startingPoint.x; + unsigned int y = cc->startingPoint.y; + contour->push_back(cvPoint(x, y)); + + if (cc->chainCode.size()) + { + CvChainCodes::const_iterator it=cc->chainCode.begin(); + CvChainCode lastCode = *it; + + x += cvChainCodeMoves[*it][0]; + y += cvChainCodeMoves[*it][1]; + + ++it; + + for (; it!=cc->chainCode.end(); ++it) + { + if (lastCode!=*it) + { + contour->push_back(cvPoint(x, y)); + lastCode=*it; + } + + x += cvChainCodeMoves[*it][0]; + y += cvChainCodeMoves[*it][1]; + } + } + + return contour; + } + __CV_END__; + } + + void cvRenderContourPolygon(CvContourPolygon const *contour, IplImage *img, CvScalar const &color) + { + CV_FUNCNAME("cvRenderContourPolygon"); + __CV_BEGIN__; + { + CV_ASSERT(img&&(img->depth==IPL_DEPTH_8U)&&(img->nChannels==3)); + + CvContourPolygon::const_iterator it=contour->begin(); + + if (it!=contour->end()) + { + unsigned int fx, x, fy, y; + fx = x = it->x; + fy = y = it->y; + + for (; it!=contour->end(); ++it) + { + cvLine(img, cvPoint(x, y), cvPoint(it->x, it->y), color, 1); + x = it->x; + y = it->y; + } + + cvLine(img, cvPoint(x, y), cvPoint(fx, fy), color, 1); + } + } + __CV_END__; + } + + double cvContourPolygonArea(CvContourPolygon const *p) + { + CV_FUNCNAME("cvContourPolygonArea"); + __CV_BEGIN__; + { + CV_ASSERT(p!=NULL); + + if (p->size()<=2) + return 1.; + + CvContourPolygon::const_iterator it=p->begin(); + CvPoint lastPoint = p->back(); + + double a = 0.; + + for (; it!=p->end(); ++it) + { + a += lastPoint.x*it->y - lastPoint.y*it->x; + lastPoint = *it; + } + + return a*0.5; + } + __CV_END__; + } + + double cvContourChainCodePerimeter(CvContourChainCode const *c) + { + CV_FUNCNAME("cvContourChainCodePerimeter"); + __CV_BEGIN__; + { + CV_ASSERT(c!=NULL); + + double perimeter = 0.; + + for(CvChainCodes::const_iterator it=c->chainCode.begin(); it!=c->chainCode.end(); ++it) + { + if ((*it)%2) + perimeter+=sqrt(1.+1.); + else + perimeter+=1.; + } + + return perimeter; + } + __CV_END__; + } + + double cvContourPolygonPerimeter(CvContourPolygon const *p) + { + CV_FUNCNAME("cvContourPolygonPerimeter"); + __CV_BEGIN__; + { + CV_ASSERT(p!=NULL); + + double perimeter = cvDistancePointPoint((*p)[p->size()-1], (*p)[0]); + + for (unsigned int i=0; isize()-1; i++) + perimeter+=cvDistancePointPoint((*p)[i], (*p)[i+1]); + + return perimeter; + } + __CV_END__; + } + + double cvContourPolygonCircularity(const CvContourPolygon *p) + { + CV_FUNCNAME("cvContourPolygonCircularity"); + __CV_BEGIN__; + { + CV_ASSERT(p!=NULL); + + double l = cvContourPolygonPerimeter(p); + double c = (l*l/cvContourPolygonArea(p)) - 4.*pi; + + if (c>=0.) + return c; + else // This could happen if the blob it's only a pixel: the perimeter will be 0. Another solution would be to force "cvContourPolygonPerimeter" to be 1 or greater. + return 0.; + } + __CV_END__; + } + + void simplifyPolygonRecursive(CvContourPolygon const *p, int const i1, int const i2, bool *pnUseFlag, double const delta) + { + CV_FUNCNAME("cvSimplifyPolygonRecursive"); + __CV_BEGIN__; + { + int endIndex = (i2<0)?p->size():i2; + + if (abs(i1-endIndex)<=1) + return; + + CvPoint firstPoint = (*p)[i1]; + CvPoint lastPoint = (i2<0)?p->front():(*p)[i2]; + + double furtherDistance=0.; + int furtherIndex=0; + + for (int i=i1+1; i=delta)&&(d>furtherDistance)) + { + furtherDistance=d; + furtherIndex=i; + } + } + + if (furtherIndex) + { + pnUseFlag[furtherIndex]=true; + + simplifyPolygonRecursive(p, i1, furtherIndex, pnUseFlag, delta); + simplifyPolygonRecursive(p, furtherIndex, i2, pnUseFlag, delta); + } + } + __CV_END__; + } + + CvContourPolygon *cvSimplifyPolygon(CvContourPolygon const *p, double const delta) + { + CV_FUNCNAME("cvSimplifyPolygon"); + __CV_BEGIN__; + { + CV_ASSERT(p!=NULL); + + double furtherDistance=0.; + unsigned int furtherIndex=0; + + CvContourPolygon::const_iterator it=p->begin(); + ++it; + for (unsigned int i=1; it!=p->end(); ++it, i++) + { + double d = cvDistancePointPoint(*it, p->front()); + + if (d>furtherDistance) + { + furtherDistance = d; + furtherIndex = i; + } + } + + if (furtherDistancepush_back(p->front()); + return result; + } + + bool *pnUseFlag = new bool[p->size()]; + for (unsigned int i=1; isize(); i++) pnUseFlag[i] = false; + + pnUseFlag[0] = pnUseFlag[furtherIndex] = true; + + simplifyPolygonRecursive(p, 0, furtherIndex, pnUseFlag, delta); + simplifyPolygonRecursive(p, furtherIndex, -1, pnUseFlag, delta); + + CvContourPolygon *result = new CvContourPolygon; + + for (unsigned int i=0; isize(); i++) + if (pnUseFlag[i]) + result->push_back((*p)[i]); + + delete[] pnUseFlag; + + return result; + } + __CV_END__; + } + + CvContourPolygon *cvPolygonContourConvexHull(CvContourPolygon const *p) + { + CV_FUNCNAME("cvPolygonContourConvexHull"); + __CV_BEGIN__; + { + CV_ASSERT(p!=NULL); + + if (p->size()<=3) + { + return new CvContourPolygon(p->begin(), p->end()); + } + + deque dq; + + if (cvCrossProductPoints((*p)[0], (*p)[1], (*p)[2])>0) + { + dq.push_back((*p)[0]); + dq.push_back((*p)[1]); + } + else + { + dq.push_back((*p)[1]); + dq.push_back((*p)[0]); + } + + dq.push_back((*p)[2]); + dq.push_front((*p)[2]); + + for (unsigned int i=3; isize(); i++) + { + int s = dq.size(); + + if ((cvCrossProductPoints((*p)[i], dq.at(0), dq.at(1))>=0) && (cvCrossProductPoints(dq.at(s-2), dq.at(s-1), (*p)[i])>=0)) + continue; // TODO Optimize. + + while (cvCrossProductPoints(dq.at(s-2), dq.at(s-1), (*p)[i])<0) + { + dq.pop_back(); + s = dq.size(); + } + + dq.push_back((*p)[i]); + + while (cvCrossProductPoints((*p)[i], dq.at(0), dq.at(1))<0) + dq.pop_front(); + + dq.push_front((*p)[i]); + } + + return new CvContourPolygon(dq.begin(), dq.end()); + } + __CV_END__; + } + + void cvWriteContourPolygonCSV(const CvContourPolygon& p, const string& filename) + { + ofstream f; + f.open(filename.c_str()); + + f << p << endl; + + f.close(); + } + + void cvWriteContourPolygonSVG(const CvContourPolygon& p, const string& filename, const CvScalar& stroke, const CvScalar& fill) + { + int minx=INT_MAX; + int miny=INT_MAX; + int maxx=INT_MIN; + int maxy=INT_MIN; + + stringstream buffer(""); + + for (CvContourPolygon::const_iterator it=p.begin(); it!=p.end(); ++it) + { + if (it->x>maxx) + maxx = it->x; + if (it->xx; + + if (it->y>maxy) + maxy = it->y; + if (it->yy; + + buffer << it->x << "," << it->y << " "; + } + + ofstream f; + f.open(filename.c_str()); + + f << "" << endl; + f << "" << endl; + f << "" << endl; + + f << "" << endl; + + f << "" << endl; + + f.close(); + } + +} + +ostream& operator<< (ostream& output, const cvb::CvContourPolygon& p) +{ + for (cvb::CvContourPolygon::const_iterator it=p.begin(); it!=p.end(); ++it) + output << it->x << ", " << it->y << endl; + + return output; +} diff --git a/mariusz/include/cvBlob/cvlabel.cpp b/mariusz/include/cvBlob/cvlabel.cpp new file mode 100644 index 0000000..61ff01d --- /dev/null +++ b/mariusz/include/cvBlob/cvlabel.cpp @@ -0,0 +1,444 @@ +// Copyright (C) 2007 by Cristóbal Carnero Liñán +// grendel.ccl@gmail.com +// +// This file is part of cvBlob. +// +// cvBlob is free software: you can redistribute it and/or modify +// it under the terms of the Lesser GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// cvBlob is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Lesser GNU General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License +// along with cvBlob. If not, see . +// + +#include +#include +using namespace std; + +#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__))) +#include +#else +#include +#endif + +#include "cvblob.h" + +namespace cvb +{ + const char movesE[4][3][4] = { { {-1, -1, 3, CV_CHAINCODE_UP_LEFT }, { 0, -1, 0, CV_CHAINCODE_UP }, { 1, -1, 0, CV_CHAINCODE_UP_RIGHT } }, + { { 1, -1, 0, CV_CHAINCODE_UP_RIGHT }, { 1, 0, 1, CV_CHAINCODE_RIGHT}, { 1, 1, 1, CV_CHAINCODE_DOWN_RIGHT } }, + { { 1, 1, 1, CV_CHAINCODE_DOWN_RIGHT}, { 0, 1, 2, CV_CHAINCODE_DOWN }, {-1, 1, 2, CV_CHAINCODE_DOWN_LEFT } }, + { {-1, 1, 2, CV_CHAINCODE_DOWN_LEFT }, {-1, 0, 3, CV_CHAINCODE_LEFT }, {-1, -1, 3, CV_CHAINCODE_UP_LEFT } } + }; + + const char movesI[4][3][4] = { { { 1, -1, 3, CV_CHAINCODE_UP_RIGHT }, { 0, -1, 0, CV_CHAINCODE_UP }, {-1, -1, 0, CV_CHAINCODE_UP_LEFT } }, + { {-1, -1, 0, CV_CHAINCODE_UP_LEFT }, {-1, 0, 1, CV_CHAINCODE_LEFT }, {-1, 1, 1, CV_CHAINCODE_DOWN_LEFT } }, + { {-1, 1, 1, CV_CHAINCODE_DOWN_LEFT }, { 0, 1, 2, CV_CHAINCODE_DOWN }, { 1, 1, 2, CV_CHAINCODE_DOWN_RIGHT } }, + { { 1, 1, 2, CV_CHAINCODE_DOWN_RIGHT }, { 1, 0, 3, CV_CHAINCODE_RIGHT}, { 1, -1, 3, CV_CHAINCODE_UP_RIGHT } } + }; + + + unsigned int cvLabel (IplImage const *img, IplImage *imgOut, CvBlobs &blobs) + { + CV_FUNCNAME("cvLabel"); + __CV_BEGIN__; + { + CV_ASSERT(img&&(img->depth==IPL_DEPTH_8U)&&(img->nChannels==1)); + CV_ASSERT(imgOut&&(imgOut->depth==IPL_DEPTH_LABEL)&&(imgOut->nChannels==1)); + + unsigned int numPixels=0; + + cvSetZero(imgOut); + + CvLabel label=0; + cvReleaseBlobs(blobs); + + unsigned int stepIn = img->widthStep / (img->depth / 8); + unsigned int stepOut = imgOut->widthStep / (imgOut->depth / 8); + unsigned int imgIn_width = img->width; + unsigned int imgIn_height = img->height; + unsigned int imgIn_offset = 0; + unsigned int imgOut_width = imgOut->width; + unsigned int imgOut_height = imgOut->height; + unsigned int imgOut_offset = 0; + if(img->roi) + { + imgIn_width = img->roi->width; + imgIn_height = img->roi->height; + imgIn_offset = img->roi->xOffset + (img->roi->yOffset * stepIn); + } + if(imgOut->roi) + { + imgOut_width = imgOut->roi->width; + imgOut_height = imgOut->roi->height; + imgOut_offset = imgOut->roi->xOffset + (imgOut->roi->yOffset * stepOut); + } + + unsigned char *imgDataIn = (unsigned char *)img->imageData + imgIn_offset; + CvLabel *imgDataOut = (CvLabel *)imgOut->imageData + imgOut_offset; + +#define imageIn(X, Y) imgDataIn[(X) + (Y)*stepIn] +#define imageOut(X, Y) imgDataOut[(X) + (Y)*stepOut] + + CvLabel lastLabel = 0; + CvBlob *lastBlob = NULL; + + for (unsigned int y=0; y0) + imageOut(x, y-1) = CV_BLOB_MAX_LABEL; + + CvBlob *blob = new CvBlob; + blob->label = label; + blob->area = 1; + blob->minx = x; blob->maxx = x; + blob->miny = y; blob->maxy = y; + blob->m10=x; blob->m01=y; + blob->m11=x*y; + blob->m20=x*x; blob->m02=y*y; + blob->internalContours.clear(); + blobs.insert(CvLabelBlob(label,blob)); + + lastLabel = label; + lastBlob = blob; + + blob->contour.startingPoint = cvPoint(x, y); + + unsigned char direction=1; + unsigned int xx = x; + unsigned int yy = y; + + + bool contourEnd = false; + + do + { + for (unsigned int numAttempts=0; numAttempts<3; numAttempts++) + { + bool found = false; + + for (unsigned char i=0; i<3; i++) + { + int nx = xx+movesE[direction][i][0]; + int ny = yy+movesE[direction][i][1]; + if ((nx=0)&&(ny=0)) + { + if (imageIn(nx, ny)) + { + found = true; + + blob->contour.chainCode.push_back(movesE[direction][i][3]); + + xx=nx; + yy=ny; + + direction=movesE[direction][i][2]; + break; + } + else + { + imageOut(nx, ny) = CV_BLOB_MAX_LABEL; + } + } + } + + if (!found) + direction=(direction+1)%4; + else + { + if (imageOut(xx, yy) != label) + { + imageOut(xx, yy) = label; + numPixels++; + + if (xxminx) blob->minx = xx; + else if (xx>blob->maxx) blob->maxx = xx; + if (yyminy) blob->miny = yy; + else if (yy>blob->maxy) blob->maxy = yy; + + blob->area++; + blob->m10+=xx; blob->m01+=yy; + blob->m11+=xx*yy; + blob->m20+=xx*xx; blob->m02+=yy*yy; + } + + break; + } + + if (contourEnd = ((xx==x) && (yy==y) && (direction==1))) + break; + } + } + while (!contourEnd); + + } + + if ((y+1second; + lastLabel = l; + lastBlob = blob; + } + blob->area++; + blob->m10+=x; blob->m01+=y; + blob->m11+=x*y; + blob->m20+=x*x; blob->m02+=y*y; + } + else + { + l = imageOut(x, y); + + if (l==lastLabel) + blob = lastBlob; + else + { + blob = blobs.find(l)->second; + lastLabel = l; + lastBlob = blob; + } + } + + // XXX This is not necessary (I believe). I only do this for consistency. + imageOut(x, y+1) = CV_BLOB_MAX_LABEL; + + CvContourChainCode *contour = new CvContourChainCode; + contour->startingPoint = cvPoint(x, y); + + unsigned char direction = 3; + unsigned int xx = x; + unsigned int yy = y; + + do + { + for (unsigned int numAttempts=0; numAttempts<3; numAttempts++) + { + bool found = false; + + for (unsigned char i=0; i<3; i++) + { + int nx = xx+movesI[direction][i][0]; + int ny = yy+movesI[direction][i][1]; + if (imageIn(nx, ny)) + { + found = true; + + contour->chainCode.push_back(movesI[direction][i][3]); + + xx=nx; + yy=ny; + + direction=movesI[direction][i][2]; + break; + } + else + { + imageOut(nx, ny) = CV_BLOB_MAX_LABEL; + } + } + + if (!found) + direction=(direction+1)%4; + else + { + if (!imageOut(xx, yy)) + { + imageOut(xx, yy) = l; + numPixels++; + + blob->area++; + blob->m10+=xx; blob->m01+=yy; + blob->m11+=xx*yy; + blob->m20+=xx*xx; blob->m02+=yy*yy; + } + + break; + } + } + } + while (!(xx==x && yy==y)); + + blob->internalContours.push_back(contour); + } + + //else if (!imageOut(x, y)) + if (!labeled) + { + // Internal pixel + CvLabel l = imageOut(x-1, y); + + imageOut(x, y) = l; + numPixels++; + + CvBlob *blob = NULL; + if (l==lastLabel) + blob = lastBlob; + else + { + blob = blobs.find(l)->second; + lastLabel = l; + lastBlob = blob; + } + blob->area++; + blob->m10+=x; blob->m01+=y; + blob->m11+=x*y; + blob->m20+=x*x; blob->m02+=y*y; + } + } + } + } + + for (CvBlobs::iterator it=blobs.begin(); it!=blobs.end(); ++it) + { + cvCentroid((*it).second); + + (*it).second->u11 = (*it).second->m11 - ((*it).second->m10*(*it).second->m01)/(*it).second->m00; + (*it).second->u20 = (*it).second->m20 - ((*it).second->m10*(*it).second->m10)/(*it).second->m00; + (*it).second->u02 = (*it).second->m02 - ((*it).second->m01*(*it).second->m01)/(*it).second->m00; + + double m00_2 = (*it).second->m00 * (*it).second->m00; + + (*it).second->n11 = (*it).second->u11 / m00_2; + (*it).second->n20 = (*it).second->u20 / m00_2; + (*it).second->n02 = (*it).second->u02 / m00_2; + + (*it).second->p1 = (*it).second->n20 + (*it).second->n02; + + double nn = (*it).second->n20 - (*it).second->n02; + (*it).second->p2 = nn*nn + 4.*((*it).second->n11*(*it).second->n11); + } + + return numPixels; + + } + __CV_END__; + } + + void cvFilterLabels(IplImage *imgIn, IplImage *imgOut, const CvBlobs &blobs) + { + CV_FUNCNAME("cvFilterLabels"); + __CV_BEGIN__; + { + CV_ASSERT(imgIn&&(imgIn->depth==IPL_DEPTH_LABEL)&&(imgIn->nChannels==1)); + CV_ASSERT(imgOut&&(imgOut->depth==IPL_DEPTH_8U)&&(imgOut->nChannels==1)); + + int stepIn = imgIn->widthStep / (imgIn->depth / 8); + int stepOut = imgOut->widthStep / (imgOut->depth / 8); + int imgIn_width = imgIn->width; + int imgIn_height = imgIn->height; + int imgIn_offset = 0; + int imgOut_width = imgOut->width; + int imgOut_height = imgOut->height; + int imgOut_offset = 0; + if(imgIn->roi) + { + imgIn_width = imgIn->roi->width; + imgIn_height = imgIn->roi->height; + imgIn_offset = imgIn->roi->xOffset + (imgIn->roi->yOffset * stepIn); + } + if(imgOut->roi) + { + imgOut_width = imgOut->roi->width; + imgOut_height = imgOut->roi->height; + imgOut_offset = imgOut->roi->xOffset + (imgOut->roi->yOffset * stepOut); + } + + char *imgDataOut=imgOut->imageData + imgOut_offset; + CvLabel *imgDataIn=(CvLabel *)imgIn->imageData + imgIn_offset; + + for (unsigned int r=0;r<(unsigned int)imgIn_height;r++, + imgDataIn+=stepIn,imgDataOut+=stepOut) + { + for (unsigned int c=0;c<(unsigned int)imgIn_width;c++) + { + if (imgDataIn[c]) + { + if (blobs.find(imgDataIn[c])==blobs.end()) imgDataOut[c]=0x00; + else imgDataOut[c]=(char)0xff; + } + else + imgDataOut[c]=0x00; + } + } + } + __CV_END__; + } + + + CvLabel cvGetLabel(IplImage const *img, unsigned int x, unsigned int y) + { + CV_FUNCNAME("cvGetLabel"); + __CV_BEGIN__; + { + CV_ASSERT(img&&(img->depth==IPL_DEPTH_LABEL)&&(img->nChannels==1)); + + int step = img->widthStep / (img->depth / 8); + int img_width = 0; + int img_height= 0; + int img_offset = 0; + if(img->roi) + { + img_width = img->roi->width; + img_height = img->roi->height; + img_offset = img->roi->xOffset + (img->roi->yOffset * step); + } + else + { + img_width = img->width; + img_height= img->height; + } + + CV_ASSERT((x>=0)&&(x=0)&&(yimageData + img_offset))[x + y*step]; + } + __CV_END__; + } + +} diff --git a/mariusz/include/cvBlob/cvtrack.cpp b/mariusz/include/cvBlob/cvtrack.cpp new file mode 100644 index 0000000..6bc8ca1 --- /dev/null +++ b/mariusz/include/cvBlob/cvtrack.cpp @@ -0,0 +1,419 @@ +// Copyright (C) 2007 by Cristóbal Carnero Liñán +// grendel.ccl@gmail.com +// +// This file is part of cvBlob. +// +// cvBlob is free software: you can redistribute it and/or modify +// it under the terms of the Lesser GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// cvBlob is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// Lesser GNU General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License +// along with cvBlob. If not, see . +// + +#include +#include +#include +using namespace std; + +#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__))) +#include +#else +#include +#endif + +#include "cvblob.h" + +namespace cvb +{ + + double distantBlobTrack(CvBlob const *b, CvTrack const *t) + { + double d1; + if (b->centroid.xminx) + { + if (b->centroid.yminy) + d1 = MAX(t->minx - b->centroid.x, t->miny - b->centroid.y); + else if (b->centroid.y>t->maxy) + d1 = MAX(t->minx - b->centroid.x, b->centroid.y - t->maxy); + else // if (t->miny < b->centroid.y)&&(b->centroid.y < t->maxy) + d1 = t->minx - b->centroid.x; + } + else if (b->centroid.x>t->maxx) + { + if (b->centroid.yminy) + d1 = MAX(b->centroid.x - t->maxx, t->miny - b->centroid.y); + else if (b->centroid.y>t->maxy) + d1 = MAX(b->centroid.x - t->maxx, b->centroid.y - t->maxy); + else + d1 = b->centroid.x - t->maxx; + } + else // if (t->minx =< b->centroid.x) && (b->centroid.x =< t->maxx) + { + if (b->centroid.yminy) + d1 = t->miny - b->centroid.y; + else if (b->centroid.y>t->maxy) + d1 = b->centroid.y - t->maxy; + else + return 0.; + } + + double d2; + if (t->centroid.xminx) + { + if (t->centroid.yminy) + d2 = MAX(b->minx - t->centroid.x, b->miny - t->centroid.y); + else if (t->centroid.y>b->maxy) + d2 = MAX(b->minx - t->centroid.x, t->centroid.y - b->maxy); + else // if (b->miny < t->centroid.y)&&(t->centroid.y < b->maxy) + d2 = b->minx - t->centroid.x; + } + else if (t->centroid.x>b->maxx) + { + if (t->centroid.yminy) + d2 = MAX(t->centroid.x - b->maxx, b->miny - t->centroid.y); + else if (t->centroid.y>b->maxy) + d2 = MAX(t->centroid.x - b->maxx, t->centroid.y - b->maxy); + else + d2 = t->centroid.x - b->maxx; + } + else // if (b->minx =< t->centroid.x) && (t->centroid.x =< b->maxx) + { + if (t->centroid.yminy) + d2 = b->miny - t->centroid.y; + else if (t->centroid.y>b->maxy) + d2 = t->centroid.y - b->maxy; + else + return 0.; + } + + return MIN(d1, d2); + } + + // Access to matrix +#define C(blob, track) close[((blob) + (track)*(nBlobs+2))] + // Access to accumulators +#define AB(label) C((label), (nTracks)) +#define AT(id) C((nBlobs), (id)) + // Access to identifications +#define IB(label) C((label), (nTracks)+1) +#define IT(id) C((nBlobs)+1, (id)) + // Access to registers +#define B(label) blobs.find(IB(label))->second +#define T(id) tracks.find(IT(id))->second + + void getClusterForTrack(unsigned int trackPos, CvID *close, unsigned int nBlobs, unsigned int nTracks, CvBlobs const &blobs, CvTracks const &tracks, list &bb, list &tt); + + void getClusterForBlob(unsigned int blobPos, CvID *close, unsigned int nBlobs, unsigned int nTracks, CvBlobs const &blobs, CvTracks const &tracks, list &bb, list &tt) + { + for (unsigned int j=0; j1) + { + getClusterForTrack(j, close, nBlobs, nTracks, blobs, tracks, bb, tt); + } + } + } + } + + void getClusterForTrack(unsigned int trackPos, CvID *close, unsigned int nBlobs, unsigned int nTracks, CvBlobs const &blobs, CvTracks const &tracks, list &bb, list &tt) + { + for (unsigned int i=0; i1) + { + getClusterForBlob(i, close, nBlobs, nTracks, blobs, tracks, bb, tt); + } + } + } + } + + void cvUpdateTracks(CvBlobs const &blobs, CvTracks &tracks, const double thDistance, const unsigned int thInactive, const unsigned int thActive) + { + CV_FUNCNAME("cvUpdateTracks"); + __CV_BEGIN__; + + unsigned int nBlobs = blobs.size(); + unsigned int nTracks = tracks.size(); + + // Proximity matrix: + // Last row/column is for ID/label. + // Last-1 "/" is for accumulation. + CvID *close = new unsigned int[(nBlobs+2)*(nTracks+2)]; // XXX Must be same type than CvLabel. + + try + { + // Inicialization: + unsigned int i=0; + for (CvBlobs::const_iterator it = blobs.begin(); it!=blobs.end(); ++it, i++) + { + AB(i) = 0; + IB(i) = it->second->label; + } + + CvID maxTrackID = 0; + + unsigned int j=0; + for (CvTracks::const_iterator jt = tracks.begin(); jt!=tracks.end(); ++jt, j++) + { + AT(j) = 0; + IT(j) = jt->second->id; + if (jt->second->id > maxTrackID) + maxTrackID = jt->second->id; + } + + // Proximity matrix calculation and "used blob" list inicialization: + for (i=0; iinactive++; + track->label = 0; + } + } + + // Detect new tracks + for (i=0; iid = maxTrackID; + track->label = blob->label; + track->minx = blob->minx; + track->miny = blob->miny; + track->maxx = blob->maxx; + track->maxy = blob->maxy; + track->centroid = blob->centroid; + track->lifetime = 0; + track->active = 0; + track->inactive = 0; + tracks.insert(CvIDTrack(maxTrackID, track)); + } + } + + // Clustering + for (j=0; j tt; tt.push_back(T(j)); + list bb; + + getClusterForTrack(j, close, nBlobs, nTracks, blobs, tracks, bb, tt); + + // Select track + CvTrack *track; + unsigned int area = 0; + for (list::const_iterator it=tt.begin(); it!=tt.end(); ++it) + { + CvTrack *t = *it; + + unsigned int a = (t->maxx-t->minx)*(t->maxy-t->miny); + if (a>area) + { + area = a; + track = t; + } + } + + // Select blob + CvBlob *blob; + area = 0; + //cout << "Matching blobs: "; + for (list::const_iterator it=bb.begin(); it!=bb.end(); ++it) + { + CvBlob *b = *it; + + //cout << b->label << " "; + + if (b->area>area) + { + area = b->area; + blob = b; + } + } + //cout << endl; + + // Update track + //cout << "Matching: track=" << track->id << ", blob=" << blob->label << endl; + track->label = blob->label; + track->centroid = blob->centroid; + track->minx = blob->minx; + track->miny = blob->miny; + track->maxx = blob->maxx; + track->maxy = blob->maxy; + if (track->inactive) + track->active = 0; + track->inactive = 0; + + // Others to inactive + for (list::const_iterator it=tt.begin(); it!=tt.end(); ++it) + { + CvTrack *t = *it; + + if (t!=track) + { + //cout << "Inactive: track=" << t->id << endl; + t->inactive++; + t->label = 0; + } + } + } + } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + for (CvTracks::iterator jt=tracks.begin(); jt!=tracks.end();) + if ((jt->second->inactive>=thInactive)||((jt->second->inactive)&&(thActive)&&(jt->second->activesecond; + tracks.erase(jt++); + } + else + { + jt->second->lifetime++; + if (!jt->second->inactive) + jt->second->active++; + ++jt; + } + } + catch (...) + { + delete[] close; + throw; // TODO: OpenCV style. + } + + delete[] close; + + __CV_END__; + } + + CvFont *defaultFont = NULL; + + void cvRenderTracks(CvTracks const tracks, IplImage *imgSource, IplImage *imgDest, unsigned short mode, CvFont *font) + { + CV_FUNCNAME("cvRenderTracks"); + __CV_BEGIN__; + + CV_ASSERT(imgDest&&(imgDest->depth==IPL_DEPTH_8U)&&(imgDest->nChannels==3)); + + if ((mode&CV_TRACK_RENDER_ID)&&(!font)) + { + if (!defaultFont) + { + font = defaultFont = new CvFont; + cvInitFont(font, CV_FONT_HERSHEY_DUPLEX, 0.5, 0.5, 0, 1); + // Other fonts: + // CV_FONT_HERSHEY_SIMPLEX, CV_FONT_HERSHEY_PLAIN, + // CV_FONT_HERSHEY_DUPLEX, CV_FONT_HERSHEY_COMPLEX, + // CV_FONT_HERSHEY_TRIPLEX, CV_FONT_HERSHEY_COMPLEX_SMALL, + // CV_FONT_HERSHEY_SCRIPT_SIMPLEX, CV_FONT_HERSHEY_SCRIPT_COMPLEX + } + else + font = defaultFont; + } + + if (mode) + { + for (CvTracks::const_iterator it=tracks.begin(); it!=tracks.end(); ++it) + { + if (mode&CV_TRACK_RENDER_ID) + if (!it->second->inactive) + { + stringstream buffer; + buffer << it->first; + cvPutText(imgDest, buffer.str().c_str(), cvPoint((int)it->second->centroid.x, (int)it->second->centroid.y), font, CV_RGB(0.,255.,0.)); + } + + if (mode&CV_TRACK_RENDER_BOUNDING_BOX) + if (it->second->inactive) + cvRectangle(imgDest, cvPoint(it->second->minx, it->second->miny), cvPoint(it->second->maxx-1, it->second->maxy-1), CV_RGB(0., 0., 50.)); + else + cvRectangle(imgDest, cvPoint(it->second->minx, it->second->miny), cvPoint(it->second->maxx-1, it->second->maxy-1), CV_RGB(0., 0., 255.)); + + if (mode&CV_TRACK_RENDER_TO_LOG) + { + clog << "Track " << it->second->id << endl; + if (it->second->inactive) + clog << " - Inactive for " << it->second->inactive << " frames" << endl; + else + clog << " - Associated with blob " << it->second->label << endl; + clog << " - Lifetime " << it->second->lifetime << endl; + clog << " - Active " << it->second->active << endl; + clog << " - Bounding box: (" << it->second->minx << ", " << it->second->miny << ") - (" << it->second->maxx << ", " << it->second->maxy << ")" << endl; + clog << " - Centroid: (" << it->second->centroid.x << ", " << it->second->centroid.y << ")" << endl; + clog << endl; + } + + if (mode&CV_TRACK_RENDER_TO_STD) + { + cout << "Track " << it->second->id << endl; + if (it->second->inactive) + cout << " - Inactive for " << it->second->inactive << " frames" << endl; + else + cout << " - Associated with blobs " << it->second->label << endl; + cout << " - Lifetime " << it->second->lifetime << endl; + cout << " - Active " << it->second->active << endl; + cout << " - Bounding box: (" << it->second->minx << ", " << it->second->miny << ") - (" << it->second->maxx << ", " << it->second->maxy << ")" << endl; + cout << " - Centroid: (" << it->second->centroid.x << ", " << it->second->centroid.y << ")" << endl; + cout << endl; + } + } + } + + __CV_END__; + } + +} diff --git a/mariusz/nbproject/Makefile-Debug.mk b/mariusz/nbproject/Makefile-Debug.mk new file mode 100644 index 0000000..74f3e76 --- /dev/null +++ b/mariusz/nbproject/Makefile-Debug.mk @@ -0,0 +1,90 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux-x86 +CND_DLIB_EXT=so +CND_CONF=Debug +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/src/HandPointer/HandPointer.o \ + ${OBJECTDIR}/src/HandPointer/Mouse.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=`pkg-config opencv --cflags --libs` -lX11 -I/usr/local/include -L/usr/local/lib -lcvblob +CXXFLAGS=`pkg-config opencv --cflags --libs` -lX11 -I/usr/local/include -L/usr/local/lib -lcvblob + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS= + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/src/HandPointer/HandPointer.o: nbproject/Makefile-${CND_CONF}.mk src/HandPointer/HandPointer.cpp + ${MKDIR} -p ${OBJECTDIR}/src/HandPointer + ${RM} $@.d + $(COMPILE.cc) -g -Iinclude/cvBlob `pkg-config opencv --cflags --libs` -lX11 -I/usr/local/include -L/usr/local/lib -lcvblob -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HandPointer/HandPointer.o src/HandPointer/HandPointer.cpp + +${OBJECTDIR}/src/HandPointer/Mouse.o: nbproject/Makefile-${CND_CONF}.mk src/HandPointer/Mouse.cpp + ${MKDIR} -p ${OBJECTDIR}/src/HandPointer + ${RM} $@.d + $(COMPILE.cc) -g -Iinclude/cvBlob `pkg-config opencv --cflags --libs` -lX11 -I/usr/local/include -L/usr/local/lib -lcvblob -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HandPointer/Mouse.o src/HandPointer/Mouse.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/mariusz/nbproject/Makefile-Release.mk b/mariusz/nbproject/Makefile-Release.mk new file mode 100644 index 0000000..9fefdcb --- /dev/null +++ b/mariusz/nbproject/Makefile-Release.mk @@ -0,0 +1,90 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux-x86 +CND_DLIB_EXT=so +CND_CONF=Release +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/src/HandPointer/HandPointer.o \ + ${OBJECTDIR}/src/HandPointer/Mouse.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS= +CXXFLAGS= + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS= + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/src/HandPointer/HandPointer.o: src/HandPointer/HandPointer.cpp + ${MKDIR} -p ${OBJECTDIR}/src/HandPointer + ${RM} $@.d + $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HandPointer/HandPointer.o src/HandPointer/HandPointer.cpp + +${OBJECTDIR}/src/HandPointer/Mouse.o: src/HandPointer/Mouse.cpp + ${MKDIR} -p ${OBJECTDIR}/src/HandPointer + ${RM} $@.d + $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HandPointer/Mouse.o src/HandPointer/Mouse.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/mariusz/nbproject/Makefile-impl.mk b/mariusz/nbproject/Makefile-impl.mk new file mode 100644 index 0000000..c921dc5 --- /dev/null +++ b/mariusz/nbproject/Makefile-impl.mk @@ -0,0 +1,133 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a pre- and a post- target defined where you can add customization code. +# +# This makefile implements macros and targets common to all configurations. +# +# NOCDDL + + +# Building and Cleaning subprojects are done by default, but can be controlled with the SUB +# macro. If SUB=no, subprojects will not be built or cleaned. The following macro +# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf +# and .clean-reqprojects-conf unless SUB has the value 'no' +SUB_no=NO +SUBPROJECTS=${SUB_${SUB}} +BUILD_SUBPROJECTS_=.build-subprojects +BUILD_SUBPROJECTS_NO= +BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} +CLEAN_SUBPROJECTS_=.clean-subprojects +CLEAN_SUBPROJECTS_NO= +CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} + + +# Project Name +PROJECTNAME=mariusz + +# Active Configuration +DEFAULTCONF=Debug +CONF=${DEFAULTCONF} + +# All Configurations +ALLCONFS=Debug Release + + +# build +.build-impl: .build-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf + + +# clean +.clean-impl: .clean-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf + + +# clobber +.clobber-impl: .clobber-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \ + done + +# all +.all-impl: .all-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \ + done + +# build tests +.build-tests-impl: .build-impl .build-tests-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf + +# run tests +.test-impl: .build-tests-impl .test-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf + +# dependency checking support +.depcheck-impl: + @echo "# This code depends on make tool being used" >.dep.inc + @if [ -n "${MAKE_VERSION}" ]; then \ + echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ + echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ + echo "include \$${DEPFILES}" >>.dep.inc; \ + echo "endif" >>.dep.inc; \ + else \ + echo ".KEEP_STATE:" >>.dep.inc; \ + echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ + fi + +# configuration validation +.validate-impl: + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + echo ""; \ + echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \ + echo "See 'make help' for details."; \ + echo "Current directory: " `pwd`; \ + echo ""; \ + fi + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + exit 1; \ + fi + + +# help +.help-impl: .help-pre + @echo "This makefile supports the following configurations:" + @echo " ${ALLCONFS}" + @echo "" + @echo "and the following targets:" + @echo " build (default target)" + @echo " clean" + @echo " clobber" + @echo " all" + @echo " help" + @echo "" + @echo "Makefile Usage:" + @echo " make [CONF=] [SUB=no] build" + @echo " make [CONF=] [SUB=no] clean" + @echo " make [SUB=no] clobber" + @echo " make [SUB=no] all" + @echo " make help" + @echo "" + @echo "Target 'build' will build a specific configuration and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no'," + @echo " also clean subprojects." + @echo "Target 'clobber' will remove all built files from all configurations and," + @echo " unless 'SUB=no', also from subprojects." + @echo "Target 'all' will will build all configurations and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'help' prints this message." + @echo "" + diff --git a/mariusz/nbproject/Makefile-variables.mk b/mariusz/nbproject/Makefile-variables.mk new file mode 100644 index 0000000..9958240 --- /dev/null +++ b/mariusz/nbproject/Makefile-variables.mk @@ -0,0 +1,35 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +CND_BASEDIR=`pwd` +CND_BUILDDIR=build +CND_DISTDIR=dist +# Debug configuration +CND_PLATFORM_Debug=GNU-Linux-x86 +CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux-x86 +CND_ARTIFACT_NAME_Debug=mariusz +CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux-x86/mariusz +CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux-x86/package +CND_PACKAGE_NAME_Debug=mariusz.tar +CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/mariusz.tar +# Release configuration +CND_PLATFORM_Release=GNU-Linux-x86 +CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux-x86 +CND_ARTIFACT_NAME_Release=mariusz +CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/mariusz +CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux-x86/package +CND_PACKAGE_NAME_Release=mariusz.tar +CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/mariusz.tar +# +# include compiler specific variables +# +# dmake command +ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \ + (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk) +# +# gmake command +.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)) +# +include nbproject/private/Makefile-variables.mk diff --git a/mariusz/nbproject/Package-Debug.bash b/mariusz/nbproject/Package-Debug.bash new file mode 100644 index 0000000..ad6aa4b --- /dev/null +++ b/mariusz/nbproject/Package-Debug.bash @@ -0,0 +1,75 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux-x86 +CND_CONF=Debug +CND_DISTDIR=dist +CND_BUILDDIR=build +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz +OUTPUT_BASENAME=mariusz +PACKAGE_TOP_DIR=mariusz/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/mariusz/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/mariusz.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/mariusz.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/mariusz/nbproject/Package-Release.bash b/mariusz/nbproject/Package-Release.bash new file mode 100644 index 0000000..fe17807 --- /dev/null +++ b/mariusz/nbproject/Package-Release.bash @@ -0,0 +1,75 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux-x86 +CND_CONF=Release +CND_DISTDIR=dist +CND_BUILDDIR=build +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/mariusz +OUTPUT_BASENAME=mariusz +PACKAGE_TOP_DIR=mariusz/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/mariusz/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/mariusz.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/mariusz.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/mariusz/nbproject/configurations.xml b/mariusz/nbproject/configurations.xml new file mode 100644 index 0000000..571c1fb --- /dev/null +++ b/mariusz/nbproject/configurations.xml @@ -0,0 +1,88 @@ + + + + + src/HandPointer/Mouse.hpp + + + + + src/HandPointer/HandPointer.cpp + src/HandPointer/Mouse.cpp + + + + + Makefile + + + + src/HandPointer + + Makefile + + + + LOCAL_SOURCES + default + true + true + + + + g++ + + include/cvBlob + + `pkg-config opencv --cflags --libs` -lX11 -I/usr/local/include -L/usr/local/lib -lcvblob + + + + + + + + + + + + LOCAL_SOURCES + default + true + false + + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + + + + + + diff --git a/mariusz/nbproject/private/Makefile-variables.mk b/mariusz/nbproject/private/Makefile-variables.mk new file mode 100644 index 0000000..a64183e --- /dev/null +++ b/mariusz/nbproject/private/Makefile-variables.mk @@ -0,0 +1,7 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +# Debug configuration +# Release configuration diff --git a/mariusz/nbproject/private/configurations.xml b/mariusz/nbproject/private/configurations.xml new file mode 100644 index 0000000..3dc0394 --- /dev/null +++ b/mariusz/nbproject/private/configurations.xml @@ -0,0 +1,73 @@ + + + Makefile + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + + "${OUTPUT_PATH}" + + true + 0 + 0 + + + + + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + + "${OUTPUT_PATH}" + + true + 0 + 0 + + + + + + diff --git a/mariusz/nbproject/private/private.xml b/mariusz/nbproject/private/private.xml new file mode 100644 index 0000000..9bba057 --- /dev/null +++ b/mariusz/nbproject/private/private.xml @@ -0,0 +1,8 @@ + + + + 1 + 0 + + + diff --git a/mariusz/nbproject/project.xml b/mariusz/nbproject/project.xml new file mode 100644 index 0000000..b734b54 --- /dev/null +++ b/mariusz/nbproject/project.xml @@ -0,0 +1,27 @@ + + + org.netbeans.modules.cnd.makeproject + + + HandPointer + + cpp + hpp + UTF-8 + + + src/HandPointer + + + + Debug + 1 + + + Release + 1 + + + + + diff --git a/mariusz/src/HandPointer/HandPointer.cpp b/mariusz/src/HandPointer/HandPointer.cpp new file mode 100644 index 0000000..6a883c4 --- /dev/null +++ b/mariusz/src/HandPointer/HandPointer.cpp @@ -0,0 +1,127 @@ +/* + * File: main.cpp + * Author: mar + * + * Created on 7 kwiecień 2013, 19:36 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "opencv2/opencv.hpp" +#include +#include "Mouse.hpp" +using namespace cv; +using namespace std; +using namespace cvb; + +int r = 51, g = 99, b = 57; +int rT = 90, gT = 255, bT = 129; +int maxArea=1000, minArea=170; + +void setR(int v) {r = v;} +void setG(int v) {g = v;} +void setB(int v) {b = v;} +void setRT(int v) {rT = v;} +void setGT(int v) {gT = v;} +void setBT(int v) {bT = v;} + + +void setMax(int v){maxArea = v;} +void setMin(int v){minArea = v;} + +int main(int, char**) { + VideoCapture cap(0); // open the default camera + if (!cap.isOpened()) // check if we succeeded + return -1; + + Mouse mouse; + bool mouseon = true; + int x, y; + + namedWindow("output", 1); + namedWindow("bin", 1); + + CvBlobs blobs; + CvTracks tracks; + + IplImage *red = 0, *tmp = 0,* framee=0,*labelImg=0; + + Mat edges, frame; + + cap >> frame; + + red = cvCreateImage(cvSize(frame.cols, frame.rows), IPL_DEPTH_8U, 1); + tmp = cvCreateImage(cvSize(frame.cols, frame.rows), IPL_DEPTH_8U, 3); + labelImg = cvCreateImage(cvGetSize(red), IPL_DEPTH_LABEL, 1); + framee= cvCreateImage(cvGetSize(red), 8, 3); + + cvCreateTrackbar("R","bin",&r,255,setR); + cvCreateTrackbar("G","bin",&g,255,setG); + cvCreateTrackbar("B","bin",&b,255,setB); + + cvCreateTrackbar("RT","bin",&rT,255,setRT); + cvCreateTrackbar("BT","bin",&bT,255,setBT); + cvCreateTrackbar("GT","bin",&gT,255,setGT); + + cvCreateTrackbar("min","bin",&minArea,1000,setMin); + cvCreateTrackbar("max","bin",&maxArea,100000,setMax); + + + + for (;;) { + cap >> frame; // gt a new frame from camera + flip(frame, frame, 1); + cvtColor(frame, edges, CV_BGR2HSV); + + tmp->imageData = (char*) edges.data; + framee->imageData = (char*) frame.data; + + cvInRangeS(tmp, Scalar(r, g, b), Scalar(rT, gT, bT), red); + + cvDilate(red, red, NULL, 3); + cvErode(red, red, NULL, 4); + cvDilate(red, red, NULL, 2); + + cvLabel(red, labelImg, blobs); + cvFilterByArea(blobs, minArea, maxArea); + cvRenderBlobs(labelImg, blobs, framee, framee, CV_BLOB_RENDER_BOUNDING_BOX); + cvUpdateTracks(blobs, tracks, 200, 5); + cvRenderTracks(tracks, framee, framee, CV_TRACK_RENDER_ID | CV_TRACK_RENDER_BOUNDING_BOX); + + for (CvBlobs::const_iterator it = blobs.begin(); it != blobs.end(); ++it) { + x = (int) it->second->centroid.x; + y = (int) it->second->centroid.y; + if (mouseon) { + mouse.setMouse(x/(double)frame.cols*1600,y/(double)frame.rows*900); + } + break; + } + + + imshow("output", Mat(framee)); + imshow("bin", Mat(red)); + + char key = (char) waitKey(1); + switch (key) { + + case 'a': + mouseon = mouseon ? false : true; + break; + } + if (key == 'b') break; //exit program + + } + + destroyAllWindows(); + // the camera will be deinitialized automatically in VideoCapture destructor + return 0; +} + diff --git a/mariusz/src/HandPointer/Mouse.cpp b/mariusz/src/HandPointer/Mouse.cpp new file mode 100644 index 0000000..44d3f83 --- /dev/null +++ b/mariusz/src/HandPointer/Mouse.cpp @@ -0,0 +1,26 @@ +/* + * File: mouse.cpp + * Author: mar + * + * Created on 13 kwiecień 2013, 15:38 + */ + +#include "Mouse.hpp" + +Mouse::Mouse() { + dpy = XOpenDisplay(0); + root_window = XRootWindow(dpy, 0); + XSelectInput(dpy, root_window, KeyReleaseMask); + +} +void Mouse::setMouse(const int x,const int y){ + XWarpPointer(dpy, None, root_window, 0, 0, 0, 0, x, y); + XFlush(dpy); +} +Mouse::Mouse(const Mouse& orig) { +} + +Mouse::~Mouse() { + //free(&dpy); +} + diff --git a/mariusz/src/HandPointer/Mouse.hpp b/mariusz/src/HandPointer/Mouse.hpp new file mode 100644 index 0000000..9bd6401 --- /dev/null +++ b/mariusz/src/HandPointer/Mouse.hpp @@ -0,0 +1,24 @@ +/* + * File: mouse.hpp + * Author: mar + * + * Created on 13 kwiecień 2013, 15:38 + */ + +#ifndef MOUSE_HPP +#define MOUSE_HPP +#include +class Mouse { +public: + Mouse(); + Mouse(const Mouse& orig); + void setMouse(const int,const int); + virtual ~Mouse(); +private: + Display *dpy; + Window root_window; + +}; + +#endif /* MOUSE_HPP */ +