From 5e048d1fa5ee1277669b784f650e310c3233f71d Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Fri, 12 Apr 2013 12:11:11 +0400 Subject: [PATCH] Move C API of opencv_objdetect to separate file Also move cv::linemod to own header --- include/opencv/cv.h | 3 +- include/opencv/cv.hpp | 1 + include/opencv/cvaux.h | 3 +- modules/contrib/include/opencv2/contrib.hpp | 2 + modules/objdetect/include/opencv2/objdetect.hpp | 783 ++------------------- .../include/opencv2/objdetect/linemod.hpp | 455 ++++++++++++ .../include/opencv2/objdetect/objdetect_c.h | 289 ++++++++ modules/objdetect/src/_lsvm_routine.h | 2 + modules/objdetect/src/_lsvmparser.h | 1 + modules/objdetect/src/cascadedetect.cpp | 1 + modules/objdetect/src/datamatrix.cpp | 2 +- modules/objdetect/src/haar.cpp | 1 + modules/objdetect/src/hog.cpp | 7 +- modules/objdetect/src/latentsvmdetector.cpp | 1 + modules/objdetect/src/linemod.cpp | 8 +- modules/objdetect/src/matching.cpp | 1 + modules/objdetect/test/test_cascadeandhog.cpp | 23 +- modules/objdetect/test/test_latentsvmdetector.cpp | 1 + modules/python/src2/cv2.cpp | 4 +- modules/superres/src/btv_l1_gpu.cpp | 2 +- samples/c/convert_cascade.c | 2 +- samples/c/facedetect.cpp | 20 +- samples/c/latentsvmdetect.cpp | 2 +- samples/c/smiledetect.cpp | 20 +- samples/cpp/dbt_face_detection.cpp | 2 +- samples/cpp/peopledetect.cpp | 2 +- .../objectDetection/objectDetection.cpp | 4 +- .../objectDetection/objectDetection2.cpp | 2 +- samples/gpu/cascadeclassifier.cpp | 4 +- samples/gpu/hog.cpp | 2 +- samples/gpu/houghlines.cpp | 4 +- samples/gpu/performance/performance.cpp | 2 +- 32 files changed, 881 insertions(+), 775 deletions(-) create mode 100644 modules/objdetect/include/opencv2/objdetect/linemod.hpp create mode 100644 modules/objdetect/include/opencv2/objdetect/objdetect_c.h diff --git a/include/opencv/cv.h b/include/opencv/cv.h index 09a2baa..5a517dc 100644 --- a/include/opencv/cv.h +++ b/include/opencv/cv.h @@ -64,11 +64,10 @@ #include "opencv2/imgproc/imgproc_c.h" #include "opencv2/photo/photo_c.h" #include "opencv2/video/tracking_c.h" +#include "opencv2/objdetect/objdetect_c.h" #include "opencv2/legacy.hpp" #include "opencv2/legacy/compat.hpp" -#include "opencv2/objdetect.hpp" - #if !defined(CV_IMPL) #define CV_IMPL extern "C" #endif //CV_IMPL diff --git a/include/opencv/cv.hpp b/include/opencv/cv.hpp index f9fa3ae..e498d7a 100644 --- a/include/opencv/cv.hpp +++ b/include/opencv/cv.hpp @@ -55,5 +55,6 @@ #include "opencv2/highgui.hpp" #include "opencv2/features2d.hpp" #include "opencv2/calib3d.hpp" +#include "opencv2/objdetect.hpp" #endif diff --git a/include/opencv/cvaux.h b/include/opencv/cvaux.h index 345036b..2332c87 100644 --- a/include/opencv/cvaux.h +++ b/include/opencv/cvaux.h @@ -50,12 +50,11 @@ #include "opencv2/imgproc/imgproc_c.h" #include "opencv2/photo/photo_c.h" #include "opencv2/video/tracking_c.h" +#include "opencv2/objdetect/objdetect_c.h" #include "opencv2/legacy.hpp" #include "opencv2/legacy/compat.hpp" #include "opencv2/legacy/blobtrack.hpp" - -#include "opencv2/objdetect.hpp" #include "opencv2/contrib.hpp" #endif diff --git a/modules/contrib/include/opencv2/contrib.hpp b/modules/contrib/include/opencv2/contrib.hpp index dc4a72a..35bac1b 100644 --- a/modules/contrib/include/opencv2/contrib.hpp +++ b/modules/contrib/include/opencv2/contrib.hpp @@ -48,6 +48,8 @@ #include "opencv2/features2d.hpp" #include "opencv2/objdetect.hpp" +#include "opencv2/core/core_c.h" + #include #ifdef __cplusplus diff --git a/modules/objdetect/include/opencv2/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect.hpp index bde149e..3ccb057 100644 --- a/modules/objdetect/include/opencv2/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect.hpp @@ -7,11 +7,12 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -43,248 +44,10 @@ #ifndef __OPENCV_OBJDETECT_HPP__ #define __OPENCV_OBJDETECT_HPP__ -#ifdef __cplusplus -# include "opencv2/core.hpp" -#endif -#include "opencv2/core/core_c.h" - -#ifdef __cplusplus -#include -#include - -extern "C" { -#endif - -/****************************************************************************************\ -* Haar-like Object Detection functions * -\****************************************************************************************/ - -#define CV_HAAR_MAGIC_VAL 0x42500000 -#define CV_TYPE_NAME_HAAR "opencv-haar-classifier" - -#define CV_IS_HAAR_CLASSIFIER( haar ) \ - ((haar) != NULL && \ - (((const CvHaarClassifierCascade*)(haar))->flags & CV_MAGIC_MASK)==CV_HAAR_MAGIC_VAL) - -#define CV_HAAR_FEATURE_MAX 3 - -typedef struct CvHaarFeature -{ - int tilted; - struct - { - CvRect r; - float weight; - } rect[CV_HAAR_FEATURE_MAX]; -} CvHaarFeature; - -typedef struct CvHaarClassifier -{ - int count; - CvHaarFeature* haar_feature; - float* threshold; - int* left; - int* right; - float* alpha; -} CvHaarClassifier; - -typedef struct CvHaarStageClassifier -{ - int count; - float threshold; - CvHaarClassifier* classifier; - - int next; - int child; - int parent; -} CvHaarStageClassifier; +#include "opencv2/core.hpp" -typedef struct CvHidHaarClassifierCascade CvHidHaarClassifierCascade; - -typedef struct CvHaarClassifierCascade -{ - int flags; - int count; - CvSize orig_window_size; - CvSize real_window_size; - double scale; - CvHaarStageClassifier* stage_classifier; - CvHidHaarClassifierCascade* hid_cascade; -} CvHaarClassifierCascade; - -typedef struct CvAvgComp -{ - CvRect rect; - int neighbors; -} CvAvgComp; - -/* Loads haar classifier cascade from a directory. - It is obsolete: convert your cascade to xml and use cvLoad instead */ -CVAPI(CvHaarClassifierCascade*) cvLoadHaarClassifierCascade( - const char* directory, CvSize orig_window_size); - -CVAPI(void) cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** cascade ); - -#define CV_HAAR_DO_CANNY_PRUNING 1 -#define CV_HAAR_SCALE_IMAGE 2 -#define CV_HAAR_FIND_BIGGEST_OBJECT 4 -#define CV_HAAR_DO_ROUGH_SEARCH 8 - -//CVAPI(CvSeq*) cvHaarDetectObjectsForROC( const CvArr* image, -// CvHaarClassifierCascade* cascade, CvMemStorage* storage, -// CvSeq** rejectLevels, CvSeq** levelWeightds, -// double scale_factor CV_DEFAULT(1.1), -// int min_neighbors CV_DEFAULT(3), int flags CV_DEFAULT(0), -// CvSize min_size CV_DEFAULT(cvSize(0,0)), CvSize max_size CV_DEFAULT(cvSize(0,0)), -// bool outputRejectLevels = false ); - - -CVAPI(CvSeq*) cvHaarDetectObjects( const CvArr* image, - CvHaarClassifierCascade* cascade, CvMemStorage* storage, - double scale_factor CV_DEFAULT(1.1), - int min_neighbors CV_DEFAULT(3), int flags CV_DEFAULT(0), - CvSize min_size CV_DEFAULT(cvSize(0,0)), CvSize max_size CV_DEFAULT(cvSize(0,0))); - -/* sets images for haar classifier cascade */ -CVAPI(void) cvSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* cascade, - const CvArr* sum, const CvArr* sqsum, - const CvArr* tilted_sum, double scale ); - -/* runs the cascade on the specified window */ -CVAPI(int) cvRunHaarClassifierCascade( const CvHaarClassifierCascade* cascade, - CvPoint pt, int start_stage CV_DEFAULT(0)); - - -/****************************************************************************************\ -* Latent SVM Object Detection functions * -\****************************************************************************************/ - -// DataType: STRUCT position -// Structure describes the position of the filter in the feature pyramid -// l - level in the feature pyramid -// (x, y) - coordinate in level l -typedef struct CvLSVMFilterPosition -{ - int x; - int y; - int l; -} CvLSVMFilterPosition; - -// DataType: STRUCT filterObject -// Description of the filter, which corresponds to the part of the object -// V - ideal (penalty = 0) position of the partial filter -// from the root filter position (V_i in the paper) -// penaltyFunction - vector describes penalty function (d_i in the paper) -// pf[0] * x + pf[1] * y + pf[2] * x^2 + pf[3] * y^2 -// FILTER DESCRIPTION -// Rectangular map (sizeX x sizeY), -// every cell stores feature vector (dimension = p) -// H - matrix of feature vectors -// to set and get feature vectors (i,j) -// used formula H[(j * sizeX + i) * p + k], where -// k - component of feature vector in cell (i, j) -// END OF FILTER DESCRIPTION -typedef struct CvLSVMFilterObject{ - CvLSVMFilterPosition V; - float fineFunction[4]; - int sizeX; - int sizeY; - int numFeatures; - float *H; -} CvLSVMFilterObject; - -// data type: STRUCT CvLatentSvmDetector -// structure contains internal representation of trained Latent SVM detector -// num_filters - total number of filters (root plus part) in model -// num_components - number of components in model -// num_part_filters - array containing number of part filters for each component -// filters - root and part filters for all model components -// b - biases for all model components -// score_threshold - confidence level threshold -typedef struct CvLatentSvmDetector -{ - int num_filters; - int num_components; - int* num_part_filters; - CvLSVMFilterObject** filters; - float* b; - float score_threshold; -} -CvLatentSvmDetector; - -// data type: STRUCT CvObjectDetection -// structure contains the bounding box and confidence level for detected object -// rect - bounding box for a detected object -// score - confidence level -typedef struct CvObjectDetection -{ - CvRect rect; - float score; -} CvObjectDetection; - -//////////////// Object Detection using Latent SVM ////////////// - - -/* -// load trained detector from a file -// -// API -// CvLatentSvmDetector* cvLoadLatentSvmDetector(const char* filename); -// INPUT -// filename - path to the file containing the parameters of - - trained Latent SVM detector -// OUTPUT -// trained Latent SVM detector in internal representation -*/ -CVAPI(CvLatentSvmDetector*) cvLoadLatentSvmDetector(const char* filename); - -/* -// release memory allocated for CvLatentSvmDetector structure -// -// API -// void cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector); -// INPUT -// detector - CvLatentSvmDetector structure to be released -// OUTPUT -*/ -CVAPI(void) cvReleaseLatentSvmDetector(CvLatentSvmDetector** detector); - -/* -// find rectangular regions in the given image that are likely -// to contain objects and corresponding confidence levels -// -// API -// CvSeq* cvLatentSvmDetectObjects(const IplImage* image, -// CvLatentSvmDetector* detector, -// CvMemStorage* storage, -// float overlap_threshold = 0.5f, -// int numThreads = -1); -// INPUT -// image - image to detect objects in -// detector - Latent SVM detector in internal representation -// storage - memory storage to store the resultant sequence -// of the object candidate rectangles -// overlap_threshold - threshold for the non-maximum suppression algorithm - = 0.5f [here will be the reference to original paper] -// OUTPUT -// sequence of detected objects (bounding boxes and confidence levels stored in CvObjectDetection structures) -*/ -CVAPI(CvSeq*) cvLatentSvmDetectObjects(IplImage* image, - CvLatentSvmDetector* detector, - CvMemStorage* storage, - float overlap_threshold CV_DEFAULT(0.5f), - int numThreads CV_DEFAULT(-1)); - -#ifdef __cplusplus -} - -CV_EXPORTS CvSeq* cvHaarDetectObjectsForROC( const CvArr* image, - CvHaarClassifierCascade* cascade, CvMemStorage* storage, - std::vector& rejectLevels, std::vector& levelWeightds, - double scale_factor CV_DEFAULT(1.1), - int min_neighbors CV_DEFAULT(3), int flags CV_DEFAULT(0), - CvSize min_size CV_DEFAULT(cvSize(0,0)), CvSize max_size CV_DEFAULT(cvSize(0,0)), - bool outputRejectLevels = false ); +typedef struct CvLatentSvmDetector CvLatentSvmDetector; +typedef struct CvHaarClassifierCascade CvHaarClassifierCascade; namespace cv { @@ -303,24 +66,24 @@ public: struct CV_EXPORTS ObjectDetection { ObjectDetection(); - ObjectDetection( const Rect& rect, float score, int classID=-1 ); + ObjectDetection( const Rect& rect, float score, int classID = -1 ); Rect rect; float score; int classID; }; LatentSvmDetector(); - LatentSvmDetector( const std::vector& filenames, const std::vector& classNames=std::vector() ); + LatentSvmDetector( const std::vector& filenames, const std::vector& classNames = std::vector() ); virtual ~LatentSvmDetector(); virtual void clear(); virtual bool empty() const; - bool load( const std::vector& filenames, const std::vector& classNames=std::vector() ); + bool load( const std::vector& filenames, const std::vector& classNames = std::vector() ); virtual void detect( const Mat& image, std::vector& objectDetections, - float overlapThreshold=0.5f, - int numThreads=-1 ); + float overlapThreshold = 0.5f, + int numThreads = -1 ); const std::vector& getClassNames() const; size_t getClassCount() const; @@ -330,19 +93,22 @@ private: std::vector classNames; }; -CV_EXPORTS void groupRectangles(CV_OUT CV_IN_OUT std::vector& rectList, int groupThreshold, double eps=0.2); -CV_EXPORTS_W void groupRectangles(CV_OUT CV_IN_OUT std::vector& rectList, CV_OUT std::vector& weights, int groupThreshold, double eps=0.2); -CV_EXPORTS void groupRectangles( std::vector& rectList, int groupThreshold, double eps, std::vector* weights, std::vector* levelWeights ); -CV_EXPORTS void groupRectangles(std::vector& rectList, std::vector& rejectLevels, - std::vector& levelWeights, int groupThreshold, double eps=0.2); -CV_EXPORTS void groupRectangles_meanshift(std::vector& rectList, std::vector& foundWeights, std::vector& foundScales, +CV_EXPORTS void groupRectangles(std::vector& rectList, int groupThreshold, double eps = 0.2); +CV_EXPORTS_W void groupRectangles(CV_IN_OUT std::vector& rectList, CV_OUT std::vector& weights, int groupThreshold, double eps = 0.2); +CV_EXPORTS void groupRectangles(std::vector& rectList, int groupThreshold, double eps, std::vector* weights, std::vector* levelWeights ); +CV_EXPORTS void groupRectangles(std::vector& rectList, std::vector& rejectLevels, + std::vector& levelWeights, int groupThreshold, double eps = 0.2); +CV_EXPORTS void groupRectangles_meanshift(std::vector& rectList, std::vector& foundWeights, std::vector& foundScales, double detectThreshold = 0.0, Size winDetSize = Size(64, 128)); - class CV_EXPORTS FeatureEvaluator { public: - enum { HAAR = 0, LBP = 1, HOG = 2 }; + enum { HAAR = 0, + LBP = 1, + HOG = 2 + }; + virtual ~FeatureEvaluator(); virtual bool read(const FileNode& node); @@ -360,13 +126,11 @@ public: template<> CV_EXPORTS void Ptr::delete_obj(); -enum -{ - CASCADE_DO_CANNY_PRUNING=1, - CASCADE_SCALE_IMAGE=2, - CASCADE_FIND_BIGGEST_OBJECT=4, - CASCADE_DO_ROUGH_SEARCH=8 -}; +enum { CASCADE_DO_CANNY_PRUNING = 1, + CASCADE_SCALE_IMAGE = 2, + CASCADE_FIND_BIGGEST_OBJECT = 4, + CASCADE_DO_ROUGH_SEARCH = 8 + }; class CV_EXPORTS_W CascadeClassifier { @@ -380,20 +144,20 @@ public: virtual bool read( const FileNode& node ); CV_WRAP virtual void detectMultiScale( const Mat& image, CV_OUT std::vector& objects, - double scaleFactor=1.1, - int minNeighbors=3, int flags=0, - Size minSize=Size(), - Size maxSize=Size() ); + double scaleFactor = 1.1, + int minNeighbors = 3, int flags = 0, + Size minSize = Size(), + Size maxSize = Size() ); CV_WRAP virtual void detectMultiScale( const Mat& image, CV_OUT std::vector& objects, CV_OUT std::vector& rejectLevels, CV_OUT std::vector& levelWeights, - double scaleFactor=1.1, - int minNeighbors=3, int flags=0, - Size minSize=Size(), - Size maxSize=Size(), - bool outputRejectLevels=false ); + double scaleFactor = 1.1, + int minNeighbors = 3, int flags = 0, + Size minSize = Size(), + Size maxSize = Size(), + bool outputRejectLevels = false ); bool isOldFormatCascade() const; @@ -402,17 +166,18 @@ public: bool setImage( const Mat& ); protected: - //virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize, - // int stripSize, int yStep, double factor, std::vector& candidates ); - virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize, int stripSize, int yStep, double factor, std::vector& candidates, - std::vector& rejectLevels, std::vector& levelWeights, bool outputRejectLevels=false); + std::vector& rejectLevels, std::vector& levelWeights, bool outputRejectLevels = false); protected: - enum { BOOST = 0 }; - enum { DO_CANNY_PRUNING = 1, SCALE_IMAGE = 2, - FIND_BIGGEST_OBJECT = 4, DO_ROUGH_SEARCH = 8 }; + enum { BOOST = 0 + }; + enum { DO_CANNY_PRUNING = CASCADE_DO_CANNY_PRUNING, + SCALE_IMAGE = CASCADE_SCALE_IMAGE, + FIND_BIGGEST_OBJECT = CASCADE_FIND_BIGGEST_OBJECT, + DO_ROUGH_SEARCH = CASCADE_DO_ROUGH_SEARCH + }; friend class CascadeClassifierInvoker; @@ -507,8 +272,10 @@ struct DetectionROI struct CV_EXPORTS_W HOGDescriptor { public: - enum { L2Hys=0 }; - enum { DEFAULT_NLEVELS=64 }; + enum { L2Hys = 0 + }; + enum { DEFAULT_NLEVELS = 64 + }; CV_WRAP HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8), cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1), @@ -548,38 +315,38 @@ public: virtual bool read(FileNode& fn); virtual void write(FileStorage& fs, const String& objname) const; - CV_WRAP virtual bool load(const String& filename, const String& objname=String()); - CV_WRAP virtual void save(const String& filename, const String& objname=String()) const; + CV_WRAP virtual bool load(const String& filename, const String& objname = String()); + CV_WRAP virtual void save(const String& filename, const String& objname = String()) const; virtual void copyTo(HOGDescriptor& c) const; CV_WRAP virtual void compute(const Mat& img, CV_OUT std::vector& descriptors, - Size winStride=Size(), Size padding=Size(), - const std::vector& locations=std::vector()) const; + Size winStride = Size(), Size padding = Size(), + const std::vector& locations = std::vector()) const; //with found weights output CV_WRAP virtual void detect(const Mat& img, CV_OUT std::vector& foundLocations, CV_OUT std::vector& weights, - double hitThreshold=0, Size winStride=Size(), - Size padding=Size(), - const std::vector& searchLocations=std::vector()) const; + double hitThreshold = 0, Size winStride = Size(), + Size padding = Size(), + const std::vector& searchLocations = std::vector()) const; //without found weights output virtual void detect(const Mat& img, CV_OUT std::vector& foundLocations, - double hitThreshold=0, Size winStride=Size(), - Size padding=Size(), + double hitThreshold = 0, Size winStride = Size(), + Size padding = Size(), const std::vector& searchLocations=std::vector()) const; //with result weights output CV_WRAP virtual void detectMultiScale(const Mat& img, CV_OUT std::vector& foundLocations, - CV_OUT std::vector& foundWeights, double hitThreshold=0, - Size winStride=Size(), Size padding=Size(), double scale=1.05, - double finalThreshold=2.0,bool useMeanshiftGrouping = false) const; + CV_OUT std::vector& foundWeights, double hitThreshold = 0, + Size winStride = Size(), Size padding = Size(), double scale = 1.05, + double finalThreshold = 2.0,bool useMeanshiftGrouping = false) const; //without found weights output virtual void detectMultiScale(const Mat& img, CV_OUT std::vector& foundLocations, - double hitThreshold=0, Size winStride=Size(), - Size padding=Size(), double scale=1.05, - double finalThreshold=2.0, bool useMeanshiftGrouping = false) const; + double hitThreshold = 0, Size winStride = Size(), + Size padding = Size(), double scale = 1.05, + double finalThreshold = 2.0, bool useMeanshiftGrouping = false) const; CV_WRAP virtual void computeGradient(const Mat& img, CV_OUT Mat& grad, CV_OUT Mat& angleOfs, - Size paddingTL=Size(), Size paddingBR=Size()) const; + Size paddingTL = Size(), Size paddingBR = Size()) const; CV_WRAP static std::vector getDefaultPeopleDetector(); CV_WRAP static std::vector getDaimlerPeopleDetector(); @@ -618,430 +385,14 @@ public: CV_EXPORTS_W void findDataMatrix(InputArray image, CV_OUT std::vector& codes, - OutputArray corners=noArray(), - OutputArrayOfArrays dmtx=noArray()); + OutputArray corners = noArray(), + OutputArrayOfArrays dmtx = noArray()); + CV_EXPORTS_W void drawDataMatrixCodes(InputOutputArray image, const std::vector& codes, InputArray corners); } -/****************************************************************************************\ -* Datamatrix * -\****************************************************************************************/ - -struct CV_EXPORTS CvDataMatrixCode { - char msg[4]; - CvMat *original; - CvMat *corners; -}; - -CV_EXPORTS std::deque cvFindDataMatrix(CvMat *im); - -/****************************************************************************************\ -* LINE-MOD * -\****************************************************************************************/ - -namespace cv { -namespace linemod { - -/// @todo Convert doxy comments to rst - -/** - * \brief Discriminant feature described by its location and label. - */ -struct CV_EXPORTS Feature -{ - int x; ///< x offset - int y; ///< y offset - int label; ///< Quantization - - Feature() : x(0), y(0), label(0) {} - Feature(int x, int y, int label); - - void read(const FileNode& fn); - void write(FileStorage& fs) const; -}; - -inline Feature::Feature(int _x, int _y, int _label) : x(_x), y(_y), label(_label) {} - -struct CV_EXPORTS Template -{ - int width; - int height; - int pyramid_level; - std::vector features; - - void read(const FileNode& fn); - void write(FileStorage& fs) const; -}; - -/** - * \brief Represents a modality operating over an image pyramid. - */ -class QuantizedPyramid -{ -public: - // Virtual destructor - virtual ~QuantizedPyramid() {} - - /** - * \brief Compute quantized image at current pyramid level for online detection. - * - * \param[out] dst The destination 8-bit image. For each pixel at most one bit is set, - * representing its classification. - */ - virtual void quantize(Mat& dst) const =0; - - /** - * \brief Extract most discriminant features at current pyramid level to form a new template. - * - * \param[out] templ The new template. - */ - virtual bool extractTemplate(Template& templ) const =0; - - /** - * \brief Go to the next pyramid level. - * - * \todo Allow pyramid scale factor other than 2 - */ - virtual void pyrDown() =0; - -protected: - /// Candidate feature with a score - struct Candidate - { - Candidate(int x, int y, int label, float score); - - /// Sort candidates with high score to the front - bool operator<(const Candidate& rhs) const - { - return score > rhs.score; - } - - Feature f; - float score; - }; - - /** - * \brief Choose candidate features so that they are not bunched together. - * - * \param[in] candidates Candidate features sorted by score. - * \param[out] features Destination vector of selected features. - * \param[in] num_features Number of candidates to select. - * \param[in] distance Hint for desired distance between features. - */ - static void selectScatteredFeatures(const std::vector& candidates, - std::vector& features, - size_t num_features, float distance); -}; - -inline QuantizedPyramid::Candidate::Candidate(int x, int y, int label, float _score) : f(x, y, label), score(_score) {} - -/** - * \brief Interface for modalities that plug into the LINE template matching representation. - * - * \todo Max response, to allow optimization of summing (255/MAX) features as uint8 - */ -class CV_EXPORTS Modality -{ -public: - // Virtual destructor - virtual ~Modality() {} - - /** - * \brief Form a quantized image pyramid from a source image. - * - * \param[in] src The source image. Type depends on the modality. - * \param[in] mask Optional mask. If not empty, unmasked pixels are set to zero - * in quantized image and cannot be extracted as features. - */ - Ptr process(const Mat& src, - const Mat& mask = Mat()) const - { - return processImpl(src, mask); - } - - virtual String name() const =0; - - virtual void read(const FileNode& fn) =0; - virtual void write(FileStorage& fs) const =0; - - /** - * \brief Create modality by name. - * - * The following modality types are supported: - * - "ColorGradient" - * - "DepthNormal" - */ - static Ptr create(const String& modality_type); - - /** - * \brief Load a modality from file. - */ - static Ptr create(const FileNode& fn); - -protected: - // Indirection is because process() has a default parameter. - virtual Ptr processImpl(const Mat& src, - const Mat& mask) const =0; -}; - -/** - * \brief Modality that computes quantized gradient orientations from a color image. - */ -class CV_EXPORTS ColorGradient : public Modality -{ -public: - /** - * \brief Default constructor. Uses reasonable default parameter values. - */ - ColorGradient(); - - /** - * \brief Constructor. - * - * \param weak_threshold When quantizing, discard gradients with magnitude less than this. - * \param num_features How many features a template must contain. - * \param strong_threshold Consider as candidate features only gradients whose norms are - * larger than this. - */ - ColorGradient(float weak_threshold, size_t num_features, float strong_threshold); - - virtual String name() const; - - virtual void read(const FileNode& fn); - virtual void write(FileStorage& fs) const; - - float weak_threshold; - size_t num_features; - float strong_threshold; - -protected: - virtual Ptr processImpl(const Mat& src, - const Mat& mask) const; -}; - -/** - * \brief Modality that computes quantized surface normals from a dense depth map. - */ -class CV_EXPORTS DepthNormal : public Modality -{ -public: - /** - * \brief Default constructor. Uses reasonable default parameter values. - */ - DepthNormal(); - - /** - * \brief Constructor. - * - * \param distance_threshold Ignore pixels beyond this distance. - * \param difference_threshold When computing normals, ignore contributions of pixels whose - * depth difference with the central pixel is above this threshold. - * \param num_features How many features a template must contain. - * \param extract_threshold Consider as candidate feature only if there are no differing - * orientations within a distance of extract_threshold. - */ - DepthNormal(int distance_threshold, int difference_threshold, size_t num_features, - int extract_threshold); - - virtual String name() const; - - virtual void read(const FileNode& fn); - virtual void write(FileStorage& fs) const; - - int distance_threshold; - int difference_threshold; - size_t num_features; - int extract_threshold; - -protected: - virtual Ptr processImpl(const Mat& src, - const Mat& mask) const; -}; - -/** - * \brief Debug function to colormap a quantized image for viewing. - */ -void colormap(const Mat& quantized, Mat& dst); - -/** - * \brief Represents a successful template match. - */ -struct CV_EXPORTS Match -{ - Match() - { - } - - Match(int x, int y, float similarity, const String& class_id, int template_id); - - /// Sort matches with high similarity to the front - bool operator<(const Match& rhs) const - { - // Secondarily sort on template_id for the sake of duplicate removal - if (similarity != rhs.similarity) - return similarity > rhs.similarity; - else - return template_id < rhs.template_id; - } - - bool operator==(const Match& rhs) const - { - return x == rhs.x && y == rhs.y && similarity == rhs.similarity && class_id == rhs.class_id; - } - - int x; - int y; - float similarity; - String class_id; - int template_id; -}; - -inline Match::Match(int _x, int _y, float _similarity, const String& _class_id, int _template_id) - : x(_x), y(_y), similarity(_similarity), class_id(_class_id), template_id(_template_id) - { - } - -/** - * \brief Object detector using the LINE template matching algorithm with any set of - * modalities. - */ -class CV_EXPORTS Detector -{ -public: - /** - * \brief Empty constructor, initialize with read(). - */ - Detector(); - - /** - * \brief Constructor. - * - * \param modalities Modalities to use (color gradients, depth normals, ...). - * \param T_pyramid Value of the sampling step T at each pyramid level. The - * number of pyramid levels is T_pyramid.size(). - */ - Detector(const std::vector< Ptr >& modalities, const std::vector& T_pyramid); - - /** - * \brief Detect objects by template matching. - * - * Matches globally at the lowest pyramid level, then refines locally stepping up the pyramid. - * - * \param sources Source images, one for each modality. - * \param threshold Similarity threshold, a percentage between 0 and 100. - * \param[out] matches Template matches, sorted by similarity score. - * \param class_ids If non-empty, only search for the desired object classes. - * \param[out] quantized_images Optionally return vector of quantized images. - * \param masks The masks for consideration during matching. The masks should be CV_8UC1 - * where 255 represents a valid pixel. If non-empty, the vector must be - * the same size as sources. Each element must be - * empty or the same size as its corresponding source. - */ - void match(const std::vector& sources, float threshold, std::vector& matches, - const std::vector& class_ids = std::vector(), - OutputArrayOfArrays quantized_images = noArray(), - const std::vector& masks = std::vector()) const; - - /** - * \brief Add new object template. - * - * \param sources Source images, one for each modality. - * \param class_id Object class ID. - * \param object_mask Mask separating object from background. - * \param[out] bounding_box Optionally return bounding box of the extracted features. - * - * \return Template ID, or -1 if failed to extract a valid template. - */ - int addTemplate(const std::vector& sources, const String& class_id, - const Mat& object_mask, Rect* bounding_box = NULL); - - /** - * \brief Add a new object template computed by external means. - */ - int addSyntheticTemplate(const std::vector