├── MultipleCameraTracking.bat ├── MultipleCameraTracking.sh ├── MultipleCameraTracking.vs2008.sln ├── MultipleCameraTracking.vs2008.vcproj ├── README.md ├── config.cfg ├── obj └── Makefile ├── property_sheets ├── opencv2_3.vsprops └── opencv2_3_64.vsprops └── src ├── AdaBoostClassifier.cpp ├── AdaBoostClassifier.h ├── AppearanceBasedInformationFuser.cpp ├── AppearanceBasedInformationFuser.h ├── Camera.cpp ├── Camera.h ├── CameraNetwork.cpp ├── CameraNetwork.h ├── CameraNetworkBase.h ├── ClassifierParameters.h ├── CommonMacros.h ├── Config.cpp ├── Config.h ├── CultureColorHistogram.cpp ├── CultureColorHistogram.h ├── CultureColorHistogramFeatureVector.cpp ├── CultureColorHistogramFeatureVector.h ├── DefaultParameters.h ├── Exception.h ├── Feature.h ├── FeatureParameters.cpp ├── FeatureParameters.h ├── FeatureVector.h ├── GeometryBasedInformationFuser.cpp ├── GeometryBasedInformationFuser.h ├── HaarAndColorHistogramFeatureVector.cpp ├── HaarAndColorHistogramFeatureVector.h ├── HaarFeature.cpp ├── HaarFeature.h ├── HaarFeatureVector.cpp ├── HaarFeatureVector.h ├── MILAnyBoostClassifier.cpp ├── MILAnyBoostClassifier.h ├── MILBoostClassifier.cpp ├── MILBoostClassifier.h ├── MILEnsembleClassifier.cpp ├── MILEnsembleClassifier.h ├── Matrix.cpp ├── Matrix.h ├── MultiDimensionalColorHistogram.cpp ├── MultiDimensionalColorHistogram.h ├── MultiDimensionalColorHistogramFeatureVector.cpp ├── MultiDimensionalColorHistogramFeatureVector.h ├── MultipleCameraTrackingMain.cpp ├── Object.cpp ├── Object.h ├── OnlineStumpsWeakClassifier.cpp ├── OnlineStumpsWeakClassifier.h ├── ParticleFilter.cpp ├── ParticleFilter.h ├── ParticleFilterTracker.cpp ├── ParticleFilterTracker.h ├── PerceptronWeakClassifier.cpp ├── PerceptronWeakClassifier.h ├── Public.cpp ├── Public.h ├── Sample.cpp ├── Sample.h ├── SampleSet.cpp ├── SampleSet.h ├── SimpleTracker.cpp ├── SimpleTracker.h ├── StrongClassifierBase.cpp ├── StrongClassifierBase.h ├── StrongClassifierFactory.cpp ├── StrongClassifierFactory.h ├── Tracker.cpp ├── Tracker.h ├── TrackerParameters.cpp ├── TrackerParameters.h ├── WeakClassifierBase.cpp ├── WeakClassifierBase.h ├── WeightedStumpsWeakClassifier.cpp └── WeightedStumpsWeakClassifier.h /MultipleCameraTracking.bat: -------------------------------------------------------------------------------- 1 | MultipleCameraTracking.exe -d config.cfg -p Whether_Calculate_Tracking_Error=0 -------------------------------------------------------------------------------- /MultipleCameraTracking.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | export LD_LIBRARY_PATH=/opt/intel/composer_xe_2013_sp1/ipp/lib/intel64:$LD_LIBRARY_PATH 3 | ./MultipleCameraTracking -d config.cfg 4 | -------------------------------------------------------------------------------- /MultipleCameraTracking.vs2008.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MultipleCameraTracking", "MultipleCameraTracking.vs2008.vcproj", "{8321B0CA-7F1A-4168-9806-FE0A9CE5531C}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8321B0CA-7F1A-4168-9806-FE0A9CE5531C}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {8321B0CA-7F1A-4168-9806-FE0A9CE5531C}.Debug|Win32.Build.0 = Debug|Win32 16 | {8321B0CA-7F1A-4168-9806-FE0A9CE5531C}.Debug|x64.ActiveCfg = Debug|x64 17 | {8321B0CA-7F1A-4168-9806-FE0A9CE5531C}.Debug|x64.Build.0 = Debug|x64 18 | {8321B0CA-7F1A-4168-9806-FE0A9CE5531C}.Release|Win32.ActiveCfg = Release|Win32 19 | {8321B0CA-7F1A-4168-9806-FE0A9CE5531C}.Release|Win32.Build.0 = Release|Win32 20 | {8321B0CA-7F1A-4168-9806-FE0A9CE5531C}.Release|x64.ActiveCfg = Release|x64 21 | {8321B0CA-7F1A-4168-9806-FE0A9CE5531C}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A multi-camera tracking algorithm using OpenCV. It depends on OpenCv 2.3.1 (http://opencv.org/), Boost libraries (http://www.boost.org/) and Intel IPP (https://software.intel.com/en-us/intel-ipp). 2 | 3 | Usage 4 | ------------ 5 | 6 | In order to run the tracker, use the following command: 7 | 8 | ### Windows ### 9 | 10 | MultiCameraTracker.exe -d config.cfg 11 | 12 | (or) 13 | 14 | MultiCameraTracker.bat 15 | 16 | ### Linux ### 17 | 18 | ./MultiCameraTracker -d config.cfg 19 | 20 | (or) 21 | 22 | ./MultiCameraTracker.sh 23 | 24 | Compilation 25 | ------------ 26 | Windows: Build the Visual studio project. 27 | 28 | Linux: Run the make file inside the "obj" folder. 29 | 30 | Note: Make sure Intel IPP, OpenCv 2.3.1 and Boost libraries are located in appropriate folders. 31 | 32 | Data 33 | ------------ 34 | Here is the sample data folder: https://www.dropbox.com/s/gnheat18lotoi2k/data.tar.gz?dl=0 35 | 36 | Note: Follow a similar folder structure for new scenarios. 37 | 38 | ### Contact ### 39 | [1] Santhoshkumar Sunderrajan( santhosh@ece.ucsb.edu) 40 | Website: http://santhoshsunderrajan.com/ 41 | 42 | ### Bibtex ### 43 | If you use the code in any of your research works, please cite the following papers: 44 | ~~~ 45 | @inproceedings{ni2010particle, 46 | title={Particle filter tracking with online multiple instance learning}, 47 | author={Ni, Zefeng and Sunderrajan, Santhoshkumar and Rahimi, Amir and Manjunath, BS}, 48 | booktitle={Pattern Recognition (ICPR), 2010 20th International Conference on}, 49 | pages={2616--2619}, 50 | year={2010}, 51 | organization={IEEE} 52 | } 53 | 54 | @inproceedings{ni2010distributed, 55 | title={Distributed particle filter tracking with online multiple instance learning in a camera sensor network}, 56 | author={Ni, Zefeng and Sunderrajan, Santhoshkumar and Rahimi, Amir and Manjunath, BS}, 57 | booktitle={Image Processing (ICIP), 2010 17th IEEE International Conference on}, 58 | pages={37--40}, 59 | year={2010}, 60 | organization={IEEE} 61 | } 62 | ~~~ 63 | 64 | ### Disclaimer ### 65 | I may have used some good codes from various sources, please feel free to notify me if you find a piece of code that I need to acknowledge. 66 | -------------------------------------------------------------------------------- /obj/Makefile: -------------------------------------------------------------------------------- 1 | #Compiler 2 | CC=g++ 3 | 4 | #IPP=/opt/intel/ipp/6.1.2.051/em64t#IPP location 5 | IPP=/opt/intel/composer_xe_2013_sp1/ipp 6 | 7 | #library 8 | #for opencv 2.1 9 | #LDFLAGS=-lcxcore -lcv -lhighgui -lippiem64t -lippmem64t -lippcvem64t -lippcoreem64t -liomp5 -lpthread -lm 10 | #for opencv2.2 and 2.3 onwards, use the following 11 | LDFLAGS=-L$(IPP)/lib/intel64 -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_objdetect -lopencv_video -lopencv_ml -lippi -lipps -lippcv -lippcore 12 | 13 | #headers 14 | CFLAGS=-c -w -I$(IPP)/include -I/usr/local/include/opencv -I/usr/local/include/ -I/usr/local/include/boost 15 | 16 | SRCDIR=../src 17 | OBJDIR=./ 18 | 19 | SOURCES=$(wildcard $(SRCDIR)/*.cpp) 20 | 21 | OBJECTS_TMP := $(SOURCES:.cpp=.o) 22 | OBJECTS := $(subst src,obj, $(OBJECTS_TMP)) 23 | 24 | EXECUTABLE = MultipleCameraTracking 25 | 26 | all: $(OBJECTS) $(EXECUTABLE) 27 | 28 | clean: 29 | rm -rf $(EXECUTABLE) 30 | rm ./*.o 31 | 32 | $(EXECUTABLE): $(OBJECTS) 33 | $(CC) $(OBJECTS) $(LDFLAGS) -o $@ 34 | 35 | $(OBJECTS): $(SOURCES) 36 | $(CC) $(CFLAGS) $(SOURCES) 37 | -------------------------------------------------------------------------------- /property_sheets/opencv2_3.vsprops: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 16 | 17 | -------------------------------------------------------------------------------- /property_sheets/opencv2_3_64.vsprops: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 16 | 17 | -------------------------------------------------------------------------------- /src/AdaBoostClassifier.h: -------------------------------------------------------------------------------- 1 | #ifndef ADABOOST_H 2 | #define ADABOOST_H 3 | 4 | #include "StrongClassifierBase.h" 5 | 6 | namespace Classifier 7 | { 8 | /**************************************************************** 9 | AdaBoostClassifier 10 | Implements AdaBoost based Strong Classifier. 11 | ****************************************************************/ 12 | class AdaBoostClassifier : public StrongClassifierBase 13 | { 14 | public: 15 | 16 | //Constructor 17 | AdaBoostClassifier( Classifier::StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ); 18 | 19 | //Update the strong classifier 20 | virtual void Update( Classifier::SampleSet& positiveSampleSet, 21 | Classifier::SampleSet& negativeSampleSet ); 22 | 23 | //Classify the sample set 24 | virtual vectorf Classify( Classifier::SampleSet& sampleSet, 25 | bool isLogRatioEnabled = true ); 26 | 27 | private: 28 | 29 | //Initialize the classifier 30 | void Initialize( Classifier::StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ); 31 | 32 | AdaBoostClassifierParametersPtr m_adaBoostClassifierParametersPtr; 33 | vectorf m_alphaList; 34 | float m_sumOfAlphas; 35 | vector m_countFPv; 36 | vector m_countFNv; 37 | vector m_countTPv; 38 | vector m_countTNv; //[selector][feature] 39 | }; 40 | } 41 | #endif -------------------------------------------------------------------------------- /src/AppearanceBasedInformationFuser.cpp: -------------------------------------------------------------------------------- 1 | #include "AppearanceBasedInformationFuser.h" 2 | #include "StrongClassifierFactory.h" 3 | #include "CameraNetworkBase.h" 4 | #include "Config.h" 5 | 6 | #define RANDOM_SAMPLE_SELECTION_THRESHOLD 0.5f 7 | #define MULTIPLE_POSITIVE_BAG 0 8 | 9 | namespace MultipleCameraTracking 10 | { 11 | /******************************************************************** 12 | AppearanceBasedInformationFuser 13 | AppearanceBasedInformationFuser fuses information from multiple cameras. 14 | Exceptions: 15 | None 16 | *********************************************************************/ 17 | AppearanceBasedInformationFuser::AppearanceBasedInformationFuser( const int objectId, 18 | const int cameraId, 19 | const AppearanceFusionType appearanceFusionType, 20 | Classifier::StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ) 21 | : m_objectId( objectId ), 22 | m_cameraId( cameraId ), 23 | m_appearanceFusionType( appearanceFusionType ), 24 | m_strongClassifierParametersBasePtr( strongClassifierParametersBasePtr ) 25 | { 26 | try 27 | { 28 | strongClassifierParametersBasePtr->m_learningRate = 0; 29 | 30 | m_strongClassifierBasePtr = Classifier::StrongClassifierFactory::CreateAndInitializeClassifier( ( strongClassifierParametersBasePtr ) ); 31 | 32 | ASSERT_TRUE( m_strongClassifierBasePtr.get() != NULL ); 33 | } 34 | EXCEPTION_CATCH_AND_ABORT( "Failed to Initialize the AppearanceBasedInformationFuser"); 35 | } 36 | 37 | /******************************************************************** 38 | LearnAppearanceModel 39 | Learn the appearance model using the positive and negative 40 | samples provided by different cameras. 41 | Exceptions: 42 | None 43 | *********************************************************************/ 44 | void AppearanceBasedInformationFuser::LearnGlobalAppearanceModel( CameraNetworkBasePtr cameraNetworkBasePtr ) 45 | { 46 | try 47 | { 48 | ASSERT_TRUE( m_strongClassifierBasePtr != NULL ); 49 | ASSERT_TRUE( cameraNetworkBasePtr != NULL ); 50 | 51 | Classifier::SampleSet positiveSampleSet; 52 | Classifier::SampleSet negativeSampleSet; 53 | 54 | LOG( "Generating Training Sample Sets for Appearance Fusion" ); 55 | 56 | cameraNetworkBasePtr->GenerateTrainingSampleSetsForAppearanceFusion( m_objectId, 57 | positiveSampleSet, 58 | negativeSampleSet ); 59 | 60 | ASSERT_TRUE( positiveSampleSet.Size() > 0 ); 61 | ASSERT_TRUE( negativeSampleSet.Size() > 0 ); 62 | 63 | Classifier::SampleSet randomPositiveSampleSet; 64 | Classifier::SampleSet randomNegativeSampleSet; 65 | if( MULTIPLE_POSITIVE_BAG == 0 ) 66 | {//randomly remove positive and negative samples for robustness 67 | for ( int sampleIndex = 0; sampleIndex < positiveSampleSet.Size(); sampleIndex++ ) 68 | { 69 | if ( randfloat() > RANDOM_SAMPLE_SELECTION_THRESHOLD ) 70 | { 71 | randomPositiveSampleSet.PushBackSample( positiveSampleSet[sampleIndex] ); 72 | } 73 | } 74 | 75 | for ( int sampleIndex = 0; sampleIndex < negativeSampleSet.Size(); sampleIndex++ ) 76 | { 77 | if ( randfloat() > RANDOM_SAMPLE_SELECTION_THRESHOLD ) 78 | { 79 | randomNegativeSampleSet.PushBackSample( negativeSampleSet[sampleIndex] ); 80 | } 81 | } 82 | m_strongClassifierBasePtr->Update( randomPositiveSampleSet, randomNegativeSampleSet ); 83 | } 84 | else 85 | { 86 | m_strongClassifierBasePtr->Update( positiveSampleSet, negativeSampleSet,5 ); 87 | } 88 | } 89 | EXCEPTION_CATCH_AND_ABORT( "Failed while learning the global appearance model" ); 90 | } 91 | 92 | /******************************************************************** 93 | FuseInformation 94 | Fuse information by . 95 | Exceptions: 96 | None 97 | *********************************************************************/ 98 | void AppearanceBasedInformationFuser::FuseInformation( Classifier::SampleSet& testSampleSet, vectorf& likelihoodProbabilities ) 99 | { 100 | try 101 | { 102 | ASSERT_TRUE( testSampleSet.Size() > 0 ); 103 | ASSERT_TRUE( likelihoodProbabilities.size( ) == testSampleSet.Size() ); 104 | ASSERT_TRUE( m_strongClassifierBasePtr != NULL ); 105 | 106 | likelihoodProbabilities = m_strongClassifierBasePtr->Classify( testSampleSet ); 107 | 108 | //Use sigmoidal function 109 | for ( int index = 0; index < likelihoodProbabilities.size(); index++ ) 110 | { 111 | likelihoodProbabilities[index] = pow( sigmoid( likelihoodProbabilities[index] ), 1 ); 112 | } 113 | 114 | float totalWeight = 0.0f; 115 | for ( int i = 0; i < testSampleSet.Size(); i++ ) 116 | { 117 | totalWeight += max( likelihoodProbabilities[i], 0.0f ); 118 | } 119 | } 120 | EXCEPTION_CATCH_AND_ABORT( "Failed to Fuse AppearanceBased Information" ); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/AppearanceBasedInformationFuser.h: -------------------------------------------------------------------------------- 1 | #ifndef APPERANCE_INFORMATION_FUSER 2 | #define APPERANCE_INFORMATION_FUSER 3 | 4 | #include "StrongClassifierBase.h" 5 | #include "CameraNetworkBase.h" 6 | #include "TrackerParameters.h" 7 | #include "CommonMacros.h" 8 | #include "Matrix.h" 9 | #include "Config.h" 10 | 11 | #include 12 | 13 | namespace MultipleCameraTracking 14 | { 15 | /**************************************************************** 16 | AppearanceBasedInformationFuser 17 | AppearanceBasedInformationFuser fuses appearance 18 | information from multiple cameras. 19 | ****************************************************************/ 20 | class AppearanceBasedInformationFuser 21 | { 22 | public: 23 | // Constructor 24 | AppearanceBasedInformationFuser( const int objectId, 25 | const int cameraId, 26 | const AppearanceFusionType appearanceFusionType, 27 | Classifier::StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ); 28 | 29 | // Learn Global Appearance Model 30 | void LearnGlobalAppearanceModel( CameraNetworkBasePtr cameraNetworkBasePtr ); 31 | 32 | // Compute Likelihoods 33 | void FuseInformation( Classifier::SampleSet& testSampleSet, 34 | vectorf& likelihoodProbabilities ); 35 | 36 | private: 37 | 38 | DISALLOW_IMPLICIT_CONSTRUCTORS( AppearanceBasedInformationFuser ); 39 | 40 | const int m_objectId; 41 | const int m_cameraId; 42 | const AppearanceFusionType m_appearanceFusionType; 43 | Classifier::StrongClassifierBasePtr m_strongClassifierBasePtr; 44 | Classifier::StrongClassifierParametersBasePtr m_strongClassifierParametersBasePtr; 45 | }; 46 | 47 | //typedef for boost pointer 48 | typedef boost::shared_ptr AppearanceBasedInformationFuserPtr; 49 | } 50 | #endif -------------------------------------------------------------------------------- /src/Camera.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERA_HEADER 2 | #define CAMERA_HEADER 3 | 4 | #include "Matrix.h" 5 | #include "Feature.h" 6 | #include "Tracker.h" 7 | #include "Public.h" 8 | #include "Object.h" 9 | #include "CameraNetworkBase.h" 10 | #include "DefaultParameters.h" 11 | #include "Config.h" 12 | 13 | #include 14 | 15 | using namespace boost; 16 | 17 | namespace MultipleCameraTracking 18 | { 19 | enum ObjectTrackingStatus 20 | { 21 | OBJECT_TRACKING_UN_INITIALIZED = 0, 22 | OBJECT_TRACKING_IN_PROGRESS = 2, 23 | OBJECT_TRACKING_SUSPENDED = 3 24 | }; 25 | 26 | /**************************************************************** 27 | Camera 28 | This class is the heart of the tracking system. 29 | It holds all the information about cameras, various parameters. 30 | Objects are stored in a list. Objects across camera views are 31 | associated by their objectId. 32 | ****************************************************************/ 33 | class Camera 34 | { 35 | public: 36 | //Constructor 37 | Camera( const int cameraId, 38 | const vectori& objectIdList, 39 | CameraTrackingParametersPtr cameraTrackingParametersPtr ); 40 | 41 | ~Camera( ){ } 42 | 43 | int GetCameraID( ) const { return m_cameraID; }; 44 | ObjectPtr GetObjectPtr( const int objectId ) const; 45 | 46 | Matrixu* GetColorImageMatrix( ){ return m_pCurrentFrameImageMatrixColor; } 47 | Matrixu* GetGrayImageMatrix( ){ return m_pCurrentFrameImageMatrixGray; } 48 | Matrixu* GetHSVImageMatrix( ){ return &m_HSVImageMatrix; } 49 | 50 | //Learn global appearance model using the appearance fuser 51 | void LearnGlobalAppearanceModel( CameraNetworkBasePtr cameraNetworkBasePtr ); 52 | 53 | //Get reprojected particles from the ground plane 54 | CvMat* GetReprojectedParticlesForGeometricFusion( const int objectInd ); 55 | CvMat* GetAverageImageParticleForGeometricFusion( const int objectInd ); 56 | 57 | //Initializes the parameters for the camera 58 | void InitializeCameraParameters( const vectori& objectIdList ); 59 | 60 | //initialize all object trackers inside the camera 61 | void InitializeCameraTrackers( ); 62 | 63 | //Track all objects inside a Camera Frame 64 | void TrackCameraFrame( int frameInd ); 65 | 66 | //Store the particle filter tracker state 67 | void StoreAllParticleFilterTrackerState( int frameInd ); 68 | 69 | //Update the particle filter tracker appearance 70 | void LearnLocalAppearanceModel( int frameInd); 71 | 72 | //Save the state on the output trajectory files 73 | void SaveStatesAllFrames( ); 74 | 75 | //Update particle weights based on the ground plane kalman filter's pdf 76 | void UpdateParticleWeightsWithGroundPDF( CvMat* pMeanMatrix, CvMat* pCovarianceMatrix, int objectId ); 77 | 78 | //Get homography matrix 79 | CvMat* GetHomographyMatrix( ){ return m_pHomographyMatrix; } 80 | 81 | //draw object's predicted foot points on the image 82 | void DrawAllObjectFootPoints( ); 83 | 84 | private: 85 | 86 | DISALLOW_IMPLICIT_CONSTRUCTORS( Camera ); 87 | 88 | //update display for tracked frame 89 | void DisplayAndSaveTrackedFrame( ); 90 | 91 | //update display for training samples 92 | void DisplayAndSaveTrainingSamples(); 93 | 94 | //auto-initialize object, occlusion detection, handling, and resumption 95 | void MultipleObjectInteraction( ) { /*implement this*/ }; 96 | 97 | // create temporary frame image for displaying, tracking, initialization integral image etc. when necessary 98 | void PrepareCurrentFrameForTracking( int frameInd ); 99 | 100 | //camera property 101 | CvMat* m_pHomographyMatrix; //Stores the Homography 102 | int m_cameraID; //Camera ID 103 | vector m_objectPtrList; //List of objects being tracked 104 | vector m_objectStatusList; //List of object status 105 | 106 | 107 | //input data parameters 108 | vector m_videoMatrix; //Input video Sequence for tracking 109 | bool m_sourceIsColorImage; //read input video as color 110 | bool m_readImages; //read images or video stream 111 | Matrixf m_frameMatrix; //Stores starting and ending frame numbers 112 | Matrixf m_initialState; //Initial states for all objects 113 | 114 | Matrixu* m_pCurrentFrameImageMatrixGray; //a pointer to the currently tracked frame (Gray image) 115 | Matrixu* m_pCurrentFrameImageMatrixHSV; //a pointer to the currently tracked frame (HSV image) 116 | Matrixu* m_pCurrentFrameImageMatrixColor;//a pointer to the currently tracked frame (Color image) 117 | Matrixu m_grayScaleImageMatrix; //a temporary black and white image for Haar feature calculation if raw video is color 118 | Matrixu m_HSVImageMatrix; //a temporal HSV image matrix for HSV related feature calculation if hsv is needed. 119 | 120 | //tracking parameters 121 | //the following parameters "typically" passed from the owner CameraNetwork class 122 | CameraTrackingParametersPtr m_cameraTrackingParametersPtr; 123 | 124 | //output results (including displaying) 125 | const char* m_outputDirectoryCstr; //Directory for output result 126 | bool m_displayTrackedVideo; // display video with tracker state (colored box) 127 | bool m_saveTrackedVideo; // save video with tracking box 128 | CvVideoWriter* m_pVideoWriter; // if m_saveTrackedVideo == true 129 | Matrixu m_frameDisplay; //for displaying and saving tracked frame 130 | Matrixu* m_pFrameDisplay; 131 | 132 | bool m_displayTrainingSamples; // display video with training examples 133 | bool m_saveVideoTrainingExamples;//save the training examples 134 | CvVideoWriter* m_pVideoWriterTraining; //for saving training example on frame 135 | Matrixu m_frameDisplayTraining; //for displaying and saving training examples on frame 136 | Matrixu* m_pFrameDisplayTraining; 137 | 138 | vector m_groundTruthMatrixList; //hold the ground truth for each object in the camera 139 | }; 140 | 141 | //typedef for camera pointer 142 | typedef boost::shared_ptr CameraPtr; 143 | typedef std::vector CameraPtrList; 144 | } 145 | #endif -------------------------------------------------------------------------------- /src/CameraNetwork.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERA_NETWORK_HEADER 2 | #define CAMERA_NETWORK_HEADER 3 | 4 | #include "CameraNetworkBase.h" 5 | #include "Camera.h" 6 | #include "GeometryBasedInformationFuser.h" 7 | #include 8 | 9 | using namespace boost; 10 | 11 | namespace MultipleCameraTracking 12 | { 13 | /**************************************************************** 14 | CameraNetwork 15 | Camera Network encapsulates all the functions of a network. 16 | It holds a list of cameras, all the messages to each of the 17 | camera is passed through this class. 18 | ****************************************************************/ 19 | class CameraNetwork : public CameraNetworkBase 20 | { 21 | public : 22 | 23 | //Constructor 24 | CameraNetwork( const vectori cameraIdList, 25 | const vectori objectIdList, 26 | CameraTrackingParametersPtr cameraTrackingParametersPtr ); 27 | 28 | //Destructor 29 | ~CameraNetwork( ); 30 | 31 | //Generates training example for appearance fusion 32 | virtual void GenerateTrainingSampleSetsForAppearanceFusion( const int objectId, 33 | Classifier::SampleSet& positiveSampleSet, 34 | Classifier::SampleSet& negativeSampleSet ); 35 | 36 | //Track Objects on a given frame across different views 37 | virtual void TrackObjectsOnCurrentFrame( const int frameInd ); 38 | 39 | //Save Camera Network state in a file(if enabled) 40 | virtual void SaveCameraNetworkState( ); 41 | 42 | private : 43 | 44 | DISALLOW_IMPLICIT_CONSTRUCTORS( CameraNetwork ); 45 | 46 | void FeedbackInformationFromGeometricFusion( int frameIndex ); 47 | void FuseGeometrically( int frameIndex ); 48 | vector GetHomographyMatrixList( ); 49 | 50 | void InitializeCameraNetwork( ); 51 | void InitializeGeometricFuser( ); 52 | 53 | 54 | const int m_numberOfCameras; 55 | const int m_numberOfObjects; 56 | const vectori m_cameraIdList; 57 | const vectori m_objectIdList; 58 | CameraPtrList m_cameraPtrList; 59 | CameraTrackingParametersPtr m_cameraTrackingParametersPtr; 60 | vector m_groundPlaneParticlesPtrList; 61 | GeometryBasedInformationFuserPtrList m_geometricInformationFuserPtrList; 62 | vector m_videoWriterListGroundParticles; 63 | vector m_videoWriterListKFDistribution; 64 | vector m_videoWriterListGroundParticlesAfterFusion; 65 | }; 66 | 67 | //typedef for CameraNetwork pointer 68 | typedef boost::shared_ptr CameraNetworkPtr; 69 | } 70 | #endif -------------------------------------------------------------------------------- /src/CameraNetworkBase.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERA_NETWORK_BASE 2 | #define CAMERA_NETWORK_BASE 3 | 4 | #include "CommonMacros.h" 5 | #include "SampleSet.h" 6 | 7 | #include 8 | 9 | namespace MultipleCameraTracking 10 | { 11 | /**************************************************************** 12 | CameraNetworkBase 13 | A Base class for CameraNetwork. This is an abstract interface. 14 | Mainly for message passing across different cameras. 15 | ****************************************************************/ 16 | class CameraNetworkBase 17 | { 18 | public: 19 | virtual void GenerateTrainingSampleSetsForAppearanceFusion( const int objectId, Classifier::SampleSet& positiveSampleSet, Classifier::SampleSet& negativeSampleSet ) = 0; 20 | 21 | //Save Camera Network state in a file(if enabled) 22 | virtual void SaveCameraNetworkState( ) = 0; 23 | 24 | //Track Objects on a given frame across different views 25 | virtual void TrackObjectsOnCurrentFrame( const int frameIndex ) = 0; 26 | }; 27 | 28 | //typedef for CameraNetworkBase pointer - do not use shared_ptr, it will delete the local ptr when it goes out of scope 29 | typedef CameraNetworkBase* CameraNetworkBasePtr; 30 | }; 31 | #endif 32 | -------------------------------------------------------------------------------- /src/ClassifierParameters.h: -------------------------------------------------------------------------------- 1 | #ifndef CLASSIFIER_PARAMETERS_H 2 | #define CLASSIFIER_PARAMETERS_H 3 | 4 | #include "Public.h" 5 | #include "Feature.h" 6 | #include "WeakClassifierBase.h" 7 | #include "DefaultParameters.h" 8 | 9 | namespace Classifier 10 | { 11 | enum StrongClassifierType 12 | { 13 | ONLINE_ADABOOST = 0, // [0] Online AdaBoost (Oza/Grabner) 14 | //ONLINE_STOCHASTIC_BOOST_LR = 1, // [1] Online StochBoost_LR 15 | ONLINE_STOCHASTIC_BOOST_MIL = 2, // [2] Online StochBoost_MIL 16 | ONLINE_ENSEMBLE_BOOST_MIL = 3, // [3] Online Ensemble_MIL 17 | ONLINE_ANY_BOOST_MIL = 4, // [4] ONLINE STOCHBOOST_MIL With anyboost 18 | }; 19 | 20 | //Forward Declaration 21 | class StrongClassifierParametersBase; 22 | class AdaBoostClassifierParameters; 23 | class MILBoostClassifierParameters; 24 | class MILEnsembleClassifierParameters; 25 | class MILAnyBoostClassifierParameters; 26 | 27 | //declarations of shared ptr 28 | typedef boost::shared_ptr StrongClassifierParametersBasePtr; 29 | typedef boost::shared_ptr AdaBoostClassifierParametersPtr; 30 | typedef boost::shared_ptr MILBoostClassifierParametersPtr; 31 | typedef boost::shared_ptr MILEnsembleClassifierParametersPtr; 32 | typedef boost::shared_ptr MILAnyBoostClassifierParametersPtr; 33 | 34 | /**************************************************************** 35 | StrongClassifierParametersBase 36 | Base class for all the strong classifier parameters. 37 | ****************************************************************/ 38 | class StrongClassifierParametersBase 39 | { 40 | public: 41 | StrongClassifierParametersBase( const int numberOfSelectedWeakClassifiers, 42 | const int totalNumberOfWeakClassifiers, 43 | const float percentageOfRetainedWeakClassifiers = 0, 44 | const float learningRate = DEFAULT_GAUSSIAN_WEAK_CLASSIFIER_LEARNING_RATE, 45 | const bool storeFeatureHistory = DEFAULT_STRONG_CLASSIFIER_STORE_FEATURE_HISTORY ) 46 | : m_featureParametersPtr( ), 47 | m_weakClassifierType( STUMP ), 48 | m_learningRate( learningRate ), 49 | m_storeFeatureHistory( storeFeatureHistory ), 50 | m_numberOfSelectedWeakClassifiers( numberOfSelectedWeakClassifiers ), 51 | m_totalNumberOfWeakClassifiers( totalNumberOfWeakClassifiers ), 52 | m_percentageOfRetainedWeakClassifiers( percentageOfRetainedWeakClassifiers/100.0f ) 53 | { 54 | } 55 | 56 | virtual StrongClassifierType GetClassifierType( ) const = 0; 57 | 58 | Features::FeatureParametersPtr m_featureParametersPtr; 59 | WeakClassifierType m_weakClassifierType; 60 | float m_learningRate; 61 | bool m_storeFeatureHistory; 62 | int m_numberOfSelectedWeakClassifiers; 63 | int m_totalNumberOfWeakClassifiers; 64 | float m_percentageOfRetainedWeakClassifiers; 65 | }; 66 | 67 | /**************************************************************** 68 | AdaBoostClassifierParameters 69 | Ada boost classifier parameters. 70 | ****************************************************************/ 71 | class AdaBoostClassifierParameters : public StrongClassifierParametersBase 72 | { 73 | public: 74 | AdaBoostClassifierParameters( const int numberOfSelectedWeakClassifiers, 75 | const int totalNumberOfWeakClassifiers ) 76 | : StrongClassifierParametersBase( numberOfSelectedWeakClassifiers, 77 | totalNumberOfWeakClassifiers ) 78 | { 79 | } 80 | 81 | virtual StrongClassifierType GetClassifierType( ) const { return ONLINE_ADABOOST; }; 82 | }; 83 | 84 | /**************************************************************** 85 | MILBoostClassifierParameters 86 | MIL boost classifier parameters. 87 | ****************************************************************/ 88 | class MILBoostClassifierParameters : public StrongClassifierParametersBase 89 | { 90 | public: 91 | MILBoostClassifierParameters( const int numberOfSelectedWeakClassifiers, 92 | const int totalNumberOfWeakClassifiers ) 93 | : StrongClassifierParametersBase( numberOfSelectedWeakClassifiers, 94 | totalNumberOfWeakClassifiers ) 95 | { 96 | } 97 | 98 | virtual StrongClassifierType GetClassifierType( )const { return ONLINE_STOCHASTIC_BOOST_MIL; }; 99 | }; 100 | 101 | /**************************************************************** 102 | MILEnsembleClassifierParameters 103 | MIL Ensemble classifier parameters. 104 | ****************************************************************/ 105 | class MILEnsembleClassifierParameters : public StrongClassifierParametersBase 106 | { 107 | public: 108 | MILEnsembleClassifierParameters( const int numberOfSelectedWeakClassifiers, 109 | const int totalNumberOfWeakClassifiers, 110 | const float percentageOfRetainedWeakClassifiers ) 111 | : StrongClassifierParametersBase( numberOfSelectedWeakClassifiers, 112 | totalNumberOfWeakClassifiers, 113 | percentageOfRetainedWeakClassifiers ) 114 | { 115 | } 116 | virtual StrongClassifierType GetClassifierType( ) const { return ONLINE_ENSEMBLE_BOOST_MIL; }; 117 | }; 118 | 119 | /**************************************************************** 120 | MILAnyBoostClassifierParameters 121 | MIL Boost (AnyBoost) classifier parameters. 122 | ****************************************************************/ 123 | class MILAnyBoostClassifierParameters : public StrongClassifierParametersBase 124 | { 125 | public: 126 | MILAnyBoostClassifierParameters( const int numberOfSelectedWeakClassifiers, 127 | const int totalNumberOfWeakClassifiers ) 128 | : StrongClassifierParametersBase( numberOfSelectedWeakClassifiers, 129 | totalNumberOfWeakClassifiers ) 130 | { 131 | } 132 | 133 | virtual StrongClassifierType GetClassifierType( ) const { return ONLINE_ANY_BOOST_MIL; }; 134 | }; 135 | } 136 | #endif -------------------------------------------------------------------------------- /src/CommonMacros.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMONMACROS 2 | #define COMMONMACROS 3 | 4 | #include "Public.h" 5 | #include "Config.h" 6 | 7 | //Template function to Check if the parameter is valid 8 | template 9 | T CheckIfValidParameter( bool predicate, T arg, int line, char* file ) 10 | { 11 | if ( predicate ) 12 | { 13 | return arg; 14 | } 15 | else 16 | { 17 | abortError( line, file, "Precondition Failed on Parameter" ); 18 | } 19 | } 20 | 21 | #define EXCEPTION_CATCH_AND_ABORT(context) \ 22 | catch( std::exception& ex ) \ 23 | { \ 24 | std::cerr << "Context: " << context << " Error Message:" << ex.what() << endl; \ 25 | abortError( __LINE__, __FILE__, context ); \ 26 | } 27 | 28 | #define EXCEPTION_CATCH_AND_LOG(context) \ 29 | catch( std::exception& ex ) \ 30 | { \ 31 | g_logFile << "Context: " << context << " Error Message:" << ex.what() << endl; \ 32 | } 33 | 34 | #if defined(WIN32) || defined(WIN64) 35 | #define ASSERT_TRUE( predicate ) \ 36 | if ( (predicate) == false ) \ 37 | { \ 38 | DebugBreak(); \ 39 | abortError( __LINE__, __FILE__, "Assertion Failed." ); \ 40 | } 41 | #else 42 | #define ASSERT_TRUE( predicate ) \ 43 | if ( (predicate) == false ) \ 44 | { \ 45 | abortError( __LINE__, __FILE__, "Assertion Failed." ); \ 46 | } 47 | #endif 48 | 49 | #define ASSERT_PRECONDITION_PARAMETER( predicate, parameter ) \ 50 | CheckIfValidParameter( predicate, parameter, __LINE__, __FILE__ ) 51 | 52 | /* A macro to disallow the evil copy constructor and operator= functions 53 | This should be used in the private: declarations for a class */ 54 | #define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ 55 | TypeName(const TypeName&); \ 56 | void operator=(const TypeName&) 57 | 58 | /*A macro to disallow all the implicit constructors, namely the 59 | default constructor, copy constructor and operator= functions. 60 | This should be used in the private: declarations for a class 61 | that wants to prevent anyone from instantiating it. This is 62 | especially useful for classes containing only static methods.*/ 63 | #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 64 | TypeName(); \ 65 | DISALLOW_EVIL_CONSTRUCTORS(TypeName) 66 | 67 | #define LOG( context ) \ 68 | MultipleCameraTracking::g_logFile << context; \ 69 | if ( MultipleCameraTracking::g_verboseMode ) \ 70 | cout << context; 71 | 72 | #define LOG_CONSOLE( context ) \ 73 | cout << context 74 | 75 | #endif -------------------------------------------------------------------------------- /src/CultureColorHistogram.cpp: -------------------------------------------------------------------------------- 1 | #include "CultureColorHistogram.h" 2 | 3 | namespace Features 4 | { 5 | /**************************************************************** 6 | CultureColorHistogram 7 | Initialize the feature 8 | Exception: 9 | None. 10 | ****************************************************************/ 11 | void CultureColorHistogram::Generate( FeatureParametersPtr featureParametersPtr ) 12 | { 13 | CultureColorHistogramParametersPtr temp = boost::dynamic_pointer_cast(featureParametersPtr); 14 | m_partPercentageVertical = temp->m_partPercentageVertical; 15 | m_numberOfParts = temp->m_numberOfParts; 16 | } 17 | 18 | 19 | /**************************************************************** 20 | CultureColorHistogram 21 | Compute the feature for the sample 22 | Exception: 23 | None. 24 | ****************************************************************/ 25 | void CultureColorHistogram::Compute( const Classifier::Sample& sample, vectorf& featureValueList ) const 26 | { 27 | uint scaled_height = cvRound( static_cast(sample.m_height) * sample.m_scaleY ); 28 | uint scaled_width =cvRound( static_cast(sample.m_width) * sample.m_scaleX ); 29 | 30 | if( sample.GetHSVImage() == NULL ) 31 | { 32 | cv::Mat sampleImgHSV; 33 | // create HSV from sample image 34 | sample.GetColorImage()->createIpl(true); 35 | cv::Mat entireImg = sample.GetColorImage()->getIpl(); 36 | cv::Rect roi( sample.m_col, sample.m_row, scaled_width, scaled_height ); 37 | cv::Mat sampleImg = entireImg(roi); 38 | //cv::imshow(sampleImg, "testCultureColor"); 39 | cv::cvtColor( sampleImg, sampleImgHSV, CV_BGR2HSV ); 40 | ComputeFeature( sample, sampleImgHSV, featureValueList ); 41 | } 42 | else 43 | { 44 | Matrixu * pImgHSV = sample.GetHSVImage(); 45 | 46 | // Calculate the size for each part. 47 | vectori partRowList; 48 | int accum = 0, partEnd; 49 | 50 | 51 | partRowList.push_back( 0 ); 52 | for (int i = 0; i < m_numberOfParts; i++) 53 | { 54 | accum += m_partPercentageVertical[i]; 55 | partEnd = scaled_height*accum/100; 56 | ASSERT_TRUE ( partEnd > partRowList[i] ); 57 | partRowList.push_back( partEnd ); 58 | } 59 | 60 | // HSV Centroids: 61 | int numBins=11; 62 | // Red Pink purple blue green yellow orange brown bk gray white 63 | int HC[] = {5, 206, 181, 160, 81, 46, 28, 20, 110, 121, 133}; 64 | //int SC[] = {206,168, 186, 215, 188, 219, 211, 137, 14, 8, 15}; 65 | //int VC[] = {107,120, 117, 129, 104, 122, 137, 97, 2, 101, 237}; 66 | int i, j, byte, H=0, S=0, V=0, DistanceToCentroids[11], minimumDist, CC_Histogram[11], indicator; 67 | 68 | // calculate histogram for each part 69 | for( int partIndex = 0; partIndex < m_numberOfParts; partIndex++ ) 70 | { 71 | //initialization 72 | for( j = 1; j < numBins; j++) 73 | { 74 | CC_Histogram[j]=0; 75 | DistanceToCentroids[j] = 0; 76 | } 77 | 78 | for ( i = partRowList[partIndex]; i < partRowList[partIndex+1]; i++) 79 | { 80 | for ( j = 0; j < scaled_width; j++ ) 81 | { 82 | minimumDist = 999999; 83 | H = (*pImgHSV)( i+sample.m_row, j+sample.m_col, 0 ); 84 | //S = (*pImgHSV)( i+sample.m_row, j+sample.m_col, 1 ); 85 | //V = (*pImgHSV)( i+sample.m_row, j+sample.m_col, 2 ); 86 | for ( int c = 0; c < numBins; c++ ) 87 | { 88 | DistanceToCentroids[c]=sqrt( 89 | (double)(H-HC[0])*(double)(H-HC[0]) 90 | ); //hue channel only 91 | //+ long double(S-SC[0])*long double(S-SC[0]) 92 | //+ long double(V-VC[0])*long double(V-VC[0]) 93 | 94 | if( minimumDist > DistanceToCentroids[c] ) 95 | { 96 | minimumDist = DistanceToCentroids[c]; 97 | indicator = c; 98 | } 99 | } 100 | CC_Histogram[indicator]++; 101 | } 102 | } 103 | for( int c = 0; c < numBins; c++ ) 104 | { 105 | featureValueList[partIndex*numBins + c]= CC_Histogram[c]; 106 | } 107 | } //for each part 108 | 109 | 110 | } 111 | } 112 | 113 | /**************************************************************** 114 | CultureColorHistogram 115 | Compute the feature from sample HSV image of format cv::Mat 116 | Exception: 117 | None. 118 | ****************************************************************/ 119 | void CultureColorHistogram::ComputeFeature( const Classifier::Sample& sample, cv::Mat& sampleImgHSV, vectorf& featureValueList ) const 120 | { 121 | // Calculate the size for each part. 122 | vectori partRowList; 123 | int accum = 0, partEnd; 124 | 125 | partRowList.push_back( 0 ); 126 | for (int i = 0; i < m_numberOfParts; i++) 127 | { 128 | accum += m_partPercentageVertical[i]; 129 | partEnd = sample.m_height*accum/100; 130 | ASSERT_TRUE ( partEnd > partRowList[i] ); 131 | partRowList.push_back( partEnd ); 132 | } 133 | 134 | // HSV Centroids: 135 | int numBins=11; 136 | // Red Pink purple blue green yellow orange brown bk gray white 137 | int HC[] = {5, 206, 181, 160, 81, 46, 28, 20, 110, 121, 133}; 138 | //int SC[] = {206,168, 186, 215, 188, 219, 211, 137, 14, 8, 15}; 139 | //int VC[] = {107,120, 117, 129, 104, 122, 137, 97, 2, 101, 237}; 140 | int i, j, byte, H=0, S=0, V=0, DistanceToCentroids[11], MinimumDist, CC_Histogram[11], indicator; 141 | 142 | // calculate histogram for each part 143 | for( int partIndex = 0; partIndex < m_numberOfParts; partIndex++ ) 144 | { 145 | //initialization 146 | for( j = 1; j < numBins; j++) 147 | { 148 | CC_Histogram[j]=0; 149 | DistanceToCentroids[j] = 0; 150 | } 151 | 152 | for ( i = partRowList[partIndex]; i < partRowList[partIndex+1]; i++) 153 | { 154 | for ( j = 0; j < sample.m_width; j++ ) 155 | { 156 | MinimumDist =999999; 157 | H = sampleImgHSV.at( i, j)[0]; 158 | //S = sampleImgHSV.at( i, j)[1]; 159 | //V = sampleImgHSV.at( i, j)[2]; 160 | for ( int c = 0; c < numBins; c++ ) 161 | { 162 | DistanceToCentroids[c]=sqrt( 163 | (double)(H-HC[0])*(double)(H-HC[0]) 164 | ); //hue channel only 165 | //+ long double(S-SC[0])*long double(S-SC[0]) 166 | //+ long double(V-VC[0])*long double(V-VC[0]) 167 | 168 | if( MinimumDist > DistanceToCentroids[c] ) 169 | { 170 | MinimumDist = DistanceToCentroids[c]; 171 | indicator = c; 172 | } 173 | } 174 | CC_Histogram[indicator]++; 175 | } 176 | } 177 | for( int c = 0; c < numBins; c++ ) 178 | { 179 | featureValueList[partIndex*numBins + c]= CC_Histogram[c]; 180 | } 181 | } //for each part 182 | 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/CultureColorHistogram.h: -------------------------------------------------------------------------------- 1 | #ifndef CULTURE_COLOR 2 | #define CULTURE_COLOR 3 | 4 | #include "Feature.h" 5 | 6 | namespace Features 7 | { 8 | /**************************************************************** 9 | CultureColorHistogram 10 | A multi dimensional culture color histogram obtained by dividing 11 | the blob into horizontal slices (parts) and concatenates the culture 12 | color histogram of each part 13 | ****************************************************************/ 14 | class CultureColorHistogram : public Feature 15 | { 16 | public: 17 | CultureColorHistogram( ) { }; 18 | 19 | virtual const FeatureType GetFeatureType() const { return CULTURE_COLOR_HISTOGRAM; }; 20 | 21 | virtual float Compute( const Classifier::Sample& sample ) const 22 | { abortError( __LINE__, __FILE__, "CultureCoor is of more than one dimension" );; return 0.0f; } 23 | 24 | virtual void Compute( const Classifier::Sample& sample, vectorf& featureValueList ) const; 25 | 26 | virtual void Generate( FeatureParametersPtr featureParametersPtr ); 27 | 28 | private: 29 | vectori m_partPercentageVertical; // a list of percentage (of total height) for each part, must add up to 100 30 | uint m_numberOfParts; // number of parts 31 | void ComputeFeature( const Classifier::Sample& sample, cv::Mat& sampleImgHSV, vectorf& featureValueList ) const; 32 | }; 33 | } 34 | #endif -------------------------------------------------------------------------------- /src/CultureColorHistogramFeatureVector.cpp: -------------------------------------------------------------------------------- 1 | #include "CultureColorHistogramFeatureVector.h" 2 | #include "CultureColorHistogram.h" 3 | 4 | namespace Features 5 | { 6 | /**************************************************************** 7 | CultureColorHistogramFeatureVector::Generate 8 | Generates FeatureVector based on the specified feature type. 9 | Feature stores the culture color histogram. 10 | Note:parameter "numberOfFeatures" is not used as the size of feature vector 11 | is pre-determined. 12 | Exception: 13 | None 14 | ****************************************************************/ 15 | void CultureColorHistogramFeatureVector::Generate( FeatureParametersPtr featureParametersPtr ) 16 | { 17 | try 18 | { 19 | ASSERT_TRUE( featureParametersPtr != NULL ); 20 | 21 | m_featureParametersPtr = featureParametersPtr; 22 | 23 | m_featurePtr = boost::shared_ptr( new CultureColorHistogram() ); 24 | 25 | ASSERT_TRUE( m_featurePtr != NULL ); 26 | 27 | m_numberOfCultureColorFeatures = m_featureParametersPtr->GetColorFeatureDimension( ); 28 | 29 | m_featurePtr->Generate( m_featureParametersPtr ); 30 | 31 | //Update the feature generated flag 32 | m_isFeatureGenerated = true; 33 | 34 | m_startingIndexForFeatureMatrix = m_featureParametersPtr->GetHaarFeatureDimension( ); 35 | } 36 | EXCEPTION_CATCH_AND_ABORT( "Error While Generating CultureColorHistogram Feature Vector" ); 37 | } 38 | 39 | /**************************************************************** 40 | CultureColorHistogramFeatureVector::Compute 41 | Iterate over each sample in the given Classifier::SampleSet 42 | and compute the featurePtr. Store the computed featurePtr value 43 | in the featurePtr vector. 44 | Classifier calls this method with a set of samples for each type. 45 | Exception: 46 | None 47 | ****************************************************************/ 48 | void CultureColorHistogramFeatureVector::Compute( Classifier::SampleSet& sampleSet, bool shouldResizeFeatureMatrix ) 49 | { 50 | size_t numberOfSamples = sampleSet.Size( ); 51 | 52 | ASSERT_TRUE( m_isFeatureGenerated == true ); 53 | ASSERT_TRUE( m_numberOfCultureColorFeatures > 0 ); 54 | 55 | //return if no sample is available 56 | if ( numberOfSamples == 0 ) 57 | { 58 | return; 59 | } 60 | 61 | if ( shouldResizeFeatureMatrix ) 62 | { 63 | //resize the feature matrix size to the number of features 64 | sampleSet.ResizeFeatures( m_numberOfCultureColorFeatures ); 65 | } 66 | 67 | #pragma omp parallel for 68 | for ( int sampleIndex = 0; sampleIndex < numberOfSamples; sampleIndex++ ) 69 | { 70 | vectorf histVector( m_numberOfCultureColorFeatures, 0.0f ); 71 | m_featurePtr->Compute( sampleSet[sampleIndex], histVector ); 72 | 73 | ASSERT_TRUE( histVector.size( ) == m_numberOfCultureColorFeatures ); 74 | 75 | for ( uint featureIndex = m_startingIndexForFeatureMatrix; featureIndex < (m_startingIndexForFeatureMatrix+m_numberOfCultureColorFeatures); featureIndex++ ) 76 | { 77 | //store the feature value in the feature matrix 78 | sampleSet.GetFeatureValue( sampleIndex, featureIndex ) = histVector[featureIndex]; 79 | } 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/CultureColorHistogramFeatureVector.h: -------------------------------------------------------------------------------- 1 | #ifndef CULTURE_COLOR_FEATURE_VECTOR_H 2 | #define CULTURE_COLOR_FEATURE_VECTOR_H 3 | 4 | #include "FeatureVector.h" 5 | 6 | namespace Features 7 | { 8 | /**************************************************************** 9 | CultureColorHistogramFeatureVector 10 | This is a wrapper class for CultureColorHistogram. 11 | ****************************************************************/ 12 | class CultureColorHistogramFeatureVector :virtual public FeatureVector 13 | { 14 | public: 15 | virtual void Generate( FeatureParametersPtr featureParametersPtr ); 16 | virtual void Compute( Classifier::SampleSet& sampleSet, bool shouldResizeFeatureMatrix = true ); 17 | virtual void SaveVisualizedFeatureVector( const char *dirName ){} 18 | 19 | 20 | virtual const uint GetNumberOfFeatures( ) const { return m_numberOfCultureColorFeatures; } 21 | 22 | private: 23 | FeaturePtr m_featurePtr; 24 | uint m_numberOfCultureColorFeatures; 25 | uint m_startingIndexForFeatureMatrix; 26 | }; 27 | } 28 | #endif -------------------------------------------------------------------------------- /src/DefaultParameters.h: -------------------------------------------------------------------------------- 1 | #ifndef H_DEFAULT_PARAMS 2 | #define H_DEFAULT_PARAMS 3 | 4 | namespace MultipleCameraTracking 5 | { 6 | //default classifier parameters 7 | // #define DEFAULT_TRACKER_INIT_NEG_NUM_TRAIN 65 //default value for SimpleTrackerParameters.m_init_negNumTrain 8 | // #define DEFAULT_TRACKER_INIT_POS_RADIUS_TRAIN 3.0F //default value for SimpleTrackerParameters.m_init_posTrainRadius 9 | #define DEFAULT_TRACKER_INIT_WITH_FACE false //default value for SimpleTrackerParameters.m_initWithFace 10 | #define DEFAULT_TRACKER_DEBUGV false //default value for SimpleTrackerParameters.m_debugv 11 | 12 | #define DEFAULT_PFTRACKER_NOT_USE_SIGMOIDAL true //default TrackerParameters.m_shouldNotUseSigmoid for PFTracker, i.e. use sigmoid function to calculate probability 13 | 14 | #define DEFAULT_HAAR_MINIMUM_NUMBER_OF_RECTANGLES 2 15 | #define DEFAULT_HAAR_MAXIMUM_NUMBER_OF_RECTANGLES 6 16 | #define DEFAULT_HAAR_NUMBER_OF_CHANNELS -1 17 | 18 | #define DEFAULT_GAUSSIAN_WEAK_CLASSIFIER_LEARNING_RATE 0.85f 19 | #define DEFAULT_STRONG_CLASSIFIER_STORE_FEATURE_HISTORY true 20 | } 21 | #endif -------------------------------------------------------------------------------- /src/Exception.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace Exception 5 | { 6 | /**************************************************************** 7 | AssertionFailed 8 | ****************************************************************/ 9 | class AssertionFailed: public std::exception 10 | { 11 | AssertionFailed( const unsigned int lineNumber, 12 | const char* fileName, 13 | const char* errorMessage ) 14 | : std::exception( ), 15 | m_lineNumber( lineNumber ), 16 | m_fileName( fileName ), 17 | m_errorMessage( errorMessage ) 18 | { 19 | } 20 | 21 | virtual const char* what( ) const throw( ) 22 | { 23 | return m_errorMessage; 24 | } 25 | 26 | private: 27 | const unsigned int m_lineNumber; 28 | const char* m_fileName; 29 | const char* m_errorMessage; 30 | }; 31 | 32 | /**************************************************************** 33 | PreconditionFailed 34 | ****************************************************************/ 35 | class PreconditionFailed: public std::exception 36 | { 37 | PreconditionFailed( const unsigned int lineNumber, 38 | const char* fileName, 39 | const char* errorMessage ) 40 | : std::exception( ), 41 | m_lineNumber( lineNumber ), 42 | m_fileName( fileName ), 43 | m_errorMessage( errorMessage ) 44 | { 45 | } 46 | 47 | virtual const char* what( ) const throw( ) 48 | { 49 | return m_errorMessage; 50 | } 51 | 52 | private: 53 | const unsigned int m_lineNumber; 54 | const char* m_fileName; 55 | const char* m_errorMessage; 56 | }; 57 | 58 | /**************************************************************** 59 | ConfigurationParameterNotFound 60 | ****************************************************************/ 61 | class ConfigurationParameterNotFound : public std::exception 62 | { 63 | ConfigurationParameterNotFound( const char* parameterName, 64 | const unsigned int lineNumber, 65 | const char* fileName, 66 | const char* errorMessage ) 67 | : std::exception( ), 68 | m_parameterName( parameterName ), 69 | m_lineNumber( lineNumber ), 70 | m_fileName( fileName ), 71 | m_errorMessage( errorMessage ) 72 | { 73 | } 74 | 75 | virtual const char* what( ) const throw( ) 76 | { 77 | return m_errorMessage; 78 | } 79 | 80 | private: 81 | const unsigned int m_lineNumber; 82 | const char* m_fileName; 83 | const char* m_errorMessage; 84 | const char* m_parameterName; 85 | }; 86 | } 87 | -------------------------------------------------------------------------------- /src/Feature.h: -------------------------------------------------------------------------------- 1 | #ifndef H_IMGFTR 2 | #define H_IMGFTR 3 | 4 | #include "FeatureParameters.h" 5 | #include "Matrix.h" 6 | #include "Public.h" 7 | #include "SampleSet.h" 8 | #include "CommonMacros.h" 9 | 10 | #include 11 | 12 | namespace Features 13 | { 14 | //Forward Declaration 15 | class Feature; 16 | class FeatureVector; 17 | 18 | typedef boost::shared_ptr FeaturePtr; 19 | typedef vector FeatureList; 20 | 21 | /**************************************************************** 22 | Feature 23 | Base class for Feature. 24 | ****************************************************************/ 25 | class Feature 26 | { 27 | public: 28 | 29 | //Pure Virtual function 30 | virtual const FeatureType GetFeatureType( ) const = 0; 31 | 32 | //create (initialize) a feature instance from associated feature parameters 33 | virtual void Generate( FeatureParametersPtr featureParametersPtr ) = 0; 34 | 35 | //compute the feature value for the given sample (for one-dim feature vector) 36 | virtual float Compute( const Classifier::Sample& sample ) const = 0; 37 | 38 | //compute the feature value for the given sample (for multi-dim feature vector) 39 | virtual void Compute( const Classifier::Sample& sample, vectorf& featureValueList ) const = 0; 40 | 41 | //visualize the feature for debugging 42 | virtual Matrixu ToVisualize( int featureIndex = -1 ) { Matrixu empty; return empty; }; 43 | }; 44 | } 45 | #endif -------------------------------------------------------------------------------- /src/FeatureParameters.cpp: -------------------------------------------------------------------------------- 1 | #include "FeatureParameters.h" 2 | #include "DefaultParameters.h" 3 | 4 | namespace Features 5 | { 6 | /**************************************************************** 7 | HaarFeatureParameters: Haar-Like Feature Parameters 8 | Default Constructor 9 | ****************************************************************/ 10 | HaarFeatureParameters::HaarFeatureParameters( uint featureDimensionHaar ) 11 | : m_minimumNumberOfRectangles ( DEFAULT_HAAR_MINIMUM_NUMBER_OF_RECTANGLES ), 12 | m_maximumNumberOfRectangles ( DEFAULT_HAAR_MAXIMUM_NUMBER_OF_RECTANGLES ), 13 | m_numberOfChannels( DEFAULT_HAAR_NUMBER_OF_CHANNELS ), 14 | m_featureDimensionHaar( featureDimensionHaar ) 15 | { 16 | for ( int channelIndex = 0; channelIndex < 1024; channelIndex++ ) 17 | { 18 | m_useChannels[channelIndex] = -1; 19 | } 20 | m_useChannels[0] = 0; 21 | } 22 | 23 | /**************************************************************** 24 | CultureColorHistogramParameters 25 | Default Constructor (single part) 26 | ****************************************************************/ 27 | CultureColorHistogramParameters::CultureColorHistogramParameters( ) 28 | : m_numberOfParts(1), 29 | m_featureDimensionForCultureColor( DEFAULT_CULTURE_COLOR_DIM ), 30 | m_partPercentageVertical( 1, 100 ) 31 | { 32 | 33 | } 34 | 35 | /**************************************************************** 36 | CultureColorHistogramParameters 37 | Constructor with exact part information ( a list of percentages) 38 | ****************************************************************/ 39 | CultureColorHistogramParameters::CultureColorHistogramParameters( vectori partPercentageVertical ) 40 | : m_numberOfParts( partPercentageVertical.size() ), 41 | m_featureDimensionForCultureColor( partPercentageVertical.size()*DEFAULT_CULTURE_COLOR_DIM ), 42 | m_partPercentageVertical( partPercentageVertical ) 43 | { 44 | int count = 0; 45 | for (int i=0; i < partPercentageVertical.size(); i++) 46 | { 47 | ASSERT_TRUE(partPercentageVertical[i] > 0); 48 | count += partPercentageVertical[i]; 49 | } 50 | 51 | ASSERT_TRUE(count == 100); 52 | } 53 | } -------------------------------------------------------------------------------- /src/FeatureParameters.h: -------------------------------------------------------------------------------- 1 | #ifndef H_FEATURE_PARAMETERS 2 | #define H_FEATURE_PARAMETERS 3 | 4 | #define DEFAULT_CULTURE_COLOR_DIM 11 5 | #define COLOR_NUM_PARTS 1 //1, 2, etc. 6 | #include "Public.h" 7 | #include "CommonMacros.h" 8 | #include 9 | 10 | namespace Features 11 | { 12 | enum FeatureType { HAAR_LIKE = 0, 13 | CULTURE_COLOR_HISTOGRAM = 1, 14 | MULTI_DIMENSIONAL_COLOR_HISTOGRAM = 2, 15 | HAAR_COLOR_HISTOGRAM = 3, 16 | }; 17 | 18 | //Forward Declaration 19 | class FeatureParameters; 20 | class HaarFeatureParameters; 21 | class MultiDimensionalColorHistogramParameters; 22 | class CultureColorHistogramParameters; 23 | class HaarAndColorHistogramFeatureParameters; 24 | 25 | //typedef 26 | typedef boost::shared_ptr FeatureParametersPtr; 27 | typedef boost::shared_ptr HaarFeatureParametersPtr; 28 | typedef boost::shared_ptr MultiDimensionalColorHistogramParametersPtr; 29 | typedef boost::shared_ptr CultureColorHistogramParametersPtr; 30 | typedef boost::shared_ptr HaarAndColorHistogramFeatureParametersPtr; 31 | 32 | /***************************************************************** 33 | FeatureParameters 34 | Abstract class for feature parameters. 35 | ****************************************************************/ 36 | class FeatureParameters 37 | { 38 | public: 39 | virtual FeatureType GetFeatureType( ) const = 0; 40 | virtual uint GetFeatureDimension( ) const = 0; 41 | 42 | virtual uint GetColorFeatureDimension( ) const = 0; 43 | virtual uint GetHaarFeatureDimension( ) const = 0; 44 | 45 | uint m_width; // original width of the rectangular blob on which the feature is calculated 46 | uint m_height; // original height of the rectangular blob on which the feature is calculated 47 | }; 48 | 49 | /**************************************************************** 50 | HaarFeatureParameters 51 | General Haar Feature Parameters 52 | ****************************************************************/ 53 | class HaarFeatureParameters : virtual public FeatureParameters 54 | { 55 | public: 56 | HaarFeatureParameters( uint featureDimensionHaar ); 57 | 58 | virtual FeatureType GetFeatureType() const { return HAAR_LIKE; } 59 | 60 | virtual uint GetFeatureDimension( ) const { return m_featureDimensionHaar; } 61 | 62 | virtual uint GetColorFeatureDimension( ) const { return 0;} 63 | virtual uint GetHaarFeatureDimension( ) const { return m_featureDimensionHaar; } 64 | 65 | friend class HaarFeature; 66 | 67 | protected: 68 | uint m_maximumNumberOfRectangles; 69 | uint m_minimumNumberOfRectangles; 70 | int m_useChannels[1024]; // >=0: used; <0:not used 71 | int m_numberOfChannels; // number of channels used for the computation of feature 72 | uint m_featureDimensionHaar; 73 | }; 74 | 75 | /**************************************************************** 76 | MultiDimensionalColorHistogramParameters 77 | Multi Dimensional Color Histogram Parameters 78 | ****************************************************************/ 79 | class MultiDimensionalColorHistogramParameters : virtual public FeatureParameters 80 | { 81 | public: 82 | MultiDimensionalColorHistogramParameters( bool useHSVColor = false, uint numberOfBins = 8 ) 83 | : m_numberOfBins (numberOfBins), 84 | m_numberOfParts( COLOR_NUM_PARTS ), 85 | m_partPercentageVertical( COLOR_NUM_PARTS, 100/COLOR_NUM_PARTS ), 86 | m_featureDimensionColor( numberOfBins * numberOfBins * numberOfBins * m_numberOfParts ), 87 | m_useHSVColorSpace( useHSVColor ) 88 | { 89 | 90 | } 91 | 92 | virtual FeatureType GetFeatureType( ) const { return MULTI_DIMENSIONAL_COLOR_HISTOGRAM; }; 93 | virtual uint GetFeatureDimension( ) const { return m_featureDimensionColor; } 94 | 95 | virtual uint GetColorFeatureDimension( ) const { return m_featureDimensionColor;} 96 | virtual uint GetHaarFeatureDimension( ) const { return 0; } 97 | 98 | friend class MultiDimensionalColorHistogram; 99 | 100 | protected: 101 | const uint m_numberOfBins; //number of bins for each color 102 | const vectori m_partPercentageVertical; // a list of percentage (of total height) for each part, must add up to 100 103 | const uint m_numberOfParts; // number of parts 104 | const uint m_featureDimensionColor; 105 | const bool m_useHSVColorSpace; // use HSV instead of RGB 106 | }; 107 | 108 | /**************************************************************** 109 | CultureColorHistogramParameters 110 | Multi-part Culture Color Histogram Parameters 111 | ****************************************************************/ 112 | class CultureColorHistogramParameters : virtual public FeatureParameters 113 | { 114 | public: 115 | CultureColorHistogramParameters( ); 116 | CultureColorHistogramParameters( vectori partPercentage ); 117 | virtual FeatureType GetFeatureType() const { return CULTURE_COLOR_HISTOGRAM; } 118 | virtual uint GetFeatureDimension( ) const { return m_featureDimensionForCultureColor; } 119 | 120 | virtual uint GetColorFeatureDimension( ) const { return m_featureDimensionForCultureColor;} 121 | virtual uint GetHaarFeatureDimension( ) const { return 0; } 122 | 123 | friend class CultureColorHistogram; 124 | 125 | private: 126 | const vectori m_partPercentageVertical; // a list of percentage (of total height) for each part, must add up to 100 127 | const uint m_numberOfParts; // number of parts 128 | const uint m_featureDimensionForCultureColor; // total number of feature dimension 129 | }; 130 | 131 | /**************************************************************** 132 | HaarAndColorHistogramFeatureParameters 133 | HaarAndColorHistogramFeatureParameters 134 | ****************************************************************/ 135 | class HaarAndColorHistogramFeatureParameters : public HaarFeatureParameters, 136 | public MultiDimensionalColorHistogramParameters 137 | { 138 | public: 139 | HaarAndColorHistogramFeatureParameters( uint featureDimensionHaar, bool useHSVColor = false, uint numberOfBins = 8 ) 140 | : HaarFeatureParameters( featureDimensionHaar ), 141 | MultiDimensionalColorHistogramParameters( useHSVColor, numberOfBins ) 142 | {} 143 | 144 | virtual FeatureType GetFeatureType( ) const { return HAAR_COLOR_HISTOGRAM; }; 145 | virtual uint GetFeatureDimension( ) const { return (m_featureDimensionHaar+m_featureDimensionColor); } 146 | virtual uint GetColorFeatureDimension( ) const { return m_featureDimensionColor; } 147 | virtual uint GetHaarFeatureDimension( ) const { return m_featureDimensionHaar; } 148 | }; 149 | } 150 | #endif -------------------------------------------------------------------------------- /src/FeatureVector.h: -------------------------------------------------------------------------------- 1 | #ifndef FEATURE_VECTOR_H 2 | #define FEATURE_VECTOR_H 3 | 4 | #include "FeatureParameters.h" 5 | #include "Feature.h" 6 | #include "SampleSet.h" 7 | #include "CommonMacros.h" 8 | 9 | namespace Features 10 | { 11 | //Forward Declarations 12 | class FeatureVector; 13 | class HaarFeatureVector; 14 | class MultiDimensionalColorHistogramFeatureVector; 15 | class CultureColorHistogramFeatureVector; 16 | class HaarAndColorHistogramFeatureVector; 17 | 18 | typedef boost::shared_ptr FeatureVectorPtr; 19 | typedef boost::shared_ptr HaarFeatureVectorPtr; 20 | typedef boost::shared_ptr MultiDimensionalColorHistogramFeatureVectorPtr; 21 | typedef boost::shared_ptr CultureColorHistogramFeatureVectorPtr; 22 | typedef boost::shared_ptr HaarAndColorHistogramFeatureVectorPtr; 23 | 24 | /**************************************************************** 25 | FeatureVector 26 | This is a wrapper class for features. 27 | ****************************************************************/ 28 | class FeatureVector 29 | { 30 | public: 31 | FeatureVector( ) 32 | : m_featureParametersPtr( ), 33 | m_isFeatureGenerated( false ) 34 | { 35 | } 36 | 37 | //Pure virtual functions 38 | virtual void Generate( FeatureParametersPtr featureParametersPtr ) = 0; 39 | virtual void Compute( Classifier::SampleSet& sampleSet, bool shouldResizeFeatureMatrix = true ) = 0; 40 | virtual void SaveVisualizedFeatureVector( const char *dirName ) = 0; 41 | 42 | virtual const uint GetNumberOfFeatures( ) const = 0; 43 | 44 | protected: 45 | FeatureParametersPtr m_featureParametersPtr; 46 | bool m_isFeatureGenerated; 47 | }; 48 | } 49 | #endif -------------------------------------------------------------------------------- /src/GeometryBasedInformationFuser.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | Information fusion based on Expectation Maximization Algorithm in OpenCV 3 | http://opencv.willowgarage.com/documentation/expectation-maximization.html 4 | ********************************************************************************/ 5 | #ifndef GEOMETRIC_INFORMATION_FUSER 6 | #define GEOMETRIC_INFORMATION_FUSER 7 | 8 | #include "Matrix.h" 9 | #include "Config.h" 10 | #include "CommonMacros.h" 11 | 12 | #include "ml.h" 13 | #include "highgui.h" 14 | #include "math.h" 15 | 16 | #include 17 | 18 | #define MAX_NUMBER_CAMERA_COLORS 5 19 | 20 | namespace MultipleCameraTracking 21 | { 22 | /*************************************************************************** 23 | GeometryBasedInformationFuser 24 | 25 | GeometryBasedInformationFuser fuses information from multiple cameras. 26 | It uses Kalman filter to fuse information from multiple cameras. 27 | It fits a GMM over the shared particles and re-weights the particles 28 | based on GMM distribution. 29 | 30 | Reference: 31 | http://vision.ece.ucsb.edu/publications/view_abstract.cgi?357 32 | ****************************************************************************/ 33 | class GeometryBasedInformationFuser 34 | { 35 | public: 36 | 37 | enum GroundPlaneMeasurmentType { HIGHEST_WEIGHT_CLUSTER = 0, 38 | WEIGHTED_AVERAGE_OF_CLUSTERS = 1, 39 | PRINCIPAL_AXIS_INTERSECTION = 2, 40 | }; 41 | 42 | GeometryBasedInformationFuser( const unsigned int numberOfCamera, 43 | CvMat* particles, 44 | GroundPlaneMeasurmentType groundPlaneMeasurementType, 45 | vector homographyMatrixList ); 46 | ~GeometryBasedInformationFuser( ); 47 | 48 | 49 | GroundPlaneMeasurmentType GetGroundPlaneMeasurementType( ){ return m_groundPlaneMeasurementType; } 50 | 51 | void FuseInformation( CvMat* pParticlesMatrix ); 52 | 53 | CvMat* GetGroundPlaneKalmanMeanMatrix( int index ); 54 | CvMat* GetGroundPlaneKalmanCovarianceMatrix( ); 55 | 56 | Matrixu* DisplayOriginalGroundParticles( CvMat* particles, int frameInd = -1 ) ; 57 | Matrixu* DisplayKalmanFilterPdf( CvMat* pMeanMatrix, CvMat* pCovarianceMatrix, int frameInd = -1 ); 58 | Matrixu* DisplayGMMGroundParticles( int frameInd = -1, CvMat* particles=NULL ); 59 | 60 | //static methods 61 | static void CopyMatrix( CvMat* pSourceMatrix, 62 | CvMat* pDestinationMatrix, 63 | int sourceStartRowIndex = 0, 64 | int destinationStartRowIndex = 0, 65 | int option = 0 ); 66 | 67 | static float MultiVariateNormalPdf( CvMat* dataVector, CvMat* meanVector, CvMat* covarianceMatrix ); 68 | 69 | //Project the Particles to Ground Plane using the Homography 70 | static CvMat* TransformWithHomography( CvMat* particles, CvMat* pHomographyMatrix ); 71 | 72 | //estimate ground plane positions from principle axis 73 | static vectord EstimateGroundPlanePrincipleAxisIntersection( CvMat* pPixelMatrix, 74 | vector homographyMatrixList ); 75 | private: 76 | 77 | DISALLOW_IMPLICIT_CONSTRUCTORS( GeometryBasedInformationFuser ); 78 | 79 | //set the default EM parameters 80 | void SetDefaultEMParameters( ); 81 | 82 | //initialize the Kalman Filter 83 | void InitializeKalman( CvMat* particles ); 84 | 85 | //Update the Kalman Filter 86 | void UpdateKalmanFilter( CvMat* measurement, CvMat* measurementCov =NULL ); 87 | 88 | //Fuse information by picking the best cluster for measurement 89 | void FuseInformationByPickingTheBestCluster( CvMat* pParticlesMatrix ); 90 | 91 | //Fuse information by using weighted average for measurement 92 | void FuseInformationByAveragingClusters( CvMat* pParticlesMatrix ); 93 | 94 | //Fuse information using the principal axis intersection 95 | void FuseInformationByUsingPrincipalAxisIntersection( CvMat* pParticlesMatrix ); 96 | 97 | //given a point on the ground plane, find its corresponding position on the ground plane image 98 | void MetricToPixels( float xPosFeet, float yPosFeet, int * xPosPixel, int * yPosPixel ); 99 | 100 | //given a pixel on the ground plane image, find its corresponding position on the ground plane 101 | void PixelsToMetric( float * xPosFeet, float * yPosFeet, int xPosPixel, int yPosPixel ); 102 | 103 | //initialize the ground plane display 104 | void InitializeGroundplaneDisplay( ); 105 | 106 | CvEM m_emModel; //EM Model 107 | CvEMParams m_emParamters; //Parameters of the expectation maximization algorithm 108 | CvKalman* m_pKalman; //Kalman Filter 109 | const unsigned int m_numberOfClusters; //Number of Clusters or Gaussian 110 | unsigned int m_numberOfCameras; //Number of Cameras to be fused 111 | //member variables for display purpose 112 | Matrixu m_colorMatrix; //hold the colors to use for different cameras 113 | Matrixu m_GroundPlaneDisplayMatrix; 114 | Matrixu m_GroundPlaneDisplayMatrixKF; 115 | Matrixu m_GroundPlaneDisplayMatrixGMM; 116 | GroundPlaneMeasurmentType m_groundPlaneMeasurementType; 117 | vector m_homographyMatrixList; 118 | }; 119 | 120 | //typedef for a boost pointer 121 | typedef boost::shared_ptr GeometryBasedInformationFuserPtr; 122 | typedef std::vector GeometryBasedInformationFuserPtrList; 123 | } 124 | #endif 125 | -------------------------------------------------------------------------------- /src/HaarAndColorHistogramFeatureVector.cpp: -------------------------------------------------------------------------------- 1 | #include "HaarAndColorHistogramFeatureVector.h" 2 | #include "HaarFeature.h" 3 | #include "MultiDimensionalColorHistogram.h" 4 | 5 | namespace Features 6 | { 7 | /**************************************************************** 8 | HaarAndColorHistogramFeatureVector::Generate 9 | Exception: 10 | None 11 | ****************************************************************/ 12 | void HaarAndColorHistogramFeatureVector::Generate( FeatureParametersPtr featureParametersPtr ) 13 | { 14 | try 15 | { 16 | //Call Generate Features of the HaarFeatureVector 17 | HaarFeatureVector::Generate( featureParametersPtr ); 18 | MultiDimensionalColorHistogramFeatureVector::Generate( featureParametersPtr ); 19 | 20 | m_numberOfHaarColorFeatures = m_numberOfHaarFeatures + m_numberOfColorFeatures; 21 | 22 | ASSERT_TRUE( m_numberOfHaarColorFeatures > 0 ); 23 | } 24 | EXCEPTION_CATCH_AND_ABORT( "Error While Generating MultiDimensionalColorHistogram Feature Vector" ); 25 | } 26 | 27 | /**************************************************************** 28 | HaarAndColorHistogramFeatureVector::Compute 29 | 30 | Exception: 31 | None 32 | ****************************************************************/ 33 | void HaarAndColorHistogramFeatureVector::Compute( Classifier::SampleSet& sampleSet, bool /*shouldResizeFeatureMatrix*/ ) 34 | { 35 | try 36 | { 37 | //resize the feature matrix for efficiency 38 | sampleSet.ResizeFeatures( m_numberOfHaarColorFeatures ); 39 | 40 | HaarFeatureVector::Compute( sampleSet, false/*shouldResizeFeatureMatrix*/ ); 41 | MultiDimensionalColorHistogramFeatureVector::Compute( sampleSet, false/*shouldResizeFeatureMatrix*/ ); 42 | } 43 | EXCEPTION_CATCH_AND_ABORT( "Error While Generating MultiDimensionalColorHistogram Feature Vector" ); 44 | } 45 | } -------------------------------------------------------------------------------- /src/HaarAndColorHistogramFeatureVector.h: -------------------------------------------------------------------------------- 1 | #ifndef HAAR_COLOR_FEATURE_VECTOR_H 2 | #define HAAR_COLOR_FEATURE_VECTOR_H 3 | 4 | #include "FeatureVector.h" 5 | #include "HaarFeatureVector.h" 6 | #include "MultiDimensionalColorHistogramFeatureVector.h" 7 | 8 | namespace Features 9 | { 10 | /**************************************************************** 11 | HaarAndColorHistogramFeatureVector 12 | This is a wrapper class for HaarAndColorHistogramFeatureVector. 13 | ****************************************************************/ 14 | class HaarAndColorHistogramFeatureVector : public HaarFeatureVector, 15 | public MultiDimensionalColorHistogramFeatureVector 16 | { 17 | public: 18 | 19 | virtual void Generate( FeatureParametersPtr featureParametersPtr ); 20 | virtual void Compute( Classifier::SampleSet& sampleSet, bool shouldResizeFeatureMatrix = true ); 21 | virtual void SaveVisualizedFeatureVector( const char *dirName ){} 22 | 23 | virtual const uint GetNumberOfFeatures( ) const 24 | { 25 | ASSERT_TRUE( m_numberOfHaarColorFeatures != 0 ); return m_numberOfHaarColorFeatures; 26 | } 27 | 28 | private: 29 | uint m_numberOfHaarColorFeatures; 30 | }; 31 | } 32 | #endif -------------------------------------------------------------------------------- /src/HaarFeature.cpp: -------------------------------------------------------------------------------- 1 | #include "HaarFeature.h" 2 | 3 | namespace Features 4 | { 5 | /**************************************************************** 6 | HaarFeature::HaarFeature 7 | Constructor 8 | Exception: 9 | None 10 | ****************************************************************/ 11 | HaarFeature::HaarFeature( ) 12 | : m_channel( 0 ) 13 | { 14 | m_width = 0; 15 | m_height = 0; 16 | } 17 | 18 | /**************************************************************** 19 | HaarFeature::Generate 20 | Generate a Haar Feature based on the haar feature parameters 21 | (the rectangles and their weights are randomly generated) 22 | Exception: 23 | None 24 | ****************************************************************/ 25 | void HaarFeature::Generate( FeatureParametersPtr featureParametersPtr ) 26 | { 27 | ASSERT_TRUE( featureParametersPtr != NULL ); 28 | 29 | //type cast to haar featurePtr 30 | HaarFeatureParametersPtr haarFeatureParametersPtr = boost::dynamic_pointer_cast( featureParametersPtr ); 31 | 32 | m_width = haarFeatureParametersPtr->m_width; 33 | m_height = haarFeatureParametersPtr->m_height; 34 | m_maxSum = 0.0f; 35 | 36 | //choose the random number of rectangles for Haar Feature Generation 37 | int numberOfRectangles = randint(haarFeatureParametersPtr->m_minimumNumberOfRectangles, haarFeatureParametersPtr->m_maximumNumberOfRectangles ); 38 | m_rects.resize( numberOfRectangles ); 39 | m_weights.resize( numberOfRectangles ); 40 | m_rsums.resize( numberOfRectangles ); 41 | 42 | for ( int rectangleIndex=0; rectangleIndex < numberOfRectangles; rectangleIndex++ ) 43 | { 44 | m_weights[rectangleIndex] = randfloat( )*2 - 1; 45 | m_rects[rectangleIndex].x = randint( 0,(uint)(haarFeatureParametersPtr->m_width-3) ); 46 | m_rects[rectangleIndex].y = randint( 0,(uint)(haarFeatureParametersPtr->m_height-3) ); 47 | m_rects[rectangleIndex].width = randint(1,(haarFeatureParametersPtr->m_width-m_rects[rectangleIndex].x-2)); 48 | m_rects[rectangleIndex].height = randint(1 ,(haarFeatureParametersPtr->m_height-m_rects[rectangleIndex].y-2)); 49 | m_rsums[rectangleIndex] = abs( m_weights[rectangleIndex] * (m_rects[rectangleIndex].width+1)*(m_rects[rectangleIndex].height+1)*255); 50 | 51 | ASSERT_TRUE( m_rects[rectangleIndex].x >=0 && 52 | m_rects[rectangleIndex].y>= 0 && 53 | m_rects[rectangleIndex].width > 0 && 54 | m_rects[rectangleIndex].height > 0 55 | ) 56 | } 57 | 58 | if ( haarFeatureParametersPtr->m_numberOfChannels < 0 ) 59 | { 60 | haarFeatureParametersPtr->m_numberOfChannels = 0; 61 | 62 | for( int k=0; k < 1024; k++ ) 63 | { 64 | haarFeatureParametersPtr->m_numberOfChannels += haarFeatureParametersPtr->m_useChannels[k]>=0; 65 | } 66 | } 67 | 68 | m_channel = haarFeatureParametersPtr->m_useChannels[randint(0,haarFeatureParametersPtr->m_numberOfChannels-1)]; 69 | } 70 | 71 | /**************************************************************** 72 | Feature::ToVisualize 73 | Visualize the Haar-Like feature 74 | Return an image. 75 | Exception: 76 | None 77 | *******************************************************************/ 78 | Matrixu HaarFeature::ToVisualize( int featureIndex ) 79 | { 80 | Matrixu v(m_height,m_width,3); 81 | v.Set(0); 82 | v._keepIpl = true; 83 | 84 | for( uint k=0; k= 0 ) 95 | { 96 | v.display( ("HaarFeature-" + int2str(featureIndex,3)).c_str(), 2 ); 97 | cvWaitKey(1); 98 | } 99 | 100 | v._keepIpl = false; 101 | 102 | return v; 103 | } 104 | 105 | /**************************************************************** 106 | HaarFeature::Compute 107 | Computes Haar-Like features and stores it in the sampleSet. 108 | Exception: 109 | None 110 | ****************************************************************/ 111 | inline float HaarFeature::Compute( const Classifier::Sample& sample ) const 112 | { 113 | //Integral image should be initialized 114 | if ( !sample.m_pImgGray->isInitII() ) 115 | { 116 | abortError(__LINE__,__FILE__,"Integral image not initialized before called Compute()"); 117 | } 118 | 119 | IppiRect r; 120 | float sum = 0.0f; 121 | 122 | for ( int k=0; k<(int)m_rects.size(); k++ ) 123 | { 124 | r = m_rects[k]; // the rectangle in the original scale 125 | //find the scaled rectangle 126 | r.x = cvRound( float(r.x) * sample.m_scaleX ) + sample.m_col;//r.x += sample.m_col; 127 | r.y = cvRound( float(r.y) * sample.m_scaleY ) + sample.m_row;//r.y += sample.m_row; 128 | r.height = cvRound( float(r.height) * sample.m_scaleY ); 129 | r.width = cvRound( float(r.width) * sample.m_scaleX ); 130 | 131 | sum += m_weights[k] * sample.m_pImgGray->sumRect( r, m_channel ); 132 | } 133 | 134 | /* r.x = sample.m_col; 135 | r.y = sample.m_row; 136 | r.width = (int)sample.m_weight; 137 | r.height = (int)sample.m_height; */ 138 | 139 | //return (float)(sum); 140 | return (float)(sum/(sample.m_scaleX*sample.m_scaleY)); //return the Haar feature as if the sample is of original scale (1.0) 141 | } 142 | 143 | /**************************************************************** 144 | HaarFeature::= 145 | Assignment Operator - deep copy 146 | Exception: 147 | None 148 | ****************************************************************/ 149 | inline HaarFeature& HaarFeature::operator= ( const HaarFeature &a ) 150 | { 151 | m_width = a.m_width; 152 | m_height = a.m_height; 153 | m_channel = a.m_channel; 154 | m_weights = a.m_weights; 155 | m_rects = a.m_rects; 156 | m_maxSum = a.m_maxSum; 157 | return (*this); 158 | } 159 | 160 | /**************************************************************** 161 | HaarFeature::GetExpectedValue 162 | Get Expected value 163 | Exception: 164 | None 165 | ****************************************************************/ 166 | inline float HaarFeature::GetExpectedValue() const 167 | { 168 | float sum = 0.0f; 169 | for ( int k=0; k<(int)m_rects.size(); k++ ) 170 | { 171 | sum += m_weights[k] * m_rects[k].height * m_rects[k].width * 125; 172 | } 173 | return sum; 174 | } 175 | } -------------------------------------------------------------------------------- /src/HaarFeature.h: -------------------------------------------------------------------------------- 1 | #ifndef HAAR_FEATURE 2 | #define HAAR_FEATURE 3 | 4 | #include "Feature.h" 5 | 6 | namespace Features 7 | { 8 | /**************************************************************** 9 | HaarFeature 10 | Haar type features. Obtained using wavelet based mother basis. 11 | ****************************************************************/ 12 | class HaarFeature : public Feature 13 | { 14 | public: 15 | HaarFeature( ); 16 | 17 | virtual const FeatureType GetFeatureType() const { return HAAR_LIKE; }; 18 | 19 | //randomly generate a feature instance (this) based on feature parameters 20 | virtual void Generate( FeatureParametersPtr featureParametersPtr ); 21 | 22 | //copy from another haar feature instance 23 | HaarFeature& operator= ( const HaarFeature& aHaarFeature ); 24 | 25 | virtual Matrixu ToVisualize( int featureIndex = -1 ); 26 | 27 | float GetExpectedValue() const; 28 | 29 | // Haar-like feature is of one dim 30 | virtual float Compute( const Classifier::Sample& sample ) const; 31 | virtual void Compute( const Classifier::Sample& sample, vectorf& featureValueList ) const 32 | { abortError( __LINE__, __FILE__, "Error: HaarFeature has only one Dimension" );} 33 | 34 | //member variables 35 | static StopWatch m_sw; 36 | 37 | private: 38 | uint m_width; 39 | uint m_height; 40 | uint m_channel; 41 | vectorf m_weights; 42 | vector m_rects; 43 | vectorf m_rsums; 44 | double m_maxSum; 45 | }; 46 | } 47 | #endif -------------------------------------------------------------------------------- /src/HaarFeatureVector.cpp: -------------------------------------------------------------------------------- 1 | #include "HaarFeatureVector.h" 2 | #include "HaarFeature.h" 3 | 4 | namespace Features 5 | { 6 | /**************************************************************** 7 | HaarFeatureVector::Generate 8 | Generates FeatureVector based on the specified feature type. 9 | FeatureList stores a list of haar features. 10 | Call to Compute actually calculates the feature values. 11 | Exception: 12 | None 13 | ****************************************************************/ 14 | void HaarFeatureVector::Generate( FeatureParametersPtr featureParametersPtr ) 15 | { 16 | try 17 | { 18 | ASSERT_TRUE( featureParametersPtr != NULL ); 19 | 20 | m_featureParametersPtr = featureParametersPtr; 21 | m_numberOfHaarFeatures = featureParametersPtr->GetHaarFeatureDimension(); 22 | 23 | m_featureList.resize( m_numberOfHaarFeatures ); 24 | 25 | for ( uint featureIndex = 0; featureIndex < m_numberOfHaarFeatures; featureIndex++ ) 26 | { 27 | m_featureList[featureIndex] = boost::shared_ptr( new HaarFeature() ); 28 | ASSERT_TRUE( m_featureList[featureIndex] != 0 ); 29 | m_featureList[featureIndex]->Generate( m_featureParametersPtr ); 30 | } 31 | 32 | //Update the feature generated flag 33 | m_isFeatureGenerated = true; 34 | } 35 | EXCEPTION_CATCH_AND_ABORT( "Error While Generating Haar Feature" ); 36 | } 37 | 38 | 39 | /**************************************************************** 40 | HaarFeatureVector::Compute 41 | Iterate over each sample in the given Classifier::SampleSet 42 | and compute the featurePtr. Store the computed featurePtr value 43 | in the featurePtr vector. 44 | Classifier calls this method with a set of samples for each type. 45 | Exception: 46 | None 47 | ****************************************************************/ 48 | void HaarFeatureVector::Compute( Classifier::SampleSet& sampleSet, bool shouldResizeFeatureMatrix ) 49 | { 50 | size_t numberOfSamples = sampleSet.Size( ); 51 | 52 | ASSERT_TRUE( m_isFeatureGenerated == true ); 53 | ASSERT_TRUE( m_numberOfHaarFeatures > 0 ); 54 | 55 | //return if no sample is available 56 | if ( numberOfSamples == 0 ) 57 | { 58 | return; 59 | } 60 | 61 | //resize the feature matrix size to the number of features 62 | if ( shouldResizeFeatureMatrix ) 63 | { 64 | sampleSet.ResizeFeatures( m_numberOfHaarFeatures ); 65 | } 66 | 67 | #pragma omp parallel for 68 | for ( uint featureIndex = 0; featureIndex < m_numberOfHaarFeatures; featureIndex++ ) 69 | { 70 | //#pragma omp parallel for 71 | for ( int sampleIndex = 0; sampleIndex < numberOfSamples; sampleIndex++ ) 72 | { 73 | ASSERT_TRUE( m_featureList[featureIndex] != NULL ); 74 | 75 | //store the feature value in the feature matrix 76 | sampleSet.GetFeatureValue( sampleIndex, featureIndex ) = m_featureList[featureIndex]->Compute( sampleSet[sampleIndex] ); 77 | } 78 | } 79 | } 80 | 81 | /**************************************************************** 82 | HaarFeatureVector::SaveVisualizedFeatureVector 83 | Save the visualized haar features to a given directory 84 | Exception: 85 | None 86 | ****************************************************************/ 87 | void HaarFeatureVector::SaveVisualizedFeatureVector(const char* dirName) 88 | { 89 | char fname[1024]; 90 | Matrixu img; 91 | for( uint featureIndex = 0; featureIndex < m_featureList.size(); featureIndex++ ) 92 | { 93 | sprintf_s( fname, "%s/HaarFeature%05d.png", dirName, featureIndex ); 94 | img = m_featureList[featureIndex]->ToVisualize( ); 95 | img.SaveImage(fname); 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /src/HaarFeatureVector.h: -------------------------------------------------------------------------------- 1 | #ifndef HAAR_FEATURE_VECTOR_H 2 | #define HAAR_FEATURE_VECTOR_H 3 | 4 | #include "FeatureVector.h" 5 | 6 | namespace Features 7 | { 8 | /**************************************************************** 9 | HaarFeatureVector 10 | This is a wrapper class for HaarFeature. 11 | ****************************************************************/ 12 | class HaarFeatureVector : virtual public FeatureVector 13 | { 14 | public: 15 | HaarFeatureVector( ){} 16 | 17 | virtual void Generate( FeatureParametersPtr featureParametersPtr ); 18 | virtual void Compute( Classifier::SampleSet& sampleSet, bool shouldResizeFeatureMatrix = true ); 19 | 20 | virtual void SaveVisualizedFeatureVector( const char * dirname ); 21 | 22 | virtual const uint GetNumberOfFeatures( ) const { return m_numberOfHaarFeatures; } 23 | 24 | protected: 25 | FeatureList m_featureList; 26 | uint m_numberOfHaarFeatures; 27 | }; 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /src/MILAnyBoostClassifier.h: -------------------------------------------------------------------------------- 1 | #ifndef MIL_ANYBOOST_H 2 | #define MIL_ANYBOOST_H 3 | 4 | #include "StrongClassifierBase.h" 5 | 6 | namespace Classifier 7 | { 8 | /**************************************************************** 9 | MILAnyBoostClassifier 10 | The class that implements MIL Anyboost based classifier. 11 | ****************************************************************/ 12 | class MILAnyBoostClassifier : public StrongClassifierBase 13 | { 14 | public: 15 | MILAnyBoostClassifier( Classifier::StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ) 16 | : StrongClassifierBase( strongClassifierParametersBasePtr ) 17 | { 18 | try 19 | { 20 | m_milAnyBoostClassifierParametersPtr = boost::static_pointer_cast( strongClassifierParametersBasePtr ); 21 | } 22 | EXCEPTION_CATCH_AND_ABORT( "Failed to Construct MILAnyBoost" ); 23 | } 24 | 25 | //update the classifier 26 | virtual void Update( Classifier::SampleSet& positiveSampleSet, Classifier::SampleSet& negativeSampleSet ); 27 | 28 | //classify the set of samples 29 | virtual vectorf Classify( Classifier::SampleSet& sampleSet, bool isLogRatioEnabled = true ); 30 | 31 | private: 32 | MILAnyBoostClassifierParametersPtr m_milAnyBoostClassifierParametersPtr; 33 | }; 34 | } 35 | #endif 36 | -------------------------------------------------------------------------------- /src/MILBoostClassifier.h: -------------------------------------------------------------------------------- 1 | #ifndef MILBOOST_H 2 | #define MILBOOST_H 3 | 4 | #include "StrongClassifierBase.h" 5 | 6 | namespace Classifier 7 | { 8 | /**************************************************************** 9 | MILBoostClassifier 10 | The class that implements MIL boost based classifier. 11 | ****************************************************************/ 12 | class MILBoostClassifier : public StrongClassifierBase 13 | { 14 | public: 15 | 16 | MILBoostClassifier( Classifier::StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ) 17 | : StrongClassifierBase( strongClassifierParametersBasePtr ) 18 | { 19 | m_MILBoostClassifierParametersPtr = 20 | boost::static_pointer_cast( strongClassifierParametersBasePtr ); 21 | } 22 | 23 | virtual void Update( Classifier::SampleSet& positiveSampleSet, 24 | Classifier::SampleSet& negativeSampleSet ); 25 | 26 | virtual vectorf Classify( Classifier::SampleSet& sampleSet, 27 | bool isLogRatioEnabled = true ); 28 | 29 | //multiple positive bags 30 | virtual void Update( Classifier::SampleSet& positiveSampleSet, 31 | Classifier::SampleSet& negativeSampleSet, 32 | int numPositiveBags ); 33 | 34 | private: 35 | MILBoostClassifierParametersPtr m_MILBoostClassifierParametersPtr; 36 | }; 37 | } 38 | #endif 39 | -------------------------------------------------------------------------------- /src/MILEnsembleClassifier.h: -------------------------------------------------------------------------------- 1 | #ifndef MILENSEMBLE_H 2 | #define MILENSEMBLE_H 3 | 4 | #include "StrongClassifierBase.h" 5 | 6 | namespace Classifier 7 | { 8 | /**************************************************************** 9 | MILEnsembleClassifier 10 | The class that implements MIL Ensemble boosting based classifier. 11 | ****************************************************************/ 12 | class MILEnsembleClassifier : public StrongClassifierBase 13 | { 14 | public: 15 | 16 | MILEnsembleClassifier( Classifier::StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ) 17 | : StrongClassifierBase( strongClassifierParametersBasePtr ) 18 | { 19 | m_MILEnsembleClassifierParametersPtr = boost::static_pointer_cast( strongClassifierParametersBasePtr ); 20 | } 21 | 22 | virtual void Update( Classifier::SampleSet& positiveSampleSet, Classifier::SampleSet& negativeSampleSet ); 23 | virtual vectorf Classify( Classifier::SampleSet& sampleSet, bool isLogRatioEnabled = true ); 24 | 25 | private: 26 | 27 | void RetainBestPerformingWeakClassifiers( Classifier::SampleSet& positiveSampleSet, 28 | Classifier::SampleSet& negativeSampleSet, 29 | vectorf& positiveHypothesis, 30 | vectorf& negativeHypothesis ); 31 | 32 | void RetainBestPerformingWeakClassifiersWithAdaptiveWeighting( Classifier::SampleSet& positiveSampleSet, 33 | Classifier::SampleSet& negativeSampleSet, 34 | vectorf& positiveHypothesis, 35 | vectorf& negativeHypothesis ); 36 | 37 | void UpdateWithAdaptiveWeighting( Classifier::SampleSet& positiveSampleSet, Classifier::SampleSet& negativeSampleSet ); 38 | 39 | MILEnsembleClassifierParametersPtr m_MILEnsembleClassifierParametersPtr; 40 | }; 41 | } 42 | #endif 43 | -------------------------------------------------------------------------------- /src/MultiDimensionalColorHistogram.cpp: -------------------------------------------------------------------------------- 1 | #include "MultiDimensionalColorHistogram.h" 2 | 3 | namespace Features 4 | { 5 | /**************************************************************** 6 | MultiDimensionalColorHistogram::Compute 7 | Generate the multi-dimensional color histogram (multi-part) 8 | Exception: 9 | None 10 | ****************************************************************/ 11 | void MultiDimensionalColorHistogram::Generate( FeatureParametersPtr featureParametersPtr ) 12 | { 13 | try 14 | { 15 | MultiDimensionalColorHistogramParametersPtr temp = boost::dynamic_pointer_cast(featureParametersPtr); 16 | 17 | m_numberOfBins = temp->m_numberOfBins; 18 | m_numberOfParts = temp->m_numberOfParts; 19 | m_partPercentageVertical = temp->m_partPercentageVertical; 20 | m_useHSVColorSpace = temp->m_useHSVColorSpace; 21 | } 22 | EXCEPTION_CATCH_AND_ABORT( "Failed to Generate Multi-dimensional color histrogram" ); 23 | } 24 | 25 | /**************************************************************** 26 | MultiDimensionalColorHistogram::Compute 27 | Compute the multi-dimensional color histogram and store it in the 28 | given vector. 29 | Exception: 30 | None 31 | ****************************************************************/ 32 | void MultiDimensionalColorHistogram::Compute( const Classifier::Sample& sample, vectorf& featureValueList ) const 33 | { 34 | try 35 | { 36 | ASSERT_TRUE( !featureValueList.empty( ) ); 37 | 38 | // Calculate the size for each part. 39 | vectori partRowList; 40 | int accum = 0, partEnd; 41 | 42 | float numberOfRows = cvRound( static_cast(sample.m_height) * sample.m_scaleY ); 43 | 44 | partRowList.push_back( 0 ); 45 | for (int i = 0; i < m_numberOfParts; i++) 46 | { 47 | accum += m_partPercentageVertical[i]; 48 | partEnd = cvRound( numberOfRows * accum/100 ); 49 | ASSERT_TRUE ( partEnd > partRowList[i] ); 50 | partRowList.push_back( partEnd ); 51 | } 52 | 53 | Matrixu* pImageMatrix = NULL; 54 | 55 | if ( m_useHSVColorSpace ) 56 | { 57 | pImageMatrix = sample.GetHSVImage(); 58 | } 59 | else 60 | { 61 | pImageMatrix = sample.GetColorImage(); 62 | } 63 | 64 | ASSERT_TRUE ( pImageMatrix != NULL ); 65 | 66 | float numberOfColumns =cvRound( static_cast(sample.m_width) * sample.m_scaleX ); 67 | 68 | float varianceX = pow( (numberOfColumns / 2), 2); 69 | float sampleCenterX = sample.m_col + numberOfColumns/2; 70 | 71 | ASSERT_TRUE( pImageMatrix->depth( ) == 3 ); 72 | ASSERT_TRUE( m_numberOfBins > 0 ); 73 | 74 | float binWidth = 256 / m_numberOfBins; 75 | 76 | int partFeatureDimension = m_numberOfBins*m_numberOfBins*m_numberOfBins; 77 | 78 | vectorf partFeatureValueList; 79 | 80 | partFeatureValueList.resize( partFeatureDimension ); 81 | 82 | 83 | for( int partIndex = 0; partIndex < m_numberOfParts; partIndex++ ) 84 | { 85 | #pragma omp parallel for 86 | 87 | float partNumberOfRows = partRowList[partIndex+1] - partRowList[partIndex]; 88 | float varianceY = pow( (partNumberOfRows / 2), 2); 89 | float sampleCenterY = sample.m_row + partRowList[partIndex] + partNumberOfRows/2; 90 | 91 | for ( uint rowIndex = sample.m_row+partRowList[partIndex]; rowIndex < (sample.m_row+partRowList[partIndex+1]); rowIndex++ ) 92 | { 93 | for ( uint columnIndex = sample.m_col; columnIndex < (sample.m_col+numberOfColumns); columnIndex++ ) 94 | { 95 | uint rPixel = (*pImageMatrix)( rowIndex, columnIndex, 0 /*depth*/ ); 96 | uint gPixel = (*pImageMatrix)( rowIndex, columnIndex, 1 /*depth*/ ); 97 | uint bPixel = (*pImageMatrix)( rowIndex, columnIndex, 2 /*depth*/ ); 98 | 99 | uint rBin = floor( rPixel / binWidth ); 100 | uint gBin = floor( gPixel / binWidth ); 101 | uint bBin = floor( bPixel / binWidth ); 102 | 103 | uint featureIndex = rBin + m_numberOfBins * gBin + m_numberOfBins * m_numberOfBins * bBin; 104 | 105 | float featureWeight = 1.0f; 106 | 107 | if ( m_shouldWeightFromCenter ) 108 | { 109 | float weightedDistanceFromCenter = pow( ( sampleCenterX - columnIndex ), 2 ) / (2.0f * varianceX) + 110 | pow( ( sampleCenterY - rowIndex ), 2 ) / ( 2.0f * varianceY ); 111 | 112 | featureWeight = exp( -1 * weightedDistanceFromCenter ); 113 | } 114 | 115 | partFeatureValueList[ featureIndex ] = partFeatureValueList[ featureIndex ] + featureWeight; 116 | } 117 | } 118 | ::normalizeVec( partFeatureValueList ); 119 | 120 | for ( int i = 0; i < partFeatureDimension; i++ ) 121 | { 122 | featureValueList[partIndex*partFeatureDimension + i]= partFeatureValueList[i]; 123 | } 124 | } //to next part 125 | } 126 | EXCEPTION_CATCH_AND_ABORT( "Failed to Compute Multi-Dimensional Color Histogram" ) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/MultiDimensionalColorHistogram.h: -------------------------------------------------------------------------------- 1 | #ifndef MULTI_COLOR_HISTOGRAM 2 | #define MULTI_COLOR_HISTOGRAM 3 | 4 | #include "Feature.h" 5 | 6 | namespace Features 7 | { 8 | /**************************************************************** 9 | MultiDimensionalColorHistogram 10 | A multi dimensional color histogram obtained by binning the 11 | pixels in R,G and B spaces separately. 12 | ****************************************************************/ 13 | class MultiDimensionalColorHistogram : public Feature 14 | { 15 | public: 16 | MultiDimensionalColorHistogram( ) 17 | : m_shouldWeightFromCenter( true ) 18 | { 19 | } 20 | 21 | virtual const FeatureType GetFeatureType( ) const { return MULTI_DIMENSIONAL_COLOR_HISTOGRAM; }; 22 | 23 | //MultiDimensionalColorHistogram has more than one dim 24 | virtual float Compute( const Classifier::Sample& sample ) const 25 | { 26 | abortError( __LINE__, __FILE__, "Error: MultiDimensionalColorHistogram has only one Dimension" ); return 0.0f; 27 | } 28 | 29 | virtual void Compute( const Classifier::Sample& sample, vectorf& featureValueList ) const; 30 | 31 | //initialize feature instance (unlike the haar feature) 32 | virtual void Generate( FeatureParametersPtr featureParametersPtr ) ; 33 | 34 | private: 35 | vectori m_partPercentageVertical; // a list of percentage (of total height) for each part, must add up to 100 36 | uint m_numberOfBins; 37 | uint m_numberOfParts; // number of parts 38 | bool m_useHSVColorSpace; // use HSV instead of RGB 39 | bool m_shouldWeightFromCenter; 40 | }; 41 | } 42 | #endif -------------------------------------------------------------------------------- /src/MultiDimensionalColorHistogramFeatureVector.cpp: -------------------------------------------------------------------------------- 1 | #include "MultiDimensionalColorHistogramFeatureVector.h" 2 | #include "MultiDimensionalColorHistogram.h" 3 | 4 | namespace Features 5 | { 6 | /**************************************************************** 7 | MultiDimensionalColorHistogramFeatureVector::Generate 8 | Generates FeatureVector based on the specified feature type. 9 | Feature stores the multi dimensional color histogram. 10 | Note: parameter "numberOfColorFeatures" is not used as the size of feature vector 11 | is pre-determined. 12 | Exception: 13 | None 14 | ****************************************************************/ 15 | void MultiDimensionalColorHistogramFeatureVector::Generate( FeatureParametersPtr featureParametersPtr ) 16 | { 17 | try 18 | { 19 | ASSERT_TRUE( featureParametersPtr != NULL ); 20 | 21 | m_featureParametersPtr = featureParametersPtr; 22 | 23 | m_featurePtr = boost::shared_ptr( new MultiDimensionalColorHistogram() ); 24 | 25 | ASSERT_TRUE( m_featurePtr != NULL ); 26 | 27 | m_numberOfColorFeatures = m_featureParametersPtr->GetColorFeatureDimension( ); 28 | 29 | m_featurePtr->Generate( m_featureParametersPtr ); 30 | 31 | //Update the feature generated flag 32 | m_isFeatureGenerated = true; 33 | 34 | ///feature index starts from this location 35 | m_startingIndexForFeatureMatrix = m_featureParametersPtr->GetHaarFeatureDimension( ); 36 | 37 | ASSERT_TRUE( m_startingIndexForFeatureMatrix >= 0 ); 38 | } 39 | EXCEPTION_CATCH_AND_ABORT( "Error While Generating MultiDimensionalColorHistogram Feature Vector" ); 40 | } 41 | 42 | 43 | /**************************************************************** 44 | MultiDimensionalColorHistogramFeatureVector::Compute 45 | Iterate over each sample in the given Classifier::SampleSet 46 | and compute the featurePtr. Store the computed featurePtr value 47 | in the featurePtr vector. 48 | Classifier calls this method with a set of samples for each type. 49 | Exception: 50 | None 51 | ****************************************************************/ 52 | void MultiDimensionalColorHistogramFeatureVector::Compute( Classifier::SampleSet& sampleSet, bool shouldResizeFeatureMatrix ) 53 | { 54 | try 55 | { 56 | size_t numberOfSamples = sampleSet.Size( ); 57 | 58 | ASSERT_TRUE( m_isFeatureGenerated == true ); 59 | ASSERT_TRUE( m_numberOfColorFeatures > 0 ); 60 | 61 | //return if no sample is available 62 | if ( numberOfSamples == 0 ) 63 | { 64 | return; 65 | } 66 | 67 | //resize the feature matrix size to the number of features 68 | if ( shouldResizeFeatureMatrix ) 69 | { 70 | sampleSet.ResizeFeatures( m_numberOfColorFeatures ); 71 | } 72 | 73 | #pragma omp parallel for 74 | for ( int sampleIndex = 0; sampleIndex < numberOfSamples; sampleIndex++ ) 75 | { 76 | vectorf colorHistogramVector( m_numberOfColorFeatures, 0.0f ); 77 | m_featurePtr->Compute( sampleSet[sampleIndex], colorHistogramVector ); 78 | 79 | ASSERT_TRUE( m_featurePtr != NULL ); 80 | ASSERT_TRUE( colorHistogramVector.size( ) == m_numberOfColorFeatures ); 81 | 82 | for ( uint featureIndex = m_startingIndexForFeatureMatrix; featureIndex < (m_startingIndexForFeatureMatrix+m_numberOfColorFeatures); featureIndex++ ) 83 | { 84 | //store the feature value in the feature matrix 85 | sampleSet.GetFeatureValue( sampleIndex, featureIndex ) = colorHistogramVector[featureIndex-m_startingIndexForFeatureMatrix]; 86 | } 87 | } 88 | } 89 | EXCEPTION_CATCH_AND_ABORT( "Failed to Multi-Dimensional Color Histogram Feature Vector" ); 90 | } 91 | } -------------------------------------------------------------------------------- /src/MultiDimensionalColorHistogramFeatureVector.h: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_FEATURE_VECTOR_H 2 | #define COLOR_FEATURE_VECTOR_H 3 | 4 | #include "FeatureVector.h" 5 | namespace Features 6 | { 7 | /**************************************************************** 8 | MultiDimensionalColorHistogramFeatureVector 9 | This is a wrapper class for MultiDimensionalColorHistogram. 10 | ****************************************************************/ 11 | class MultiDimensionalColorHistogramFeatureVector : virtual public FeatureVector 12 | { 13 | public: 14 | //Generate features 15 | virtual void Generate( FeatureParametersPtr featureParametersPtr ); 16 | 17 | //Computes features for the given sample set 18 | virtual void Compute( Classifier::SampleSet& sampleSet, bool shouldResizeFeatureMatrix = true ); 19 | 20 | //Save the visualized feature vector - Unused 21 | virtual void SaveVisualizedFeatureVector( const char *dirName ){} 22 | 23 | //Get Number of Features 24 | virtual const uint GetNumberOfFeatures( ) const { return m_numberOfColorFeatures; } 25 | 26 | protected: 27 | 28 | FeaturePtr m_featurePtr; 29 | uint m_numberOfColorFeatures; 30 | uint m_startingIndexForFeatureMatrix; //Used while Color Feature is concatenated to the Other features. 31 | }; 32 | } 33 | #endif -------------------------------------------------------------------------------- /src/Object.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERA_OBJECT_HEADER 2 | #define CAMERA_OBJECT_HEADER 3 | 4 | #include "Matrix.h" 5 | #include "Feature.h" 6 | #include "Tracker.h" 7 | #include "SimpleTracker.h" 8 | #include "ParticleFilterTracker.h" 9 | #include "Public.h" 10 | #include "CameraNetworkBase.h" 11 | #include "AppearanceBasedInformationFuser.h" 12 | #include "DefaultParameters.h" 13 | #include "Config.h" 14 | 15 | namespace MultipleCameraTracking 16 | { 17 | /**************************************************************** 18 | Object 19 | This class holds all the information about an 20 | object(target of interest) inside a particular camera, 21 | i.e. an object instance belong to a camera 22 | instance. 23 | ****************************************************************/ 24 | class Object 25 | { 26 | public: 27 | //Constructor 28 | Object( const int objectId, 29 | const int cameraId, 30 | const bool isColorEnabled, 31 | CameraTrackingParametersPtr cameraTrackingParametersPtr, 32 | CvMat* pHomographyMatrix ); 33 | 34 | int GetObjectID( ) const { return m_objectID; }; 35 | 36 | //Initializes the object parameters with initial state and file name for saving its trajectory 37 | void InitializeObjectParameters( const vectorf& initialState, const string& trajSaveStrBase ); 38 | 39 | /***** Basic Object Tracker *****/ 40 | // Initialize the tracker for the object 41 | bool InitializeObjectTracker( Matrixu* pFrameImageColor, 42 | Matrixu* pFrameImageGray, 43 | int frameInd, 44 | uint videoLength, 45 | Matrixu* pFrameDisplay = NULL, 46 | Matrixu* pFrameDisplayTraining = NULL, 47 | Matrixu* pFrameImageHSV = NULL, 48 | Matrixf* pGroundTruthMatrix = NULL ); 49 | 50 | // Track the object in a given frame 51 | void TrackObjectFrame( int frameind, 52 | Matrixu* pFrameImageColor, 53 | Matrixu* pFrameImageGray, 54 | Matrixu* pFrameDisplay=NULL, 55 | Matrixu* pFrameDisplayTraining=NULL, 56 | Matrixu* pFrameImageHSV=NULL ); 57 | 58 | // Notify the tracker to keep the particle filter tracker state as the final state for the frame, 59 | void StoreParticleFilterTrackerState( int frameInd, Matrixu* pFrameDisplay = NULL ); 60 | 61 | // Update the particle filter tracker appearance model 62 | void UpdateParticleFilterTrackerAppearanceModel( Matrixu* pFrameImageColor, 63 | Matrixu* pFrameImageGray, 64 | Matrixu* pFrameDisplayTraining = NULL, 65 | Matrixu* pFrameImageHSV = NULL ); 66 | 67 | // Save the state on the object's trajectory file 68 | void SaveObjectStatesAllFrames( ); 69 | 70 | /***** For Ground Plane Fusion *****/ 71 | // Get ground plane position particles (still on the image plane) 72 | CvMat* GetParticlesFootPositionOnImagePlaneForGeometricFusion( ); 73 | CvMat* GetAverageParticleFootPositionOnImagePlaneForGeometricFusion( ); 74 | 75 | /***** For Color Appearance Fusion *****/ 76 | void GenerateTrainingSampleSetsForAppearanceFusion( Classifier::SampleSet& positiveSampleSet, 77 | Classifier::SampleSet& negativeSampleSet, 78 | Matrixu* pFrameImageColor, 79 | Matrixu* pFrameImageGray, 80 | Matrixu* pFrameImageHSV ); 81 | 82 | void LearnGlobalAppearanceModel( CameraNetworkBasePtr cameraNetworkBasePtr ); 83 | 84 | /***** For Occlusion Handling *****/ 85 | void AutoInitialize( Matrixf AppearanceModel ) { }; 86 | void SuspendTracking( ) {}; 87 | void ResumeTracking( Matrixf AppearanceModel) { }; 88 | 89 | void UpdateParticleWeightUsingMultiCameraAppearanceModel( Matrixu* pFrameImageColor, 90 | Matrixu* pFrameImageGray, 91 | Matrixu* pFrameImageHSV ); 92 | 93 | void UpdateParticleWeightsWithGroundPDF( CvMat* pMeanMatrix, 94 | CvMat* pCovarianceMatrix, 95 | Matrixu* pColorImageMatrix, 96 | Matrixu* pGrayImageMatrix, 97 | Matrixu* pHsvImageMatrix ); 98 | 99 | void DrawObjectFootPoint(Matrixu* pFrameDisplay); 100 | private: 101 | DISALLOW_IMPLICIT_CONSTRUCTORS( Object ); 102 | 103 | Features::FeatureParametersPtr GenerateDefaultTrackerFeatureParameters( ); 104 | Features::FeatureParametersPtr GenerateDefaultAppearanceFusionFeatureParameters( ); 105 | Classifier::StrongClassifierParametersBasePtr GenerateDefaultAppearanceFusionClassifierParameters( ); 106 | 107 | CameraTrackingParametersPtr m_cameraTrackingParametersPtr; 108 | CvMat* m_pHomographyMatrix; 109 | 110 | Classifier::StrongClassifierParametersBasePtr m_classifierParamPtr; //Strong Classifier Parameters 111 | TrackerParametersPtr m_trackerParametersPtr; //Simple Tracker Parameters 112 | TrackerPtr m_trackerPtr; //Object for Tracking Module 113 | AppearanceBasedInformationFuserPtr m_appearanceFuserPtr; 114 | const int m_objectID; //Object ID 115 | const int m_cameraID; //which camera does this object belongs to 116 | 117 | const bool m_colorImage; //whether input raw video is color 118 | int m_indPreviousTrackedFrame; //the frame index in the most recent call to TrackObjectFrame 119 | 120 | }; 121 | 122 | typedef boost::shared_ptr ObjectPtr; 123 | } 124 | #endif -------------------------------------------------------------------------------- /src/OnlineStumpsWeakClassifier.cpp: -------------------------------------------------------------------------------- 1 | #include "OnlineStumpsWeakClassifier.h" 2 | 3 | #define FEATURE_DIMENSION 1 4 | #define MAXIMUM_NUMBER_OF_ITERATIONS 10 5 | #define MINIMUM_ERROR_THRESHOLD_FOR_PERCEPTRON 0.5 6 | 7 | namespace Classifier 8 | { 9 | /**************************************************************** 10 | OnlineStumpsWeakClassifier 11 | C'tor 12 | ****************************************************************/ 13 | OnlineStumpsWeakClassifier::OnlineStumpsWeakClassifier( ) 14 | : WeakClassifierBase( ) 15 | { 16 | Initialize(); 17 | } 18 | 19 | /**************************************************************** 20 | IsValidWeakClassifier 21 | ****************************************************************/ 22 | bool OnlineStumpsWeakClassifier::IsValidWeakClassifier( ) 23 | { 24 | try 25 | { 26 | if ( m_mu0 == m_mu1 ) 27 | { 28 | return false; 29 | } 30 | 31 | return true; 32 | } 33 | EXCEPTION_CATCH_AND_ABORT( "Failed to check the weak claassifier validity" ); 34 | } 35 | 36 | /**************************************************************** 37 | OnlineStumpsWeakClassifier 38 | C'tor 39 | ****************************************************************/ 40 | OnlineStumpsWeakClassifier::OnlineStumpsWeakClassifier( const int featureId ) 41 | : WeakClassifierBase( featureId ) 42 | { 43 | Initialize( ); 44 | m_learningRate = 0.85f; 45 | } 46 | 47 | /**************************************************************** 48 | OnlineStumpsWeakClassifier::Initialize 49 | Initializes the parameters 50 | Exceptions: 51 | None 52 | ****************************************************************/ 53 | void OnlineStumpsWeakClassifier::Initialize() 54 | { 55 | m_mu0 = 0; 56 | m_mu1 = 0; 57 | m_sig0 = 1; 58 | m_sig1 = 1; 59 | m_isWeakClassifierTrained = false; 60 | } 61 | 62 | /**************************************************************** 63 | OnlineStumpsWeakClassifier::Classify 64 | Classify 65 | Exceptions: 66 | None 67 | ****************************************************************/ 68 | bool OnlineStumpsWeakClassifier::Classify( const Classifier::SampleSet& sampleSet, const int sampleIndex ) 69 | { 70 | float xx = GetFeatureValue( sampleSet, sampleIndex ); 71 | double p0 = exp( (xx-m_mu0)*(xx-m_mu0)*m_e0 )*m_n0; 72 | double p1 = exp( (xx-m_mu1)*(xx-m_mu1)*m_e1 )*m_n1; 73 | bool r = p1>p0; 74 | return r; 75 | } 76 | 77 | /**************************************************************** 78 | OnlineStumpsWeakClassifier::ClassifyF 79 | ClassifyF 80 | Exceptions: 81 | None 82 | ****************************************************************/ 83 | float OnlineStumpsWeakClassifier::ClassifyF( const Classifier::SampleSet& sampleSet, const int sampleIndex ) 84 | { 85 | float xx = GetFeatureValue(sampleSet,sampleIndex); 86 | double p0 = exp( (xx-m_mu0)*(xx-m_mu0)*m_e0 )*m_n0; 87 | double p1 = exp( (xx-m_mu1)*(xx-m_mu1)*m_e1 )*m_n1; 88 | float r = (float)(log(1e-5+p1)-log(1e-5+p0)); 89 | return r; 90 | } 91 | 92 | 93 | /**************************************************************** 94 | OnlineStumpsWeakClassifier::Update 95 | Update 96 | Exceptions: 97 | None 98 | ****************************************************************/ 99 | void OnlineStumpsWeakClassifier::Update( const Classifier::SampleSet& positiveSampleSet, 100 | const Classifier::SampleSet& negativeSampleSet, 101 | vectorf* /*pPositiveSamplesWeightList*/, 102 | vectorf* /*pNegativeSamplesWeightList*/ ) 103 | { 104 | float positiveSampleFeatureMeanValue=0.0; 105 | if ( positiveSampleSet.Size() > 0 ) 106 | { 107 | positiveSampleFeatureMeanValue = positiveSampleSet.FeatureValues(m_featureIndex).Mean(); 108 | } 109 | 110 | float negativeSampleFeatureMeanValue = 0.0f; 111 | if( negativeSampleSet.Size() > 0 ) 112 | { 113 | negativeSampleFeatureMeanValue = negativeSampleSet.FeatureValues(m_featureIndex).Mean(); 114 | } 115 | 116 | if ( m_isWeakClassifierTrained ) 117 | { 118 | if ( positiveSampleSet.Size()>0 ) 119 | { 120 | m_mu1 = ( m_learningRate*m_mu1 + (1-m_learningRate) * positiveSampleFeatureMeanValue ); 121 | m_sig1 = ( m_learningRate*m_sig1 + (1-m_learningRate) * ( (positiveSampleSet.FeatureValues(m_featureIndex)-m_mu1).Sqr().Mean() ) ); 122 | } 123 | 124 | if ( negativeSampleSet.Size()>0 ) 125 | { 126 | m_mu0 = ( m_learningRate*m_mu0 + (1-m_learningRate) * negativeSampleFeatureMeanValue ); 127 | m_sig0 = ( m_learningRate*m_sig0 + (1-m_learningRate) * ( (negativeSampleSet.FeatureValues(m_featureIndex)-m_mu0).Sqr().Mean() ) ); 128 | } 129 | } 130 | else 131 | { 132 | m_isWeakClassifierTrained = true; 133 | if ( positiveSampleSet.Size() > 0 ) 134 | { 135 | m_mu1 = positiveSampleFeatureMeanValue; 136 | m_sig1 = positiveSampleSet.FeatureValues(m_featureIndex).Var()+1e-9f; 137 | } 138 | 139 | if ( negativeSampleSet.Size()>0 ) 140 | { 141 | m_mu0 = negativeSampleFeatureMeanValue; 142 | m_sig0 = negativeSampleSet.FeatureValues(m_featureIndex).Var()+1e-9f; 143 | } 144 | } 145 | 146 | //update the factors for fast computation 147 | m_n0 = 1.0f / pow(m_sig0,0.5f); 148 | m_n1 = 1.0f / pow(m_sig1,0.5f); 149 | m_e1 = -1.0f/(2.0f*m_sig1+1e-99f); 150 | m_e0 = -1.0f/(2.0f*m_sig0+1e-99f); 151 | } 152 | } -------------------------------------------------------------------------------- /src/OnlineStumpsWeakClassifier.h: -------------------------------------------------------------------------------- 1 | #ifndef ONLINE_STUMP_WEAK_CLASSIFIER_H 2 | #define ONLINE_STUMP_WEAK_CLASSIFIER_H 3 | 4 | #include "WeakClassifierBase.h" 5 | 6 | namespace Classifier 7 | { 8 | /**************************************************************** 9 | OnlineStumpsWeakClassifier 10 | Online stumps weak classifier. 11 | ****************************************************************/ 12 | class OnlineStumpsWeakClassifier : public WeakClassifierBase 13 | { 14 | public: 15 | OnlineStumpsWeakClassifier( ); 16 | OnlineStumpsWeakClassifier( const int featureId ); 17 | 18 | virtual WeakClassifierType GetClassifierType( ) { return STUMP; } 19 | 20 | virtual void Update( const Classifier::SampleSet& positiveSampleSet, 21 | const Classifier::SampleSet& negativeSampleSet, 22 | vectorf* pPositiveSamplesWeightList, 23 | vectorf* pNegativeSamplesWeightList ); 24 | 25 | virtual bool Classify( const Classifier::SampleSet& sampleSet, const int sampleIndex ); 26 | virtual float ClassifyF( const Classifier::SampleSet& sampleSet, const int sampleIndex ); 27 | 28 | virtual bool IsValidWeakClassifier( ); 29 | 30 | private: 31 | virtual void Initialize( ); 32 | 33 | float m_mu0; 34 | float m_mu1; 35 | float m_sig0; 36 | float m_sig1; 37 | float m_n1; 38 | float m_n0; 39 | float m_e1; 40 | float m_e0; 41 | }; 42 | } 43 | #endif -------------------------------------------------------------------------------- /src/ParticleFilter.h: -------------------------------------------------------------------------------- 1 | #ifndef PARTICLE_FILTER 2 | #define PARTICLE_FILTER 3 | 4 | #include "Exception.h" 5 | #include "CommonMacros.h" 6 | #include "Matrix.h" 7 | #include "Public.h" 8 | 9 | #include "cxcore.hpp" 10 | 11 | #define PF_INITIALIZATION_BOUNDARY 0 12 | 13 | namespace MultipleCameraTracking 14 | { 15 | //Forward Declaration 16 | class ParticleFilter; 17 | 18 | //Declaration of shared ptr 19 | typedef boost::shared_ptr ParticleFilterPtr; 20 | 21 | /**************************************************************** 22 | Particle Filters 23 | This class implements a BootsStrap ParticleFilter. 24 | 25 | State Diagram: 26 | 27 | ****************************************************************/ 28 | class ParticleFilter 29 | { 30 | public: 31 | 32 | //to find whether m_particlesOrderedUniqueMatrix is unique after re sampling 33 | enum State { UNINTIALIZED = 0, 34 | INITIALIZED = 1 , 35 | PREDICTED = 2, 36 | RESAMPLED = 3, 37 | }; 38 | 39 | enum ResamplingStrategy { WEIGHT_BASED, 40 | TIME_INTERVAL_BASED, 41 | WEIGHT_OR_TIME_INTERVAL_BASED 42 | }; 43 | 44 | //constructor 45 | ParticleFilter( const float imageWidth, 46 | const float imageHeight, 47 | const unsigned short particleStateDimension = 4, 48 | const ResamplingStrategy resamplingStrategy = WEIGHT_BASED ) 49 | : m_imageWidth( imageWidth ), 50 | m_imageHeight( imageHeight ), 51 | m_particlesStateMatrix( ), 52 | m_particlesResampledMatrix( ), 53 | m_particlesOrderedUniqueMatrix( ), 54 | m_resampleIndexList( ), 55 | m_numberOfParticles( ), 56 | m_maximumScaleChange( ), 57 | m_filterState( UNINTIALIZED ), 58 | m_particleStateDimension( particleStateDimension ), 59 | m_initializationRelaxation ( PF_INITIALIZATION_BOUNDARY ), 60 | m_timeIndex( 0 ), 61 | m_isOrderedUniqueParticlesFound( false ), 62 | m_resamplingStrategy( resamplingStrategy ) 63 | { 64 | } 65 | 66 | // Initialize particle filters 67 | void Initialize( int numberOfParticles, 68 | float centerX, 69 | float centerY, 70 | float scaleX, 71 | float scaleY, 72 | float maximumScaleChangeBetweenFrame = 0.5, 73 | float maxScale = 10, 74 | float minScale = 0.1 ); 75 | 76 | // Prediction from m_particlesResampledMatrix based on Brownian motion 77 | void PredictWithBrownianMotion( float standardDeviationX, 78 | float standardDeviationY, 79 | float standardDeviationScaleX, 80 | float standardDeviationScaleY, 81 | float width, 82 | float height ); 83 | 84 | //check for particle refinement 85 | void CheckForParticleRefinement( float width, float height ); 86 | 87 | //Prediction from m_particlesResampledMatrix based on Uniform motion 88 | void PredictWithUniformMotion( float standardDeviationX, 89 | float standardDeviationY, 90 | float standardDeviationScaleX, 91 | float standardDeviationScaleY ); 92 | 93 | void ForceParticleFilterRefinement( float width, 94 | float height ); 95 | 96 | // access functions to retrieve individual particle 97 | void GetParticle( int index, vectorf& particle ); 98 | void GetResampledParticle( int index, vectorf& particle ); 99 | void GetOrderedUniqueParticles( int index, vectorf& particle ); 100 | void GetHighestOrderedUniqueParticleCloseToTheGivenState( vectorf& particle, vectorf& closestState ); 101 | void GetAverageofAllParticles(vectorf& particle) const; 102 | void GetHighestWeightParticle( vectorf& particle ); 103 | 104 | // Number of unique particles in m_particlesResampledMatrix 105 | int GetNumberOfOrderedUniqueParticles( ); 106 | 107 | float GetMaxScale( ) const { return m_maxScale; } 108 | 109 | // Set a particular predicted particle with a new weight 110 | void UpdateParticleWeight( int index, float probability, bool shouldForceReset = false ); 111 | 112 | // Update the weights of non-zero-weight predicated particles followed by re sampling to m_particlesResampledMatrix 113 | void UpdateAllParticlesWeight( vectorf& probability, bool shouldUpdateOnlyNonZeroWeights = true, bool shouldForceReset = false, bool shouldResample = true ); 114 | 115 | //Resample the particles 116 | void ResampleParticles( bool shouldForceFilterStateChange = false ); 117 | 118 | //Get Number of Unique Particles 119 | int GetNumberOfParticles( ) const { return m_numberOfParticles; }; 120 | 121 | void GetACopyOfVectorFormat( vector< vector > & particlesVector ); 122 | 123 | void RearrangeParticlesBasedOnGroundLocation( vectorf& meanGroundPlaneFootPositionOnImageList, 124 | vectorf& varianceGroundPlaneFootPositionOnImageList, 125 | bool shouldChangeTheScaleAccordingToOffset = false, 126 | float width = 0.0f, 127 | float height = 0.0f ); 128 | private: 129 | 130 | //Find the unique particles within ParticleResampled and order them in terms of weight 131 | void FindOrderedUniqueParticles( ); 132 | 133 | //Check for re-sampling required 134 | void ResampleIfRequired( ); 135 | 136 | //Normalize Particle weights 137 | void NormalizeParticleWeights( ); 138 | 139 | Matrixf m_particlesStateMatrix; //[centerX, centerY, scaleX, scaleY, weight]; 140 | Matrixf m_tempParticleStateMatrix; 141 | Matrixf m_particlesResampledMatrix; 142 | Matrixf m_particlesOrderedUniqueMatrix; 143 | vectori m_resampleIndexList; 144 | int m_numberOfParticles; 145 | float m_maximumScaleChange; // maximum scale changes between frame 146 | State m_filterState; 147 | const unsigned short m_particleStateDimension; //dimension of the particle filter state (i.e. the index for the particle weight) 148 | float m_maxScale; 149 | float m_minScale; 150 | float m_imageWidth; 151 | float m_imageHeight; 152 | const int m_initializationRelaxation; 153 | uint m_timeIndex; 154 | bool m_isOrderedUniqueParticlesFound; //For optimization, so that repeated calculation 155 | const ResamplingStrategy m_resamplingStrategy; 156 | }; 157 | } 158 | #endif 159 | -------------------------------------------------------------------------------- /src/ParticleFilterTracker.h: -------------------------------------------------------------------------------- 1 | #ifndef PARTICLE_TRACKER_PUBLIC 2 | #define PARTICLE_TRACKER_PUBLIC 3 | 4 | #include "Tracker.h" 5 | #include "SimpleTracker.h" 6 | #include "ParticleFilter.h" 7 | #include "AppearanceBasedInformationFuser.h" 8 | 9 | namespace MultipleCameraTracking 10 | { 11 | //Forward Declaration 12 | class ParticleFilterTracker; 13 | //declarations of shared ptr 14 | typedef boost::shared_ptr ParticleFilterTrackerPtr; 15 | 16 | /**************************************************************** 17 | ParticleFilterTracker (Particle Filter Tracker) 18 | Derives from SimpleTracker. 19 | ****************************************************************/ 20 | class ParticleFilterTracker : public SimpleTracker 21 | { 22 | public: 23 | //constructor 24 | ParticleFilterTracker( CvMat* pHomographyMatrix, 25 | AppearanceBasedInformationFuserPtr appearanceFuserPtr, 26 | bool isAppearanceFusionEnabled = false ) 27 | : SimpleTracker( pHomographyMatrix ), 28 | m_meanGroundPlaneFootPositionOnImageList( 2, 0.0f ), 29 | m_particleFilterPtr( ), 30 | m_pGroundLocation( ), 31 | m_particleFilterTrackerParamsPtr( ), 32 | m_pWeightedAverageParticleMatrix( cvCreateMat( 1, 2, CV_32FC1 ) ), 33 | m_appearanceFuserPtr( appearanceFuserPtr ), 34 | m_isAppearanceFusionEnabled( isAppearanceFusionEnabled ) 35 | { 36 | if ( m_isAppearanceFusionEnabled ) 37 | { 38 | ASSERT_TRUE( m_appearanceFuserPtr != NULL ); 39 | } 40 | } 41 | 42 | //destructor 43 | ~ParticleFilterTracker( ); 44 | 45 | //(override SimpleTracker) initializes tracker with first frame(s) and other parameters 46 | virtual void InitializeTrackerWithParameters( Matrixu* pFrameImageColor, 47 | Matrixu* pFrameImageGray, 48 | int frameInd, 49 | uint videoLength, 50 | TrackerParametersPtr trackerParametersPtr, 51 | Classifier::StrongClassifierParametersBasePtr clfparamsPtr, 52 | Matrixu* pFrameDisplay = NULL, 53 | Matrixu* pFrameDisplayTraining = NULL, 54 | Matrixu* pFrameImageHSV = NULL, 55 | Matrixf* pGroundTruthMatrix = NULL ); 56 | 57 | //(override SimpleTracker) Track an object and store states (by calling StoreObjectStates) 58 | virtual void TrackObjectAndSaveState( int frameind, 59 | Matrixu* pFrameImageColor, 60 | Matrixu* pFrameImageGray, 61 | Matrixu* pFrameDisplay = NULL, 62 | Matrixu* pFrameDisplayTraining = NULL, 63 | Matrixu* pFrameImageHSV = NULL ); 64 | 65 | Classifier::SampleSet& GetTestSampleSet( ) { return m_testSampleSet; } 66 | 67 | CvMat* GetGroundLocation( bool shouldUseResampledParticles = false ){ EstimateGroundPoint( shouldUseResampledParticles ); return m_pGroundLocation; } 68 | 69 | CvMat* GetAverageParticleOnGroundMatrix( ); 70 | 71 | //track an object without any saving, 72 | void TrackObjectWithoutSaveState( Matrixu* pFrameImageColor, Matrixu* pFrameImageGray, Matrixu* pFrameImageHSV = NULL ) ; 73 | 74 | // store the state of the object in the frame (typically followed by a call to TrackObjectWithoutSaveState 75 | void StoreObjectState( int frameind, Matrixu * pFrameDisplay=NULL ); 76 | 77 | //Update particle weights based on the PDF obtained using geometric fuser 78 | void UpdateParticlesWithGroundPDF( CvMat* pMeanMatrix, 79 | CvMat* pCovarianceMatrix, 80 | Matrixu* pColorImageMatrix, 81 | Matrixu* pGrayImageMatrix, 82 | Matrixu* pHsvImageMatrix, 83 | const bool shouldUseAppFusionWeights ); 84 | 85 | void UpdateParticleWeights( vectorf& likelihoodList, 86 | bool shouldUpdateOnlyNonZeroWeights = true, 87 | bool shouldForceReset = false, 88 | bool shouldResample = true ); 89 | 90 | //Force resampling 91 | void ForceParticleResampling( ){ m_particleFilterPtr->ResampleParticles(); } 92 | 93 | //generate training sample sets 94 | virtual void GenerateTrainingSampleSet( Matrixu* pFrameImageColor, 95 | Matrixu* pFrameImageGray, 96 | Matrixu* pFrameImageHSV = NULL ); 97 | 98 | //Generate Test Sample Set 99 | virtual void GenerateTestSampleSet( Matrixu* pFrameImageColor, 100 | Matrixu* pFrameImageGray, 101 | Matrixu* pFrameImageHSV ); 102 | 103 | // With ParticleFilterTracker, UpdateClassifier has to been called externally so that Particles can be adjusted before model updating 104 | virtual void UpdateClassifier( Matrixu* pFrameImageColor, 105 | Matrixu* pFrameImageGray, 106 | Matrixu* pFrameDisplayTraining = NULL, 107 | Matrixu* pFrameImageHSV = NULL ); 108 | 109 | /*****function to be implemented********/ 110 | // Suspend the tracking due to various reasons (e.g. occlusion, not-inialized, out of view/boundary etc.) 111 | void SuspendTracking( ) {}; 112 | // Check the reliability of tracking results (e.g. too much appearance changes?) 113 | void CheckTrackingReliability( ) {}; 114 | // Resume the tracking 115 | void ResumeTracking( ) {}; 116 | virtual void DrawObjectFootPosition( Matrixu* pFrameDisplay ) const; 117 | 118 | protected: 119 | bool InitializeTracker( Matrixu* pFrameImageColor, 120 | Matrixu* pFrameImageGray, 121 | TrackerParametersPtr trackerParametersPtr, 122 | Classifier::StrongClassifierParametersBasePtr clfparamsPtr, 123 | Matrixu* pFrameDisplay = NULL, 124 | Matrixu* pFrameDisplayTraining = NULL, 125 | Matrixu* pFrameImageHSV = NULL ); 126 | 127 | // track the object on the given frame, classifier is not updated, and therefore pFrameDisplayTraining is not updated 128 | virtual double TrackObjectOnTheGivenFrame( Matrixu* pFrameImageColor, 129 | Matrixu* pFrameImageGray, 130 | Matrixu* pFrameDisplayTraining= NULL, 131 | Matrixu* pFrameImageHSV = NULL ); 132 | 133 | void UpdateParticleWeightsForRearrangedParticles( Matrixu* pFrameImageColor, 134 | Matrixu* pFrameImageGray, 135 | Matrixu* pFrameImageHSV = NULL, 136 | const bool shouldUseAppFusionWeights = false ); 137 | 138 | private: 139 | 140 | //Find mean position on the image plane 141 | vectorf FindMeanFootPositionOnImagePlane( CvMat* pMeanGroundPlaneLocationMatrix ); 142 | 143 | //generate positive sample set based on the current particle state 144 | virtual void GeneratePositiveTrainingSampleSet( Matrixu* pFrameImageColor, 145 | Matrixu* pFrameImageGray, 146 | Matrixu* pFrameImageHSV = NULL ); 147 | 148 | //generate negative sample set based on the current particle state 149 | virtual void GenerateNegativeTrainingSampleSet( Matrixu* pFrameImageColor, 150 | Matrixu* pFrameImageGray, 151 | Matrixu* pFrameImageHSV = NULL ); 152 | 153 | // Locate object's foot position on the image plane. 154 | void EstimateGroundPoint( bool shouldUseResampledParticle = false ); 155 | 156 | // Draw predicted particles on a plane (for debugging purpose) 157 | void DrawTestSamples( Classifier::SampleSet testSamples, Matrixu* pFrame ); 158 | 159 | vectorf m_meanGroundPlaneFootPositionOnImageList; 160 | ParticleFilterPtr m_particleFilterPtr; // Pointer to the particle filter 161 | CvMat* m_pGroundLocation; // object's ground location (on the image plane) 162 | ParticleFilterTrackerParametersPtr m_particleFilterTrackerParamsPtr; // ParticleFilter tracking parameters 163 | CvMat* m_pWeightedAverageParticleMatrix; 164 | AppearanceBasedInformationFuserPtr m_appearanceFuserPtr; 165 | bool m_isAppearanceFusionEnabled; 166 | }; 167 | } 168 | #endif -------------------------------------------------------------------------------- /src/PerceptronWeakClassifier.cpp: -------------------------------------------------------------------------------- 1 | #include "PerceptronWeakClassifier.h" 2 | 3 | #define FEATURE_DIMENSION 1 4 | #define MAXIMUM_NUMBER_OF_ITERATIONS 100 5 | #define NEGATIVE_EXAMPLE_LABEL 0 6 | #define POSITIVE_EXAMPLE_LABEL 1 7 | #define PERCEPTRON_LEARNING_RATE 0.1 8 | #define PERCEPTRON_THRESHOLD 0.5 9 | 10 | namespace Classifier 11 | { 12 | /**************************************************************** 13 | PerceptronWeakClassifier 14 | Constructor 15 | ****************************************************************/ 16 | PerceptronWeakClassifier::PerceptronWeakClassifier( ) 17 | : WeakClassifierBase( ) 18 | { 19 | try 20 | { 21 | Initialize( ); 22 | } 23 | EXCEPTION_CATCH_AND_ABORT( "Error While Creating Perceptron Based Weak Classifier" ); 24 | } 25 | 26 | /**************************************************************** 27 | PerceptronWeakClassifier 28 | Constructor 29 | ****************************************************************/ 30 | PerceptronWeakClassifier::PerceptronWeakClassifier( const int featureId ) 31 | : WeakClassifierBase( featureId ) 32 | { 33 | try 34 | { 35 | Initialize( ); 36 | } 37 | EXCEPTION_CATCH_AND_ABORT( "Error While Creating Perceptron Based Weak Classifier" ); 38 | } 39 | 40 | /**************************************************************** 41 | PerceptronWeakClassifier::Initialize 42 | Initializes the parameters 43 | Exceptions: 44 | None 45 | ****************************************************************/ 46 | void PerceptronWeakClassifier::Initialize() 47 | { 48 | try 49 | { 50 | m_weightList = vectorf( FEATURE_DIMENSION + 1 ); 51 | } 52 | EXCEPTION_CATCH_AND_ABORT( "Error While Creating Perceptron Based Weak Classifier" ); 53 | } 54 | 55 | /**************************************************************** 56 | PerceptronWeakClassifier::Classify 57 | Classify 58 | Exceptions: 59 | None 60 | ****************************************************************/ 61 | bool PerceptronWeakClassifier::Classify( const Classifier::SampleSet& sampleSet, const int sampleIndex ) 62 | { 63 | try 64 | { 65 | return ( ClassifyF( sampleSet,sampleIndex ) > 0 ); 66 | } 67 | EXCEPTION_CATCH_AND_ABORT( "Error while classifying perceptron based classifier" ); 68 | } 69 | 70 | /**************************************************************** 71 | PerceptronWeakClassifier::ClassifyF 72 | ClassifyF 73 | Exceptions: 74 | None 75 | ****************************************************************/ 76 | float PerceptronWeakClassifier::ClassifyF( const Classifier::SampleSet& sampleSet, const int sampleIndex ) 77 | { 78 | try 79 | { 80 | double featureValue = GetFeatureValue( sampleSet, sampleIndex ); 81 | 82 | ASSERT_TRUE( m_weightList.size( ) == 2 ); 83 | double response = featureValue * m_weightList[0] > m_weightList[1] ? 1 : -1; 84 | 85 | return static_cast( response ); 86 | } 87 | EXCEPTION_CATCH_AND_ABORT( "Error while classifying perceptron based classifier" ); 88 | } 89 | 90 | 91 | /**************************************************************** 92 | PerceptronWeakClassifier::Update 93 | Update 94 | Exceptions: 95 | None 96 | ****************************************************************/ 97 | void PerceptronWeakClassifier::Update( const Classifier::SampleSet& positiveSampleSet, 98 | const Classifier::SampleSet& negativeSampleSet, 99 | vectorf* /*pPositiveSamplesWeightList*/, 100 | vectorf* /*pNegativeSamplesWeightList*/ ) 101 | { 102 | try 103 | { 104 | ASSERT_TRUE( positiveSampleSet.Size() > 0 && negativeSampleSet.Size() > 0 ); 105 | 106 | unsigned int numberOfIterations = 0; 107 | m_weightList = vectorf( FEATURE_DIMENSION+1, 0.0f ); 108 | m_weightList[1] = PERCEPTRON_THRESHOLD; 109 | 110 | unsigned int totalNumberOfSamples = positiveSampleSet.Size() + negativeSampleSet.Size(); 111 | int error; 112 | int maximumAllowedErrorCount = min( positiveSampleSet.Size(), negativeSampleSet.Size() ); 113 | int previousErrorCount = maximumAllowedErrorCount; 114 | 115 | while ( numberOfIterations < MAXIMUM_NUMBER_OF_ITERATIONS ) 116 | { 117 | unsigned int errorCount = 0; 118 | 119 | for ( int positiveSampleIndex = 0; positiveSampleIndex < positiveSampleSet.Size(); positiveSampleIndex++ ) 120 | { 121 | double featureValue = GetFeatureValue( positiveSampleSet, positiveSampleIndex ); 122 | int result = (featureValue * m_weightList[0] ) > m_weightList[1] ? POSITIVE_EXAMPLE_LABEL : NEGATIVE_EXAMPLE_LABEL; 123 | error = POSITIVE_EXAMPLE_LABEL - result; 124 | if ( error != 0 ) 125 | { 126 | m_weightList[0] = m_weightList[0] + PERCEPTRON_LEARNING_RATE * error * featureValue; 127 | errorCount++; 128 | } 129 | } 130 | 131 | for ( int negativeSampleIndex = 0; negativeSampleIndex < negativeSampleSet.Size(); negativeSampleIndex++ ) 132 | { 133 | double featureValue = GetFeatureValue( negativeSampleSet, negativeSampleIndex ); 134 | double response = featureValue * m_weightList[0]; 135 | int result = (featureValue * m_weightList[0] ) > m_weightList[1] ? POSITIVE_EXAMPLE_LABEL : NEGATIVE_EXAMPLE_LABEL; 136 | error = NEGATIVE_EXAMPLE_LABEL - result; 137 | if ( error != 0 ) 138 | { 139 | m_weightList[0] = m_weightList[0] + PERCEPTRON_LEARNING_RATE * error * featureValue; 140 | errorCount++; 141 | } 142 | } 143 | 144 | float errorRateImprovement = ( static_cast( previousErrorCount - errorCount ) / totalNumberOfSamples ); 145 | 146 | if ( errorCount < maximumAllowedErrorCount && errorRateImprovement < 0.01 ) 147 | { 148 | break; 149 | } 150 | 151 | previousErrorCount = errorCount; 152 | numberOfIterations++; 153 | } 154 | } 155 | EXCEPTION_CATCH_AND_ABORT( "Error while classifying perceptron based classifier" ); 156 | } 157 | } -------------------------------------------------------------------------------- /src/PerceptronWeakClassifier.h: -------------------------------------------------------------------------------- 1 | #ifndef PERCEPTRON_WEAK_CLASSIFIER_H 2 | #define PERCEPTRON_WEAK_CLASSIFIER_H 3 | 4 | #include "WeakClassifierBase.h" 5 | 6 | namespace Classifier 7 | { 8 | /**************************************************************** 9 | PerceptronWeakClassifier 10 | Perceptron weak classifier. 11 | ****************************************************************/ 12 | class PerceptronWeakClassifier : public WeakClassifierBase 13 | { 14 | public: 15 | PerceptronWeakClassifier( ); 16 | 17 | PerceptronWeakClassifier( const int featureId ); 18 | 19 | virtual WeakClassifierType GetClassifierType( ) { return PERCEPTRON; } 20 | 21 | virtual void Initialize( ); 22 | 23 | virtual void Update( const Classifier::SampleSet& positiveSampleSet, 24 | const Classifier::SampleSet& negativeSampleSet, 25 | vectorf* pPositiveSamplesWeightList = NULL, 26 | vectorf* pNegativeSamplesWeightList = NULL ); 27 | 28 | virtual bool Classify( const Classifier::SampleSet& sampleSet, 29 | const int sampleIndex ); 30 | 31 | virtual float ClassifyF( const Classifier::SampleSet& sampleSet, const int sampleIndex ); 32 | 33 | virtual bool IsValidWeakClassifier( ){ return true; } 34 | 35 | private: 36 | vectorf m_weightList; 37 | }; 38 | } 39 | #endif -------------------------------------------------------------------------------- /src/Public.cpp: -------------------------------------------------------------------------------- 1 | // MILTRACK 2 | // Copyright 2009 Boris Babenko (bbabenko@cs.ucsd.edu | http://vision.ucsd.edu/~bbabenko). Distributed under the terms of the GNU Lesser General Public License 3 | // (see the included gpl.txt and lgpl.txt files). Use at own risk. Please send me your feedback/suggestions/bugs. 4 | 5 | #include "Public.h" 6 | 7 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 8 | // random functions 9 | 10 | void randinitalize( const int init ) 11 | { 12 | rng_state = cvRNG(init); 13 | } 14 | 15 | int randint( const int min, const int max ) 16 | { 17 | return cvRandInt( &rng_state )%(max-min+1) + min; 18 | } 19 | 20 | float randfloat( ) 21 | { 22 | return (float)cvRandReal( &rng_state ); 23 | } 24 | 25 | vectori randintvec( const int min, const int max, const uint num ) 26 | { 27 | vectori v(num); 28 | for( uint k=0; k 1.0 || r2 == 0); 47 | 48 | return (float) (sigma * y * sqrt (-2.0 * log (r2) / r2)) + mean; 49 | } 50 | 51 | vectorf randgausvec(const float mean, const float sigma, const int num) 52 | { 53 | vectorf v(num); 54 | for( int k=0; k nw[j] && inds[k]= 0 && m_col >= 0 && m_height >= 0 && m_width >= 0 && m_scaleY > 0 && m_scaleX ); 53 | } 54 | 55 | /**************************************************************** 56 | Sample::operator= 57 | Assignment operator. 58 | Everything copied except the weight 59 | Exceptions: 60 | None 61 | ****************************************************************/ 62 | Sample& Sample::operator= ( const Sample& sample ) 63 | { 64 | m_pImgGray = sample.m_pImgGray; 65 | m_pImgColor = sample.m_pImgColor; 66 | m_pImgHSV = sample.m_pImgHSV; 67 | 68 | m_row = sample.m_row; 69 | m_col = sample.m_col; 70 | m_width = sample.m_width; 71 | m_height = sample.m_height; 72 | m_scaleX = sample.m_scaleX; 73 | m_scaleY = sample.m_scaleY; 74 | 75 | return (*this); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Sample.h: -------------------------------------------------------------------------------- 1 | #ifndef H_SAMPLE 2 | #define H_SAMPLE 3 | 4 | #include "Matrix.h" 5 | #include "Public.h" 6 | #include "CommonMacros.h" 7 | 8 | namespace Classifier 9 | { 10 | /**************************************************************** 11 | Sample 12 | Wrapper for image samples. 13 | ****************************************************************/ 14 | class Sample 15 | { 16 | public: 17 | //default constructor 18 | Sample( ); 19 | 20 | //overloaded constructor 21 | Sample( Matrixu* imgGray, 22 | int row, 23 | int col, 24 | int width = 0, 25 | int height = 0, 26 | float weight = 1.0, 27 | Matrixu* imgColor = NULL, 28 | Matrixu* imgHSV = NULL, 29 | float scaleX = 1.0, 30 | float scaleY = 1.0 ); 31 | 32 | //assignment operator 33 | Sample& operator = ( const Sample& sample ); 34 | 35 | Matrixu* GetColorImage( ) const { return m_pImgColor; } 36 | Matrixu* GetGrayImage( ) const { return m_pImgGray; } 37 | Matrixu* GetHSVImage( ) const { return m_pImgHSV;} 38 | 39 | public: 40 | 41 | Matrixu* m_pImgGray; 42 | Matrixu* m_pImgColor;//RGB color 43 | Matrixu* m_pImgHSV; 44 | int m_row; 45 | int m_col; 46 | int m_width; 47 | int m_height; 48 | float m_weight; 49 | float m_scaleX; 50 | float m_scaleY; 51 | int m_cameraID; //which camera the sample originates 52 | }; 53 | } 54 | #endif -------------------------------------------------------------------------------- /src/SampleSet.h: -------------------------------------------------------------------------------- 1 | #ifndef H_SAMPLE_SET 2 | #define H_SAMPLE_SET 3 | 4 | #include "Sample.h" 5 | 6 | namespace Classifier 7 | { 8 | /**************************************************************** 9 | SampleSet 10 | List of Samples. Takes care resizing samples, 11 | calculating features etc. 12 | ****************************************************************/ 13 | class SampleSet 14 | { 15 | public: 16 | 17 | SampleSet( ); 18 | SampleSet( const Sample& s ); 19 | 20 | //sample list related 21 | const size_t Size() const { return m_sampleList.size(); }; 22 | //Careful while using Resize, its a partial clearing. 23 | void Resize( size_t newSize ) { m_sampleList.resize(newSize); }; 24 | void Clear() { m_featureMatrix.clear(); m_sampleList.clear(); }; 25 | Classifier::Sample & operator[] (const int sampleIndex) { return m_sampleList[sampleIndex]; }; 26 | 27 | void PushBackSample( const Classifier::Sample &s ) { m_sampleList.push_back(s); }; 28 | void PushBackSample( Matrixu* pGrayImageMatrix, 29 | int x, 30 | int y, 31 | int width = 0, 32 | int height = 0, 33 | float weight = 1.0f, 34 | Matrixu* pRGBImageMatrix = NULL, 35 | Matrixu* pHSVImageMatrix = NULL, 36 | float scaleX = 1.0, 37 | float scaleY = 1.0 ); 38 | 39 | //feature matrix related 40 | void ResizeFeatures( size_t newSize ); 41 | float & GetFeatureValue( int sample, int ftr) { return m_featureMatrix[ftr](sample); }; 42 | float GetFeatureValue( int sample, int ftr) const { return m_featureMatrix[ftr](sample); }; 43 | Matrixf FeatureValues(int ftr) const { return m_featureMatrix[ftr]; }; 44 | bool IsFeatureComputed( ) const { return !m_featureMatrix.empty() && !m_sampleList.empty() && m_featureMatrix[0].size()>0; }; 45 | 46 | //Classifier::Sample images in the given ring of interest 47 | void SampleImage( Matrixu* pGrayImageMatrix, 48 | int x, 49 | int y, 50 | int width, 51 | int height, 52 | float outerCircleRadius, 53 | float innerCircleRadius = 0 , 54 | int maximumNumberOfSamples = 1000000, 55 | Matrixu* pRGBImageMatrix = NULL, 56 | Matrixu* pHSVImageMatrix = NULL, 57 | float scaleX = 1, 58 | float scaleY = 1 ); 59 | 60 | //randomly sample "numberOfSamples" samples in the given grayImage 61 | void SampleImage( Matrixu* pGrayImageMatrix, 62 | uint numberOfSamples, 63 | int w, 64 | int h, 65 | Matrixu* pRGBImageMatrix = NULL, 66 | Matrixu* pHSVImageMatrix = NULL, 67 | float scaleX = 1, 68 | float scaleY = 1 ); 69 | 70 | 71 | //sample image between two rectangles 72 | void SampleImage( Matrixu* pGrayImageMatrix, 73 | int x, 74 | int y, 75 | int width, 76 | int height, 77 | float maximumDistanceX, 78 | float maximumDistanceY, 79 | float minimumDistanceX, 80 | float minimumDistanceY, 81 | int maximumNumberOfSamples = 1000000, 82 | Matrixu* pRGBImageMatrix = NULL, 83 | Matrixu* pHSVImageMatrix = NULL, 84 | float scaleX = 1, 85 | float scaleY = 1 ); 86 | 87 | 88 | private: 89 | 90 | void SelectSamplesUniformlyFromLargerSet( int maximumNumberOfSamples ); 91 | 92 | vector m_sampleList; 93 | vector m_featureMatrix; 94 | }; 95 | } 96 | #endif -------------------------------------------------------------------------------- /src/SimpleTracker.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_TRACKER_PUBLIC 2 | #define SIMPLE_TRACKER_PUBLIC 3 | 4 | #include "Tracker.h" 5 | 6 | namespace MultipleCameraTracking 7 | { 8 | //Forward Declaration 9 | class SimpleTracker; 10 | 11 | //declarations of shared ptr 12 | typedef boost::shared_ptr SimpleTrackerPtr; 13 | 14 | /**************************************************************** 15 | SimpleTracker 16 | Derives from Tracker. 17 | ****************************************************************/ 18 | class SimpleTracker : public Tracker 19 | { 20 | public: 21 | // Constructor 22 | SimpleTracker( CvMat* pHomographyMatrix ) 23 | : m_pHomographyMatrix( pHomographyMatrix ) 24 | { 25 | s_faceCascade = NULL; 26 | } 27 | 28 | // Virtual destructor 29 | virtual ~SimpleTracker( ) 30 | { 31 | } 32 | 33 | // Initializes tracking with video information 34 | virtual void InitializeTrackerWithParameters( Matrixu* pFrameImageColor, 35 | Matrixu* pFrameImageGray, 36 | int frameInd, 37 | uint videoLength, 38 | TrackerParametersPtr trackerParametersPtr, 39 | Classifier::StrongClassifierParametersBasePtr clfparamsPtr, 40 | Matrixu* pFrameDisplay = NULL, 41 | Matrixu* pFrameDisplayTraining = NULL, 42 | Matrixu* pFrameImageHSV = NULL, 43 | Matrixf* pGroundTruthMatrix = NULL ) ; 44 | 45 | // Track each frame, store the results to m_states, and update pFrameDisplay and pFrameDisplayTraining (if required) 46 | virtual void TrackObjectAndSaveState( int frameind, 47 | Matrixu* pFrameImageColor, 48 | Matrixu* pFrameImageGray, 49 | Matrixu* pFrameDisplay = NULL, 50 | Matrixu* pFrameDisplayTraining = NULL, 51 | Matrixu* pFrameImageHSV = NULL ); 52 | 53 | // Saves the states to file after finishing tracking the object 54 | virtual void SaveStates( ); 55 | virtual void CalculateTrackingErrroFromGroundTruth( ); 56 | 57 | virtual const vectorf& GetCurrentTrackerState( ) const { return m_currentStateList; } 58 | 59 | virtual void GenerateTrainingSampleSet( Matrixu* pFrameImageColor, 60 | Matrixu* pFrameImageGray, 61 | Matrixu* pFrameImageHSV = NULL ) ; 62 | 63 | virtual void GenerateTestSampleSet( Matrixu* pFrameImageColor, 64 | Matrixu* pFrameImageGray, 65 | Matrixu* pFrameImageHSV ); 66 | 67 | virtual void GetTrainingSampleSets( Classifier::SampleSet& positiveSampleSet, Classifier::SampleSet& negativeSampleSet ); 68 | virtual void DisplayTrainingSamples( Matrixu* pFrameDisplayTraining ); 69 | 70 | // With SimpleTracker, classifier is automatically updated within TrackObjectOnTheGivenFrame 71 | virtual void UpdateClassifier( Matrixu* pFrameImageColor, 72 | Matrixu* pFrameImageGray, 73 | Matrixu* pFrameDisplayTraining = NULL, 74 | Matrixu* pFrameImageHSV = NULL ); 75 | 76 | CvMat* GetHomographyMatrix( ){ return m_pHomographyMatrix; } 77 | 78 | virtual void DrawObjectFootPosition( Matrixu* pFrameDisplay ) const { return; }; 79 | 80 | protected: 81 | // Initializes tracker with first frame(s) and other parameters 82 | bool InitializeTracker( Matrixu* pFrameImageColor, 83 | Matrixu* pFrameImageGray, 84 | TrackerParametersPtr trackerParametersPtr, 85 | Classifier::StrongClassifierParametersBasePtr clfparamsPtr, 86 | Matrixu* pFrameDisplay = NULL, 87 | Matrixu* pFrameDisplayTraining = NULL, 88 | Matrixu* pFrameImageHSV = NULL ); 89 | 90 | // Track object in a frame; 91 | // Classifier is automatically updated and pFrameDisplayTraining is updated if given 92 | virtual double TrackObjectOnTheGivenFrame( Matrixu* pFrameImageColor, 93 | Matrixu* pFrameImageGray, 94 | Matrixu* pFrameDisplayTraining= NULL, 95 | Matrixu* pFrameImageHSV = NULL ); 96 | 97 | Classifier::StrongClassifierBasePtr m_strongClassifierBasePtr; 98 | vectorf m_currentStateList; //[leftX, topY, sizeX, sizeY, scaleX, scaleY] 99 | SimpleTrackerParametersPtr m_simpleTrackerParamsPtr; 100 | 101 | Matrixf m_states; //saves entire track history 102 | Classifier::SampleSet m_positiveSampleSet; //positive samples 103 | Classifier::SampleSet m_negativeSampleSet; //negative samples 104 | Classifier::SampleSet m_testSampleSet; //detect samples 105 | vectorf m_liklihoodProbabilityList; //probability vector 106 | bool m_isInitialized; //is the tracker initialized 107 | bool m_shouldPreComputeHSV; //save temporal copy of HSV image for each frame to be tracked 108 | 109 | CvMat* m_pHomographyMatrix; 110 | private: 111 | 112 | virtual void GeneratePositiveTrainingSampleSet( Matrixu* pFrameImageColor, 113 | Matrixu* pFrameImageGray, 114 | Matrixu* pFrameImageHSV = NULL ); 115 | 116 | virtual void GenerateNegativeTrainingSampleSet( Matrixu* pFrameImageColor, 117 | Matrixu* pFrameImageGray, 118 | Matrixu* pFrameImageHSV = NULL ); 119 | }; 120 | } 121 | #endif -------------------------------------------------------------------------------- /src/StrongClassifierBase.cpp: -------------------------------------------------------------------------------- 1 | #include "StrongClassifierBase.h" 2 | 3 | namespace Classifier 4 | { 5 | /**************************************************************** 6 | StrongClassifierBase 7 | ****************************************************************/ 8 | StrongClassifierBase::StrongClassifierBase( StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ) 9 | : m_strongClassifierParametersBasePtr( strongClassifierParametersBasePtr ), 10 | m_featureVectorPtr( ), 11 | m_classifierStopWatch( ), 12 | m_numberOfSamples( 0 ), 13 | m_counter( 0 ) 14 | { 15 | try 16 | { 17 | ASSERT_TRUE( m_strongClassifierParametersBasePtr != NULL ); 18 | 19 | //set the number of features to be selected by the weak classifier 20 | if ( m_strongClassifierParametersBasePtr->m_numberOfSelectedWeakClassifiers > m_strongClassifierParametersBasePtr->m_totalNumberOfWeakClassifiers || m_strongClassifierParametersBasePtr->m_numberOfSelectedWeakClassifiers < 1 ) 21 | { 22 | m_strongClassifierParametersBasePtr->m_numberOfSelectedWeakClassifiers = m_strongClassifierParametersBasePtr->m_totalNumberOfWeakClassifiers/2; 23 | } 24 | 25 | //initialize the feature vector 26 | InitializeFeatureVector( ); 27 | 28 | ASSERT_TRUE( m_featureVectorPtr != NULL ); 29 | 30 | //initialize the weak classifiers 31 | InitializeWeakClassifiers( ); 32 | 33 | ASSERT_TRUE( !m_weakClassifierPtrList.empty() ); 34 | 35 | //store the feature history 36 | if ( m_strongClassifierParametersBasePtr->m_storeFeatureHistory ) 37 | { 38 | m_featureVectorPtr->SaveVisualizedFeatureVector( "Haar Features" ); 39 | } 40 | 41 | } 42 | EXCEPTION_CATCH_AND_ABORT( "Failed to Construct StrongClassifierBase" ); 43 | } 44 | 45 | /**************************************************************** 46 | InitializeFeatureVector 47 | 48 | Exceptions: 49 | None 50 | ****************************************************************/ 51 | void StrongClassifierBase::InitializeFeatureVector( ) 52 | { 53 | try 54 | { 55 | ASSERT_TRUE( m_strongClassifierParametersBasePtr != NULL ); 56 | 57 | //create the feature vector according to the feature type 58 | if ( m_strongClassifierParametersBasePtr->m_featureParametersPtr->GetFeatureType() == Features::HAAR_LIKE ) 59 | { 60 | m_featureVectorPtr = Features::FeatureVectorPtr(new Features::HaarFeatureVector( )); 61 | } 62 | else if ( m_strongClassifierParametersBasePtr->m_featureParametersPtr->GetFeatureType() == Features::MULTI_DIMENSIONAL_COLOR_HISTOGRAM ) 63 | { 64 | m_featureVectorPtr = Features::FeatureVectorPtr( new Features::MultiDimensionalColorHistogramFeatureVector( ) ); 65 | } 66 | else if ( m_strongClassifierParametersBasePtr->m_featureParametersPtr->GetFeatureType() == Features::CULTURE_COLOR_HISTOGRAM ) 67 | { 68 | m_featureVectorPtr = Features::FeatureVectorPtr( new Features::CultureColorHistogramFeatureVector( ) ); 69 | } 70 | else if ( m_strongClassifierParametersBasePtr->m_featureParametersPtr->GetFeatureType() == Features::HAAR_COLOR_HISTOGRAM ) 71 | { 72 | m_featureVectorPtr = Features::FeatureVectorPtr( new Features::HaarAndColorHistogramFeatureVector( ) ); 73 | } 74 | else 75 | { 76 | abortError( __LINE__, __FILE__, "Unsupported Feature Type" ); 77 | } 78 | 79 | //Generate feature vectors 80 | ASSERT_TRUE( m_featureVectorPtr != NULL ); 81 | 82 | //Generate Features 83 | m_featureVectorPtr->Generate( m_strongClassifierParametersBasePtr->m_featureParametersPtr ); 84 | } 85 | EXCEPTION_CATCH_AND_ABORT( "Failed to initialize the feature vector" ); 86 | } 87 | 88 | /**************************************************************** 89 | InitializeWeakClassifiers 90 | 91 | Exceptions: 92 | None 93 | ****************************************************************/ 94 | void StrongClassifierBase::InitializeWeakClassifiers( ) 95 | { 96 | try 97 | { 98 | ASSERT_TRUE( m_strongClassifierParametersBasePtr != NULL ); 99 | 100 | m_selectorList.resize( m_strongClassifierParametersBasePtr->m_numberOfSelectedWeakClassifiers, 0 ); 101 | m_weakClassifierPtrList.resize( m_strongClassifierParametersBasePtr->m_totalNumberOfWeakClassifiers ); 102 | 103 | for ( int featureIndex = 0; featureIndex < m_strongClassifierParametersBasePtr->m_totalNumberOfWeakClassifiers; featureIndex++ ) 104 | { 105 | if ( m_strongClassifierParametersBasePtr->m_weakClassifierType == STUMP ) 106 | { 107 | m_weakClassifierPtrList[featureIndex] = new OnlineStumpsWeakClassifier(featureIndex); 108 | m_weakClassifierPtrList[featureIndex]->SetLearningRate( m_strongClassifierParametersBasePtr->m_learningRate ); 109 | } 110 | else if ( m_strongClassifierParametersBasePtr->m_weakClassifierType == WEIGHTED_STUMP ) 111 | { 112 | m_weakClassifierPtrList[featureIndex] = new WeightedStumpsWeakClassifier(featureIndex); 113 | m_weakClassifierPtrList[featureIndex]->SetLearningRate( m_strongClassifierParametersBasePtr->m_learningRate ); 114 | } 115 | else if ( m_strongClassifierParametersBasePtr->m_weakClassifierType == PERCEPTRON ) 116 | { 117 | m_weakClassifierPtrList[featureIndex] = new PerceptronWeakClassifier(featureIndex); 118 | m_weakClassifierPtrList[featureIndex]->SetLearningRate( m_strongClassifierParametersBasePtr->m_learningRate ); 119 | } 120 | else 121 | { 122 | abortError(__LINE__,__FILE__,"incorrect weak pStrongClassifierBase name"); 123 | } 124 | } 125 | 126 | ASSERT_TRUE( !m_weakClassifierPtrList.empty() ); 127 | } 128 | EXCEPTION_CATCH_AND_ABORT( "Failed to initialize the weak classifiers" ); 129 | } 130 | } -------------------------------------------------------------------------------- /src/StrongClassifierBase.h: -------------------------------------------------------------------------------- 1 | #ifndef STRONG_CLASSIFIER_BASE_H 2 | #define STRONG_CLASSIFIER_BASE_H 3 | 4 | #include "ClassifierParameters.h" 5 | #include "WeakClassifierBase.h" 6 | #include "OnlineStumpsWeakClassifier.h" 7 | #include "WeightedStumpsWeakClassifier.h" 8 | #include "PerceptronWeakClassifier.h" 9 | 10 | #include "FeatureVector.h" 11 | #include "HaarFeatureVector.h" 12 | #include "CultureColorHistogramFeatureVector.h" 13 | #include "MultiDimensionalColorHistogramFeatureVector.h" 14 | #include "HaarAndColorHistogramFeatureVector.h" 15 | 16 | namespace Classifier 17 | { 18 | //Forward Declaration 19 | class StrongClassifierBase; 20 | class AdaBoostClassifier; 21 | class MILBoostClassifier; 22 | class MILEnsembleClassifier; 23 | 24 | //declarations of shared ptr 25 | typedef boost::shared_ptr StrongClassifierBasePtr; 26 | typedef boost::shared_ptr AdaBoostClassifierPtr; 27 | typedef boost::shared_ptr MILBoostClassifierPtr; 28 | typedef boost::shared_ptr MILEnsembleClassifierPtr; 29 | 30 | #define MIL_STOPPING_THRESHOLD 1e-100 31 | 32 | /**************************************************************** 33 | StrongClassifierBase 34 | Base class for all the strong classifiers. 35 | ****************************************************************/ 36 | class StrongClassifierBase 37 | { 38 | public: 39 | 40 | StrongClassifierBase( StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ); 41 | 42 | // pure virtual functions 43 | virtual void Update( Classifier::SampleSet& positiveSampleSet, Classifier::SampleSet& negativeSampleSet ) = 0; 44 | virtual vectorf Classify( Classifier::SampleSet& sampleSet, bool isLogRatioEnabled = true ) = 0; 45 | 46 | virtual void Update( Classifier::SampleSet& positiveSampleSet, Classifier::SampleSet& negativeSampleSet, int numPositiveBags ) { }; 47 | //member functions 48 | int GetNumberOfFeatures( ) 49 | { 50 | ASSERT_TRUE( m_featureVectorPtr != NULL ); 51 | return m_featureVectorPtr->GetNumberOfFeatures( ); 52 | } 53 | 54 | 55 | private: 56 | void InitializeFeatureVector( ); 57 | void InitializeWeakClassifiers( ); 58 | 59 | protected: 60 | StrongClassifierParametersBasePtr m_strongClassifierParametersBasePtr; 61 | Features::FeatureVectorPtr m_featureVectorPtr; 62 | StopWatch m_classifierStopWatch; 63 | vectori m_selectorList; //List of features selected in boosting 64 | vector m_weakClassifierPtrList; //List of weak classifiers that are available. 65 | uint m_numberOfSamples; 66 | uint m_counter; 67 | }; 68 | } 69 | #endif -------------------------------------------------------------------------------- /src/StrongClassifierFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "StrongClassifierFactory.h" 2 | #include "AdaBoostClassifier.h" 3 | #include "MILBoostClassifier.h" 4 | #include "MILEnsembleClassifier.h" 5 | #include "MILAnyBoostClassifier.h" 6 | 7 | namespace Classifier 8 | { 9 | /**************************************************************** 10 | CreateAndInitializeClassifier 11 | Creates a classifier according to the type specified in the 12 | parameters. Initializes appropriate classifier. 13 | ****************************************************************/ 14 | StrongClassifierBasePtr StrongClassifierFactory::CreateAndInitializeClassifier( StrongClassifierParametersBasePtr strongClassifierParametersBasePtr ) 15 | { 16 | try 17 | { 18 | StrongClassifierBasePtr strongClassifierBasePtr; 19 | 20 | switch ( strongClassifierParametersBasePtr->GetClassifierType( ) ) 21 | { 22 | case ONLINE_ADABOOST: 23 | strongClassifierBasePtr = StrongClassifierBasePtr( new AdaBoostClassifier( strongClassifierParametersBasePtr ) ); 24 | break; 25 | case ONLINE_STOCHASTIC_BOOST_MIL: 26 | strongClassifierBasePtr = StrongClassifierBasePtr( new MILBoostClassifier( strongClassifierParametersBasePtr ) ); 27 | break; 28 | case ONLINE_ENSEMBLE_BOOST_MIL: 29 | strongClassifierBasePtr = StrongClassifierBasePtr( new MILEnsembleClassifier( strongClassifierParametersBasePtr ) ); 30 | break; 31 | case ONLINE_ANY_BOOST_MIL: 32 | strongClassifierBasePtr = StrongClassifierBasePtr( new MILAnyBoostClassifier( strongClassifierParametersBasePtr ) ); 33 | break; 34 | default: 35 | abortError(__LINE__,__FILE__,"Incorrect pStrongClassifierBase type!"); 36 | } 37 | 38 | ASSERT_TRUE( strongClassifierBasePtr.get( ) != NULL ); 39 | 40 | return strongClassifierBasePtr; 41 | } 42 | EXCEPTION_CATCH_AND_ABORT("Failed to create and initialize the classifier" ) 43 | } 44 | } -------------------------------------------------------------------------------- /src/StrongClassifierFactory.h: -------------------------------------------------------------------------------- 1 | #include "StrongClassifierBase.h" 2 | 3 | namespace Classifier 4 | { 5 | class StrongClassifierFactory 6 | { 7 | public: 8 | //static functions 9 | static StrongClassifierBasePtr CreateAndInitializeClassifier( Classifier::StrongClassifierParametersBasePtr clfParamsPtr ); 10 | }; 11 | } -------------------------------------------------------------------------------- /src/Tracker.cpp: -------------------------------------------------------------------------------- 1 | #include "StrongClassifierBase.h" 2 | #include "Tracker.h" 3 | #include "Public.h" 4 | #include "Sample.h" 5 | #include "CommonMacros.h" 6 | 7 | #define HAAR_CASCADE_FILE_NAME "haarcascade_frontalface_alt_tree.xml" 8 | 9 | namespace MultipleCameraTracking 10 | { 11 | CvHaarClassifierCascade* Tracker::s_faceCascade = NULL; 12 | 13 | /**************************************************************** 14 | Tracker::InitializeWithFace 15 | Initialize the tracker with opencv's face detector. 16 | Exceptions: 17 | None 18 | ****************************************************************/ 19 | bool Tracker::InitializeWithFace( TrackerParameters* params, Matrixu& frame ) 20 | { 21 | const int minsz = 20; 22 | 23 | //Get the name of the haar-cascade .xml file 24 | const char* cascade_name = HAAR_CASCADE_FILE_NAME; 25 | ASSERT_TRUE( cascade_name != NULL ); 26 | 27 | //Load the cascade 28 | if ( Tracker::s_faceCascade == NULL ) 29 | { 30 | Tracker::s_faceCascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 ); 31 | } 32 | 33 | frame.createIpl(); 34 | IplImage* img = frame.getIpl(); 35 | ASSERT_TRUE( img != NULL ); 36 | 37 | //convert to grayscale 38 | IplImage* gray = cvCreateImage( cvSize(img->width, img->height), IPL_DEPTH_8U, 1 ); 39 | ASSERT_TRUE( gray != NULL ); 40 | cvCvtColor(img, gray, CV_BGR2GRAY ); 41 | 42 | frame.freeIpl(); 43 | 44 | //histogram equalization 45 | cvEqualizeHist( gray, gray ); 46 | 47 | //memory storage 48 | CvMemStorage* storage = cvCreateMemStorage(0); 49 | cvClearMemStorage(storage); 50 | 51 | //call opencv's haar feature based detector 52 | CvSeq* faces = cvHaarDetectObjects( gray, 53 | Tracker::s_faceCascade, 54 | storage, 55 | 1.05, 56 | 3, 57 | CV_HAAR_DO_CANNY_PRUNING, 58 | cvSize( minsz, minsz ) ); 59 | 60 | int index = faces->total-1; 61 | CvRect* r = (CvRect*)cvGetSeqElem( faces, index ); 62 | if ( r == NULL ) 63 | { 64 | return false; 65 | } 66 | 67 | while ( r && (r->widthheight < minsz || (r->y+r->height+10)>frame.rows() || (r->x+r->width)>frame.cols() || 68 | r->y<0 || r->x<0) ) 69 | { 70 | r = (CvRect*)cvGetSeqElem( faces, --index ); 71 | } 72 | 73 | //set the params 74 | params->m_initState.resize(4); 75 | params->m_initState[0] = (float)r->x; 76 | params->m_initState[1] = (float)r->y; 77 | params->m_initState[2] = (float)r->width; 78 | params->m_initState[3] = (float)r->height+10; 79 | 80 | return true; 81 | } 82 | 83 | /**************************************************************** 84 | Tracker::ReplayTracker 85 | Replays the tracker based on the saved output. 86 | Exceptions: 87 | None 88 | ****************************************************************/ 89 | void Tracker::ReplayTracker( vector& vid, string statesfile, string outputvid, uint R, uint G, uint B) 90 | { 91 | Matrixf states; 92 | states.DLMRead(statesfile.c_str()); 93 | 94 | Matrixu colorframe; 95 | // save videoList file 96 | CvVideoWriter* w = NULL; 97 | if ( ! outputvid.empty() ) 98 | { 99 | w = cvCreateVideoWriter( outputvid.c_str(), CV_FOURCC('x','v','i','d'), 15, cvSize(vid[0].cols(), vid[0].rows()), 3 ); 100 | 101 | if( w==NULL ) 102 | { 103 | abortError(__LINE__,__FILE__,"Error opening videoList file for output"); 104 | } 105 | } 106 | 107 | for( uint k=0; k < vid.size(); k++ ) 108 | { 109 | vid[k].conv2RGB(colorframe); 110 | colorframe.drawRect(states(k,2),states(k,3),states(k,0),states(k,1),1,0,2,R,G,B); 111 | colorframe.drawText(("#"+int2str(k,3)).c_str(),1,25,255,255,0); 112 | colorframe._keepIpl=true; 113 | colorframe.display(0,2); 114 | cvWaitKey(1); 115 | if( w != NULL ) 116 | { 117 | cvWriteFrame( w, colorframe.getIpl() ); 118 | } 119 | colorframe._keepIpl=false; colorframe.freeIpl(); 120 | } 121 | 122 | // clean up 123 | if( w != NULL ) 124 | { 125 | cvReleaseVideoWriter( &w ); 126 | } 127 | } 128 | 129 | /**************************************************************** 130 | Tracker::ReplaysTracker 131 | Replays the tracker based on the saved output. 132 | Exceptions: 133 | None 134 | ****************************************************************/ 135 | void Tracker::ReplayTrackers(vector &vid, vector statesfile, string outputvid, Matrixu colors) 136 | { 137 | Matrixu states; 138 | 139 | vector resvid(vid.size()); 140 | Matrixu colorframe; 141 | 142 | // save videoList file 143 | CvVideoWriter* w = NULL; 144 | if ( ! outputvid.empty() ) 145 | { 146 | w = cvCreateVideoWriter( outputvid.c_str(), CV_FOURCC('x','v','i','d'), 15, cvSize(vid[0].cols(), vid[0].rows()), 3 ); 147 | 148 | if ( w==NULL ) 149 | { 150 | abortError(__LINE__,__FILE__,"Error opening videoList file for output"); 151 | } 152 | } 153 | 154 | for ( uint k=0; k TrackerPtr; 16 | 17 | /**************************************************************** 18 | Tracker 19 | Base class for all the trackers. 20 | ****************************************************************/ 21 | class Tracker 22 | { 23 | public: 24 | static bool InitializeWithFace( TrackerParameters* params, Matrixu& frame ); 25 | static void ReplayTracker( vector& vid, string states, string outputvid = "", uint R = 255, uint G = 0, uint B = 0 ); 26 | static void ReplayTrackers( vector& vid, vector statesfile, string outputvid, Matrixu colors ); 27 | 28 | // Initializes tracking with video information 29 | virtual void InitializeTrackerWithParameters( Matrixu* pFrameImageColor, 30 | Matrixu* pFrameImageGray, 31 | int frameInd, 32 | uint videoLength, 33 | TrackerParametersPtr trackerParametersPtr, 34 | Classifier::StrongClassifierParametersBasePtr clfparamsPtr, 35 | Matrixu* pFrameDisplay = NULL, 36 | Matrixu* pFrameDisplayTraining = NULL, 37 | Matrixu* pFrameImageHSV = NULL, 38 | Matrixf* pGroundTruthMatrix = NULL ) = 0; 39 | 40 | // Track each frame, and update pFrameDisplay and pFrameDisplayTraining (if required) 41 | virtual void TrackObjectAndSaveState( int frameind, 42 | Matrixu* pFrameImageColor, 43 | Matrixu* pFrameImageGray, 44 | Matrixu* pFrameDisplay = NULL, 45 | Matrixu* pFrameDisplayTraining = NULL, 46 | Matrixu* pFrameImageHSV = NULL ) = 0; 47 | // Saves the states to file after finishing tracking the object 48 | virtual void SaveStates( ) = 0; 49 | virtual void CalculateTrackingErrroFromGroundTruth( ) = 0; 50 | virtual void GenerateTrainingSampleSet( Matrixu* pFrameImageColor, 51 | Matrixu* pFrameImageGray, 52 | Matrixu* pFrameImageHSV = NULL ) = 0; 53 | 54 | virtual void GenerateTestSampleSet( Matrixu* pFrameImageColor, 55 | Matrixu* pFrameImageGray, 56 | Matrixu* pFrameImageHSV ) = 0; 57 | 58 | virtual void GetTrainingSampleSets( Classifier::SampleSet& positiveSampleSet, Classifier::SampleSet& negativeSampleSet ) = 0; 59 | virtual void DisplayTrainingSamples( Matrixu* pFrameDisplayTraining ) = 0; 60 | virtual void UpdateClassifier( Matrixu* pFrameImageColor, 61 | Matrixu* pFrameImageGray, 62 | Matrixu* pFrameDisplayTraining = NULL, 63 | Matrixu* pFrameImageHSV = NULL ) = 0; 64 | 65 | virtual const vectorf& GetCurrentTrackerState( ) const = 0; 66 | 67 | virtual void DrawObjectFootPosition( Matrixu* pFrameDisplay ) const = 0; 68 | 69 | protected: 70 | 71 | virtual void GeneratePositiveTrainingSampleSet( Matrixu* pFrameImageColor, 72 | Matrixu* pFrameImageGray, 73 | Matrixu* pFrameImageHSV = NULL ) = 0; 74 | 75 | virtual void GenerateNegativeTrainingSampleSet( Matrixu* pFrameImageColor, 76 | Matrixu* pFrameImageGray, 77 | Matrixu* pFrameImageHSV = NULL ) = 0; 78 | 79 | static CvHaarClassifierCascade* s_faceCascade; 80 | CameraTrackingParametersPtr m_cameraTrackingParametersPtr; 81 | Matrixf m_groundTruthMatrix; 82 | }; 83 | } 84 | #endif -------------------------------------------------------------------------------- /src/TrackerParameters.cpp: -------------------------------------------------------------------------------- 1 | #include "TrackerParameters.h" 2 | 3 | namespace MultipleCameraTracking 4 | { 5 | /**************************************************************** 6 | CameraTrackingParameters 7 | Stores the tracking parameters for each camera 8 | ****************************************************************/ 9 | CameraTrackingParameters::CameraTrackingParameters( InputParameters * pInputConfigeration, 10 | const TrackerType trackerType, 11 | const Classifier::StrongClassifierType localTrackerStrongClassifierType, 12 | const Classifier::WeakClassifierType localTrackerWeakClassifierType, 13 | const Features::FeatureType trackerFeatureType, 14 | const GeometricFusionType geometricFusionType, 15 | const int numberOfParticles, 16 | const AppearanceFusionType appearanceFusionType, 17 | const AppearanceFusionStrongClassifierType appearanceFusionStrongClassifierType, 18 | const Classifier::WeakClassifierType appearanceFusionWeakClassifierType ) 19 | : m_trialNumber( pInputConfigeration->m_trialNumber ), 20 | m_localObjectTrackerType( trackerType), 21 | m_localTrackerStrongClassifierType( localTrackerStrongClassifierType ), 22 | m_localTrackerWeakClassifierType( localTrackerWeakClassifierType ), 23 | m_trackerFeatureType( trackerFeatureType ), 24 | m_geometricFusionType( geometricFusionType ), 25 | m_saveGroundParticlesImage( pInputConfigeration->m_saveGroundParticlesImage == 1 ), 26 | m_displayGroundParticlesImage( pInputConfigeration->m_displayGroundParticlesImage == 1 ), 27 | m_saveGroundPlaneKFImage( pInputConfigeration->m_saveGroundPlaneKFImage == 1 ), 28 | m_displayGroundPlaneKFImage( pInputConfigeration->m_displayGroundPlaneKFImage == 1 ), 29 | m_numberOfParticles( numberOfParticles ), 30 | m_appearanceFusionType( appearanceFusionType ), 31 | m_appearanceFusionStrongClassifierType( appearanceFusionStrongClassifierType ), 32 | m_appearanceFusionWeakClassifierType( appearanceFusionWeakClassifierType ), 33 | m_isCrossCameraAutoInitializationEnabled( pInputConfigeration->m_enableCrossCameraAutoInitialization == 1 ), 34 | m_isCrossCameraOcclusionHandlingEnabled( pInputConfigeration->m_enableCrossCameraOcclusionHandling == 1 ), 35 | m_displayGMMCenters ( pInputConfigeration->m_displayGMMCenters == 1), 36 | m_outputDirectoryString( pInputConfigeration->m_outputDirectoryNameCstr ), 37 | m_inputDirectoryString( pInputConfigeration->m_inputDirectoryNameCstr ), 38 | m_dataNameString( pInputConfigeration->m_dataFilesNameCstr ), 39 | m_nameInitilizationString( pInputConfigeration->m_intializationDirectoryCstr ), 40 | m_calculateTrackingError ( pInputConfigeration->m_calculateTrackingError == 1 ), 41 | m_numberOfBinsForColorHistogram ( static_cast(pInputConfigeration->m_numofBinsColor) ), 42 | m_useHSVColorSpaceForColorHistogram ( pInputConfigeration->m_useHSVColor == 1 ), 43 | m_HSVRequired ( pInputConfigeration->m_useHSVColor == 1 || appearanceFusionType == FUSION_CULTURE_COLOR_HISTOGRAM ), 44 | m_appearanceFusionNumberOfPositiveExamples( pInputConfigeration->m_AFNumberOfPositiveExamples ), 45 | m_appearanceFusionNumberOfNegativeExamples( pInputConfigeration->m_AFNumberOfNegativeExamples ), 46 | m_appearanceFusionRefreshRate( pInputConfigeration->m_AFRefreshRate ) 47 | { 48 | }; 49 | 50 | /**************************************************************** 51 | TrackerParams 52 | Stores the tracker parameters for the tracker (associated with each object) 53 | ****************************************************************/ 54 | TrackerParameters::TrackerParameters() 55 | { 56 | m_outputBoxColor.resize(3); 57 | //default box color similar to Magenta. 58 | m_outputBoxColor[0] = 0; 59 | m_outputBoxColor[1] = 255; 60 | m_outputBoxColor[2] = 0; 61 | m_outputBoxLineWidth = 2; 62 | m_numberOfNegativeTrainingSamples = 15; 63 | m_posRadiusTrain = 1; 64 | m_maximumNumberOfPositiveTrainingSamples = 100000; 65 | m_init_negNumTrain = 1000; 66 | m_init_posTrainRadius = 3; 67 | m_initState.resize(4); 68 | m_debugv = false; 69 | m_shouldNotUseSigmoid = true; 70 | m_initializeWithFaceDetection = true; 71 | m_isColor = true; 72 | m_trajSave = ""; 73 | } 74 | 75 | /**************************************************************** 76 | SimpleTrackerParams 77 | ****************************************************************/ 78 | SimpleTrackerParameters::SimpleTrackerParameters() 79 | { 80 | m_searchWindSize = 30; 81 | m_negSampleStrategy = 1; 82 | } 83 | } -------------------------------------------------------------------------------- /src/WeakClassifierBase.cpp: -------------------------------------------------------------------------------- 1 | #include "WeakClassifierBase.h" 2 | 3 | namespace Classifier 4 | { 5 | /**************************************************************** 6 | WeakClassifierBase 7 | Constructor 8 | Exceptions: 9 | None 10 | ****************************************************************/ 11 | WeakClassifierBase::WeakClassifierBase( ) 12 | : m_isWeakClassifierTrained( false ), 13 | m_featureIndex( -1 ) 14 | { 15 | } 16 | 17 | /**************************************************************** 18 | WeakClassifierBase 19 | Constructor 20 | Exceptions: 21 | None 22 | ****************************************************************/ 23 | WeakClassifierBase::WeakClassifierBase( const int featureId ) 24 | :m_isWeakClassifierTrained( false ), 25 | m_featureIndex( featureId ) 26 | { 27 | } 28 | 29 | /**************************************************************** 30 | WeakClassifierBase::ClassifySet 31 | Classifies the given set of samples. 32 | Exceptions: 33 | None 34 | ****************************************************************/ 35 | vectorb WeakClassifierBase::ClassifySet( const Classifier::SampleSet& sampleSet ) 36 | { 37 | vectorb responseList( sampleSet.Size() ); 38 | 39 | #pragma omp parallel for 40 | for ( int sampleIndex = 0; sampleIndex < sampleSet.Size() ; sampleIndex++ ) 41 | { 42 | responseList[sampleIndex] = Classify( sampleSet, sampleIndex ); 43 | } 44 | return responseList; 45 | } 46 | 47 | /**************************************************************** 48 | WeakClassifierBase::ClassifySetF 49 | Classifies the given set of samples. 50 | Exceptions: 51 | None 52 | ****************************************************************/ 53 | vectorf WeakClassifierBase::ClassifySetF( const Classifier::SampleSet& sampleSet ) 54 | { 55 | vectorf responseList( sampleSet.Size( ) ); 56 | 57 | #pragma omp parallel for 58 | for ( int sampleIndex = 0; sampleIndex < sampleSet.Size(); sampleIndex++ ) 59 | { 60 | responseList[sampleIndex] = ClassifyF( sampleSet, sampleIndex ); 61 | } 62 | return responseList; 63 | } 64 | 65 | /**************************************************************** 66 | WeakClassifierBase::ClassifySetF 67 | Classifies the given set of samples. 68 | Exceptions: 69 | None 70 | ****************************************************************/ 71 | float WeakClassifierBase::GetFeatureValue( const Classifier::SampleSet& sampleSet, const int sampleIndex ) 72 | { 73 | ASSERT_TRUE( sampleSet.IsFeatureComputed() ); 74 | return sampleSet.GetFeatureValue( sampleIndex, m_featureIndex ); 75 | } 76 | } -------------------------------------------------------------------------------- /src/WeakClassifierBase.h: -------------------------------------------------------------------------------- 1 | #ifndef WEAK_CLASSIFIER_BASE_H 2 | #define WEAK_CLASSIFIER_BASE_H 3 | 4 | #include "Feature.h" 5 | 6 | namespace Classifier 7 | { 8 | //Forward declarations 9 | class OnlineStumpsWeakClassifier; 10 | class WeightedStumpsWeakClassifier; 11 | class PerceptronWeakClassifier; 12 | 13 | enum WeakClassifierType{ STUMP, 14 | WEIGHTED_STUMP, 15 | PERCEPTRON, 16 | }; 17 | 18 | /**************************************************************** 19 | WeakClassifierBase 20 | Base class for all the weak classifiers. 21 | ****************************************************************/ 22 | class WeakClassifierBase 23 | { 24 | public: 25 | WeakClassifierBase( ); 26 | WeakClassifierBase( const int featureId ); 27 | 28 | //pure virtual functions 29 | virtual void Initialize( ) = 0; 30 | 31 | virtual void Update( const Classifier::SampleSet& positiveSampleSet, 32 | const Classifier::SampleSet& negativeSampleSet, 33 | vectorf* pPositiveSamplesWeightList = NULL, 34 | vectorf* pNegativeSamplesWeightList = NULL ) = 0; 35 | 36 | virtual bool Classify( const Classifier::SampleSet& sampleSet, const int sampleIndex )=0; 37 | 38 | virtual float ClassifyF( const Classifier::SampleSet& sampleSet, const int sampleIndex )=0; 39 | 40 | virtual WeakClassifierType GetClassifierType( ) = 0; 41 | 42 | virtual bool IsValidWeakClassifier( ) = 0; 43 | 44 | //member functions 45 | virtual vectorb ClassifySet( const Classifier::SampleSet& sampleSet ); 46 | virtual vectorf ClassifySetF( const Classifier::SampleSet& sampleSet ); 47 | 48 | float GetFeatureValue( const Classifier::SampleSet& sampleSet, const int sampleIndex ); 49 | void SetLearningRate( const float learningRate ){ m_learningRate = learningRate; } 50 | 51 | protected: 52 | 53 | bool m_isWeakClassifierTrained; 54 | const int m_featureIndex; 55 | float m_learningRate; 56 | }; 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /src/WeightedStumpsWeakClassifier.cpp: -------------------------------------------------------------------------------- 1 | #include "WeightedStumpsWeakClassifier.h" 2 | 3 | #define FEATURE_DIMENSION 1 4 | #define MAXIMUM_NUMBER_OF_ITERATIONS 10 5 | #define MINIMUM_ERROR_THRESHOLD_FOR_PERCEPTRON 0.5 6 | 7 | namespace Classifier 8 | { 9 | /**************************************************************** 10 | ClfWStump::ClfWStump( ) 11 | C'tor 12 | ****************************************************************/ 13 | WeightedStumpsWeakClassifier::WeightedStumpsWeakClassifier( ) 14 | : WeakClassifierBase( ) 15 | { 16 | Initialize(); 17 | } 18 | 19 | /**************************************************************** 20 | WeightedStumpsWeakClassifier::WeightedStumpsWeakClassifier( ) 21 | C'tor 22 | ****************************************************************/ 23 | WeightedStumpsWeakClassifier::WeightedStumpsWeakClassifier( const int featureId ) 24 | : WeakClassifierBase(featureId) 25 | { 26 | 27 | m_learningRate = 0.85f; 28 | Initialize(); 29 | } 30 | 31 | /**************************************************************** 32 | ClfWStump::Initialize 33 | C'tor 34 | ****************************************************************/ 35 | void WeightedStumpsWeakClassifier::Initialize( ) 36 | { 37 | m_mu0 = 0; 38 | m_mu1 = 0; 39 | m_sig0 = 1; 40 | m_sig1 = 1; 41 | m_isWeakClassifierTrained = false; 42 | } 43 | 44 | /**************************************************************** 45 | WeightedStumpsWeakClassifier::ClassifyF 46 | Classify the set of samples using the learned weak classifier. 47 | Exceptions: 48 | None 49 | ****************************************************************/ 50 | float WeightedStumpsWeakClassifier::ClassifyF( const Classifier::SampleSet& sampleSet, const int sampleIndex ) 51 | { 52 | float xx = GetFeatureValue(sampleSet,sampleIndex); 53 | double p0 = exp( (xx-m_mu0)*(xx-m_mu0)*m_e0 )*m_n0; 54 | double p1 = exp( (xx-m_mu1)*(xx-m_mu1)*m_e1 )*m_n1; 55 | float r = (float)(log(1e-5+p1)-log(1e-5+p0)); 56 | return r; 57 | } 58 | 59 | /**************************************************************** 60 | WeightedStumpsWeakClassifier::Update 61 | Update the weak classifier 62 | Exceptions: 63 | None 64 | ****************************************************************/ 65 | void WeightedStumpsWeakClassifier::Update( const Classifier::SampleSet& positiveSampleSet, 66 | const Classifier::SampleSet& negativeSampleSet, 67 | vectorf* pPositiveSamplesWeightList, 68 | vectorf* pNegativeSamplesWeightList ) 69 | { 70 | Matrixf poswm, negwm, poswn, negwn; 71 | if( ( positiveSampleSet.Size() != pPositiveSamplesWeightList->size() ) || (negativeSampleSet.Size() != pNegativeSamplesWeightList->size()) ) 72 | { 73 | abortError(__LINE__,__FILE__,"ClfWStump::Update - number of samples and number of weights mismatch"); 74 | } 75 | 76 | float posmu=0.0, negmu=0.0; 77 | if( positiveSampleSet.Size()>0 ) 78 | { 79 | poswm = *pPositiveSamplesWeightList; 80 | poswn = poswm.normalize(); 81 | posmu = positiveSampleSet.FeatureValues(m_featureIndex).MeanW(poswn); 82 | } 83 | 84 | if( negativeSampleSet.Size()>0 ) 85 | { 86 | negwm = *pNegativeSamplesWeightList; 87 | negwn = negwm.normalize(); 88 | negmu = negativeSampleSet.FeatureValues(m_featureIndex).MeanW(negwn); 89 | } 90 | 91 | if( m_isWeakClassifierTrained ) 92 | { 93 | if( positiveSampleSet.Size()>0 ) 94 | { 95 | m_mu1 = ( m_learningRate*m_mu1 + (1-m_learningRate)*posmu ); 96 | m_sig1 = ( m_learningRate*m_sig1 + (1-m_learningRate)*positiveSampleSet.FeatureValues(m_featureIndex).VarW(poswn,&m_mu1) ); 97 | } 98 | 99 | if( negativeSampleSet.Size()>0 ) 100 | { 101 | m_mu0 = ( m_learningRate*m_mu0 + (1-m_learningRate)*negmu ); 102 | m_sig0 = ( m_learningRate*m_sig0 + (1-m_learningRate)*negativeSampleSet.FeatureValues(m_featureIndex).VarW(negwn,&m_mu0) ); 103 | } 104 | } 105 | else 106 | { 107 | m_isWeakClassifierTrained = true; 108 | m_mu1 = posmu; 109 | m_mu0 = negmu; 110 | if( negativeSampleSet.Size()>0 ) m_sig0 = negativeSampleSet.FeatureValues(m_featureIndex).VarW(negwn,&negmu)+1e-9f; 111 | if( positiveSampleSet.Size()>0 ) m_sig1 = positiveSampleSet.FeatureValues(m_featureIndex).VarW(poswn,&posmu)+1e-9f; 112 | } 113 | 114 | m_n0 = 1.0f/pow(m_sig0,0.5f); 115 | m_n1 = 1.0f/pow(m_sig1,0.5f); 116 | m_e1 = -1.0f/(2.0f*m_sig1); 117 | m_e0 = -1.0f/(2.0f*m_sig0); 118 | } 119 | } -------------------------------------------------------------------------------- /src/WeightedStumpsWeakClassifier.h: -------------------------------------------------------------------------------- 1 | #ifndef WEIGHTED_STUMP_WEAK_CLASSIFIER_H 2 | #define WEIGHTED_STUMP_WEAK_CLASSIFIER_H 3 | 4 | #include "WeakClassifierBase.h" 5 | 6 | namespace Classifier 7 | { 8 | /**************************************************************** 9 | WeightedStumpsWeakClassifier 10 | Stumps weak classifier. 11 | ****************************************************************/ 12 | class WeightedStumpsWeakClassifier : public WeakClassifierBase 13 | { 14 | public: 15 | WeightedStumpsWeakClassifier( ); 16 | WeightedStumpsWeakClassifier( const int featureId ); 17 | 18 | virtual WeakClassifierType GetClassifierType( ) { return WEIGHTED_STUMP; } 19 | 20 | virtual void Initialize( ); 21 | virtual void Update( const Classifier::SampleSet& positiveSampleSet, 22 | const Classifier::SampleSet& negativeSampleSet, 23 | vectorf* pPositiveSamplesWeightList = NULL, 24 | vectorf* pNegativeSamplesWeightList = NULL ); 25 | virtual bool Classify( const Classifier::SampleSet& sampleSet, const int sampleIndex ){ return ClassifyF( sampleSet, sampleIndex ) > 0; } 26 | virtual float ClassifyF( const Classifier::SampleSet& sampleSet, const int sampleIndex ); 27 | 28 | virtual bool IsValidWeakClassifier( ){ return true; } 29 | 30 | private: 31 | float m_mu0; 32 | float m_mu1; 33 | float m_sig0; 34 | float m_sig1; 35 | float m_n1; 36 | float m_n0; 37 | float m_e1; 38 | float m_e0; 39 | }; 40 | } 41 | #endif --------------------------------------------------------------------------------