wstępne poruszanie kursorem

This commit is contained in:
Mariusz Pacek committed 2013-04-13 17:41:26 +02:00
1 parent f81b88acfe
commit b2e1e6f82e
42 files changed
+3527 -33

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
# This code depends on make tool being used
DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
ifneq (${DEPFILES},)
include ${DEPFILES}
endif
@@ -0,0 +1 @@
build/Debug/GNU-Linux-x86/main.o: main.cpp
BIN
View File
Binary file not shown.
+7 -7
View File
@@ -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:
+4 -4
View File
@@ -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:
+1 -1
View File
@@ -24,7 +24,7 @@ CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
# Project Name
PROJECTNAME=Modal-HandPointer
PROJECTNAME=Przyklad
# Active Configuration
DEFAULTCONF=Debug
+8 -8
View File
@@ -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
#
+6 -6
View File
@@ -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
+6 -6
View File
@@ -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
+1 -1
View File
@@ -41,7 +41,7 @@
<commandLine>pkg-config --cflags --libs opencv</commandLine>
</cTool>
<ccTool>
<commandLine>`pkg-config --cflags --libs opencv`</commandLine>
<commandLine>`pkg-config --cflags --libs opencv` -lX11</commandLine>
</ccTool>
</compileType>
<item path="main.cpp" ex="false" tool="1" flavor2="0">
File renamed without changes.
+5
View File
@@ -0,0 +1,5 @@
# This code depends on make tool being used
DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
ifneq (${DEPFILES},)
include ${DEPFILES}
endif
+128
View File
@@ -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
@@ -0,0 +1,3 @@
build/Debug/GNU-Linux-x86/Mouse.o: Mouse.cpp Mouse.hpp
Mouse.hpp:
@@ -0,0 +1 @@
build/Debug/GNU-Linux-x86/main.o: main.cpp
@@ -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:
@@ -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:
@@ -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:
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+45
View File
@@ -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 <http://www.gnu.org/licenses/>.
#
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
)
+79
View File
@@ -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 <http://www.gnu.org/licenses/>.
//
#include <cmath>
#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__)))
#include <cv.h>
#else
#include <opencv/cv.h>
#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));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
+344
View File
@@ -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 <http://www.gnu.org/licenses/>.
//
#include <cmath>
#include <iostream>
using namespace std;
#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__)))
#include <cv.h>
#include <highgui.h>
#else
#include <opencv/cv.h>
#include <opencv/highgui.h>
#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->area<minArea)||(blob->area>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;
r<blob->maxy;
r++,imgData+=stepIn)
for (unsigned int c=blob->minx;c<blob->maxx;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; r<blob->maxy; r++, labels+=stepLbl, source+=stepSrc, imgData+=stepDst)
for (unsigned int c=blob->minx; c<blob->maxx; 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<CvLabel, CvScalar> 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;
}
+587
View File
@@ -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 <http://www.gnu.org/licenses/>.
//
/// \file cvblob.h
/// \brief OpenCV Blob header file.
#ifdef SWIG
%module cvblob
%{
#include "cvblob.h"
%}
#endif
#ifndef CVBLOB_H
#define CVBLOB_H
#include <iostream>
#include <map>
#include <list>
#include <vector>
#include <limits>
#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__)))
#include <cv.h>
#else
#include <opencv/cv.h>
#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<CvChainCode> 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<CvContourChainCode *> CvContoursChainCode; ///< List of contours (chain codes type).
/// \brief Polygon based contour.
typedef std::vector<CvPoint> 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<CvLabel>::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<CvLabel,CvBlob *> CvBlobs
/// \brief List of blobs.
/// A map is used to access each blob from its label number.
/// \see CvLabel
/// \see CvBlob
typedef std::map<CvLabel,CvBlob *> CvBlobs;
/// \var typedef std::pair<CvLabel,CvBlob *> CvLabelBlob
/// \brief Pair (label, blob).
/// \see CvLabel
/// \see CvBlob
typedef std::pair<CvLabel,CvBlob *> 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<CvID, CvTrack *> CvTracks
/// \brief List of tracks.
/// \see CvID
/// \see CvTrack
typedef std::map<CvID, CvTrack *> CvTracks;
/// \var typedef std::pair<CvID, CvTrack *> CvIDTrack
/// \brief Pair (identification number, track).
/// \see CvID
/// \see CvTrack
typedef std::pair<CvID, CvTrack *> 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
+104
View File
@@ -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 <http://www.gnu.org/licenses/>.
//
#include <cmath>
#include <iostream>
using namespace std;
#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__)))
#include <cv.h>
#else
#include <opencv/cv.h>
#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; y<imgLabel->height; y++)
for (unsigned int x=0; x<imgLabel->width; 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__;
}
}
+436
View File
@@ -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 <http://www.gnu.org/licenses/>.
//
#include <climits>
#define _USE_MATH_DEFINES
#include <cmath>
#include <deque>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__)))
#include <cv.h>
#else
#include <opencv/cv.h>
#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; i<p->size()-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<endIndex; i++)
{
double d = cvDistanceLinePoint(firstPoint, lastPoint, (*p)[i]);
if ((d>=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 (furtherDistance<delta)
{
CvContourPolygon *result = new CvContourPolygon;
result->push_back(p->front());
return result;
}
bool *pnUseFlag = new bool[p->size()];
for (unsigned int i=1; i<p->size(); 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; i<p->size(); 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<CvPoint> 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; i<p->size(); 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->x<minx)
minx = it->x;
if (it->y>maxy)
maxy = it->y;
if (it->y<miny)
miny = it->y;
buffer << it->x << "," << it->y << " ";
}
ofstream f;
f.open(filename.c_str());
f << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?>" << endl;
f << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">" << endl;
f << "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" width=\"" << maxx-minx << "px\" height=\"" << maxy-miny << "px\" viewBox=\"" << minx << " " << miny << " " << maxx << " " << maxy << "\" zoomAndPan=\"disable\" >" << endl;
f << "<polygon fill=\"rgb(" << fill.val[0] << "," << fill.val[1] << "," << fill.val[2] << ")\" stroke=\"rgb(" << stroke.val[0] << "," << stroke.val[1] << "," << stroke.val[2] << ")\" stroke-width=\"1\" points=\"" << buffer.str() << "\"/>" << endl;
f << "</svg>" << 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;
}
+444
View File
@@ -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 <http://www.gnu.org/licenses/>.
//
#include <stdexcept>
#include <iostream>
using namespace std;
#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__)))
#include <cv.h>
#else
#include <opencv/cv.h>
#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; y<imgIn_height; y++)
{
for (unsigned int x=0; x<imgIn_width; x++)
{
if (imageIn(x, y))
{
bool labeled = imageOut(x, y);
if ((!imageOut(x, y))&&((y==0)||(!imageIn(x, y-1))))
{
labeled = true;
// Label contour.
label++;
CV_ASSERT(label!=CV_BLOB_MAX_LABEL);
imageOut(x, y) = label;
numPixels++;
// XXX This is not necessary at all. I only do this for consistency.
if (y>0)
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<imgIn_width)&&(nx>=0)&&(ny<imgIn_height)&&(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 (xx<blob->minx) blob->minx = xx;
else if (xx>blob->maxx) blob->maxx = xx;
if (yy<blob->miny) 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+1<imgIn_height)&&(!imageIn(x, y+1))&&(!imageOut(x, y+1)))
{
labeled = true;
// Label internal contour
CvLabel l;
CvBlob *blob = NULL;
if (!imageOut(x, y))
{
/*if (!imageOut(x-1, y))
{
cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
continue;
}*/
l = imageOut(x-1, y);
imageOut(x, y) = l;
numPixels++;
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;
}
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<img_width)&&(y>=0)&&(y<img_height));
return ((CvLabel *)(img->imageData + img_offset))[x + y*step];
}
__CV_END__;
}
}
+419
View File
@@ -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 <http://www.gnu.org/licenses/>.
//
#include <cmath>
#include <iostream>
#include <sstream>
using namespace std;
#if (defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) || (defined(__APPLE__) & defined(__MACH__)))
#include <cv.h>
#else
#include <opencv/cv.h>
#endif
#include "cvblob.h"
namespace cvb
{
double distantBlobTrack(CvBlob const *b, CvTrack const *t)
{
double d1;
if (b->centroid.x<t->minx)
{
if (b->centroid.y<t->miny)
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.y<t->miny)
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.y<t->miny)
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.x<b->minx)
{
if (t->centroid.y<b->miny)
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.y<b->miny)
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.y<b->miny)
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<CvBlob*> &bb, list<CvTrack*> &tt);
void getClusterForBlob(unsigned int blobPos, CvID *close, unsigned int nBlobs, unsigned int nTracks, CvBlobs const &blobs, CvTracks const &tracks, list<CvBlob*> &bb, list<CvTrack*> &tt)
{
for (unsigned int j=0; j<nTracks; j++)
{
if (C(blobPos, j))
{
tt.push_back(T(j));
unsigned int c = AT(j);
C(blobPos, j) = 0;
AB(blobPos)--;
AT(j)--;
if (c>1)
{
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<CvBlob*> &bb, list<CvTrack*> &tt)
{
for (unsigned int i=0; i<nBlobs; i++)
{
if (C(i, trackPos))
{
bb.push_back(B(i));
unsigned int c = AB(i);
C(i, trackPos) = 0;
AB(i)--;
AT(trackPos)--;
if (c>1)
{
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; i<nBlobs; i++)
for (j=0; j<nTracks; j++)
if (C(i, j) = (distantBlobTrack(B(i), T(j)) < thDistance))
{
AB(i)++;
AT(j)++;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Detect inactive tracks
for (j=0; j<nTracks; j++)
{
unsigned int c = AT(j);
if (c==0)
{
//cout << "Inactive track: " << j << endl;
// Inactive track.
CvTrack *track = T(j);
track->inactive++;
track->label = 0;
}
}
// Detect new tracks
for (i=0; i<nBlobs; i++)
{
unsigned int c = AB(i);
if (c==0)
{
//cout << "Blob (new track): " << maxTrackID+1 << endl;
//cout << *B(i) << endl;
// New track.
maxTrackID++;
CvBlob *blob = B(i);
CvTrack *track = new CvTrack;
track->id = 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<nTracks; j++)
{
unsigned int c = AT(j);
if (c)
{
list<CvTrack*> tt; tt.push_back(T(j));
list<CvBlob*> bb;
getClusterForTrack(j, close, nBlobs, nTracks, blobs, tracks, bb, tt);
// Select track
CvTrack *track;
unsigned int area = 0;
for (list<CvTrack*>::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<CvBlob*>::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<CvTrack*>::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->active<thActive)))
{
delete jt->second;
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__;
}
}
+90
View File
@@ -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
+90
View File
@@ -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
+133
View File
@@ -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=<CONFIGURATION>] [SUB=no] build"
@echo " make [CONF=<CONFIGURATION>] [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 ""
+35
View File
@@ -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
+75
View File
@@ -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}
+75
View File
@@ -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}
+88
View File
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="88">
<logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
<logicalFolder name="HeaderFiles"
displayName="Header Files"
projectFiles="true">
<itemPath>src/HandPointer/Mouse.hpp</itemPath>
</logicalFolder>
<logicalFolder name="ResourceFiles"
displayName="Resource Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="SourceFiles"
displayName="Source Files"
projectFiles="true">
<itemPath>src/HandPointer/HandPointer.cpp</itemPath>
<itemPath>src/HandPointer/Mouse.cpp</itemPath>
</logicalFolder>
<logicalFolder name="TestFiles"
displayName="Test Files"
projectFiles="false"
kind="TEST_LOGICAL_FOLDER">
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
projectFiles="false"
kind="IMPORTANT_FILES_FOLDER">
<itemPath>Makefile</itemPath>
</logicalFolder>
</logicalFolder>
<sourceRootList>
<Elem>src/HandPointer</Elem>
</sourceRootList>
<projectmakefile>Makefile</projectmakefile>
<confs>
<conf name="Debug" type="1">
<toolsSet>
<remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
<compilerSet>default</compilerSet>
<dependencyChecking>true</dependencyChecking>
<rebuildPropChanged>true</rebuildPropChanged>
</toolsSet>
<compileType>
<ccTool>
<commandlineTool>g++</commandlineTool>
<incDir>
<pElem>include/cvBlob</pElem>
</incDir>
<commandLine>`pkg-config opencv --cflags --libs` -lX11 -I/usr/local/include -L/usr/local/lib -lcvblob </commandLine>
</ccTool>
</compileType>
<item path="src/HandPointer/HandPointer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="src/HandPointer/Mouse.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="src/HandPointer/Mouse.hpp" ex="false" tool="3" flavor2="0">
</item>
</conf>
<conf name="Release" type="1">
<toolsSet>
<remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
<compilerSet>default</compilerSet>
<dependencyChecking>true</dependencyChecking>
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
<compileType>
<cTool>
<developmentMode>5</developmentMode>
</cTool>
<ccTool>
<developmentMode>5</developmentMode>
</ccTool>
<fortranCompilerTool>
<developmentMode>5</developmentMode>
</fortranCompilerTool>
<asmTool>
<developmentMode>5</developmentMode>
</asmTool>
</compileType>
<item path="src/HandPointer/HandPointer.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="src/HandPointer/Mouse.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="src/HandPointer/Mouse.hpp" ex="false" tool="3" flavor2="0">
</item>
</conf>
</confs>
</configurationDescriptor>
@@ -0,0 +1,7 @@
#
# Generated - do not edit!
#
# NOCDDL
#
# Debug configuration
# Release configuration
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="88">
<projectmakefile>Makefile</projectmakefile>
<confs>
<conf name="Debug" type="1">
<toolsSet>
<developmentServer>localhost</developmentServer>
<platform>2</platform>
</toolsSet>
<dbx_gdbdebugger version="1">
<gdb_pathmaps>
</gdb_pathmaps>
<gdb_interceptlist>
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
</gdb_interceptlist>
<gdb_options>
<DebugOptions>
</DebugOptions>
</gdb_options>
<gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
</dbx_gdbdebugger>
<nativedebugger version="1">
<engine>gdb</engine>
</nativedebugger>
<runprofile version="9">
<runcommandpicklist>
<runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
</runcommandpicklist>
<runcommand>"${OUTPUT_PATH}"</runcommand>
<rundir></rundir>
<buildfirst>true</buildfirst>
<terminal-type>0</terminal-type>
<remove-instrumentation>0</remove-instrumentation>
<environment>
<variable name="LD_LIBRARY_PATH" value="lib/"/>
</environment>
</runprofile>
</conf>
<conf name="Release" type="1">
<toolsSet>
<developmentServer>localhost</developmentServer>
<platform>2</platform>
</toolsSet>
<dbx_gdbdebugger version="1">
<gdb_pathmaps>
</gdb_pathmaps>
<gdb_interceptlist>
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
</gdb_interceptlist>
<gdb_options>
<DebugOptions>
</DebugOptions>
</gdb_options>
<gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
</dbx_gdbdebugger>
<nativedebugger version="1">
<engine>gdb</engine>
</nativedebugger>
<runprofile version="9">
<runcommandpicklist>
<runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
</runcommandpicklist>
<runcommand>"${OUTPUT_PATH}"</runcommand>
<rundir></rundir>
<buildfirst>true</buildfirst>
<terminal-type>0</terminal-type>
<remove-instrumentation>0</remove-instrumentation>
<environment>
</environment>
</runprofile>
</conf>
</confs>
</configurationDescriptor>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<data xmlns="http://www.netbeans.org/ns/make-project-private/1">
<activeConfTypeElem>1</activeConfTypeElem>
<activeConfIndexElem>0</activeConfIndexElem>
</data>
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
</project-private>
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.cnd.makeproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/make-project/1">
<name>HandPointer</name>
<c-extensions/>
<cpp-extensions>cpp</cpp-extensions>
<header-extensions>hpp</header-extensions>
<sourceEncoding>UTF-8</sourceEncoding>
<make-dep-projects/>
<sourceRootList>
<sourceRootElem>src/HandPointer</sourceRootElem>
</sourceRootList>
<confList>
<confElem>
<name>Debug</name>
<type>1</type>
</confElem>
<confElem>
<name>Release</name>
<type>1</type>
</confElem>
</confList>
</data>
</configuration>
</project>
+127
View File
@@ -0,0 +1,127 @@
/*
* File: main.cpp
* Author: mar
*
* Created on 7 kwiecień 2013, 19:36
*/
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <cvblob.h>
#include "opencv2/opencv.hpp"
#include <opencv/cv.h>
#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;
}
+26
View File
@@ -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);
}
+24
View File
@@ -0,0 +1,24 @@
/*
* File: mouse.hpp
* Author: mar
*
* Created on 13 kwiecień 2013, 15:38
*/
#ifndef MOUSE_HPP
#define MOUSE_HPP
#include <X11/Xlib.h>
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 */