mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3504 lines
136 KiB
3504 lines
136 KiB
/*M/////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. |
|
// |
|
// By downloading, copying, installing or using the software you agree to this license. |
|
// If you do not agree to this license, do not download, install, |
|
// copy or use the software. |
|
// |
|
// |
|
// Intel License Agreement |
|
// For Open Source Computer Vision Library |
|
// |
|
// Copyright (C) 2000, Intel Corporation, all rights reserved. |
|
// Third party copyrights are property of their respective owners. |
|
// |
|
// Redistribution and use in source and binary forms, with or without modification, |
|
// are permitted provided that the following conditions are met: |
|
// |
|
// * Redistribution's of source code must retain the above copyright notice, |
|
// this list of conditions and the following disclaimer. |
|
// |
|
// * Redistribution's in binary form must reproduce the above copyright notice, |
|
// this list of conditions and the following disclaimer in the documentation |
|
// and/or other materials provided with the distribution. |
|
// |
|
// * The name of Intel Corporation may not be used to endorse or promote products |
|
// derived from this software without specific prior written permission. |
|
// |
|
// This software is provided by the copyright holders and contributors "as is" and |
|
// any express or implied warranties, including, but not limited to, the implied |
|
// warranties of merchantability and fitness for a particular purpose are disclaimed. |
|
// In no event shall the Intel Corporation or contributors be liable for any direct, |
|
// indirect, incidental, special, exemplary, or consequential damages |
|
// (including, but not limited to, procurement of substitute goods or services; |
|
// loss of use, data, or profits; or business interruption) however caused |
|
// and on any theory of liability, whether in contract, strict liability, |
|
// or tort (including negligence or otherwise) arising in any way out of |
|
// the use of this software, even if advised of the possibility of such damage. |
|
// |
|
//M*/ |
|
|
|
#ifndef __OPENCV_LEGACY_HPP__ |
|
#define __OPENCV_LEGACY_HPP__ |
|
|
|
#include "opencv2/imgproc.hpp" |
|
#include "opencv2/imgproc/imgproc_c.h" |
|
#include "opencv2/features2d.hpp" |
|
#include "opencv2/calib3d.hpp" |
|
#include "opencv2/ml.hpp" |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
CVAPI(CvSeq*) cvSegmentImage( const CvArr* srcarr, CvArr* dstarr, |
|
double canny_threshold, |
|
double ffill_threshold, |
|
CvMemStorage* storage ); |
|
|
|
/****************************************************************************************\ |
|
* Eigen objects * |
|
\****************************************************************************************/ |
|
|
|
typedef int (CV_CDECL * CvCallback)(int index, void* buffer, void* user_data); |
|
typedef union |
|
{ |
|
CvCallback callback; |
|
void* data; |
|
} |
|
CvInput; |
|
|
|
#define CV_EIGOBJ_NO_CALLBACK 0 |
|
#define CV_EIGOBJ_INPUT_CALLBACK 1 |
|
#define CV_EIGOBJ_OUTPUT_CALLBACK 2 |
|
#define CV_EIGOBJ_BOTH_CALLBACK 3 |
|
|
|
/* Calculates covariation matrix of a set of arrays */ |
|
CVAPI(void) cvCalcCovarMatrixEx( int nObjects, void* input, int ioFlags, |
|
int ioBufSize, uchar* buffer, void* userData, |
|
IplImage* avg, float* covarMatrix ); |
|
|
|
/* Calculates eigen values and vectors of covariation matrix of a set of |
|
arrays */ |
|
CVAPI(void) cvCalcEigenObjects( int nObjects, void* input, void* output, |
|
int ioFlags, int ioBufSize, void* userData, |
|
CvTermCriteria* calcLimit, IplImage* avg, |
|
float* eigVals ); |
|
|
|
/* Calculates dot product (obj - avg) * eigObj (i.e. projects image to eigen vector) */ |
|
CVAPI(double) cvCalcDecompCoeff( IplImage* obj, IplImage* eigObj, IplImage* avg ); |
|
|
|
/* Projects image to eigen space (finds all decomposion coefficients */ |
|
CVAPI(void) cvEigenDecomposite( IplImage* obj, int nEigObjs, void* eigInput, |
|
int ioFlags, void* userData, IplImage* avg, |
|
float* coeffs ); |
|
|
|
/* Projects original objects used to calculate eigen space basis to that space */ |
|
CVAPI(void) cvEigenProjection( void* eigInput, int nEigObjs, int ioFlags, |
|
void* userData, float* coeffs, IplImage* avg, |
|
IplImage* proj ); |
|
|
|
/****************************************************************************************\ |
|
* 1D/2D HMM * |
|
\****************************************************************************************/ |
|
|
|
typedef struct CvImgObsInfo |
|
{ |
|
int obs_x; |
|
int obs_y; |
|
int obs_size; |
|
float* obs;//consequtive observations |
|
|
|
int* state;/* arr of pairs superstate/state to which observation belong */ |
|
int* mix; /* number of mixture to which observation belong */ |
|
|
|
} CvImgObsInfo;/*struct for 1 image*/ |
|
|
|
typedef CvImgObsInfo Cv1DObsInfo; |
|
|
|
typedef struct CvEHMMState |
|
{ |
|
int num_mix; /*number of mixtures in this state*/ |
|
float* mu; /*mean vectors corresponding to each mixture*/ |
|
float* inv_var; /* square root of inversed variances corresp. to each mixture*/ |
|
float* log_var_val; /* sum of 0.5 (LN2PI + ln(variance[i]) ) for i=1,n */ |
|
float* weight; /*array of mixture weights. Summ of all weights in state is 1. */ |
|
|
|
} CvEHMMState; |
|
|
|
typedef struct CvEHMM |
|
{ |
|
int level; /* 0 - lowest(i.e its states are real states), ..... */ |
|
int num_states; /* number of HMM states */ |
|
float* transP;/*transition probab. matrices for states */ |
|
float** obsProb; /* if level == 0 - array of brob matrices corresponding to hmm |
|
if level == 1 - martix of matrices */ |
|
union |
|
{ |
|
CvEHMMState* state; /* if level == 0 points to real states array, |
|
if not - points to embedded hmms */ |
|
struct CvEHMM* ehmm; /* pointer to an embedded model or NULL, if it is a leaf */ |
|
} u; |
|
|
|
} CvEHMM; |
|
|
|
/*CVAPI(int) icvCreate1DHMM( CvEHMM** this_hmm, |
|
int state_number, int* num_mix, int obs_size ); |
|
|
|
CVAPI(int) icvRelease1DHMM( CvEHMM** phmm ); |
|
|
|
CVAPI(int) icvUniform1DSegm( Cv1DObsInfo* obs_info, CvEHMM* hmm ); |
|
|
|
CVAPI(int) icvInit1DMixSegm( Cv1DObsInfo** obs_info_array, int num_img, CvEHMM* hmm); |
|
|
|
CVAPI(int) icvEstimate1DHMMStateParams( CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm); |
|
|
|
CVAPI(int) icvEstimate1DObsProb( CvImgObsInfo* obs_info, CvEHMM* hmm ); |
|
|
|
CVAPI(int) icvEstimate1DTransProb( Cv1DObsInfo** obs_info_array, |
|
int num_seq, |
|
CvEHMM* hmm ); |
|
|
|
CVAPI(float) icvViterbi( Cv1DObsInfo* obs_info, CvEHMM* hmm); |
|
|
|
CVAPI(int) icv1DMixSegmL2( CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm );*/ |
|
|
|
/*********************************** Embedded HMMs *************************************/ |
|
|
|
/* Creates 2D HMM */ |
|
CVAPI(CvEHMM*) cvCreate2DHMM( int* stateNumber, int* numMix, int obsSize ); |
|
|
|
/* Releases HMM */ |
|
CVAPI(void) cvRelease2DHMM( CvEHMM** hmm ); |
|
|
|
#define CV_COUNT_OBS(roi, win, delta, numObs ) \ |
|
{ \ |
|
(numObs)->width =((roi)->width -(win)->width +(delta)->width)/(delta)->width; \ |
|
(numObs)->height =((roi)->height -(win)->height +(delta)->height)/(delta)->height;\ |
|
} |
|
|
|
/* Creates storage for observation vectors */ |
|
CVAPI(CvImgObsInfo*) cvCreateObsInfo( CvSize numObs, int obsSize ); |
|
|
|
/* Releases storage for observation vectors */ |
|
CVAPI(void) cvReleaseObsInfo( CvImgObsInfo** obs_info ); |
|
|
|
|
|
/* The function takes an image on input and and returns the sequnce of observations |
|
to be used with an embedded HMM; Each observation is top-left block of DCT |
|
coefficient matrix */ |
|
CVAPI(void) cvImgToObs_DCT( const CvArr* arr, float* obs, CvSize dctSize, |
|
CvSize obsSize, CvSize delta ); |
|
|
|
|
|
/* Uniformly segments all observation vectors extracted from image */ |
|
CVAPI(void) cvUniformImgSegm( CvImgObsInfo* obs_info, CvEHMM* ehmm ); |
|
|
|
/* Does mixture segmentation of the states of embedded HMM */ |
|
CVAPI(void) cvInitMixSegm( CvImgObsInfo** obs_info_array, |
|
int num_img, CvEHMM* hmm ); |
|
|
|
/* Function calculates means, variances, weights of every Gaussian mixture |
|
of every low-level state of embedded HMM */ |
|
CVAPI(void) cvEstimateHMMStateParams( CvImgObsInfo** obs_info_array, |
|
int num_img, CvEHMM* hmm ); |
|
|
|
/* Function computes transition probability matrices of embedded HMM |
|
given observations segmentation */ |
|
CVAPI(void) cvEstimateTransProb( CvImgObsInfo** obs_info_array, |
|
int num_img, CvEHMM* hmm ); |
|
|
|
/* Function computes probabilities of appearing observations at any state |
|
(i.e. computes P(obs|state) for every pair(obs,state)) */ |
|
CVAPI(void) cvEstimateObsProb( CvImgObsInfo* obs_info, |
|
CvEHMM* hmm ); |
|
|
|
/* Runs Viterbi algorithm for embedded HMM */ |
|
CVAPI(float) cvEViterbi( CvImgObsInfo* obs_info, CvEHMM* hmm ); |
|
|
|
|
|
/* Function clusters observation vectors from several images |
|
given observations segmentation. |
|
Euclidean distance used for clustering vectors. |
|
Centers of clusters are given means of every mixture */ |
|
CVAPI(void) cvMixSegmL2( CvImgObsInfo** obs_info_array, |
|
int num_img, CvEHMM* hmm ); |
|
|
|
/****************************************************************************************\ |
|
* A few functions from old stereo gesture recognition demosions * |
|
\****************************************************************************************/ |
|
|
|
/* Creates hand mask image given several points on the hand */ |
|
CVAPI(void) cvCreateHandMask( CvSeq* hand_points, |
|
IplImage *img_mask, CvRect *roi); |
|
|
|
/* Finds hand region in range image data */ |
|
CVAPI(void) cvFindHandRegion (CvPoint3D32f* points, int count, |
|
CvSeq* indexs, |
|
float* line, CvSize2D32f size, int flag, |
|
CvPoint3D32f* center, |
|
CvMemStorage* storage, CvSeq **numbers); |
|
|
|
/* Finds hand region in range image data (advanced version) */ |
|
CVAPI(void) cvFindHandRegionA( CvPoint3D32f* points, int count, |
|
CvSeq* indexs, |
|
float* line, CvSize2D32f size, int jc, |
|
CvPoint3D32f* center, |
|
CvMemStorage* storage, CvSeq **numbers); |
|
|
|
/* Calculates the cooficients of the homography matrix */ |
|
CVAPI(void) cvCalcImageHomography( float* line, CvPoint3D32f* center, |
|
float* intrinsic, float* homography ); |
|
|
|
/****************************************************************************************\ |
|
* More operations on sequences * |
|
\****************************************************************************************/ |
|
|
|
/*****************************************************************************************/ |
|
|
|
#define CV_CURRENT_INT( reader ) (*((int *)(reader).ptr)) |
|
#define CV_PREV_INT( reader ) (*((int *)(reader).prev_elem)) |
|
|
|
#define CV_GRAPH_WEIGHTED_VERTEX_FIELDS() CV_GRAPH_VERTEX_FIELDS()\ |
|
float weight; |
|
|
|
#define CV_GRAPH_WEIGHTED_EDGE_FIELDS() CV_GRAPH_EDGE_FIELDS() |
|
|
|
typedef struct CvGraphWeightedVtx |
|
{ |
|
CV_GRAPH_WEIGHTED_VERTEX_FIELDS() |
|
} CvGraphWeightedVtx; |
|
|
|
typedef struct CvGraphWeightedEdge |
|
{ |
|
CV_GRAPH_WEIGHTED_EDGE_FIELDS() |
|
} CvGraphWeightedEdge; |
|
|
|
typedef enum CvGraphWeightType |
|
{ |
|
CV_NOT_WEIGHTED, |
|
CV_WEIGHTED_VTX, |
|
CV_WEIGHTED_EDGE, |
|
CV_WEIGHTED_ALL |
|
} CvGraphWeightType; |
|
|
|
|
|
/* Calculates histogram of a contour */ |
|
CVAPI(void) cvCalcPGH( const CvSeq* contour, CvHistogram* hist ); |
|
|
|
#define CV_DOMINANT_IPAN 1 |
|
|
|
/* Finds high-curvature points of the contour */ |
|
CVAPI(CvSeq*) cvFindDominantPoints( CvSeq* contour, CvMemStorage* storage, |
|
int method CV_DEFAULT(CV_DOMINANT_IPAN), |
|
double parameter1 CV_DEFAULT(0), |
|
double parameter2 CV_DEFAULT(0), |
|
double parameter3 CV_DEFAULT(0), |
|
double parameter4 CV_DEFAULT(0)); |
|
|
|
/*****************************************************************************************/ |
|
|
|
|
|
/*******************************Stereo correspondence*************************************/ |
|
|
|
typedef struct CvCliqueFinder |
|
{ |
|
CvGraph* graph; |
|
int** adj_matr; |
|
int N; //graph size |
|
|
|
// stacks, counters etc/ |
|
int k; //stack size |
|
int* current_comp; |
|
int** All; |
|
|
|
int* ne; |
|
int* ce; |
|
int* fixp; //node with minimal disconnections |
|
int* nod; |
|
int* s; //for selected candidate |
|
int status; |
|
int best_score; |
|
int weighted; |
|
int weighted_edges; |
|
float best_weight; |
|
float* edge_weights; |
|
float* vertex_weights; |
|
float* cur_weight; |
|
float* cand_weight; |
|
|
|
} CvCliqueFinder; |
|
|
|
#define CLIQUE_TIME_OFF 2 |
|
#define CLIQUE_FOUND 1 |
|
#define CLIQUE_END 0 |
|
|
|
/*CVAPI(void) cvStartFindCliques( CvGraph* graph, CvCliqueFinder* finder, int reverse, |
|
int weighted CV_DEFAULT(0), int weighted_edges CV_DEFAULT(0)); |
|
CVAPI(int) cvFindNextMaximalClique( CvCliqueFinder* finder, int* clock_rest CV_DEFAULT(0) ); |
|
CVAPI(void) cvEndFindCliques( CvCliqueFinder* finder ); |
|
|
|
CVAPI(void) cvBronKerbosch( CvGraph* graph );*/ |
|
|
|
|
|
/*F/////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Name: cvSubgraphWeight |
|
// Purpose: finds weight of subgraph in a graph |
|
// Context: |
|
// Parameters: |
|
// graph - input graph. |
|
// subgraph - sequence of pairwise different ints. These are indices of vertices of subgraph. |
|
// weight_type - describes the way we measure weight. |
|
// one of the following: |
|
// CV_NOT_WEIGHTED - weight of a clique is simply its size |
|
// CV_WEIGHTED_VTX - weight of a clique is the sum of weights of its vertices |
|
// CV_WEIGHTED_EDGE - the same but edges |
|
// CV_WEIGHTED_ALL - the same but both edges and vertices |
|
// weight_vtx - optional vector of floats, with size = graph->total. |
|
// If weight_type is either CV_WEIGHTED_VTX or CV_WEIGHTED_ALL |
|
// weights of vertices must be provided. If weight_vtx not zero |
|
// these weights considered to be here, otherwise function assumes |
|
// that vertices of graph are inherited from CvGraphWeightedVtx. |
|
// weight_edge - optional matrix of floats, of width and height = graph->total. |
|
// If weight_type is either CV_WEIGHTED_EDGE or CV_WEIGHTED_ALL |
|
// weights of edges ought to be supplied. If weight_edge is not zero |
|
// function finds them here, otherwise function expects |
|
// edges of graph to be inherited from CvGraphWeightedEdge. |
|
// If this parameter is not zero structure of the graph is determined from matrix |
|
// rather than from CvGraphEdge's. In particular, elements corresponding to |
|
// absent edges should be zero. |
|
// Returns: |
|
// weight of subgraph. |
|
// Notes: |
|
//F*/ |
|
/*CVAPI(float) cvSubgraphWeight( CvGraph *graph, CvSeq *subgraph, |
|
CvGraphWeightType weight_type CV_DEFAULT(CV_NOT_WEIGHTED), |
|
CvVect32f weight_vtx CV_DEFAULT(0), |
|
CvMatr32f weight_edge CV_DEFAULT(0) );*/ |
|
|
|
|
|
/*F/////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Name: cvFindCliqueEx |
|
// Purpose: tries to find clique with maximum possible weight in a graph |
|
// Context: |
|
// Parameters: |
|
// graph - input graph. |
|
// storage - memory storage to be used by the result. |
|
// is_complementary - optional flag showing whether function should seek for clique |
|
// in complementary graph. |
|
// weight_type - describes our notion about weight. |
|
// one of the following: |
|
// CV_NOT_WEIGHTED - weight of a clique is simply its size |
|
// CV_WEIGHTED_VTX - weight of a clique is the sum of weights of its vertices |
|
// CV_WEIGHTED_EDGE - the same but edges |
|
// CV_WEIGHTED_ALL - the same but both edges and vertices |
|
// weight_vtx - optional vector of floats, with size = graph->total. |
|
// If weight_type is either CV_WEIGHTED_VTX or CV_WEIGHTED_ALL |
|
// weights of vertices must be provided. If weight_vtx not zero |
|
// these weights considered to be here, otherwise function assumes |
|
// that vertices of graph are inherited from CvGraphWeightedVtx. |
|
// weight_edge - optional matrix of floats, of width and height = graph->total. |
|
// If weight_type is either CV_WEIGHTED_EDGE or CV_WEIGHTED_ALL |
|
// weights of edges ought to be supplied. If weight_edge is not zero |
|
// function finds them here, otherwise function expects |
|
// edges of graph to be inherited from CvGraphWeightedEdge. |
|
// Note that in case of CV_WEIGHTED_EDGE or CV_WEIGHTED_ALL |
|
// nonzero is_complementary implies nonzero weight_edge. |
|
// start_clique - optional sequence of pairwise different ints. They are indices of |
|
// vertices that shall be present in the output clique. |
|
// subgraph_of_ban - optional sequence of (maybe equal) ints. They are indices of |
|
// vertices that shall not be present in the output clique. |
|
// clique_weight_ptr - optional output parameter. Weight of found clique stored here. |
|
// num_generations - optional number of generations in evolutionary part of algorithm, |
|
// zero forces to return first found clique. |
|
// quality - optional parameter determining degree of required quality/speed tradeoff. |
|
// Must be in the range from 0 to 9. |
|
// 0 is fast and dirty, 9 is slow but hopefully yields good clique. |
|
// Returns: |
|
// sequence of pairwise different ints. |
|
// These are indices of vertices that form found clique. |
|
// Notes: |
|
// in cases of CV_WEIGHTED_EDGE and CV_WEIGHTED_ALL weights should be nonnegative. |
|
// start_clique has a priority over subgraph_of_ban. |
|
//F*/ |
|
/*CVAPI(CvSeq*) cvFindCliqueEx( CvGraph *graph, CvMemStorage *storage, |
|
int is_complementary CV_DEFAULT(0), |
|
CvGraphWeightType weight_type CV_DEFAULT(CV_NOT_WEIGHTED), |
|
CvVect32f weight_vtx CV_DEFAULT(0), |
|
CvMatr32f weight_edge CV_DEFAULT(0), |
|
CvSeq *start_clique CV_DEFAULT(0), |
|
CvSeq *subgraph_of_ban CV_DEFAULT(0), |
|
float *clique_weight_ptr CV_DEFAULT(0), |
|
int num_generations CV_DEFAULT(3), |
|
int quality CV_DEFAULT(2) );*/ |
|
|
|
|
|
#define CV_UNDEF_SC_PARAM 12345 //default value of parameters |
|
|
|
#define CV_IDP_BIRCHFIELD_PARAM1 25 |
|
#define CV_IDP_BIRCHFIELD_PARAM2 5 |
|
#define CV_IDP_BIRCHFIELD_PARAM3 12 |
|
#define CV_IDP_BIRCHFIELD_PARAM4 15 |
|
#define CV_IDP_BIRCHFIELD_PARAM5 25 |
|
|
|
|
|
#define CV_DISPARITY_BIRCHFIELD 0 |
|
|
|
|
|
/*F/////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Name: cvFindStereoCorrespondence |
|
// Purpose: find stereo correspondence on stereo-pair |
|
// Context: |
|
// Parameters: |
|
// leftImage - left image of stereo-pair (format 8uC1). |
|
// rightImage - right image of stereo-pair (format 8uC1). |
|
// mode - mode of correspondence retrieval (now CV_DISPARITY_BIRCHFIELD only) |
|
// dispImage - destination disparity image |
|
// maxDisparity - maximal disparity |
|
// param1, param2, param3, param4, param5 - parameters of algorithm |
|
// Returns: |
|
// Notes: |
|
// Images must be rectified. |
|
// All images must have format 8uC1. |
|
//F*/ |
|
CVAPI(void) |
|
cvFindStereoCorrespondence( |
|
const CvArr* leftImage, const CvArr* rightImage, |
|
int mode, |
|
CvArr* dispImage, |
|
int maxDisparity, |
|
double param1 CV_DEFAULT(CV_UNDEF_SC_PARAM), |
|
double param2 CV_DEFAULT(CV_UNDEF_SC_PARAM), |
|
double param3 CV_DEFAULT(CV_UNDEF_SC_PARAM), |
|
double param4 CV_DEFAULT(CV_UNDEF_SC_PARAM), |
|
double param5 CV_DEFAULT(CV_UNDEF_SC_PARAM) ); |
|
|
|
/*****************************************************************************************/ |
|
/************ Epiline functions *******************/ |
|
|
|
|
|
|
|
typedef struct CvStereoLineCoeff |
|
{ |
|
double Xcoef; |
|
double XcoefA; |
|
double XcoefB; |
|
double XcoefAB; |
|
|
|
double Ycoef; |
|
double YcoefA; |
|
double YcoefB; |
|
double YcoefAB; |
|
|
|
double Zcoef; |
|
double ZcoefA; |
|
double ZcoefB; |
|
double ZcoefAB; |
|
}CvStereoLineCoeff; |
|
|
|
|
|
typedef struct CvCamera |
|
{ |
|
float imgSize[2]; /* size of the camera view, used during calibration */ |
|
float matrix[9]; /* intinsic camera parameters: [ fx 0 cx; 0 fy cy; 0 0 1 ] */ |
|
float distortion[4]; /* distortion coefficients - two coefficients for radial distortion |
|
and another two for tangential: [ k1 k2 p1 p2 ] */ |
|
float rotMatr[9]; |
|
float transVect[3]; /* rotation matrix and transition vector relatively |
|
to some reference point in the space. */ |
|
} CvCamera; |
|
|
|
typedef struct CvStereoCamera |
|
{ |
|
CvCamera* camera[2]; /* two individual camera parameters */ |
|
float fundMatr[9]; /* fundamental matrix */ |
|
|
|
/* New part for stereo */ |
|
CvPoint3D32f epipole[2]; |
|
CvPoint2D32f quad[2][4]; /* coordinates of destination quadrangle after |
|
epipolar geometry rectification */ |
|
double coeffs[2][3][3];/* coefficients for transformation */ |
|
CvPoint2D32f border[2][4]; |
|
CvSize warpSize; |
|
CvStereoLineCoeff* lineCoeffs; |
|
int needSwapCameras;/* flag set to 1 if need to swap cameras for good reconstruction */ |
|
float rotMatrix[9]; |
|
float transVector[3]; |
|
} CvStereoCamera; |
|
|
|
|
|
typedef struct CvContourOrientation |
|
{ |
|
float egvals[2]; |
|
float egvects[4]; |
|
|
|
float max, min; // minimum and maximum projections |
|
int imax, imin; |
|
} CvContourOrientation; |
|
|
|
#define CV_CAMERA_TO_WARP 1 |
|
#define CV_WARP_TO_CAMERA 2 |
|
|
|
CVAPI(int) icvConvertWarpCoordinates(double coeffs[3][3], |
|
CvPoint2D32f* cameraPoint, |
|
CvPoint2D32f* warpPoint, |
|
int direction); |
|
|
|
CVAPI(int) icvGetSymPoint3D( CvPoint3D64f pointCorner, |
|
CvPoint3D64f point1, |
|
CvPoint3D64f point2, |
|
CvPoint3D64f *pointSym2); |
|
|
|
CVAPI(void) icvGetPieceLength3D(CvPoint3D64f point1,CvPoint3D64f point2,double* dist); |
|
|
|
CVAPI(int) icvCompute3DPoint( double alpha,double betta, |
|
CvStereoLineCoeff* coeffs, |
|
CvPoint3D64f* point); |
|
|
|
CVAPI(int) icvCreateConvertMatrVect( double* rotMatr1, |
|
double* transVect1, |
|
double* rotMatr2, |
|
double* transVect2, |
|
double* convRotMatr, |
|
double* convTransVect); |
|
|
|
CVAPI(int) icvConvertPointSystem(CvPoint3D64f M2, |
|
CvPoint3D64f* M1, |
|
double* rotMatr, |
|
double* transVect |
|
); |
|
|
|
CVAPI(int) icvComputeCoeffForStereo( CvStereoCamera* stereoCamera); |
|
|
|
CVAPI(int) icvGetCrossPieceVector(CvPoint2D32f p1_start,CvPoint2D32f p1_end,CvPoint2D32f v2_start,CvPoint2D32f v2_end,CvPoint2D32f *cross); |
|
CVAPI(int) icvGetCrossLineDirect(CvPoint2D32f p1,CvPoint2D32f p2,float a,float b,float c,CvPoint2D32f* cross); |
|
CVAPI(float) icvDefinePointPosition(CvPoint2D32f point1,CvPoint2D32f point2,CvPoint2D32f point); |
|
CVAPI(int) icvStereoCalibration( int numImages, |
|
int* nums, |
|
CvSize imageSize, |
|
CvPoint2D32f* imagePoints1, |
|
CvPoint2D32f* imagePoints2, |
|
CvPoint3D32f* objectPoints, |
|
CvStereoCamera* stereoparams |
|
); |
|
|
|
|
|
CVAPI(int) icvComputeRestStereoParams(CvStereoCamera *stereoparams); |
|
|
|
CVAPI(void) cvComputePerspectiveMap( const double coeffs[3][3], CvArr* rectMapX, CvArr* rectMapY ); |
|
|
|
CVAPI(int) icvComCoeffForLine( CvPoint2D64f point1, |
|
CvPoint2D64f point2, |
|
CvPoint2D64f point3, |
|
CvPoint2D64f point4, |
|
double* camMatr1, |
|
double* rotMatr1, |
|
double* transVect1, |
|
double* camMatr2, |
|
double* rotMatr2, |
|
double* transVect2, |
|
CvStereoLineCoeff* coeffs, |
|
int* needSwapCameras); |
|
|
|
CVAPI(int) icvGetDirectionForPoint( CvPoint2D64f point, |
|
double* camMatr, |
|
CvPoint3D64f* direct); |
|
|
|
CVAPI(int) icvGetCrossLines(CvPoint3D64f point11,CvPoint3D64f point12, |
|
CvPoint3D64f point21,CvPoint3D64f point22, |
|
CvPoint3D64f* midPoint); |
|
|
|
CVAPI(int) icvComputeStereoLineCoeffs( CvPoint3D64f pointA, |
|
CvPoint3D64f pointB, |
|
CvPoint3D64f pointCam1, |
|
double gamma, |
|
CvStereoLineCoeff* coeffs); |
|
|
|
/*CVAPI(int) icvComputeFundMatrEpipoles ( double* camMatr1, |
|
double* rotMatr1, |
|
double* transVect1, |
|
double* camMatr2, |
|
double* rotMatr2, |
|
double* transVect2, |
|
CvPoint2D64f* epipole1, |
|
CvPoint2D64f* epipole2, |
|
double* fundMatr);*/ |
|
|
|
CVAPI(int) icvGetAngleLine( CvPoint2D64f startPoint, CvSize imageSize,CvPoint2D64f *point1,CvPoint2D64f *point2); |
|
|
|
CVAPI(void) icvGetCoefForPiece( CvPoint2D64f p_start,CvPoint2D64f p_end, |
|
double *a,double *b,double *c, |
|
int* result); |
|
|
|
/*CVAPI(void) icvGetCommonArea( CvSize imageSize, |
|
CvPoint2D64f epipole1,CvPoint2D64f epipole2, |
|
double* fundMatr, |
|
double* coeff11,double* coeff12, |
|
double* coeff21,double* coeff22, |
|
int* result);*/ |
|
|
|
CVAPI(void) icvComputeeInfiniteProject1(double* rotMatr, |
|
double* camMatr1, |
|
double* camMatr2, |
|
CvPoint2D32f point1, |
|
CvPoint2D32f *point2); |
|
|
|
CVAPI(void) icvComputeeInfiniteProject2(double* rotMatr, |
|
double* camMatr1, |
|
double* camMatr2, |
|
CvPoint2D32f* point1, |
|
CvPoint2D32f point2); |
|
|
|
CVAPI(void) icvGetCrossDirectDirect( double* direct1,double* direct2, |
|
CvPoint2D64f *cross,int* result); |
|
|
|
CVAPI(void) icvGetCrossPieceDirect( CvPoint2D64f p_start,CvPoint2D64f p_end, |
|
double a,double b,double c, |
|
CvPoint2D64f *cross,int* result); |
|
|
|
CVAPI(void) icvGetCrossPiecePiece( CvPoint2D64f p1_start,CvPoint2D64f p1_end, |
|
CvPoint2D64f p2_start,CvPoint2D64f p2_end, |
|
CvPoint2D64f* cross, |
|
int* result); |
|
|
|
CVAPI(void) icvGetPieceLength(CvPoint2D64f point1,CvPoint2D64f point2,double* dist); |
|
|
|
CVAPI(void) icvGetCrossRectDirect( CvSize imageSize, |
|
double a,double b,double c, |
|
CvPoint2D64f *start,CvPoint2D64f *end, |
|
int* result); |
|
|
|
CVAPI(void) icvProjectPointToImage( CvPoint3D64f point, |
|
double* camMatr,double* rotMatr,double* transVect, |
|
CvPoint2D64f* projPoint); |
|
|
|
CVAPI(void) icvGetQuadsTransform( CvSize imageSize, |
|
double* camMatr1, |
|
double* rotMatr1, |
|
double* transVect1, |
|
double* camMatr2, |
|
double* rotMatr2, |
|
double* transVect2, |
|
CvSize* warpSize, |
|
double quad1[4][2], |
|
double quad2[4][2], |
|
double* fundMatr, |
|
CvPoint3D64f* epipole1, |
|
CvPoint3D64f* epipole2 |
|
); |
|
|
|
CVAPI(void) icvGetQuadsTransformStruct( CvStereoCamera* stereoCamera); |
|
|
|
CVAPI(void) icvComputeStereoParamsForCameras(CvStereoCamera* stereoCamera); |
|
|
|
CVAPI(void) icvGetCutPiece( double* areaLineCoef1,double* areaLineCoef2, |
|
CvPoint2D64f epipole, |
|
CvSize imageSize, |
|
CvPoint2D64f* point11,CvPoint2D64f* point12, |
|
CvPoint2D64f* point21,CvPoint2D64f* point22, |
|
int* result); |
|
|
|
CVAPI(void) icvGetMiddleAnglePoint( CvPoint2D64f basePoint, |
|
CvPoint2D64f point1,CvPoint2D64f point2, |
|
CvPoint2D64f* midPoint); |
|
|
|
CVAPI(void) icvGetNormalDirect(double* direct,CvPoint2D64f point,double* normDirect); |
|
|
|
CVAPI(double) icvGetVect(CvPoint2D64f basePoint,CvPoint2D64f point1,CvPoint2D64f point2); |
|
|
|
CVAPI(void) icvProjectPointToDirect( CvPoint2D64f point,double* lineCoeff, |
|
CvPoint2D64f* projectPoint); |
|
|
|
CVAPI(void) icvGetDistanceFromPointToDirect( CvPoint2D64f point,double* lineCoef,double*dist); |
|
|
|
CVAPI(IplImage*) icvCreateIsometricImage( IplImage* src, IplImage* dst, |
|
int desired_depth, int desired_num_channels ); |
|
|
|
CVAPI(void) cvDeInterlace( const CvArr* frame, CvArr* fieldEven, CvArr* fieldOdd ); |
|
|
|
/*CVAPI(int) icvSelectBestRt( int numImages, |
|
int* numPoints, |
|
CvSize imageSize, |
|
CvPoint2D32f* imagePoints1, |
|
CvPoint2D32f* imagePoints2, |
|
CvPoint3D32f* objectPoints, |
|
|
|
CvMatr32f cameraMatrix1, |
|
CvVect32f distortion1, |
|
CvMatr32f rotMatrs1, |
|
CvVect32f transVects1, |
|
|
|
CvMatr32f cameraMatrix2, |
|
CvVect32f distortion2, |
|
CvMatr32f rotMatrs2, |
|
CvVect32f transVects2, |
|
|
|
CvMatr32f bestRotMatr, |
|
CvVect32f bestTransVect |
|
);*/ |
|
|
|
|
|
/****************************************************************************************\ |
|
* Contour Tree * |
|
\****************************************************************************************/ |
|
|
|
/* Contour tree header */ |
|
typedef struct CvContourTree |
|
{ |
|
CV_SEQUENCE_FIELDS() |
|
CvPoint p1; /* the first point of the binary tree root segment */ |
|
CvPoint p2; /* the last point of the binary tree root segment */ |
|
} CvContourTree; |
|
|
|
/* Builds hierarhical representation of a contour */ |
|
CVAPI(CvContourTree*) cvCreateContourTree( const CvSeq* contour, |
|
CvMemStorage* storage, |
|
double threshold ); |
|
|
|
/* Reconstruct (completelly or partially) contour a from contour tree */ |
|
CVAPI(CvSeq*) cvContourFromContourTree( const CvContourTree* tree, |
|
CvMemStorage* storage, |
|
CvTermCriteria criteria ); |
|
|
|
/* Compares two contour trees */ |
|
enum { CV_CONTOUR_TREES_MATCH_I1 = 1 }; |
|
|
|
CVAPI(double) cvMatchContourTrees( const CvContourTree* tree1, |
|
const CvContourTree* tree2, |
|
int method, double threshold ); |
|
|
|
/****************************************************************************************\ |
|
* Contour Morphing * |
|
\****************************************************************************************/ |
|
|
|
/* finds correspondence between two contours */ |
|
CvSeq* cvCalcContoursCorrespondence( const CvSeq* contour1, |
|
const CvSeq* contour2, |
|
CvMemStorage* storage); |
|
|
|
/* morphs contours using the pre-calculated correspondence: |
|
alpha=0 ~ contour1, alpha=1 ~ contour2 */ |
|
CvSeq* cvMorphContours( const CvSeq* contour1, const CvSeq* contour2, |
|
CvSeq* corr, double alpha, |
|
CvMemStorage* storage ); |
|
|
|
|
|
/****************************************************************************************\ |
|
* Active Contours * |
|
\****************************************************************************************/ |
|
|
|
#define CV_VALUE 1 |
|
#define CV_ARRAY 2 |
|
/* Updates active contour in order to minimize its cummulative |
|
(internal and external) energy. */ |
|
CVAPI(void) cvSnakeImage( const IplImage* image, CvPoint* points, |
|
int length, float* alpha, |
|
float* beta, float* gamma, |
|
int coeff_usage, CvSize win, |
|
CvTermCriteria criteria, int calc_gradient CV_DEFAULT(1)); |
|
|
|
/****************************************************************************************\ |
|
* Texture Descriptors * |
|
\****************************************************************************************/ |
|
|
|
#define CV_GLCM_OPTIMIZATION_NONE -2 |
|
#define CV_GLCM_OPTIMIZATION_LUT -1 |
|
#define CV_GLCM_OPTIMIZATION_HISTOGRAM 0 |
|
|
|
#define CV_GLCMDESC_OPTIMIZATION_ALLOWDOUBLENEST 10 |
|
#define CV_GLCMDESC_OPTIMIZATION_ALLOWTRIPLENEST 11 |
|
#define CV_GLCMDESC_OPTIMIZATION_HISTOGRAM 4 |
|
|
|
#define CV_GLCMDESC_ENTROPY 0 |
|
#define CV_GLCMDESC_ENERGY 1 |
|
#define CV_GLCMDESC_HOMOGENITY 2 |
|
#define CV_GLCMDESC_CONTRAST 3 |
|
#define CV_GLCMDESC_CLUSTERTENDENCY 4 |
|
#define CV_GLCMDESC_CLUSTERSHADE 5 |
|
#define CV_GLCMDESC_CORRELATION 6 |
|
#define CV_GLCMDESC_CORRELATIONINFO1 7 |
|
#define CV_GLCMDESC_CORRELATIONINFO2 8 |
|
#define CV_GLCMDESC_MAXIMUMPROBABILITY 9 |
|
|
|
#define CV_GLCM_ALL 0 |
|
#define CV_GLCM_GLCM 1 |
|
#define CV_GLCM_DESC 2 |
|
|
|
typedef struct CvGLCM CvGLCM; |
|
|
|
CVAPI(CvGLCM*) cvCreateGLCM( const IplImage* srcImage, |
|
int stepMagnitude, |
|
const int* stepDirections CV_DEFAULT(0), |
|
int numStepDirections CV_DEFAULT(0), |
|
int optimizationType CV_DEFAULT(CV_GLCM_OPTIMIZATION_NONE)); |
|
|
|
CVAPI(void) cvReleaseGLCM( CvGLCM** GLCM, int flag CV_DEFAULT(CV_GLCM_ALL)); |
|
|
|
CVAPI(void) cvCreateGLCMDescriptors( CvGLCM* destGLCM, |
|
int descriptorOptimizationType |
|
CV_DEFAULT(CV_GLCMDESC_OPTIMIZATION_ALLOWDOUBLENEST)); |
|
|
|
CVAPI(double) cvGetGLCMDescriptor( CvGLCM* GLCM, int step, int descriptor ); |
|
|
|
CVAPI(void) cvGetGLCMDescriptorStatistics( CvGLCM* GLCM, int descriptor, |
|
double* average, double* standardDeviation ); |
|
|
|
CVAPI(IplImage*) cvCreateGLCMImage( CvGLCM* GLCM, int step ); |
|
|
|
/****************************************************************************************\ |
|
* Face eyes&mouth tracking * |
|
\****************************************************************************************/ |
|
|
|
|
|
typedef struct CvFaceTracker CvFaceTracker; |
|
|
|
#define CV_NUM_FACE_ELEMENTS 3 |
|
enum CV_FACE_ELEMENTS |
|
{ |
|
CV_FACE_MOUTH = 0, |
|
CV_FACE_LEFT_EYE = 1, |
|
CV_FACE_RIGHT_EYE = 2 |
|
}; |
|
|
|
CVAPI(CvFaceTracker*) cvInitFaceTracker(CvFaceTracker* pFaceTracking, const IplImage* imgGray, |
|
CvRect* pRects, int nRects); |
|
CVAPI(int) cvTrackFace( CvFaceTracker* pFaceTracker, IplImage* imgGray, |
|
CvRect* pRects, int nRects, |
|
CvPoint* ptRotate, double* dbAngleRotate); |
|
CVAPI(void) cvReleaseFaceTracker(CvFaceTracker** ppFaceTracker); |
|
|
|
|
|
typedef struct CvFace |
|
{ |
|
CvRect MouthRect; |
|
CvRect LeftEyeRect; |
|
CvRect RightEyeRect; |
|
} CvFaceData; |
|
|
|
CvSeq * cvFindFace(IplImage * Image,CvMemStorage* storage); |
|
CvSeq * cvPostBoostingFindFace(IplImage * Image,CvMemStorage* storage); |
|
|
|
|
|
/****************************************************************************************\ |
|
* 3D Tracker * |
|
\****************************************************************************************/ |
|
|
|
typedef unsigned char CvBool; |
|
|
|
typedef struct Cv3dTracker2dTrackedObject |
|
{ |
|
int id; |
|
CvPoint2D32f p; // pgruebele: So we do not loose precision, this needs to be float |
|
} Cv3dTracker2dTrackedObject; |
|
|
|
CV_INLINE Cv3dTracker2dTrackedObject cv3dTracker2dTrackedObject(int id, CvPoint2D32f p) |
|
{ |
|
Cv3dTracker2dTrackedObject r; |
|
r.id = id; |
|
r.p = p; |
|
return r; |
|
} |
|
|
|
typedef struct Cv3dTrackerTrackedObject |
|
{ |
|
int id; |
|
CvPoint3D32f p; // location of the tracked object |
|
} Cv3dTrackerTrackedObject; |
|
|
|
CV_INLINE Cv3dTrackerTrackedObject cv3dTrackerTrackedObject(int id, CvPoint3D32f p) |
|
{ |
|
Cv3dTrackerTrackedObject r; |
|
r.id = id; |
|
r.p = p; |
|
return r; |
|
} |
|
|
|
typedef struct Cv3dTrackerCameraInfo |
|
{ |
|
CvBool valid; |
|
float mat[4][4]; /* maps camera coordinates to world coordinates */ |
|
CvPoint2D32f principal_point; /* copied from intrinsics so this structure */ |
|
/* has all the info we need */ |
|
} Cv3dTrackerCameraInfo; |
|
|
|
typedef struct Cv3dTrackerCameraIntrinsics |
|
{ |
|
CvPoint2D32f principal_point; |
|
float focal_length[2]; |
|
float distortion[4]; |
|
} Cv3dTrackerCameraIntrinsics; |
|
|
|
CVAPI(CvBool) cv3dTrackerCalibrateCameras(int num_cameras, |
|
const Cv3dTrackerCameraIntrinsics camera_intrinsics[], /* size is num_cameras */ |
|
CvSize etalon_size, |
|
float square_size, |
|
IplImage *samples[], /* size is num_cameras */ |
|
Cv3dTrackerCameraInfo camera_info[]); /* size is num_cameras */ |
|
|
|
CVAPI(int) cv3dTrackerLocateObjects(int num_cameras, int num_objects, |
|
const Cv3dTrackerCameraInfo camera_info[], /* size is num_cameras */ |
|
const Cv3dTracker2dTrackedObject tracking_info[], /* size is num_objects*num_cameras */ |
|
Cv3dTrackerTrackedObject tracked_objects[]); /* size is num_objects */ |
|
/**************************************************************************************** |
|
tracking_info is a rectangular array; one row per camera, num_objects elements per row. |
|
The id field of any unused slots must be -1. Ids need not be ordered or consecutive. On |
|
completion, the return value is the number of objects located; i.e., the number of objects |
|
visible by more than one camera. The id field of any unused slots in tracked objects is |
|
set to -1. |
|
****************************************************************************************/ |
|
|
|
|
|
/****************************************************************************************\ |
|
* Skeletons and Linear-Contour Models * |
|
\****************************************************************************************/ |
|
|
|
typedef enum CvLeeParameters |
|
{ |
|
CV_LEE_INT = 0, |
|
CV_LEE_FLOAT = 1, |
|
CV_LEE_DOUBLE = 2, |
|
CV_LEE_AUTO = -1, |
|
CV_LEE_ERODE = 0, |
|
CV_LEE_ZOOM = 1, |
|
CV_LEE_NON = 2 |
|
} CvLeeParameters; |
|
|
|
#define CV_NEXT_VORONOISITE2D( SITE ) ((SITE)->edge[0]->site[((SITE)->edge[0]->site[0] == (SITE))]) |
|
#define CV_PREV_VORONOISITE2D( SITE ) ((SITE)->edge[1]->site[((SITE)->edge[1]->site[0] == (SITE))]) |
|
#define CV_FIRST_VORONOIEDGE2D( SITE ) ((SITE)->edge[0]) |
|
#define CV_LAST_VORONOIEDGE2D( SITE ) ((SITE)->edge[1]) |
|
#define CV_NEXT_VORONOIEDGE2D( EDGE, SITE ) ((EDGE)->next[(EDGE)->site[0] != (SITE)]) |
|
#define CV_PREV_VORONOIEDGE2D( EDGE, SITE ) ((EDGE)->next[2 + ((EDGE)->site[0] != (SITE))]) |
|
#define CV_VORONOIEDGE2D_BEGINNODE( EDGE, SITE ) ((EDGE)->node[((EDGE)->site[0] != (SITE))]) |
|
#define CV_VORONOIEDGE2D_ENDNODE( EDGE, SITE ) ((EDGE)->node[((EDGE)->site[0] == (SITE))]) |
|
#define CV_TWIN_VORONOISITE2D( SITE, EDGE ) ( (EDGE)->site[((EDGE)->site[0] == (SITE))]) |
|
|
|
#define CV_VORONOISITE2D_FIELDS() \ |
|
struct CvVoronoiNode2D *node[2]; \ |
|
struct CvVoronoiEdge2D *edge[2]; |
|
|
|
typedef struct CvVoronoiSite2D |
|
{ |
|
CV_VORONOISITE2D_FIELDS() |
|
struct CvVoronoiSite2D *next[2]; |
|
} CvVoronoiSite2D; |
|
|
|
#define CV_VORONOIEDGE2D_FIELDS() \ |
|
struct CvVoronoiNode2D *node[2]; \ |
|
struct CvVoronoiSite2D *site[2]; \ |
|
struct CvVoronoiEdge2D *next[4]; |
|
|
|
typedef struct CvVoronoiEdge2D |
|
{ |
|
CV_VORONOIEDGE2D_FIELDS() |
|
} CvVoronoiEdge2D; |
|
|
|
#define CV_VORONOINODE2D_FIELDS() \ |
|
CV_SET_ELEM_FIELDS(CvVoronoiNode2D) \ |
|
CvPoint2D32f pt; \ |
|
float radius; |
|
|
|
typedef struct CvVoronoiNode2D |
|
{ |
|
CV_VORONOINODE2D_FIELDS() |
|
} CvVoronoiNode2D; |
|
|
|
#define CV_VORONOIDIAGRAM2D_FIELDS() \ |
|
CV_GRAPH_FIELDS() \ |
|
CvSet *sites; |
|
|
|
typedef struct CvVoronoiDiagram2D |
|
{ |
|
CV_VORONOIDIAGRAM2D_FIELDS() |
|
} CvVoronoiDiagram2D; |
|
|
|
/* Computes Voronoi Diagram for given polygons with holes */ |
|
CVAPI(int) cvVoronoiDiagramFromContour(CvSeq* ContourSeq, |
|
CvVoronoiDiagram2D** VoronoiDiagram, |
|
CvMemStorage* VoronoiStorage, |
|
CvLeeParameters contour_type CV_DEFAULT(CV_LEE_INT), |
|
int contour_orientation CV_DEFAULT(-1), |
|
int attempt_number CV_DEFAULT(10)); |
|
|
|
/* Computes Voronoi Diagram for domains in given image */ |
|
CVAPI(int) cvVoronoiDiagramFromImage(IplImage* pImage, |
|
CvSeq** ContourSeq, |
|
CvVoronoiDiagram2D** VoronoiDiagram, |
|
CvMemStorage* VoronoiStorage, |
|
CvLeeParameters regularization_method CV_DEFAULT(CV_LEE_NON), |
|
float approx_precision CV_DEFAULT(CV_LEE_AUTO)); |
|
|
|
/* Deallocates the storage */ |
|
CVAPI(void) cvReleaseVoronoiStorage(CvVoronoiDiagram2D* VoronoiDiagram, |
|
CvMemStorage** pVoronoiStorage); |
|
|
|
/*********************** Linear-Contour Model ****************************/ |
|
|
|
struct CvLCMEdge; |
|
struct CvLCMNode; |
|
|
|
typedef struct CvLCMEdge |
|
{ |
|
CV_GRAPH_EDGE_FIELDS() |
|
CvSeq* chain; |
|
float width; |
|
int index1; |
|
int index2; |
|
} CvLCMEdge; |
|
|
|
typedef struct CvLCMNode |
|
{ |
|
CV_GRAPH_VERTEX_FIELDS() |
|
CvContour* contour; |
|
} CvLCMNode; |
|
|
|
|
|
/* Computes hybrid model from Voronoi Diagram */ |
|
CVAPI(CvGraph*) cvLinearContorModelFromVoronoiDiagram(CvVoronoiDiagram2D* VoronoiDiagram, |
|
float maxWidth); |
|
|
|
/* Releases hybrid model storage */ |
|
CVAPI(int) cvReleaseLinearContorModelStorage(CvGraph** Graph); |
|
|
|
|
|
/* two stereo-related functions */ |
|
|
|
CVAPI(void) cvInitPerspectiveTransform( CvSize size, const CvPoint2D32f vertex[4], double matrix[3][3], |
|
CvArr* rectMap ); |
|
|
|
/*CVAPI(void) cvInitStereoRectification( CvStereoCamera* params, |
|
CvArr* rectMap1, CvArr* rectMap2, |
|
int do_undistortion );*/ |
|
|
|
/*************************** View Morphing Functions ************************/ |
|
|
|
typedef struct CvMatrix3 |
|
{ |
|
float m[3][3]; |
|
} CvMatrix3; |
|
|
|
/* The order of the function corresponds to the order they should appear in |
|
the view morphing pipeline */ |
|
|
|
/* Finds ending points of scanlines on left and right images of stereo-pair */ |
|
CVAPI(void) cvMakeScanlines( const CvMatrix3* matrix, CvSize img_size, |
|
int* scanlines1, int* scanlines2, |
|
int* lengths1, int* lengths2, |
|
int* line_count ); |
|
|
|
/* Grab pixel values from scanlines and stores them sequentially |
|
(some sort of perspective image transform) */ |
|
CVAPI(void) cvPreWarpImage( int line_count, |
|
IplImage* img, |
|
uchar* dst, |
|
int* dst_nums, |
|
int* scanlines); |
|
|
|
/* Approximate each grabbed scanline by a sequence of runs |
|
(lossy run-length compression) */ |
|
CVAPI(void) cvFindRuns( int line_count, |
|
uchar* prewarp1, |
|
uchar* prewarp2, |
|
int* line_lengths1, |
|
int* line_lengths2, |
|
int* runs1, |
|
int* runs2, |
|
int* num_runs1, |
|
int* num_runs2); |
|
|
|
/* Compares two sets of compressed scanlines */ |
|
CVAPI(void) cvDynamicCorrespondMulti( int line_count, |
|
int* first, |
|
int* first_runs, |
|
int* second, |
|
int* second_runs, |
|
int* first_corr, |
|
int* second_corr); |
|
|
|
/* Finds scanline ending coordinates for some intermediate "virtual" camera position */ |
|
CVAPI(void) cvMakeAlphaScanlines( int* scanlines1, |
|
int* scanlines2, |
|
int* scanlinesA, |
|
int* lengths, |
|
int line_count, |
|
float alpha); |
|
|
|
/* Blends data of the left and right image scanlines to get |
|
pixel values of "virtual" image scanlines */ |
|
CVAPI(void) cvMorphEpilinesMulti( int line_count, |
|
uchar* first_pix, |
|
int* first_num, |
|
uchar* second_pix, |
|
int* second_num, |
|
uchar* dst_pix, |
|
int* dst_num, |
|
float alpha, |
|
int* first, |
|
int* first_runs, |
|
int* second, |
|
int* second_runs, |
|
int* first_corr, |
|
int* second_corr); |
|
|
|
/* Does reverse warping of the morphing result to make |
|
it fill the destination image rectangle */ |
|
CVAPI(void) cvPostWarpImage( int line_count, |
|
uchar* src, |
|
int* src_nums, |
|
IplImage* img, |
|
int* scanlines); |
|
|
|
/* Deletes Moire (missed pixels that appear due to discretization) */ |
|
CVAPI(void) cvDeleteMoire( IplImage* img ); |
|
|
|
|
|
typedef struct CvConDensation |
|
{ |
|
int MP; |
|
int DP; |
|
float* DynamMatr; /* Matrix of the linear Dynamics system */ |
|
float* State; /* Vector of State */ |
|
int SamplesNum; /* Number of the Samples */ |
|
float** flSamples; /* arr of the Sample Vectors */ |
|
float** flNewSamples; /* temporary array of the Sample Vectors */ |
|
float* flConfidence; /* Confidence for each Sample */ |
|
float* flCumulative; /* Cumulative confidence */ |
|
float* Temp; /* Temporary vector */ |
|
float* RandomSample; /* RandomVector to update sample set */ |
|
struct CvRandState* RandS; /* Array of structures to generate random vectors */ |
|
} CvConDensation; |
|
|
|
/* Creates ConDensation filter state */ |
|
CVAPI(CvConDensation*) cvCreateConDensation( int dynam_params, |
|
int measure_params, |
|
int sample_count ); |
|
|
|
/* Releases ConDensation filter state */ |
|
CVAPI(void) cvReleaseConDensation( CvConDensation** condens ); |
|
|
|
/* Updates ConDensation filter by time (predict future state of the system) */ |
|
CVAPI(void) cvConDensUpdateByTime( CvConDensation* condens); |
|
|
|
/* Initializes ConDensation filter samples */ |
|
CVAPI(void) cvConDensInitSampleSet( CvConDensation* condens, CvMat* lower_bound, CvMat* upper_bound ); |
|
|
|
CV_INLINE int iplWidth( const IplImage* img ) |
|
{ |
|
return !img ? 0 : !img->roi ? img->width : img->roi->width; |
|
} |
|
|
|
CV_INLINE int iplHeight( const IplImage* img ) |
|
{ |
|
return !img ? 0 : !img->roi ? img->height : img->roi->height; |
|
} |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#ifdef __cplusplus |
|
|
|
/****************************************************************************************\ |
|
* Calibration engine * |
|
\****************************************************************************************/ |
|
|
|
typedef enum CvCalibEtalonType |
|
{ |
|
CV_CALIB_ETALON_USER = -1, |
|
CV_CALIB_ETALON_CHESSBOARD = 0, |
|
CV_CALIB_ETALON_CHECKERBOARD = CV_CALIB_ETALON_CHESSBOARD |
|
} |
|
CvCalibEtalonType; |
|
|
|
class CV_EXPORTS CvCalibFilter |
|
{ |
|
public: |
|
/* Constructor & destructor */ |
|
CvCalibFilter(); |
|
virtual ~CvCalibFilter(); |
|
|
|
/* Sets etalon type - one for all cameras. |
|
etalonParams is used in case of pre-defined etalons (such as chessboard). |
|
Number of elements in etalonParams is determined by etalonType. |
|
E.g., if etalon type is CV_ETALON_TYPE_CHESSBOARD then: |
|
etalonParams[0] is number of squares per one side of etalon |
|
etalonParams[1] is number of squares per another side of etalon |
|
etalonParams[2] is linear size of squares in the board in arbitrary units. |
|
pointCount & points are used in case of |
|
CV_CALIB_ETALON_USER (user-defined) etalon. */ |
|
virtual bool |
|
SetEtalon( CvCalibEtalonType etalonType, double* etalonParams, |
|
int pointCount = 0, CvPoint2D32f* points = 0 ); |
|
|
|
/* Retrieves etalon parameters/or and points */ |
|
virtual CvCalibEtalonType |
|
GetEtalon( int* paramCount = 0, const double** etalonParams = 0, |
|
int* pointCount = 0, const CvPoint2D32f** etalonPoints = 0 ) const; |
|
|
|
/* Sets number of cameras calibrated simultaneously. It is equal to 1 initially */ |
|
virtual void SetCameraCount( int cameraCount ); |
|
|
|
/* Retrieves number of cameras */ |
|
int GetCameraCount() const { return cameraCount; } |
|
|
|
/* Starts cameras calibration */ |
|
virtual bool SetFrames( int totalFrames ); |
|
|
|
/* Stops cameras calibration */ |
|
virtual void Stop( bool calibrate = false ); |
|
|
|
/* Retrieves number of cameras */ |
|
bool IsCalibrated() const { return isCalibrated; } |
|
|
|
/* Feeds another serie of snapshots (one per each camera) to filter. |
|
Etalon points on these images are found automatically. |
|
If the function can't locate points, it returns false */ |
|
virtual bool FindEtalon( IplImage** imgs ); |
|
|
|
/* The same but takes matrices */ |
|
virtual bool FindEtalon( CvMat** imgs ); |
|
|
|
/* Lower-level function for feeding filter with already found etalon points. |
|
Array of point arrays for each camera is passed. */ |
|
virtual bool Push( const CvPoint2D32f** points = 0 ); |
|
|
|
/* Returns total number of accepted frames and, optionally, |
|
total number of frames to collect */ |
|
virtual int GetFrameCount( int* framesTotal = 0 ) const; |
|
|
|
/* Retrieves camera parameters for specified camera. |
|
If camera is not calibrated the function returns 0 */ |
|
virtual const CvCamera* GetCameraParams( int idx = 0 ) const; |
|
|
|
virtual const CvStereoCamera* GetStereoParams() const; |
|
|
|
/* Sets camera parameters for all cameras */ |
|
virtual bool SetCameraParams( CvCamera* params ); |
|
|
|
/* Saves all camera parameters to file */ |
|
virtual bool SaveCameraParams( const char* filename ); |
|
|
|
/* Loads all camera parameters from file */ |
|
virtual bool LoadCameraParams( const char* filename ); |
|
|
|
/* Undistorts images using camera parameters. Some of src pointers can be NULL. */ |
|
virtual bool Undistort( IplImage** src, IplImage** dst ); |
|
|
|
/* Undistorts images using camera parameters. Some of src pointers can be NULL. */ |
|
virtual bool Undistort( CvMat** src, CvMat** dst ); |
|
|
|
/* Returns array of etalon points detected/partally detected |
|
on the latest frame for idx-th camera */ |
|
virtual bool GetLatestPoints( int idx, CvPoint2D32f** pts, |
|
int* count, bool* found ); |
|
|
|
/* Draw the latest detected/partially detected etalon */ |
|
virtual void DrawPoints( IplImage** dst ); |
|
|
|
/* Draw the latest detected/partially detected etalon */ |
|
virtual void DrawPoints( CvMat** dst ); |
|
|
|
virtual bool Rectify( IplImage** srcarr, IplImage** dstarr ); |
|
virtual bool Rectify( CvMat** srcarr, CvMat** dstarr ); |
|
|
|
protected: |
|
|
|
enum { MAX_CAMERAS = 3 }; |
|
|
|
/* etalon data */ |
|
CvCalibEtalonType etalonType; |
|
int etalonParamCount; |
|
double* etalonParams; |
|
int etalonPointCount; |
|
CvPoint2D32f* etalonPoints; |
|
CvSize imgSize; |
|
CvMat* grayImg; |
|
CvMat* tempImg; |
|
CvMemStorage* storage; |
|
|
|
/* camera data */ |
|
int cameraCount; |
|
CvCamera cameraParams[MAX_CAMERAS]; |
|
CvStereoCamera stereo; |
|
CvPoint2D32f* points[MAX_CAMERAS]; |
|
CvMat* undistMap[MAX_CAMERAS][2]; |
|
CvMat* undistImg; |
|
int latestCounts[MAX_CAMERAS]; |
|
CvPoint2D32f* latestPoints[MAX_CAMERAS]; |
|
CvMat* rectMap[MAX_CAMERAS][2]; |
|
|
|
/* Added by Valery */ |
|
//CvStereoCamera stereoParams; |
|
|
|
int maxPoints; |
|
int framesTotal; |
|
int framesAccepted; |
|
bool isCalibrated; |
|
}; |
|
|
|
#include <iosfwd> |
|
#include <limits> |
|
|
|
class CV_EXPORTS CvImage |
|
{ |
|
public: |
|
CvImage() : image(0), refcount(0) {} |
|
CvImage( CvSize _size, int _depth, int _channels ) |
|
{ |
|
image = cvCreateImage( _size, _depth, _channels ); |
|
refcount = image ? new int(1) : 0; |
|
} |
|
|
|
CvImage( IplImage* img ) : image(img) |
|
{ |
|
refcount = image ? new int(1) : 0; |
|
} |
|
|
|
CvImage( const CvImage& img ) : image(img.image), refcount(img.refcount) |
|
{ |
|
if( refcount ) ++(*refcount); |
|
} |
|
|
|
CvImage( const char* filename, const char* imgname=0, int color=-1 ) : image(0), refcount(0) |
|
{ load( filename, imgname, color ); } |
|
|
|
CvImage( CvFileStorage* fs, const char* mapname, const char* imgname ) : image(0), refcount(0) |
|
{ read( fs, mapname, imgname ); } |
|
|
|
CvImage( CvFileStorage* fs, const char* seqname, int idx ) : image(0), refcount(0) |
|
{ read( fs, seqname, idx ); } |
|
|
|
~CvImage() |
|
{ |
|
if( refcount && !(--*refcount) ) |
|
{ |
|
cvReleaseImage( &image ); |
|
delete refcount; |
|
} |
|
} |
|
|
|
CvImage clone() { return CvImage(image ? cvCloneImage(image) : 0); } |
|
|
|
void create( CvSize _size, int _depth, int _channels ) |
|
{ |
|
if( !image || !refcount || |
|
image->width != _size.width || image->height != _size.height || |
|
image->depth != _depth || image->nChannels != _channels ) |
|
attach( cvCreateImage( _size, _depth, _channels )); |
|
} |
|
|
|
void release() { detach(); } |
|
void clear() { detach(); } |
|
|
|
void attach( IplImage* img, bool use_refcount=true ) |
|
{ |
|
if( refcount && --*refcount == 0 ) |
|
{ |
|
cvReleaseImage( &image ); |
|
delete refcount; |
|
} |
|
image = img; |
|
refcount = use_refcount && image ? new int(1) : 0; |
|
} |
|
|
|
void detach() |
|
{ |
|
if( refcount && --*refcount == 0 ) |
|
{ |
|
cvReleaseImage( &image ); |
|
delete refcount; |
|
} |
|
image = 0; |
|
refcount = 0; |
|
} |
|
|
|
bool load( const char* filename, const char* imgname=0, int color=-1 ); |
|
bool read( CvFileStorage* fs, const char* mapname, const char* imgname ); |
|
bool read( CvFileStorage* fs, const char* seqname, int idx ); |
|
void save( const char* filename, const char* imgname, const int* params=0 ); |
|
void write( CvFileStorage* fs, const char* imgname ); |
|
|
|
void show( const char* window_name ); |
|
bool is_valid() { return image != 0; } |
|
|
|
int width() const { return image ? image->width : 0; } |
|
int height() const { return image ? image->height : 0; } |
|
|
|
CvSize size() const { return image ? cvSize(image->width, image->height) : cvSize(0,0); } |
|
|
|
CvSize roi_size() const |
|
{ |
|
return !image ? cvSize(0,0) : |
|
!image->roi ? cvSize(image->width,image->height) : |
|
cvSize(image->roi->width, image->roi->height); |
|
} |
|
|
|
CvRect roi() const |
|
{ |
|
return !image ? cvRect(0,0,0,0) : |
|
!image->roi ? cvRect(0,0,image->width,image->height) : |
|
cvRect(image->roi->xOffset,image->roi->yOffset, |
|
image->roi->width,image->roi->height); |
|
} |
|
|
|
int coi() const { return !image || !image->roi ? 0 : image->roi->coi; } |
|
|
|
void set_roi(CvRect _roi) { cvSetImageROI(image,_roi); } |
|
void reset_roi() { cvResetImageROI(image); } |
|
void set_coi(int _coi) { cvSetImageCOI(image,_coi); } |
|
int depth() const { return image ? image->depth : 0; } |
|
int channels() const { return image ? image->nChannels : 0; } |
|
int pix_size() const { return image ? ((image->depth & 255)>>3)*image->nChannels : 0; } |
|
|
|
uchar* data() { return image ? (uchar*)image->imageData : 0; } |
|
const uchar* data() const { return image ? (const uchar*)image->imageData : 0; } |
|
int step() const { return image ? image->widthStep : 0; } |
|
int origin() const { return image ? image->origin : 0; } |
|
|
|
uchar* roi_row(int y) |
|
{ |
|
assert(0<=y); |
|
assert(!image ? |
|
1 : image->roi ? |
|
y<image->roi->height : y<image->height); |
|
|
|
return !image ? 0 : |
|
!image->roi ? |
|
(uchar*)(image->imageData + y*image->widthStep) : |
|
(uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep + |
|
image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels); |
|
} |
|
|
|
const uchar* roi_row(int y) const |
|
{ |
|
assert(0<=y); |
|
assert(!image ? |
|
1 : image->roi ? |
|
y<image->roi->height : y<image->height); |
|
|
|
return !image ? 0 : |
|
!image->roi ? |
|
(const uchar*)(image->imageData + y*image->widthStep) : |
|
(const uchar*)(image->imageData + (y+image->roi->yOffset)*image->widthStep + |
|
image->roi->xOffset*((image->depth & 255)>>3)*image->nChannels); |
|
} |
|
|
|
operator const IplImage* () const { return image; } |
|
operator IplImage* () { return image; } |
|
|
|
CvImage& operator = (const CvImage& img) |
|
{ |
|
if( img.refcount ) |
|
++*img.refcount; |
|
if( refcount && !(--*refcount) ) |
|
cvReleaseImage( &image ); |
|
image=img.image; |
|
refcount=img.refcount; |
|
return *this; |
|
} |
|
|
|
protected: |
|
IplImage* image; |
|
int* refcount; |
|
}; |
|
|
|
|
|
class CV_EXPORTS CvMatrix |
|
{ |
|
public: |
|
CvMatrix() : matrix(0) {} |
|
CvMatrix( int _rows, int _cols, int _type ) |
|
{ matrix = cvCreateMat( _rows, _cols, _type ); } |
|
|
|
CvMatrix( int _rows, int _cols, int _type, CvMat* hdr, |
|
void* _data=0, int _step=CV_AUTOSTEP ) |
|
{ matrix = cvInitMatHeader( hdr, _rows, _cols, _type, _data, _step ); } |
|
|
|
CvMatrix( int rows, int cols, int type, CvMemStorage* storage, bool alloc_data=true ); |
|
|
|
CvMatrix( int _rows, int _cols, int _type, void* _data, int _step=CV_AUTOSTEP ) |
|
{ matrix = cvCreateMatHeader( _rows, _cols, _type ); |
|
cvSetData( matrix, _data, _step ); } |
|
|
|
CvMatrix( CvMat* m ) |
|
{ matrix = m; } |
|
|
|
CvMatrix( const CvMatrix& m ) |
|
{ |
|
matrix = m.matrix; |
|
addref(); |
|
} |
|
|
|
CvMatrix( const char* filename, const char* matname=0, int color=-1 ) : matrix(0) |
|
{ load( filename, matname, color ); } |
|
|
|
CvMatrix( CvFileStorage* fs, const char* mapname, const char* matname ) : matrix(0) |
|
{ read( fs, mapname, matname ); } |
|
|
|
CvMatrix( CvFileStorage* fs, const char* seqname, int idx ) : matrix(0) |
|
{ read( fs, seqname, idx ); } |
|
|
|
~CvMatrix() |
|
{ |
|
release(); |
|
} |
|
|
|
CvMatrix clone() { return CvMatrix(matrix ? cvCloneMat(matrix) : 0); } |
|
|
|
void set( CvMat* m, bool add_ref ) |
|
{ |
|
release(); |
|
matrix = m; |
|
if( add_ref ) |
|
addref(); |
|
} |
|
|
|
void create( int _rows, int _cols, int _type ) |
|
{ |
|
if( !matrix || !matrix->refcount || |
|
matrix->rows != _rows || matrix->cols != _cols || |
|
CV_MAT_TYPE(matrix->type) != _type ) |
|
set( cvCreateMat( _rows, _cols, _type ), false ); |
|
} |
|
|
|
void addref() const |
|
{ |
|
if( matrix ) |
|
{ |
|
if( matrix->hdr_refcount ) |
|
++matrix->hdr_refcount; |
|
else if( matrix->refcount ) |
|
++*matrix->refcount; |
|
} |
|
} |
|
|
|
void release() |
|
{ |
|
if( matrix ) |
|
{ |
|
if( matrix->hdr_refcount ) |
|
{ |
|
if( --matrix->hdr_refcount == 0 ) |
|
cvReleaseMat( &matrix ); |
|
} |
|
else if( matrix->refcount ) |
|
{ |
|
if( --*matrix->refcount == 0 ) |
|
cvFree( &matrix->refcount ); |
|
} |
|
matrix = 0; |
|
} |
|
} |
|
|
|
void clear() |
|
{ |
|
release(); |
|
} |
|
|
|
bool load( const char* filename, const char* matname=0, int color=-1 ); |
|
bool read( CvFileStorage* fs, const char* mapname, const char* matname ); |
|
bool read( CvFileStorage* fs, const char* seqname, int idx ); |
|
void save( const char* filename, const char* matname, const int* params=0 ); |
|
void write( CvFileStorage* fs, const char* matname ); |
|
|
|
void show( const char* window_name ); |
|
|
|
bool is_valid() { return matrix != 0; } |
|
|
|
int rows() const { return matrix ? matrix->rows : 0; } |
|
int cols() const { return matrix ? matrix->cols : 0; } |
|
|
|
CvSize size() const |
|
{ |
|
return !matrix ? cvSize(0,0) : cvSize(matrix->rows,matrix->cols); |
|
} |
|
|
|
int type() const { return matrix ? CV_MAT_TYPE(matrix->type) : 0; } |
|
int depth() const { return matrix ? CV_MAT_DEPTH(matrix->type) : 0; } |
|
int channels() const { return matrix ? CV_MAT_CN(matrix->type) : 0; } |
|
int pix_size() const { return matrix ? CV_ELEM_SIZE(matrix->type) : 0; } |
|
|
|
uchar* data() { return matrix ? matrix->data.ptr : 0; } |
|
const uchar* data() const { return matrix ? matrix->data.ptr : 0; } |
|
int step() const { return matrix ? matrix->step : 0; } |
|
|
|
void set_data( void* _data, int _step=CV_AUTOSTEP ) |
|
{ cvSetData( matrix, _data, _step ); } |
|
|
|
uchar* row(int i) { return !matrix ? 0 : matrix->data.ptr + i*matrix->step; } |
|
const uchar* row(int i) const |
|
{ return !matrix ? 0 : matrix->data.ptr + i*matrix->step; } |
|
|
|
operator const CvMat* () const { return matrix; } |
|
operator CvMat* () { return matrix; } |
|
|
|
CvMatrix& operator = (const CvMatrix& _m) |
|
{ |
|
_m.addref(); |
|
release(); |
|
matrix = _m.matrix; |
|
return *this; |
|
} |
|
|
|
protected: |
|
CvMat* matrix; |
|
}; |
|
|
|
/****************************************************************************************\ |
|
* CamShiftTracker * |
|
\****************************************************************************************/ |
|
|
|
class CV_EXPORTS CvCamShiftTracker |
|
{ |
|
public: |
|
|
|
CvCamShiftTracker(); |
|
virtual ~CvCamShiftTracker(); |
|
|
|
/**** Characteristics of the object that are calculated by track_object method *****/ |
|
float get_orientation() const // orientation of the object in degrees |
|
{ return m_box.angle; } |
|
float get_length() const // the larger linear size of the object |
|
{ return m_box.size.height; } |
|
float get_width() const // the smaller linear size of the object |
|
{ return m_box.size.width; } |
|
CvPoint2D32f get_center() const // center of the object |
|
{ return m_box.center; } |
|
CvRect get_window() const // bounding rectangle for the object |
|
{ return m_comp.rect; } |
|
|
|
/*********************** Tracking parameters ************************/ |
|
int get_threshold() const // thresholding value that applied to back project |
|
{ return m_threshold; } |
|
|
|
int get_hist_dims( int* dims = 0 ) const // returns number of histogram dimensions and sets |
|
{ return m_hist ? cvGetDims( m_hist->bins, dims ) : 0; } |
|
|
|
int get_min_ch_val( int channel ) const // get the minimum allowed value of the specified channel |
|
{ return m_min_ch_val[channel]; } |
|
|
|
int get_max_ch_val( int channel ) const // get the maximum allowed value of the specified channel |
|
{ return m_max_ch_val[channel]; } |
|
|
|
// set initial object rectangle (must be called before initial calculation of the histogram) |
|
bool set_window( CvRect window) |
|
{ m_comp.rect = window; return true; } |
|
|
|
bool set_threshold( int threshold ) // threshold applied to the histogram bins |
|
{ m_threshold = threshold; return true; } |
|
|
|
bool set_hist_bin_range( int dim, int min_val, int max_val ); |
|
|
|
bool set_hist_dims( int c_dims, int* dims );// set the histogram parameters |
|
|
|
bool set_min_ch_val( int channel, int val ) // set the minimum allowed value of the specified channel |
|
{ m_min_ch_val[channel] = val; return true; } |
|
bool set_max_ch_val( int channel, int val ) // set the maximum allowed value of the specified channel |
|
{ m_max_ch_val[channel] = val; return true; } |
|
|
|
/************************ The processing methods *********************************/ |
|
// update object position |
|
virtual bool track_object( const IplImage* cur_frame ); |
|
|
|
// update object histogram |
|
virtual bool update_histogram( const IplImage* cur_frame ); |
|
|
|
// reset histogram |
|
virtual void reset_histogram(); |
|
|
|
/************************ Retrieving internal data *******************************/ |
|
// get back project image |
|
virtual IplImage* get_back_project() |
|
{ return m_back_project; } |
|
|
|
float query( int* bin ) const |
|
{ return m_hist ? (float)cvGetRealND(m_hist->bins, bin) : 0.f; } |
|
|
|
protected: |
|
|
|
// internal method for color conversion: fills m_color_planes group |
|
virtual void color_transform( const IplImage* img ); |
|
|
|
CvHistogram* m_hist; |
|
|
|
CvBox2D m_box; |
|
CvConnectedComp m_comp; |
|
|
|
float m_hist_ranges_data[CV_MAX_DIM][2]; |
|
float* m_hist_ranges[CV_MAX_DIM]; |
|
|
|
int m_min_ch_val[CV_MAX_DIM]; |
|
int m_max_ch_val[CV_MAX_DIM]; |
|
int m_threshold; |
|
|
|
IplImage* m_color_planes[CV_MAX_DIM]; |
|
IplImage* m_back_project; |
|
IplImage* m_temp; |
|
IplImage* m_mask; |
|
}; |
|
|
|
/****************************************************************************************\ |
|
* Expectation - Maximization * |
|
\****************************************************************************************/ |
|
struct CV_EXPORTS_W_MAP CvEMParams |
|
{ |
|
CvEMParams(); |
|
CvEMParams( int nclusters, int cov_mat_type=cv::EM::COV_MAT_DIAGONAL, |
|
int start_step=cv::EM::START_AUTO_STEP, |
|
CvTermCriteria term_crit=cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, FLT_EPSILON), |
|
const CvMat* probs=0, const CvMat* weights=0, const CvMat* means=0, const CvMat** covs=0 ); |
|
|
|
CV_PROP_RW int nclusters; |
|
CV_PROP_RW int cov_mat_type; |
|
CV_PROP_RW int start_step; |
|
const CvMat* probs; |
|
const CvMat* weights; |
|
const CvMat* means; |
|
const CvMat** covs; |
|
CV_PROP_RW CvTermCriteria term_crit; |
|
}; |
|
|
|
|
|
class CV_EXPORTS_W CvEM : public CvStatModel |
|
{ |
|
public: |
|
// Type of covariation matrices |
|
enum { COV_MAT_SPHERICAL=cv::EM::COV_MAT_SPHERICAL, |
|
COV_MAT_DIAGONAL =cv::EM::COV_MAT_DIAGONAL, |
|
COV_MAT_GENERIC =cv::EM::COV_MAT_GENERIC }; |
|
|
|
// The initial step |
|
enum { START_E_STEP=cv::EM::START_E_STEP, |
|
START_M_STEP=cv::EM::START_M_STEP, |
|
START_AUTO_STEP=cv::EM::START_AUTO_STEP }; |
|
|
|
CV_WRAP CvEM(); |
|
CvEM( const CvMat* samples, const CvMat* sampleIdx=0, |
|
CvEMParams params=CvEMParams(), CvMat* labels=0 ); |
|
|
|
virtual ~CvEM(); |
|
|
|
virtual bool train( const CvMat* samples, const CvMat* sampleIdx=0, |
|
CvEMParams params=CvEMParams(), CvMat* labels=0 ); |
|
|
|
virtual float predict( const CvMat* sample, CV_OUT CvMat* probs ) const; |
|
|
|
CV_WRAP CvEM( const cv::Mat& samples, const cv::Mat& sampleIdx=cv::Mat(), |
|
CvEMParams params=CvEMParams() ); |
|
|
|
CV_WRAP virtual bool train( const cv::Mat& samples, |
|
const cv::Mat& sampleIdx=cv::Mat(), |
|
CvEMParams params=CvEMParams(), |
|
CV_OUT cv::Mat* labels=0 ); |
|
|
|
CV_WRAP virtual float predict( const cv::Mat& sample, CV_OUT cv::Mat* probs=0 ) const; |
|
CV_WRAP virtual double calcLikelihood( const cv::Mat &sample ) const; |
|
|
|
CV_WRAP int getNClusters() const; |
|
CV_WRAP cv::Mat getMeans() const; |
|
CV_WRAP void getCovs(CV_OUT std::vector<cv::Mat>& covs) const; |
|
CV_WRAP cv::Mat getWeights() const; |
|
CV_WRAP cv::Mat getProbs() const; |
|
|
|
CV_WRAP inline double getLikelihood() const { return emObj.isTrained() ? logLikelihood : DBL_MAX; } |
|
|
|
CV_WRAP virtual void clear(); |
|
|
|
int get_nclusters() const; |
|
const CvMat* get_means() const; |
|
const CvMat** get_covs() const; |
|
const CvMat* get_weights() const; |
|
const CvMat* get_probs() const; |
|
|
|
inline double get_log_likelihood() const { return getLikelihood(); } |
|
|
|
virtual void read( CvFileStorage* fs, CvFileNode* node ); |
|
virtual void write( CvFileStorage* fs, const char* name ) const; |
|
|
|
protected: |
|
void set_mat_hdrs(); |
|
|
|
cv::EM emObj; |
|
cv::Mat probs; |
|
double logLikelihood; |
|
|
|
CvMat meansHdr; |
|
std::vector<CvMat> covsHdrs; |
|
std::vector<CvMat*> covsPtrs; |
|
CvMat weightsHdr; |
|
CvMat probsHdr; |
|
}; |
|
|
|
namespace cv |
|
{ |
|
|
|
typedef CvEMParams EMParams; |
|
typedef CvEM ExpectationMaximization; |
|
|
|
/*! |
|
The Patch Generator class |
|
*/ |
|
class CV_EXPORTS PatchGenerator |
|
{ |
|
public: |
|
PatchGenerator(); |
|
PatchGenerator(double _backgroundMin, double _backgroundMax, |
|
double _noiseRange, bool _randomBlur=true, |
|
double _lambdaMin=0.6, double _lambdaMax=1.5, |
|
double _thetaMin=-CV_PI, double _thetaMax=CV_PI, |
|
double _phiMin=-CV_PI, double _phiMax=CV_PI ); |
|
void operator()(const Mat& image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const; |
|
void operator()(const Mat& image, const Mat& transform, Mat& patch, |
|
Size patchSize, RNG& rng) const; |
|
void warpWholeImage(const Mat& image, Mat& matT, Mat& buf, |
|
CV_OUT Mat& warped, int border, RNG& rng) const; |
|
void generateRandomTransform(Point2f srcCenter, Point2f dstCenter, |
|
CV_OUT Mat& transform, RNG& rng, |
|
bool inverse=false) const; |
|
void setAffineParam(double lambda, double theta, double phi); |
|
|
|
double backgroundMin, backgroundMax; |
|
double noiseRange; |
|
bool randomBlur; |
|
double lambdaMin, lambdaMax; |
|
double thetaMin, thetaMax; |
|
double phiMin, phiMax; |
|
}; |
|
|
|
|
|
class CV_EXPORTS LDetector |
|
{ |
|
public: |
|
LDetector(); |
|
LDetector(int _radius, int _threshold, int _nOctaves, |
|
int _nViews, double _baseFeatureSize, double _clusteringDistance); |
|
void operator()(const Mat& image, |
|
CV_OUT std::vector<KeyPoint>& keypoints, |
|
int maxCount=0, bool scaleCoords=true) const; |
|
void operator()(const std::vector<Mat>& pyr, |
|
CV_OUT std::vector<KeyPoint>& keypoints, |
|
int maxCount=0, bool scaleCoords=true) const; |
|
void getMostStable2D(const Mat& image, CV_OUT std::vector<KeyPoint>& keypoints, |
|
int maxCount, const PatchGenerator& patchGenerator) const; |
|
void setVerbose(bool verbose); |
|
|
|
void read(const FileNode& node); |
|
void write(FileStorage& fs, const std::string& name=std::string()) const; |
|
|
|
int radius; |
|
int threshold; |
|
int nOctaves; |
|
int nViews; |
|
bool verbose; |
|
|
|
double baseFeatureSize; |
|
double clusteringDistance; |
|
}; |
|
|
|
typedef LDetector YAPE; |
|
|
|
class CV_EXPORTS FernClassifier |
|
{ |
|
public: |
|
FernClassifier(); |
|
FernClassifier(const FileNode& node); |
|
FernClassifier(const std::vector<std::vector<Point2f> >& points, |
|
const std::vector<Mat>& refimgs, |
|
const std::vector<std::vector<int> >& labels=std::vector<std::vector<int> >(), |
|
int _nclasses=0, int _patchSize=PATCH_SIZE, |
|
int _signatureSize=DEFAULT_SIGNATURE_SIZE, |
|
int _nstructs=DEFAULT_STRUCTS, |
|
int _structSize=DEFAULT_STRUCT_SIZE, |
|
int _nviews=DEFAULT_VIEWS, |
|
int _compressionMethod=COMPRESSION_NONE, |
|
const PatchGenerator& patchGenerator=PatchGenerator()); |
|
virtual ~FernClassifier(); |
|
virtual void read(const FileNode& n); |
|
virtual void write(FileStorage& fs, const std::string& name=std::string()) const; |
|
virtual void trainFromSingleView(const Mat& image, |
|
const std::vector<KeyPoint>& keypoints, |
|
int _patchSize=PATCH_SIZE, |
|
int _signatureSize=DEFAULT_SIGNATURE_SIZE, |
|
int _nstructs=DEFAULT_STRUCTS, |
|
int _structSize=DEFAULT_STRUCT_SIZE, |
|
int _nviews=DEFAULT_VIEWS, |
|
int _compressionMethod=COMPRESSION_NONE, |
|
const PatchGenerator& patchGenerator=PatchGenerator()); |
|
virtual void train(const std::vector<std::vector<Point2f> >& points, |
|
const std::vector<Mat>& refimgs, |
|
const std::vector<std::vector<int> >& labels=std::vector<std::vector<int> >(), |
|
int _nclasses=0, int _patchSize=PATCH_SIZE, |
|
int _signatureSize=DEFAULT_SIGNATURE_SIZE, |
|
int _nstructs=DEFAULT_STRUCTS, |
|
int _structSize=DEFAULT_STRUCT_SIZE, |
|
int _nviews=DEFAULT_VIEWS, |
|
int _compressionMethod=COMPRESSION_NONE, |
|
const PatchGenerator& patchGenerator=PatchGenerator()); |
|
virtual int operator()(const Mat& img, Point2f kpt, std::vector<float>& signature) const; |
|
virtual int operator()(const Mat& patch, std::vector<float>& signature) const; |
|
virtual void clear(); |
|
virtual bool empty() const; |
|
void setVerbose(bool verbose); |
|
|
|
int getClassCount() const; |
|
int getStructCount() const; |
|
int getStructSize() const; |
|
int getSignatureSize() const; |
|
int getCompressionMethod() const; |
|
Size getPatchSize() const; |
|
|
|
struct Feature |
|
{ |
|
uchar x1, y1, x2, y2; |
|
Feature() : x1(0), y1(0), x2(0), y2(0) {} |
|
Feature(int _x1, int _y1, int _x2, int _y2) |
|
: x1((uchar)_x1), y1((uchar)_y1), x2((uchar)_x2), y2((uchar)_y2) |
|
{} |
|
template<typename _Tp> bool operator ()(const Mat_<_Tp>& patch) const |
|
{ return patch(y1,x1) > patch(y2, x2); } |
|
}; |
|
|
|
enum |
|
{ |
|
PATCH_SIZE = 31, |
|
DEFAULT_STRUCTS = 50, |
|
DEFAULT_STRUCT_SIZE = 9, |
|
DEFAULT_VIEWS = 5000, |
|
DEFAULT_SIGNATURE_SIZE = 176, |
|
COMPRESSION_NONE = 0, |
|
COMPRESSION_RANDOM_PROJ = 1, |
|
COMPRESSION_PCA = 2, |
|
DEFAULT_COMPRESSION_METHOD = COMPRESSION_NONE |
|
}; |
|
|
|
protected: |
|
virtual void prepare(int _nclasses, int _patchSize, int _signatureSize, |
|
int _nstructs, int _structSize, |
|
int _nviews, int _compressionMethod); |
|
virtual void finalize(RNG& rng); |
|
virtual int getLeaf(int fidx, const Mat& patch) const; |
|
|
|
bool verbose; |
|
int nstructs; |
|
int structSize; |
|
int nclasses; |
|
int signatureSize; |
|
int compressionMethod; |
|
int leavesPerStruct; |
|
Size patchSize; |
|
std::vector<Feature> features; |
|
std::vector<int> classCounters; |
|
std::vector<float> posteriors; |
|
}; |
|
|
|
|
|
/****************************************************************************************\ |
|
* Calonder Classifier * |
|
\****************************************************************************************/ |
|
|
|
struct RTreeNode; |
|
|
|
struct CV_EXPORTS BaseKeypoint |
|
{ |
|
int x; |
|
int y; |
|
IplImage* image; |
|
|
|
BaseKeypoint() |
|
: x(0), y(0), image(NULL) |
|
{} |
|
|
|
BaseKeypoint(int _x, int _y, IplImage* _image) |
|
: x(_x), y(_y), image(_image) |
|
{} |
|
}; |
|
|
|
class CV_EXPORTS RandomizedTree |
|
{ |
|
public: |
|
friend class RTreeClassifier; |
|
|
|
static const uchar PATCH_SIZE = 32; |
|
static const int DEFAULT_DEPTH = 9; |
|
static const int DEFAULT_VIEWS = 5000; |
|
static const size_t DEFAULT_REDUCED_NUM_DIM = 176; |
|
static float GET_LOWER_QUANT_PERC() { return .03f; } |
|
static float GET_UPPER_QUANT_PERC() { return .92f; } |
|
|
|
RandomizedTree(); |
|
~RandomizedTree(); |
|
|
|
void train(std::vector<BaseKeypoint> const& base_set, RNG &rng, |
|
int depth, int views, size_t reduced_num_dim, int num_quant_bits); |
|
void train(std::vector<BaseKeypoint> const& base_set, RNG &rng, |
|
PatchGenerator &make_patch, int depth, int views, size_t reduced_num_dim, |
|
int num_quant_bits); |
|
|
|
// following two funcs are EXPERIMENTAL (do not use unless you know exactly what you do) |
|
static void quantizeVector(float *vec, int dim, int N, float bnds[2], int clamp_mode=0); |
|
static void quantizeVector(float *src, int dim, int N, float bnds[2], uchar *dst); |
|
|
|
// patch_data must be a 32x32 array (no row padding) |
|
float* getPosterior(uchar* patch_data); |
|
const float* getPosterior(uchar* patch_data) const; |
|
uchar* getPosterior2(uchar* patch_data); |
|
const uchar* getPosterior2(uchar* patch_data) const; |
|
|
|
void read(const char* file_name, int num_quant_bits); |
|
void read(std::istream &is, int num_quant_bits); |
|
void write(const char* file_name) const; |
|
void write(std::ostream &os) const; |
|
|
|
int classes() { return classes_; } |
|
int depth() { return depth_; } |
|
|
|
//void setKeepFloatPosteriors(bool b) { keep_float_posteriors_ = b; } |
|
void discardFloatPosteriors() { freePosteriors(1); } |
|
|
|
inline void applyQuantization(int num_quant_bits) { makePosteriors2(num_quant_bits); } |
|
|
|
// debug |
|
void savePosteriors(std::string url, bool append=false); |
|
void savePosteriors2(std::string url, bool append=false); |
|
|
|
private: |
|
int classes_; |
|
int depth_; |
|
int num_leaves_; |
|
std::vector<RTreeNode> nodes_; |
|
float **posteriors_; // 16-bytes aligned posteriors |
|
uchar **posteriors2_; // 16-bytes aligned posteriors |
|
std::vector<int> leaf_counts_; |
|
|
|
void createNodes(int num_nodes, RNG &rng); |
|
void allocPosteriorsAligned(int num_leaves, int num_classes); |
|
void freePosteriors(int which); // which: 1=posteriors_, 2=posteriors2_, 3=both |
|
void init(int classes, int depth, RNG &rng); |
|
void addExample(int class_id, uchar* patch_data); |
|
void finalize(size_t reduced_num_dim, int num_quant_bits); |
|
int getIndex(uchar* patch_data) const; |
|
inline float* getPosteriorByIndex(int index); |
|
inline const float* getPosteriorByIndex(int index) const; |
|
inline uchar* getPosteriorByIndex2(int index); |
|
inline const uchar* getPosteriorByIndex2(int index) const; |
|
//void makeRandomMeasMatrix(float *cs_phi, PHI_DISTR_TYPE dt, size_t reduced_num_dim); |
|
void convertPosteriorsToChar(); |
|
void makePosteriors2(int num_quant_bits); |
|
void compressLeaves(size_t reduced_num_dim); |
|
void estimateQuantPercForPosteriors(float perc[2]); |
|
}; |
|
|
|
|
|
inline uchar* getData(IplImage* image) |
|
{ |
|
return reinterpret_cast<uchar*>(image->imageData); |
|
} |
|
|
|
inline float* RandomizedTree::getPosteriorByIndex(int index) |
|
{ |
|
return const_cast<float*>(const_cast<const RandomizedTree*>(this)->getPosteriorByIndex(index)); |
|
} |
|
|
|
inline const float* RandomizedTree::getPosteriorByIndex(int index) const |
|
{ |
|
return posteriors_[index]; |
|
} |
|
|
|
inline uchar* RandomizedTree::getPosteriorByIndex2(int index) |
|
{ |
|
return const_cast<uchar*>(const_cast<const RandomizedTree*>(this)->getPosteriorByIndex2(index)); |
|
} |
|
|
|
inline const uchar* RandomizedTree::getPosteriorByIndex2(int index) const |
|
{ |
|
return posteriors2_[index]; |
|
} |
|
|
|
struct CV_EXPORTS RTreeNode |
|
{ |
|
short offset1, offset2; |
|
|
|
RTreeNode() {} |
|
RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2) |
|
: offset1(y1*RandomizedTree::PATCH_SIZE + x1), |
|
offset2(y2*RandomizedTree::PATCH_SIZE + x2) |
|
{} |
|
|
|
//! Left child on 0, right child on 1 |
|
inline bool operator() (uchar* patch_data) const |
|
{ |
|
return patch_data[offset1] > patch_data[offset2]; |
|
} |
|
}; |
|
|
|
class CV_EXPORTS RTreeClassifier |
|
{ |
|
public: |
|
static const int DEFAULT_TREES = 48; |
|
static const size_t DEFAULT_NUM_QUANT_BITS = 4; |
|
|
|
RTreeClassifier(); |
|
void train(std::vector<BaseKeypoint> const& base_set, |
|
RNG &rng, |
|
int num_trees = RTreeClassifier::DEFAULT_TREES, |
|
int depth = RandomizedTree::DEFAULT_DEPTH, |
|
int views = RandomizedTree::DEFAULT_VIEWS, |
|
size_t reduced_num_dim = RandomizedTree::DEFAULT_REDUCED_NUM_DIM, |
|
int num_quant_bits = DEFAULT_NUM_QUANT_BITS); |
|
void train(std::vector<BaseKeypoint> const& base_set, |
|
RNG &rng, |
|
PatchGenerator &make_patch, |
|
int num_trees = RTreeClassifier::DEFAULT_TREES, |
|
int depth = RandomizedTree::DEFAULT_DEPTH, |
|
int views = RandomizedTree::DEFAULT_VIEWS, |
|
size_t reduced_num_dim = RandomizedTree::DEFAULT_REDUCED_NUM_DIM, |
|
int num_quant_bits = DEFAULT_NUM_QUANT_BITS); |
|
|
|
// sig must point to a memory block of at least classes()*sizeof(float|uchar) bytes |
|
void getSignature(IplImage *patch, uchar *sig) const; |
|
void getSignature(IplImage *patch, float *sig) const; |
|
void getSparseSignature(IplImage *patch, float *sig, float thresh) const; |
|
// TODO: deprecated in favor of getSignature overload, remove |
|
void getFloatSignature(IplImage *patch, float *sig) const { getSignature(patch, sig); } |
|
|
|
static int countNonZeroElements(float *vec, int n, double tol=1e-10); |
|
static inline void safeSignatureAlloc(uchar **sig, int num_sig=1, int sig_len=176); |
|
static inline uchar* safeSignatureAlloc(int num_sig=1, int sig_len=176); |
|
|
|
inline int classes() const { return classes_; } |
|
inline int original_num_classes() const { return original_num_classes_; } |
|
|
|
void setQuantization(int num_quant_bits); |
|
void discardFloatPosteriors(); |
|
|
|
void read(const char* file_name); |
|
void read(std::istream &is); |
|
void write(const char* file_name) const; |
|
void write(std::ostream &os) const; |
|
|
|
// experimental and debug |
|
void saveAllFloatPosteriors(std::string file_url); |
|
void saveAllBytePosteriors(std::string file_url); |
|
void setFloatPosteriorsFromTextfile_176(std::string url); |
|
float countZeroElements(); |
|
|
|
std::vector<RandomizedTree> trees_; |
|
|
|
private: |
|
int classes_; |
|
int num_quant_bits_; |
|
mutable uchar **posteriors_; |
|
mutable unsigned short *ptemp_; |
|
int original_num_classes_; |
|
bool keep_floats_; |
|
}; |
|
|
|
/****************************************************************************************\ |
|
* One-Way Descriptor * |
|
\****************************************************************************************/ |
|
|
|
// CvAffinePose: defines a parameterized affine transformation of an image patch. |
|
// An image patch is rotated on angle phi (in degrees), then scaled lambda1 times |
|
// along horizontal and lambda2 times along vertical direction, and then rotated again |
|
// on angle (theta - phi). |
|
class CV_EXPORTS CvAffinePose |
|
{ |
|
public: |
|
float phi; |
|
float theta; |
|
float lambda1; |
|
float lambda2; |
|
}; |
|
|
|
class CV_EXPORTS OneWayDescriptor |
|
{ |
|
public: |
|
OneWayDescriptor(); |
|
~OneWayDescriptor(); |
|
|
|
// allocates memory for given descriptor parameters |
|
void Allocate(int pose_count, CvSize size, int nChannels); |
|
|
|
// GenerateSamples: generates affine transformed patches with averaging them over small transformation variations. |
|
// If external poses and transforms were specified, uses them instead of generating random ones |
|
// - pose_count: the number of poses to be generated |
|
// - frontal: the input patch (can be a roi in a larger image) |
|
// - norm: if nonzero, normalizes the output patch so that the sum of pixel intensities is 1 |
|
void GenerateSamples(int pose_count, IplImage* frontal, int norm = 0); |
|
|
|
// GenerateSamplesFast: generates affine transformed patches with averaging them over small transformation variations. |
|
// Uses precalculated transformed pca components. |
|
// - frontal: the input patch (can be a roi in a larger image) |
|
// - pca_hr_avg: pca average vector |
|
// - pca_hr_eigenvectors: pca eigenvectors |
|
// - pca_descriptors: an array of precomputed descriptors of pca components containing their affine transformations |
|
// pca_descriptors[0] corresponds to the average, pca_descriptors[1]-pca_descriptors[pca_dim] correspond to eigenvectors |
|
void GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg, |
|
CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors); |
|
|
|
// sets the poses and corresponding transforms |
|
void SetTransforms(CvAffinePose* poses, CvMat** transforms); |
|
|
|
// Initialize: builds a descriptor. |
|
// - pose_count: the number of poses to build. If poses were set externally, uses them rather than generating random ones |
|
// - frontal: input patch. Can be a roi in a larger image |
|
// - feature_name: the feature name to be associated with the descriptor |
|
// - norm: if 1, the affine transformed patches are normalized so that their sum is 1 |
|
void Initialize(int pose_count, IplImage* frontal, const char* feature_name = 0, int norm = 0); |
|
|
|
// InitializeFast: builds a descriptor using precomputed descriptors of pca components |
|
// - pose_count: the number of poses to build |
|
// - frontal: input patch. Can be a roi in a larger image |
|
// - feature_name: the feature name to be associated with the descriptor |
|
// - pca_hr_avg: average vector for PCA |
|
// - pca_hr_eigenvectors: PCA eigenvectors (one vector per row) |
|
// - pca_descriptors: precomputed descriptors of PCA components, the first descriptor for the average vector |
|
// followed by the descriptors for eigenvectors |
|
void InitializeFast(int pose_count, IplImage* frontal, const char* feature_name, |
|
CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors); |
|
|
|
// ProjectPCASample: unwarps an image patch into a vector and projects it into PCA space |
|
// - patch: input image patch |
|
// - avg: PCA average vector |
|
// - eigenvectors: PCA eigenvectors, one per row |
|
// - pca_coeffs: output PCA coefficients |
|
void ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const; |
|
|
|
// InitializePCACoeffs: projects all warped patches into PCA space |
|
// - avg: PCA average vector |
|
// - eigenvectors: PCA eigenvectors, one per row |
|
void InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors); |
|
|
|
// EstimatePose: finds the closest match between an input patch and a set of patches with different poses |
|
// - patch: input image patch |
|
// - pose_idx: the output index of the closest pose |
|
// - distance: the distance to the closest pose (L2 distance) |
|
void EstimatePose(IplImage* patch, int& pose_idx, float& distance) const; |
|
|
|
// EstimatePosePCA: finds the closest match between an input patch and a set of patches with different poses. |
|
// The distance between patches is computed in PCA space |
|
// - patch: input image patch |
|
// - pose_idx: the output index of the closest pose |
|
// - distance: distance to the closest pose (L2 distance in PCA space) |
|
// - avg: PCA average vector. If 0, matching without PCA is used |
|
// - eigenvectors: PCA eigenvectors, one per row |
|
void EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvalues) const; |
|
|
|
// GetPatchSize: returns the size of each image patch after warping (2 times smaller than the input patch) |
|
CvSize GetPatchSize() const |
|
{ |
|
return m_patch_size; |
|
} |
|
|
|
// GetInputPatchSize: returns the required size of the patch that the descriptor is built from |
|
// (2 time larger than the patch after warping) |
|
CvSize GetInputPatchSize() const |
|
{ |
|
return cvSize(m_patch_size.width*2, m_patch_size.height*2); |
|
} |
|
|
|
// GetPatch: returns a patch corresponding to specified pose index |
|
// - index: pose index |
|
// - return value: the patch corresponding to specified pose index |
|
IplImage* GetPatch(int index); |
|
|
|
// GetPose: returns a pose corresponding to specified pose index |
|
// - index: pose index |
|
// - return value: the pose corresponding to specified pose index |
|
CvAffinePose GetPose(int index) const; |
|
|
|
// Save: saves all patches with different poses to a specified path |
|
void Save(const char* path); |
|
|
|
// ReadByName: reads a descriptor from a file storage |
|
// - fs: file storage |
|
// - parent: parent node |
|
// - name: node name |
|
// - return value: 1 if succeeded, 0 otherwise |
|
int ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name); |
|
|
|
// ReadByName: reads a descriptor from a file node |
|
// - parent: parent node |
|
// - name: node name |
|
// - return value: 1 if succeeded, 0 otherwise |
|
int ReadByName(const FileNode &parent, const char* name); |
|
|
|
// Write: writes a descriptor into a file storage |
|
// - fs: file storage |
|
// - name: node name |
|
void Write(CvFileStorage* fs, const char* name); |
|
|
|
// GetFeatureName: returns a name corresponding to a feature |
|
const char* GetFeatureName() const; |
|
|
|
// GetCenter: returns the center of the feature |
|
CvPoint GetCenter() const; |
|
|
|
void SetPCADimHigh(int pca_dim_high) {m_pca_dim_high = pca_dim_high;}; |
|
void SetPCADimLow(int pca_dim_low) {m_pca_dim_low = pca_dim_low;}; |
|
|
|
int GetPCADimLow() const; |
|
int GetPCADimHigh() const; |
|
|
|
CvMat** GetPCACoeffs() const {return m_pca_coeffs;} |
|
|
|
protected: |
|
int m_pose_count; // the number of poses |
|
CvSize m_patch_size; // size of each image |
|
IplImage** m_samples; // an array of length m_pose_count containing the patch in different poses |
|
IplImage* m_input_patch; |
|
IplImage* m_train_patch; |
|
CvMat** m_pca_coeffs; // an array of length m_pose_count containing pca decomposition of the patch in different poses |
|
CvAffinePose* m_affine_poses; // an array of poses |
|
CvMat** m_transforms; // an array of affine transforms corresponding to poses |
|
|
|
std::string m_feature_name; // the name of the feature associated with the descriptor |
|
CvPoint m_center; // the coordinates of the feature (the center of the input image ROI) |
|
|
|
int m_pca_dim_high; // the number of descriptor pca components to use for generating affine poses |
|
int m_pca_dim_low; // the number of pca components to use for comparison |
|
}; |
|
|
|
|
|
// OneWayDescriptorBase: encapsulates functionality for training/loading a set of one way descriptors |
|
// and finding the nearest closest descriptor to an input feature |
|
class CV_EXPORTS OneWayDescriptorBase |
|
{ |
|
public: |
|
|
|
// creates an instance of OneWayDescriptor from a set of training files |
|
// - patch_size: size of the input (large) patch |
|
// - pose_count: the number of poses to generate for each descriptor |
|
// - train_path: path to training files |
|
// - pca_config: the name of the file that contains PCA for small patches (2 times smaller |
|
// than patch_size each dimension |
|
// - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size) |
|
// - pca_desc_config: the name of the file that contains descriptors of PCA components |
|
OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path = 0, const char* pca_config = 0, |
|
const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1, |
|
int pca_dim_high = 100, int pca_dim_low = 100); |
|
|
|
OneWayDescriptorBase(CvSize patch_size, int pose_count, const std::string &pca_filename, const std::string &train_path = std::string(), const std::string &images_list = std::string(), |
|
float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1, |
|
int pca_dim_high = 100, int pca_dim_low = 100); |
|
|
|
|
|
virtual ~OneWayDescriptorBase(); |
|
void clear (); |
|
|
|
|
|
// Allocate: allocates memory for a given number of descriptors |
|
void Allocate(int train_feature_count); |
|
|
|
// AllocatePCADescriptors: allocates memory for pca descriptors |
|
void AllocatePCADescriptors(); |
|
|
|
// returns patch size |
|
CvSize GetPatchSize() const {return m_patch_size;}; |
|
// returns the number of poses for each descriptor |
|
int GetPoseCount() const {return m_pose_count;}; |
|
|
|
// returns the number of pyramid levels |
|
int GetPyrLevels() const {return m_pyr_levels;}; |
|
|
|
// returns the number of descriptors |
|
int GetDescriptorCount() const {return m_train_feature_count;}; |
|
|
|
// CreateDescriptorsFromImage: creates descriptors for each of the input features |
|
// - src: input image |
|
// - features: input features |
|
// - pyr_levels: the number of pyramid levels |
|
void CreateDescriptorsFromImage(IplImage* src, const std::vector<KeyPoint>& features); |
|
|
|
// CreatePCADescriptors: generates descriptors for PCA components, needed for fast generation of feature descriptors |
|
void CreatePCADescriptors(); |
|
|
|
// returns a feature descriptor by feature index |
|
const OneWayDescriptor* GetDescriptor(int desc_idx) const {return &m_descriptors[desc_idx];}; |
|
|
|
// FindDescriptor: finds the closest descriptor |
|
// - patch: input image patch |
|
// - desc_idx: output index of the closest descriptor to the input patch |
|
// - pose_idx: output index of the closest pose of the closest descriptor to the input patch |
|
// - distance: distance from the input patch to the closest feature pose |
|
// - _scales: scales of the input patch for each descriptor |
|
// - scale_ranges: input scales variation (float[2]) |
|
void FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance, float* _scale = 0, float* scale_ranges = 0) const; |
|
|
|
// - patch: input image patch |
|
// - n: number of the closest indexes |
|
// - desc_idxs: output indexes of the closest descriptor to the input patch (n) |
|
// - pose_idx: output indexes of the closest pose of the closest descriptor to the input patch (n) |
|
// - distances: distance from the input patch to the closest feature pose (n) |
|
// - _scales: scales of the input patch |
|
// - scale_ranges: input scales variation (float[2]) |
|
void FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs, |
|
std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges = 0) const; |
|
|
|
// FindDescriptor: finds the closest descriptor |
|
// - src: input image |
|
// - pt: center of the feature |
|
// - desc_idx: output index of the closest descriptor to the input patch |
|
// - pose_idx: output index of the closest pose of the closest descriptor to the input patch |
|
// - distance: distance from the input patch to the closest feature pose |
|
void FindDescriptor(IplImage* src, cv::Point2f pt, int& desc_idx, int& pose_idx, float& distance) const; |
|
|
|
// InitializePoses: generates random poses |
|
void InitializePoses(); |
|
|
|
// InitializeTransformsFromPoses: generates 2x3 affine matrices from poses (initializes m_transforms) |
|
void InitializeTransformsFromPoses(); |
|
|
|
// InitializePoseTransforms: subsequently calls InitializePoses and InitializeTransformsFromPoses |
|
void InitializePoseTransforms(); |
|
|
|
// InitializeDescriptor: initializes a descriptor |
|
// - desc_idx: descriptor index |
|
// - train_image: image patch (ROI is supported) |
|
// - feature_label: feature textual label |
|
void InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label); |
|
|
|
void InitializeDescriptor(int desc_idx, IplImage* train_image, const KeyPoint& keypoint, const char* feature_label); |
|
|
|
// InitializeDescriptors: load features from an image and create descriptors for each of them |
|
void InitializeDescriptors(IplImage* train_image, const std::vector<KeyPoint>& features, |
|
const char* feature_label = "", int desc_start_idx = 0); |
|
|
|
// Write: writes this object to a file storage |
|
// - fs: output filestorage |
|
void Write (FileStorage &fs) const; |
|
|
|
// Read: reads OneWayDescriptorBase object from a file node |
|
// - fn: input file node |
|
void Read (const FileNode &fn); |
|
|
|
// LoadPCADescriptors: loads PCA descriptors from a file |
|
// - filename: input filename |
|
int LoadPCADescriptors(const char* filename); |
|
|
|
// LoadPCADescriptors: loads PCA descriptors from a file node |
|
// - fn: input file node |
|
int LoadPCADescriptors(const FileNode &fn); |
|
|
|
// SavePCADescriptors: saves PCA descriptors to a file |
|
// - filename: output filename |
|
void SavePCADescriptors(const char* filename); |
|
|
|
// SavePCADescriptors: saves PCA descriptors to a file storage |
|
// - fs: output file storage |
|
void SavePCADescriptors(CvFileStorage* fs) const; |
|
|
|
// GeneratePCA: calculate and save PCA components and descriptors |
|
// - img_path: path to training PCA images directory |
|
// - images_list: filename with filenames of training PCA images |
|
void GeneratePCA(const char* img_path, const char* images_list, int pose_count=500); |
|
|
|
// SetPCAHigh: sets the high resolution pca matrices (copied to internal structures) |
|
void SetPCAHigh(CvMat* avg, CvMat* eigenvectors); |
|
|
|
// SetPCALow: sets the low resolution pca matrices (copied to internal structures) |
|
void SetPCALow(CvMat* avg, CvMat* eigenvectors); |
|
|
|
int GetLowPCA(CvMat** avg, CvMat** eigenvectors) |
|
{ |
|
*avg = m_pca_avg; |
|
*eigenvectors = m_pca_eigenvectors; |
|
return m_pca_dim_low; |
|
}; |
|
|
|
int GetPCADimLow() const {return m_pca_dim_low;}; |
|
int GetPCADimHigh() const {return m_pca_dim_high;}; |
|
|
|
void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree |
|
|
|
// GetPCAFilename: get default PCA filename |
|
static std::string GetPCAFilename () { return "pca.yml"; } |
|
|
|
virtual bool empty() const { return m_train_feature_count <= 0 ? true : false; } |
|
|
|
protected: |
|
CvSize m_patch_size; // patch size |
|
int m_pose_count; // the number of poses for each descriptor |
|
int m_train_feature_count; // the number of the training features |
|
OneWayDescriptor* m_descriptors; // array of train feature descriptors |
|
CvMat* m_pca_avg; // PCA average Vector for small patches |
|
CvMat* m_pca_eigenvectors; // PCA eigenvectors for small patches |
|
CvMat* m_pca_hr_avg; // PCA average Vector for large patches |
|
CvMat* m_pca_hr_eigenvectors; // PCA eigenvectors for large patches |
|
OneWayDescriptor* m_pca_descriptors; // an array of PCA descriptors |
|
|
|
cv::flann::Index* m_pca_descriptors_tree; |
|
CvMat* m_pca_descriptors_matrix; |
|
|
|
CvAffinePose* m_poses; // array of poses |
|
CvMat** m_transforms; // array of affine transformations corresponding to poses |
|
|
|
int m_pca_dim_high; |
|
int m_pca_dim_low; |
|
|
|
int m_pyr_levels; |
|
float scale_min; |
|
float scale_max; |
|
float scale_step; |
|
|
|
// SavePCAall: saves PCA components and descriptors to a file storage |
|
// - fs: output file storage |
|
void SavePCAall (FileStorage &fs) const; |
|
|
|
// LoadPCAall: loads PCA components and descriptors from a file node |
|
// - fn: input file node |
|
void LoadPCAall (const FileNode &fn); |
|
}; |
|
|
|
class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase |
|
{ |
|
public: |
|
// creates an instance of OneWayDescriptorObject from a set of training files |
|
// - patch_size: size of the input (large) patch |
|
// - pose_count: the number of poses to generate for each descriptor |
|
// - train_path: path to training files |
|
// - pca_config: the name of the file that contains PCA for small patches (2 times smaller |
|
// than patch_size each dimension |
|
// - pca_hr_config: the name of the file that contains PCA for large patches (of patch_size size) |
|
// - pca_desc_config: the name of the file that contains descriptors of PCA components |
|
OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config, |
|
const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1); |
|
|
|
OneWayDescriptorObject(CvSize patch_size, int pose_count, const std::string &pca_filename, |
|
const std::string &train_path = std::string (), const std::string &images_list = std::string (), |
|
float _scale_min = 0.7f, float _scale_max=1.5f, float _scale_step=1.2f, int pyr_levels = 1); |
|
|
|
|
|
virtual ~OneWayDescriptorObject(); |
|
|
|
// Allocate: allocates memory for a given number of features |
|
// - train_feature_count: the total number of features |
|
// - object_feature_count: the number of features extracted from the object |
|
void Allocate(int train_feature_count, int object_feature_count); |
|
|
|
|
|
void SetLabeledFeatures(const std::vector<KeyPoint>& features) {m_train_features = features;}; |
|
std::vector<KeyPoint>& GetLabeledFeatures() {return m_train_features;}; |
|
const std::vector<KeyPoint>& GetLabeledFeatures() const {return m_train_features;}; |
|
std::vector<KeyPoint> _GetLabeledFeatures() const; |
|
|
|
// IsDescriptorObject: returns 1 if descriptor with specified index is positive, otherwise 0 |
|
int IsDescriptorObject(int desc_idx) const; |
|
|
|
// MatchPointToPart: returns the part number of a feature if it matches one of the object parts, otherwise -1 |
|
int MatchPointToPart(CvPoint pt) const; |
|
|
|
// GetDescriptorPart: returns the part number of the feature corresponding to a specified descriptor |
|
// - desc_idx: descriptor index |
|
int GetDescriptorPart(int desc_idx) const; |
|
|
|
|
|
void InitializeObjectDescriptors(IplImage* train_image, const std::vector<KeyPoint>& features, |
|
const char* feature_label, int desc_start_idx = 0, float scale = 1.0f, |
|
int is_background = 0); |
|
|
|
// GetObjectFeatureCount: returns the number of object features |
|
int GetObjectFeatureCount() const {return m_object_feature_count;}; |
|
|
|
protected: |
|
int* m_part_id; // contains part id for each of object descriptors |
|
std::vector<KeyPoint> m_train_features; // train features |
|
int m_object_feature_count; // the number of the positive features |
|
|
|
}; |
|
|
|
|
|
/* |
|
* OneWayDescriptorMatcher |
|
*/ |
|
class OneWayDescriptorMatcher; |
|
typedef OneWayDescriptorMatcher OneWayDescriptorMatch; |
|
|
|
class CV_EXPORTS OneWayDescriptorMatcher : public GenericDescriptorMatcher |
|
{ |
|
public: |
|
class CV_EXPORTS Params |
|
{ |
|
public: |
|
static const int POSE_COUNT = 500; |
|
static const int PATCH_WIDTH = 24; |
|
static const int PATCH_HEIGHT = 24; |
|
static float GET_MIN_SCALE() { return 0.7f; } |
|
static float GET_MAX_SCALE() { return 1.5f; } |
|
static float GET_STEP_SCALE() { return 1.2f; } |
|
|
|
Params( int poseCount = POSE_COUNT, |
|
Size patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT), |
|
std::string pcaFilename = std::string(), |
|
std::string trainPath = std::string(), std::string trainImagesList = std::string(), |
|
float minScale = GET_MIN_SCALE(), float maxScale = GET_MAX_SCALE(), |
|
float stepScale = GET_STEP_SCALE() ); |
|
|
|
int poseCount; |
|
Size patchSize; |
|
std::string pcaFilename; |
|
std::string trainPath; |
|
std::string trainImagesList; |
|
|
|
float minScale, maxScale, stepScale; |
|
}; |
|
|
|
OneWayDescriptorMatcher( const Params& params=Params() ); |
|
virtual ~OneWayDescriptorMatcher(); |
|
|
|
void initialize( const Params& params, const Ptr<OneWayDescriptorBase>& base=Ptr<OneWayDescriptorBase>() ); |
|
|
|
// Clears keypoints storing in collection and OneWayDescriptorBase |
|
virtual void clear(); |
|
|
|
virtual void train(); |
|
|
|
virtual bool isMaskSupported(); |
|
|
|
virtual void read( const FileNode &fn ); |
|
virtual void write( FileStorage& fs ) const; |
|
|
|
virtual bool empty() const; |
|
|
|
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const; |
|
|
|
protected: |
|
// Matches a set of keypoints from a single image of the training set. A rectangle with a center in a keypoint |
|
// and size (patch_width/2*scale, patch_height/2*scale) is cropped from the source image for each |
|
// keypoint. scale is iterated from DescriptorOneWayParams::min_scale to DescriptorOneWayParams::max_scale. |
|
// The minimum distance to each training patch with all its affine poses is found over all scales. |
|
// The class ID of a match is returned for each keypoint. The distance is calculated over PCA components |
|
// loaded with DescriptorOneWay::Initialize, kd tree is used for finding minimum distances. |
|
virtual void knnMatchImpl( const Mat& queryImage, std::vector<KeyPoint>& queryKeypoints, |
|
std::vector<std::vector<DMatch> >& matches, int k, |
|
const std::vector<Mat>& masks, bool compactResult ); |
|
virtual void radiusMatchImpl( const Mat& queryImage, std::vector<KeyPoint>& queryKeypoints, |
|
std::vector<std::vector<DMatch> >& matches, float maxDistance, |
|
const std::vector<Mat>& masks, bool compactResult ); |
|
|
|
Ptr<OneWayDescriptorBase> base; |
|
Params params; |
|
int prevTrainCount; |
|
}; |
|
|
|
/* |
|
* FernDescriptorMatcher |
|
*/ |
|
class FernDescriptorMatcher; |
|
typedef FernDescriptorMatcher FernDescriptorMatch; |
|
|
|
class CV_EXPORTS FernDescriptorMatcher : public GenericDescriptorMatcher |
|
{ |
|
public: |
|
class CV_EXPORTS Params |
|
{ |
|
public: |
|
Params( int nclasses=0, |
|
int patchSize=FernClassifier::PATCH_SIZE, |
|
int signatureSize=FernClassifier::DEFAULT_SIGNATURE_SIZE, |
|
int nstructs=FernClassifier::DEFAULT_STRUCTS, |
|
int structSize=FernClassifier::DEFAULT_STRUCT_SIZE, |
|
int nviews=FernClassifier::DEFAULT_VIEWS, |
|
int compressionMethod=FernClassifier::COMPRESSION_NONE, |
|
const PatchGenerator& patchGenerator=PatchGenerator() ); |
|
|
|
Params( const std::string& filename ); |
|
|
|
int nclasses; |
|
int patchSize; |
|
int signatureSize; |
|
int nstructs; |
|
int structSize; |
|
int nviews; |
|
int compressionMethod; |
|
PatchGenerator patchGenerator; |
|
|
|
std::string filename; |
|
}; |
|
|
|
FernDescriptorMatcher( const Params& params=Params() ); |
|
virtual ~FernDescriptorMatcher(); |
|
|
|
virtual void clear(); |
|
|
|
virtual void train(); |
|
|
|
virtual bool isMaskSupported(); |
|
|
|
virtual void read( const FileNode &fn ); |
|
virtual void write( FileStorage& fs ) const; |
|
virtual bool empty() const; |
|
|
|
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const; |
|
|
|
protected: |
|
virtual void knnMatchImpl( const Mat& queryImage, std::vector<KeyPoint>& queryKeypoints, |
|
std::vector<std::vector<DMatch> >& matches, int k, |
|
const std::vector<Mat>& masks, bool compactResult ); |
|
virtual void radiusMatchImpl( const Mat& queryImage, std::vector<KeyPoint>& queryKeypoints, |
|
std::vector<std::vector<DMatch> >& matches, float maxDistance, |
|
const std::vector<Mat>& masks, bool compactResult ); |
|
|
|
void trainFernClassifier(); |
|
void calcBestProbAndMatchIdx( const Mat& image, const Point2f& pt, |
|
float& bestProb, int& bestMatchIdx, std::vector<float>& signature ); |
|
Ptr<FernClassifier> classifier; |
|
Params params; |
|
int prevTrainCount; |
|
}; |
|
|
|
|
|
/* |
|
* CalonderDescriptorExtractor |
|
*/ |
|
template<typename T> |
|
class CV_EXPORTS CalonderDescriptorExtractor : public DescriptorExtractor |
|
{ |
|
public: |
|
CalonderDescriptorExtractor( const std::string& classifierFile ); |
|
|
|
virtual void read( const FileNode &fn ); |
|
virtual void write( FileStorage &fs ) const; |
|
|
|
virtual int descriptorSize() const { return classifier_.classes(); } |
|
virtual int descriptorType() const { return DataType<T>::type; } |
|
|
|
virtual bool empty() const; |
|
|
|
protected: |
|
virtual void computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const; |
|
|
|
RTreeClassifier classifier_; |
|
static const int BORDER_SIZE = 16; |
|
}; |
|
|
|
template<typename T> |
|
CalonderDescriptorExtractor<T>::CalonderDescriptorExtractor(const std::string& classifier_file) |
|
{ |
|
classifier_.read( classifier_file.c_str() ); |
|
} |
|
|
|
template<typename T> |
|
void CalonderDescriptorExtractor<T>::computeImpl( const Mat& image, |
|
std::vector<KeyPoint>& keypoints, |
|
Mat& descriptors) const |
|
{ |
|
// Cannot compute descriptors for keypoints on the image border. |
|
KeyPointsFilter::runByImageBorder(keypoints, image.size(), BORDER_SIZE); |
|
|
|
/// @todo Check 16-byte aligned |
|
descriptors.create((int)keypoints.size(), classifier_.classes(), cv::DataType<T>::type); |
|
|
|
int patchSize = RandomizedTree::PATCH_SIZE; |
|
int offset = patchSize / 2; |
|
for (size_t i = 0; i < keypoints.size(); ++i) |
|
{ |
|
cv::Point2f pt = keypoints[i].pt; |
|
IplImage ipl = image( Rect((int)(pt.x - offset), (int)(pt.y - offset), patchSize, patchSize) ); |
|
classifier_.getSignature( &ipl, descriptors.ptr<T>((int)i)); |
|
} |
|
} |
|
|
|
template<typename T> |
|
void CalonderDescriptorExtractor<T>::read( const FileNode& ) |
|
{} |
|
|
|
template<typename T> |
|
void CalonderDescriptorExtractor<T>::write( FileStorage& ) const |
|
{} |
|
|
|
template<typename T> |
|
bool CalonderDescriptorExtractor<T>::empty() const |
|
{ |
|
return classifier_.trees_.empty(); |
|
} |
|
|
|
|
|
////////////////////// Brute Force Matcher ////////////////////////// |
|
|
|
template<class Distance> |
|
class CV_EXPORTS BruteForceMatcher : public BFMatcher |
|
{ |
|
public: |
|
BruteForceMatcher( Distance d = Distance() ) : BFMatcher(Distance::normType, false) {(void)d;} |
|
virtual ~BruteForceMatcher() {} |
|
}; |
|
|
|
|
|
/****************************************************************************************\ |
|
* Planar Object Detection * |
|
\****************************************************************************************/ |
|
|
|
class CV_EXPORTS PlanarObjectDetector |
|
{ |
|
public: |
|
PlanarObjectDetector(); |
|
PlanarObjectDetector(const FileNode& node); |
|
PlanarObjectDetector(const std::vector<Mat>& pyr, int _npoints=300, |
|
int _patchSize=FernClassifier::PATCH_SIZE, |
|
int _nstructs=FernClassifier::DEFAULT_STRUCTS, |
|
int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE, |
|
int _nviews=FernClassifier::DEFAULT_VIEWS, |
|
const LDetector& detector=LDetector(), |
|
const PatchGenerator& patchGenerator=PatchGenerator()); |
|
virtual ~PlanarObjectDetector(); |
|
virtual void train(const std::vector<Mat>& pyr, int _npoints=300, |
|
int _patchSize=FernClassifier::PATCH_SIZE, |
|
int _nstructs=FernClassifier::DEFAULT_STRUCTS, |
|
int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE, |
|
int _nviews=FernClassifier::DEFAULT_VIEWS, |
|
const LDetector& detector=LDetector(), |
|
const PatchGenerator& patchGenerator=PatchGenerator()); |
|
virtual void train(const std::vector<Mat>& pyr, const std::vector<KeyPoint>& keypoints, |
|
int _patchSize=FernClassifier::PATCH_SIZE, |
|
int _nstructs=FernClassifier::DEFAULT_STRUCTS, |
|
int _structSize=FernClassifier::DEFAULT_STRUCT_SIZE, |
|
int _nviews=FernClassifier::DEFAULT_VIEWS, |
|
const LDetector& detector=LDetector(), |
|
const PatchGenerator& patchGenerator=PatchGenerator()); |
|
Rect getModelROI() const; |
|
std::vector<KeyPoint> getModelPoints() const; |
|
const LDetector& getDetector() const; |
|
const FernClassifier& getClassifier() const; |
|
void setVerbose(bool verbose); |
|
|
|
void read(const FileNode& node); |
|
void write(FileStorage& fs, const std::string& name=std::string()) const; |
|
bool operator()(const Mat& image, CV_OUT Mat& H, CV_OUT std::vector<Point2f>& corners) const; |
|
bool operator()(const std::vector<Mat>& pyr, const std::vector<KeyPoint>& keypoints, |
|
CV_OUT Mat& H, CV_OUT std::vector<Point2f>& corners, |
|
CV_OUT std::vector<int>* pairs=0) const; |
|
|
|
protected: |
|
bool verbose; |
|
Rect modelROI; |
|
std::vector<KeyPoint> modelPoints; |
|
LDetector ldetector; |
|
FernClassifier fernClassifier; |
|
}; |
|
|
|
} |
|
|
|
// 2009-01-12, Xavier Delacour <xavier.delacour@gmail.com> |
|
|
|
struct lsh_hash { |
|
int h1, h2; |
|
}; |
|
|
|
struct CvLSHOperations |
|
{ |
|
virtual ~CvLSHOperations() {} |
|
|
|
virtual int vector_add(const void* data) = 0; |
|
virtual void vector_remove(int i) = 0; |
|
virtual const void* vector_lookup(int i) = 0; |
|
virtual void vector_reserve(int n) = 0; |
|
virtual unsigned int vector_count() = 0; |
|
|
|
virtual void hash_insert(lsh_hash h, int l, int i) = 0; |
|
virtual void hash_remove(lsh_hash h, int l, int i) = 0; |
|
virtual int hash_lookup(lsh_hash h, int l, int* ret_i, int ret_i_max) = 0; |
|
}; |
|
|
|
#endif |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
/* Splits color or grayscale image into multiple connected components |
|
of nearly the same color/brightness using modification of Burt algorithm. |
|
comp with contain a pointer to sequence (CvSeq) |
|
of connected components (CvConnectedComp) */ |
|
CVAPI(void) cvPyrSegmentation( IplImage* src, IplImage* dst, |
|
CvMemStorage* storage, CvSeq** comp, |
|
int level, double threshold1, |
|
double threshold2 ); |
|
|
|
/****************************************************************************************\ |
|
* Planar subdivisions * |
|
\****************************************************************************************/ |
|
|
|
typedef size_t CvSubdiv2DEdge; |
|
|
|
#define CV_QUADEDGE2D_FIELDS() \ |
|
int flags; \ |
|
struct CvSubdiv2DPoint* pt[4]; \ |
|
CvSubdiv2DEdge next[4]; |
|
|
|
#define CV_SUBDIV2D_POINT_FIELDS()\ |
|
int flags; \ |
|
CvSubdiv2DEdge first; \ |
|
CvPoint2D32f pt; \ |
|
int id; |
|
|
|
#define CV_SUBDIV2D_VIRTUAL_POINT_FLAG (1 << 30) |
|
|
|
typedef struct CvQuadEdge2D |
|
{ |
|
CV_QUADEDGE2D_FIELDS() |
|
} |
|
CvQuadEdge2D; |
|
|
|
typedef struct CvSubdiv2DPoint |
|
{ |
|
CV_SUBDIV2D_POINT_FIELDS() |
|
} |
|
CvSubdiv2DPoint; |
|
|
|
#define CV_SUBDIV2D_FIELDS() \ |
|
CV_GRAPH_FIELDS() \ |
|
int quad_edges; \ |
|
int is_geometry_valid; \ |
|
CvSubdiv2DEdge recent_edge; \ |
|
CvPoint2D32f topleft; \ |
|
CvPoint2D32f bottomright; |
|
|
|
typedef struct CvSubdiv2D |
|
{ |
|
CV_SUBDIV2D_FIELDS() |
|
} |
|
CvSubdiv2D; |
|
|
|
typedef enum CvSubdiv2DPointLocation |
|
{ |
|
CV_PTLOC_ERROR = -2, |
|
CV_PTLOC_OUTSIDE_RECT = -1, |
|
CV_PTLOC_INSIDE = 0, |
|
CV_PTLOC_VERTEX = 1, |
|
CV_PTLOC_ON_EDGE = 2 |
|
} |
|
CvSubdiv2DPointLocation; |
|
|
|
typedef enum CvNextEdgeType |
|
{ |
|
CV_NEXT_AROUND_ORG = 0x00, |
|
CV_NEXT_AROUND_DST = 0x22, |
|
CV_PREV_AROUND_ORG = 0x11, |
|
CV_PREV_AROUND_DST = 0x33, |
|
CV_NEXT_AROUND_LEFT = 0x13, |
|
CV_NEXT_AROUND_RIGHT = 0x31, |
|
CV_PREV_AROUND_LEFT = 0x20, |
|
CV_PREV_AROUND_RIGHT = 0x02 |
|
} |
|
CvNextEdgeType; |
|
|
|
/* get the next edge with the same origin point (counterwise) */ |
|
#define CV_SUBDIV2D_NEXT_EDGE( edge ) (((CvQuadEdge2D*)((edge) & ~3))->next[(edge)&3]) |
|
|
|
|
|
/* Initializes Delaunay triangulation */ |
|
CVAPI(void) cvInitSubdivDelaunay2D( CvSubdiv2D* subdiv, CvRect rect ); |
|
|
|
/* Creates new subdivision */ |
|
CVAPI(CvSubdiv2D*) cvCreateSubdiv2D( int subdiv_type, int header_size, |
|
int vtx_size, int quadedge_size, |
|
CvMemStorage* storage ); |
|
|
|
/************************* high-level subdivision functions ***************************/ |
|
|
|
/* Simplified Delaunay diagram creation */ |
|
CV_INLINE CvSubdiv2D* cvCreateSubdivDelaunay2D( CvRect rect, CvMemStorage* storage ) |
|
{ |
|
CvSubdiv2D* subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D, sizeof(*subdiv), |
|
sizeof(CvSubdiv2DPoint), sizeof(CvQuadEdge2D), storage ); |
|
|
|
cvInitSubdivDelaunay2D( subdiv, rect ); |
|
return subdiv; |
|
} |
|
|
|
|
|
/* Inserts new point to the Delaunay triangulation */ |
|
CVAPI(CvSubdiv2DPoint*) cvSubdivDelaunay2DInsert( CvSubdiv2D* subdiv, CvPoint2D32f pt); |
|
|
|
/* Locates a point within the Delaunay triangulation (finds the edge |
|
the point is left to or belongs to, or the triangulation point the given |
|
point coinsides with */ |
|
CVAPI(CvSubdiv2DPointLocation) cvSubdiv2DLocate( |
|
CvSubdiv2D* subdiv, CvPoint2D32f pt, |
|
CvSubdiv2DEdge* edge, |
|
CvSubdiv2DPoint** vertex CV_DEFAULT(NULL) ); |
|
|
|
/* Calculates Voronoi tesselation (i.e. coordinates of Voronoi points) */ |
|
CVAPI(void) cvCalcSubdivVoronoi2D( CvSubdiv2D* subdiv ); |
|
|
|
|
|
/* Removes all Voronoi points from the tesselation */ |
|
CVAPI(void) cvClearSubdivVoronoi2D( CvSubdiv2D* subdiv ); |
|
|
|
|
|
/* Finds the nearest to the given point vertex in subdivision. */ |
|
CVAPI(CvSubdiv2DPoint*) cvFindNearestPoint2D( CvSubdiv2D* subdiv, CvPoint2D32f pt ); |
|
|
|
|
|
/************ Basic quad-edge navigation and operations ************/ |
|
|
|
CV_INLINE CvSubdiv2DEdge cvSubdiv2DNextEdge( CvSubdiv2DEdge edge ) |
|
{ |
|
return CV_SUBDIV2D_NEXT_EDGE(edge); |
|
} |
|
|
|
|
|
CV_INLINE CvSubdiv2DEdge cvSubdiv2DRotateEdge( CvSubdiv2DEdge edge, int rotate ) |
|
{ |
|
return (edge & ~3) + ((edge + rotate) & 3); |
|
} |
|
|
|
CV_INLINE CvSubdiv2DEdge cvSubdiv2DSymEdge( CvSubdiv2DEdge edge ) |
|
{ |
|
return edge ^ 2; |
|
} |
|
|
|
CV_INLINE CvSubdiv2DEdge cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type ) |
|
{ |
|
CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3); |
|
edge = e->next[(edge + (int)type) & 3]; |
|
return (edge & ~3) + ((edge + ((int)type >> 4)) & 3); |
|
} |
|
|
|
|
|
CV_INLINE CvSubdiv2DPoint* cvSubdiv2DEdgeOrg( CvSubdiv2DEdge edge ) |
|
{ |
|
CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3); |
|
return (CvSubdiv2DPoint*)e->pt[edge & 3]; |
|
} |
|
|
|
|
|
CV_INLINE CvSubdiv2DPoint* cvSubdiv2DEdgeDst( CvSubdiv2DEdge edge ) |
|
{ |
|
CvQuadEdge2D* e = (CvQuadEdge2D*)(edge & ~3); |
|
return (CvSubdiv2DPoint*)e->pt[(edge + 2) & 3]; |
|
} |
|
|
|
/****************************************************************************************\ |
|
* Additional operations on Subdivisions * |
|
\****************************************************************************************/ |
|
|
|
// paints voronoi diagram: just demo function |
|
CVAPI(void) icvDrawMosaic( CvSubdiv2D* subdiv, IplImage* src, IplImage* dst ); |
|
|
|
// checks planar subdivision for correctness. It is not an absolute check, |
|
// but it verifies some relations between quad-edges |
|
CVAPI(int) icvSubdiv2DCheck( CvSubdiv2D* subdiv ); |
|
|
|
// returns squared distance between two 2D points with floating-point coordinates. |
|
CV_INLINE double icvSqDist2D32f( CvPoint2D32f pt1, CvPoint2D32f pt2 ) |
|
{ |
|
double dx = pt1.x - pt2.x; |
|
double dy = pt1.y - pt2.y; |
|
|
|
return dx*dx + dy*dy; |
|
} |
|
|
|
|
|
|
|
|
|
CV_INLINE double cvTriangleArea( CvPoint2D32f a, CvPoint2D32f b, CvPoint2D32f c ) |
|
{ |
|
return ((double)b.x - a.x) * ((double)c.y - a.y) - ((double)b.y - a.y) * ((double)c.x - a.x); |
|
} |
|
|
|
|
|
/* Constructs kd-tree from set of feature descriptors */ |
|
CVAPI(struct CvFeatureTree*) cvCreateKDTree(CvMat* desc); |
|
|
|
/* Constructs spill-tree from set of feature descriptors */ |
|
CVAPI(struct CvFeatureTree*) cvCreateSpillTree( const CvMat* raw_data, |
|
const int naive CV_DEFAULT(50), |
|
const double rho CV_DEFAULT(.7), |
|
const double tau CV_DEFAULT(.1) ); |
|
|
|
/* Release feature tree */ |
|
CVAPI(void) cvReleaseFeatureTree(struct CvFeatureTree* tr); |
|
|
|
/* Searches feature tree for k nearest neighbors of given reference points, |
|
searching (in case of kd-tree/bbf) at most emax leaves. */ |
|
CVAPI(void) cvFindFeatures(struct CvFeatureTree* tr, const CvMat* query_points, |
|
CvMat* indices, CvMat* dist, int k, int emax CV_DEFAULT(20)); |
|
|
|
/* Search feature tree for all points that are inlier to given rect region. |
|
Only implemented for kd trees */ |
|
CVAPI(int) cvFindFeaturesBoxed(struct CvFeatureTree* tr, |
|
CvMat* bounds_min, CvMat* bounds_max, |
|
CvMat* out_indices); |
|
|
|
|
|
/* Construct a Locality Sensitive Hash (LSH) table, for indexing d-dimensional vectors of |
|
given type. Vectors will be hashed L times with k-dimensional p-stable (p=2) functions. */ |
|
CVAPI(struct CvLSH*) cvCreateLSH(struct CvLSHOperations* ops, int d, |
|
int L CV_DEFAULT(10), int k CV_DEFAULT(10), |
|
int type CV_DEFAULT(CV_64FC1), double r CV_DEFAULT(4), |
|
int64 seed CV_DEFAULT(-1)); |
|
|
|
/* Construct in-memory LSH table, with n bins. */ |
|
CVAPI(struct CvLSH*) cvCreateMemoryLSH(int d, int n, int L CV_DEFAULT(10), int k CV_DEFAULT(10), |
|
int type CV_DEFAULT(CV_64FC1), double r CV_DEFAULT(4), |
|
int64 seed CV_DEFAULT(-1)); |
|
|
|
/* Free the given LSH structure. */ |
|
CVAPI(void) cvReleaseLSH(struct CvLSH** lsh); |
|
|
|
/* Return the number of vectors in the LSH. */ |
|
CVAPI(unsigned int) LSHSize(struct CvLSH* lsh); |
|
|
|
/* Add vectors to the LSH structure, optionally returning indices. */ |
|
CVAPI(void) cvLSHAdd(struct CvLSH* lsh, const CvMat* data, CvMat* indices CV_DEFAULT(0)); |
|
|
|
/* Remove vectors from LSH, as addressed by given indices. */ |
|
CVAPI(void) cvLSHRemove(struct CvLSH* lsh, const CvMat* indices); |
|
|
|
/* Query the LSH n times for at most k nearest points; data is n x d, |
|
indices and dist are n x k. At most emax stored points will be accessed. */ |
|
CVAPI(void) cvLSHQuery(struct CvLSH* lsh, const CvMat* query_points, |
|
CvMat* indices, CvMat* dist, int k, int emax); |
|
|
|
/* Kolmogorov-Zabin stereo-correspondence algorithm (a.k.a. KZ1) */ |
|
#define CV_STEREO_GC_OCCLUDED SHRT_MAX |
|
|
|
typedef struct CvStereoGCState |
|
{ |
|
int Ithreshold; |
|
int interactionRadius; |
|
float K, lambda, lambda1, lambda2; |
|
int occlusionCost; |
|
int minDisparity; |
|
int numberOfDisparities; |
|
int maxIters; |
|
|
|
CvMat* left; |
|
CvMat* right; |
|
CvMat* dispLeft; |
|
CvMat* dispRight; |
|
CvMat* ptrLeft; |
|
CvMat* ptrRight; |
|
CvMat* vtxBuf; |
|
CvMat* edgeBuf; |
|
} CvStereoGCState; |
|
|
|
CVAPI(CvStereoGCState*) cvCreateStereoGCState( int numberOfDisparities, int maxIters ); |
|
CVAPI(void) cvReleaseStereoGCState( CvStereoGCState** state ); |
|
|
|
CVAPI(void) cvFindStereoCorrespondenceGC( const CvArr* left, const CvArr* right, |
|
CvArr* disparityLeft, CvArr* disparityRight, |
|
CvStereoGCState* state, |
|
int useDisparityGuess CV_DEFAULT(0) ); |
|
|
|
/* Calculates optical flow for 2 images using classical Lucas & Kanade algorithm */ |
|
CVAPI(void) cvCalcOpticalFlowLK( const CvArr* prev, const CvArr* curr, |
|
CvSize win_size, CvArr* velx, CvArr* vely ); |
|
|
|
/* Calculates optical flow for 2 images using block matching algorithm */ |
|
CVAPI(void) cvCalcOpticalFlowBM( const CvArr* prev, const CvArr* curr, |
|
CvSize block_size, CvSize shift_size, |
|
CvSize max_range, int use_previous, |
|
CvArr* velx, CvArr* vely ); |
|
|
|
/* Calculates Optical flow for 2 images using Horn & Schunck algorithm */ |
|
CVAPI(void) cvCalcOpticalFlowHS( const CvArr* prev, const CvArr* curr, |
|
int use_previous, CvArr* velx, CvArr* vely, |
|
double lambda, CvTermCriteria criteria ); |
|
|
|
|
|
/****************************************************************************************\ |
|
* Background/foreground segmentation * |
|
\****************************************************************************************/ |
|
|
|
/* We discriminate between foreground and background pixels |
|
* by building and maintaining a model of the background. |
|
* Any pixel which does not fit this model is then deemed |
|
* to be foreground. |
|
* |
|
* At present we support two core background models, |
|
* one of which has two variations: |
|
* |
|
* o CV_BG_MODEL_FGD: latest and greatest algorithm, described in |
|
* |
|
* Foreground Object Detection from Videos Containing Complex Background. |
|
* Liyuan Li, Weimin Huang, Irene Y.H. Gu, and Qi Tian. |
|
* ACM MM2003 9p |
|
* |
|
* o CV_BG_MODEL_FGD_SIMPLE: |
|
* A code comment describes this as a simplified version of the above, |
|
* but the code is in fact currently identical |
|
* |
|
* o CV_BG_MODEL_MOG: "Mixture of Gaussians", older algorithm, described in |
|
* |
|
* Moving target classification and tracking from real-time video. |
|
* A Lipton, H Fujijoshi, R Patil |
|
* Proceedings IEEE Workshop on Application of Computer Vision pp 8-14 1998 |
|
* |
|
* Learning patterns of activity using real-time tracking |
|
* C Stauffer and W Grimson August 2000 |
|
* IEEE Transactions on Pattern Analysis and Machine Intelligence 22(8):747-757 |
|
*/ |
|
|
|
|
|
#define CV_BG_MODEL_FGD 0 |
|
#define CV_BG_MODEL_MOG 1 /* "Mixture of Gaussians". */ |
|
#define CV_BG_MODEL_FGD_SIMPLE 2 |
|
|
|
struct CvBGStatModel; |
|
|
|
typedef void (CV_CDECL * CvReleaseBGStatModel)( struct CvBGStatModel** bg_model ); |
|
typedef int (CV_CDECL * CvUpdateBGStatModel)( IplImage* curr_frame, struct CvBGStatModel* bg_model, |
|
double learningRate ); |
|
|
|
#define CV_BG_STAT_MODEL_FIELDS() \ |
|
int type; /*type of BG model*/ \ |
|
CvReleaseBGStatModel release; \ |
|
CvUpdateBGStatModel update; \ |
|
IplImage* background; /*8UC3 reference background image*/ \ |
|
IplImage* foreground; /*8UC1 foreground image*/ \ |
|
IplImage** layers; /*8UC3 reference background image, can be null */ \ |
|
int layer_count; /* can be zero */ \ |
|
CvMemStorage* storage; /*storage for foreground_regions*/ \ |
|
CvSeq* foreground_regions /*foreground object contours*/ |
|
|
|
typedef struct CvBGStatModel |
|
{ |
|
CV_BG_STAT_MODEL_FIELDS(); |
|
} CvBGStatModel; |
|
|
|
// |
|
|
|
// Releases memory used by BGStatModel |
|
CVAPI(void) cvReleaseBGStatModel( CvBGStatModel** bg_model ); |
|
|
|
// Updates statistical model and returns number of found foreground regions |
|
CVAPI(int) cvUpdateBGStatModel( IplImage* current_frame, CvBGStatModel* bg_model, |
|
double learningRate CV_DEFAULT(-1)); |
|
|
|
// Performs FG post-processing using segmentation |
|
// (all pixels of a region will be classified as foreground if majority of pixels of the region are FG). |
|
// parameters: |
|
// segments - pointer to result of segmentation (for example MeanShiftSegmentation) |
|
// bg_model - pointer to CvBGStatModel structure |
|
CVAPI(void) cvRefineForegroundMaskBySegm( CvSeq* segments, CvBGStatModel* bg_model ); |
|
|
|
/* Common use change detection function */ |
|
CVAPI(int) cvChangeDetection( IplImage* prev_frame, |
|
IplImage* curr_frame, |
|
IplImage* change_mask ); |
|
|
|
/* |
|
Interface of ACM MM2003 algorithm |
|
*/ |
|
|
|
/* Default parameters of foreground detection algorithm: */ |
|
#define CV_BGFG_FGD_LC 128 |
|
#define CV_BGFG_FGD_N1C 15 |
|
#define CV_BGFG_FGD_N2C 25 |
|
|
|
#define CV_BGFG_FGD_LCC 64 |
|
#define CV_BGFG_FGD_N1CC 25 |
|
#define CV_BGFG_FGD_N2CC 40 |
|
|
|
/* Background reference image update parameter: */ |
|
#define CV_BGFG_FGD_ALPHA_1 0.1f |
|
|
|
/* stat model update parameter |
|
* 0.002f ~ 1K frame(~45sec), 0.005 ~ 18sec (if 25fps and absolutely static BG) |
|
*/ |
|
#define CV_BGFG_FGD_ALPHA_2 0.005f |
|
|
|
/* start value for alpha parameter (to fast initiate statistic model) */ |
|
#define CV_BGFG_FGD_ALPHA_3 0.1f |
|
|
|
#define CV_BGFG_FGD_DELTA 2 |
|
|
|
#define CV_BGFG_FGD_T 0.9f |
|
|
|
#define CV_BGFG_FGD_MINAREA 15.f |
|
|
|
#define CV_BGFG_FGD_BG_UPDATE_TRESH 0.5f |
|
|
|
/* See the above-referenced Li/Huang/Gu/Tian paper |
|
* for a full description of these background-model |
|
* tuning parameters. |
|
* |
|
* Nomenclature: 'c' == "color", a three-component red/green/blue vector. |
|
* We use histograms of these to model the range of |
|
* colors we've seen at a given background pixel. |
|
* |
|
* 'cc' == "color co-occurrence", a six-component vector giving |
|
* RGB color for both this frame and preceding frame. |
|
* We use histograms of these to model the range of |
|
* color CHANGES we've seen at a given background pixel. |
|
*/ |
|
typedef struct CvFGDStatModelParams |
|
{ |
|
int Lc; /* Quantized levels per 'color' component. Power of two, typically 32, 64 or 128. */ |
|
int N1c; /* Number of color vectors used to model normal background color variation at a given pixel. */ |
|
int N2c; /* Number of color vectors retained at given pixel. Must be > N1c, typically ~ 5/3 of N1c. */ |
|
/* Used to allow the first N1c vectors to adapt over time to changing background. */ |
|
|
|
int Lcc; /* Quantized levels per 'color co-occurrence' component. Power of two, typically 16, 32 or 64. */ |
|
int N1cc; /* Number of color co-occurrence vectors used to model normal background color variation at a given pixel. */ |
|
int N2cc; /* Number of color co-occurrence vectors retained at given pixel. Must be > N1cc, typically ~ 5/3 of N1cc. */ |
|
/* Used to allow the first N1cc vectors to adapt over time to changing background. */ |
|
|
|
int is_obj_without_holes;/* If TRUE we ignore holes within foreground blobs. Defaults to TRUE. */ |
|
int perform_morphing; /* Number of erode-dilate-erode foreground-blob cleanup iterations. */ |
|
/* These erase one-pixel junk blobs and merge almost-touching blobs. Default value is 1. */ |
|
|
|
float alpha1; /* How quickly we forget old background pixel values seen. Typically set to 0.1 */ |
|
float alpha2; /* "Controls speed of feature learning". Depends on T. Typical value circa 0.005. */ |
|
float alpha3; /* Alternate to alpha2, used (e.g.) for quicker initial convergence. Typical value 0.1. */ |
|
|
|
float delta; /* Affects color and color co-occurrence quantization, typically set to 2. */ |
|
float T; /* "A percentage value which determines when new features can be recognized as new background." (Typically 0.9).*/ |
|
float minArea; /* Discard foreground blobs whose bounding box is smaller than this threshold. */ |
|
} CvFGDStatModelParams; |
|
|
|
typedef struct CvBGPixelCStatTable |
|
{ |
|
float Pv, Pvb; |
|
uchar v[3]; |
|
} CvBGPixelCStatTable; |
|
|
|
typedef struct CvBGPixelCCStatTable |
|
{ |
|
float Pv, Pvb; |
|
uchar v[6]; |
|
} CvBGPixelCCStatTable; |
|
|
|
typedef struct CvBGPixelStat |
|
{ |
|
float Pbc; |
|
float Pbcc; |
|
CvBGPixelCStatTable* ctable; |
|
CvBGPixelCCStatTable* cctable; |
|
uchar is_trained_st_model; |
|
uchar is_trained_dyn_model; |
|
} CvBGPixelStat; |
|
|
|
|
|
typedef struct CvFGDStatModel |
|
{ |
|
CV_BG_STAT_MODEL_FIELDS(); |
|
CvBGPixelStat* pixel_stat; |
|
IplImage* Ftd; |
|
IplImage* Fbd; |
|
IplImage* prev_frame; |
|
CvFGDStatModelParams params; |
|
} CvFGDStatModel; |
|
|
|
/* Creates FGD model */ |
|
CVAPI(CvBGStatModel*) cvCreateFGDStatModel( IplImage* first_frame, |
|
CvFGDStatModelParams* parameters CV_DEFAULT(NULL)); |
|
|
|
/* |
|
Interface of Gaussian mixture algorithm |
|
|
|
"An improved adaptive background mixture model for real-time tracking with shadow detection" |
|
P. KadewTraKuPong and R. Bowden, |
|
Proc. 2nd European Workshp on Advanced Video-Based Surveillance Systems, 2001." |
|
http://personal.ee.surrey.ac.uk/Personal/R.Bowden/publications/avbs01/avbs01.pdf |
|
*/ |
|
|
|
/* Note: "MOG" == "Mixture Of Gaussians": */ |
|
|
|
#define CV_BGFG_MOG_MAX_NGAUSSIANS 500 |
|
|
|
/* default parameters of gaussian background detection algorithm */ |
|
#define CV_BGFG_MOG_BACKGROUND_THRESHOLD 0.7 /* threshold sum of weights for background test */ |
|
#define CV_BGFG_MOG_STD_THRESHOLD 2.5 /* lambda=2.5 is 99% */ |
|
#define CV_BGFG_MOG_WINDOW_SIZE 200 /* Learning rate; alpha = 1/CV_GBG_WINDOW_SIZE */ |
|
#define CV_BGFG_MOG_NGAUSSIANS 5 /* = K = number of Gaussians in mixture */ |
|
#define CV_BGFG_MOG_WEIGHT_INIT 0.05 |
|
#define CV_BGFG_MOG_SIGMA_INIT 30 |
|
#define CV_BGFG_MOG_MINAREA 15.f |
|
|
|
|
|
#define CV_BGFG_MOG_NCOLORS 3 |
|
|
|
typedef struct CvGaussBGStatModelParams |
|
{ |
|
int win_size; /* = 1/alpha */ |
|
int n_gauss; |
|
double bg_threshold, std_threshold, minArea; |
|
double weight_init, variance_init; |
|
}CvGaussBGStatModelParams; |
|
|
|
typedef struct CvGaussBGValues |
|
{ |
|
int match_sum; |
|
double weight; |
|
double variance[CV_BGFG_MOG_NCOLORS]; |
|
double mean[CV_BGFG_MOG_NCOLORS]; |
|
} CvGaussBGValues; |
|
|
|
typedef struct CvGaussBGPoint |
|
{ |
|
CvGaussBGValues* g_values; |
|
} CvGaussBGPoint; |
|
|
|
|
|
typedef struct CvGaussBGModel |
|
{ |
|
CV_BG_STAT_MODEL_FIELDS(); |
|
CvGaussBGStatModelParams params; |
|
CvGaussBGPoint* g_point; |
|
int countFrames; |
|
void* mog; |
|
} CvGaussBGModel; |
|
|
|
|
|
/* Creates Gaussian mixture background model */ |
|
CVAPI(CvBGStatModel*) cvCreateGaussianBGModel( IplImage* first_frame, |
|
CvGaussBGStatModelParams* parameters CV_DEFAULT(NULL)); |
|
|
|
|
|
typedef struct CvBGCodeBookElem |
|
{ |
|
struct CvBGCodeBookElem* next; |
|
int tLastUpdate; |
|
int stale; |
|
uchar boxMin[3]; |
|
uchar boxMax[3]; |
|
uchar learnMin[3]; |
|
uchar learnMax[3]; |
|
} CvBGCodeBookElem; |
|
|
|
typedef struct CvBGCodeBookModel |
|
{ |
|
CvSize size; |
|
int t; |
|
uchar cbBounds[3]; |
|
uchar modMin[3]; |
|
uchar modMax[3]; |
|
CvBGCodeBookElem** cbmap; |
|
CvMemStorage* storage; |
|
CvBGCodeBookElem* freeList; |
|
} CvBGCodeBookModel; |
|
|
|
CVAPI(CvBGCodeBookModel*) cvCreateBGCodeBookModel( void ); |
|
CVAPI(void) cvReleaseBGCodeBookModel( CvBGCodeBookModel** model ); |
|
|
|
CVAPI(void) cvBGCodeBookUpdate( CvBGCodeBookModel* model, const CvArr* image, |
|
CvRect roi CV_DEFAULT(cvRect(0,0,0,0)), |
|
const CvArr* mask CV_DEFAULT(0) ); |
|
|
|
CVAPI(int) cvBGCodeBookDiff( const CvBGCodeBookModel* model, const CvArr* image, |
|
CvArr* fgmask, CvRect roi CV_DEFAULT(cvRect(0,0,0,0)) ); |
|
|
|
CVAPI(void) cvBGCodeBookClearStale( CvBGCodeBookModel* model, int staleThresh, |
|
CvRect roi CV_DEFAULT(cvRect(0,0,0,0)), |
|
const CvArr* mask CV_DEFAULT(0) ); |
|
|
|
CVAPI(CvSeq*) cvSegmentFGMask( CvArr *fgmask, int poly1Hull0 CV_DEFAULT(1), |
|
float perimScale CV_DEFAULT(4.f), |
|
CvMemStorage* storage CV_DEFAULT(0), |
|
CvPoint offset CV_DEFAULT(cvPoint(0,0))); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#endif |
|
|
|
/* End of file. */
|
|
|