├── regress ├── blas.h ├── tron.h ├── README.md ├── dscal.c ├── daxpy.c ├── ddot.c ├── HighClock.h ├── dnrm2.c ├── randomforest.h ├── linear.h ├── LBF.h ├── tree.h ├── LBFRegressor.h ├── tron.cpp ├── main.cpp ├── Utils.cpp ├── randomforest.cpp ├── blasp.h ├── tree.cpp └── LBFRegressor.cpp /regress: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kensun0/Joint-Cascade-Face-Detection-and-Alignment/HEAD/regress -------------------------------------------------------------------------------- /blas.h: -------------------------------------------------------------------------------- 1 | /* blas.h -- C header file for BLAS Ver 1.0 */ 2 | /* Jesse Bennett March 23, 2000 */ 3 | 4 | /** barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." 5 | 6 | - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */ 7 | 8 | #ifndef BLAS_INCLUDE 9 | #define BLAS_INCLUDE 10 | 11 | /* Data types specific to BLAS implementation */ 12 | typedef struct { float r, i; } fcomplex; 13 | typedef struct { float r, i; } dcomplex; 14 | typedef int blasbool; 15 | 16 | #include "blasp.h" /* Prototypes for all BLAS functions */ 17 | 18 | #define FALSE 0 19 | #define TRUE 1 20 | 21 | /* Macro functions */ 22 | #define MIN(a,b) ((a) <= (b) ? (a) : (b)) 23 | #define MAX(a,b) ((a) >= (b) ? (a) : (b)) 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tron.h: -------------------------------------------------------------------------------- 1 | #ifndef _TRON_H 2 | #define _TRON_H 3 | 4 | class function 5 | { 6 | public: 7 | virtual float fun(float *w) = 0 ; 8 | virtual void grad(float *w, float *g) = 0 ; 9 | virtual void Hv(float *s, float *Hs) = 0 ; 10 | 11 | virtual int get_nr_variable(void) = 0 ; 12 | virtual ~function(void){} 13 | }; 14 | 15 | class TRON 16 | { 17 | public: 18 | TRON(const function *fun_obj, float eps = 0.1, int max_iter = 1000); 19 | ~TRON(); 20 | 21 | void tron(float *w); 22 | void set_print_string(void (*i_print) (const char *buf)); 23 | 24 | private: 25 | int trcg(float delta, float *g, float *s, float *r); 26 | float norm_inf(int n, float *x); 27 | 28 | float eps; 29 | int max_iter; 30 | function *fun_obj; 31 | void info(const char *fmt,...); 32 | void (*tron_print_string)(const char *buf); 33 | }; 34 | #endif 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # joint-cascade-face-detection-and-alignment 2 | 3 | This project is a C++ reimplementation of joint cascade face detection and alignment in the ECCV 2014 4 | 5 | This project start with the code from https://github.com/yulequan/face-alignment-in-3000fps 6 | 7 | You should read yulequan's codes first, then compare them with mine. 8 | 9 | Add a trained model, only for raw detection without any optimization. 10 | 11 | There are some differences between paper's and mine: 12 | 13 | 1. Without SIFT+SVM 14 | 2. Without multi-scale pixel difference feature 15 | 3. Without non-maxmium suppression 16 | 17 | I do not make sure the implementation is right, but in my experiment, i get the right face with right keypoints at 50FPS on i7-3770K (optimization version). 18 | 19 | The version here is only for training. You shuold implement a version for testing by yourself. 20 | 21 | Sorry for my codestyle : ( 22 | -------------------------------------------------------------------------------- /dscal.c: -------------------------------------------------------------------------------- 1 | #include "blas.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | int dscal_(int *n, float *sa, float *sx, int *incx) 8 | { 9 | long int i, m, nincx, nn, iincx; 10 | float ssa; 11 | 12 | /* scales a vector by a constant. 13 | uses unrolled loops for increment equal to 1. 14 | jack dongarra, linpack, 3/11/78. 15 | modified 3/93 to return if incx .le. 0. 16 | modified 12/3/93, array(1) declarations changed to array(*) */ 17 | 18 | /* Dereference inputs */ 19 | nn = *n; 20 | iincx = *incx; 21 | ssa = *sa; 22 | 23 | if (nn > 0 && iincx > 0) 24 | { 25 | if (iincx == 1) /* code for increment equal to 1 */ 26 | { 27 | m = nn-4; 28 | for (i = 0; i < m; i += 5) 29 | { 30 | sx[i] = ssa * sx[i]; 31 | sx[i+1] = ssa * sx[i+1]; 32 | sx[i+2] = ssa * sx[i+2]; 33 | sx[i+3] = ssa * sx[i+3]; 34 | sx[i+4] = ssa * sx[i+4]; 35 | } 36 | for ( ; i < nn; ++i) /* clean-up loop */ 37 | sx[i] = ssa * sx[i]; 38 | } 39 | else /* code for increment not equal to 1 */ 40 | { 41 | nincx = nn * iincx; 42 | for (i = 0; i < nincx; i += iincx) 43 | sx[i] = ssa * sx[i]; 44 | } 45 | } 46 | 47 | return 0; 48 | } /* dscal_ */ 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | -------------------------------------------------------------------------------- /daxpy.c: -------------------------------------------------------------------------------- 1 | #include "blas.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | int daxpy_(int *n, float *sa, float *sx, int *incx, float *sy, 8 | int *incy) 9 | { 10 | long int i, m, ix, iy, nn, iincx, iincy; 11 | register float ssa; 12 | 13 | /* constant times a vector plus a vector. 14 | uses unrolled loop for increments equal to one. 15 | jack dongarra, linpack, 3/11/78. 16 | modified 12/3/93, array(1) declarations changed to array(*) */ 17 | 18 | /* Dereference inputs */ 19 | nn = *n; 20 | ssa = *sa; 21 | iincx = *incx; 22 | iincy = *incy; 23 | 24 | if( nn > 0 && ssa != 0.0 ) 25 | { 26 | if (iincx == 1 && iincy == 1) /* code for both increments equal to 1 */ 27 | { 28 | m = nn-3; 29 | for (i = 0; i < m; i += 4) 30 | { 31 | sy[i] += ssa * sx[i]; 32 | sy[i+1] += ssa * sx[i+1]; 33 | sy[i+2] += ssa * sx[i+2]; 34 | sy[i+3] += ssa * sx[i+3]; 35 | } 36 | for ( ; i < nn; ++i) /* clean-up loop */ 37 | sy[i] += ssa * sx[i]; 38 | } 39 | else /* code for unequal increments or equal increments not equal to 1 */ 40 | { 41 | ix = iincx >= 0 ? 0 : (1 - nn) * iincx; 42 | iy = iincy >= 0 ? 0 : (1 - nn) * iincy; 43 | for (i = 0; i < nn; i++) 44 | { 45 | sy[iy] += ssa * sx[ix]; 46 | ix += iincx; 47 | iy += iincy; 48 | } 49 | } 50 | } 51 | 52 | return 0; 53 | } /* daxpy_ */ 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | -------------------------------------------------------------------------------- /ddot.c: -------------------------------------------------------------------------------- 1 | #include "blas.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | float ddot_(int *n, float *sx, int *incx, float *sy, int *incy) 8 | { 9 | long int i, m, nn, iincx, iincy; 10 | float stemp; 11 | long int ix, iy; 12 | 13 | /* forms the dot product of two vectors. 14 | uses unrolled loops for increments equal to one. 15 | jack dongarra, linpack, 3/11/78. 16 | modified 12/3/93, array(1) declarations changed to array(*) */ 17 | 18 | /* Dereference inputs */ 19 | nn = *n; 20 | iincx = *incx; 21 | iincy = *incy; 22 | 23 | stemp = 0.0; 24 | if (nn > 0) 25 | { 26 | if (iincx == 1 && iincy == 1) /* code for both increments equal to 1 */ 27 | { 28 | m = nn-4; 29 | for (i = 0; i < m; i += 5) 30 | stemp += sx[i] * sy[i] + sx[i+1] * sy[i+1] + sx[i+2] * sy[i+2] + 31 | sx[i+3] * sy[i+3] + sx[i+4] * sy[i+4]; 32 | 33 | for ( ; i < nn; i++) /* clean-up loop */ 34 | stemp += sx[i] * sy[i]; 35 | } 36 | else /* code for unequal increments or equal increments not equal to 1 */ 37 | { 38 | ix = 0; 39 | iy = 0; 40 | if (iincx < 0) 41 | ix = (1 - nn) * iincx; 42 | if (iincy < 0) 43 | iy = (1 - nn) * iincy; 44 | for (i = 0; i < nn; i++) 45 | { 46 | stemp += sx[ix] * sy[iy]; 47 | ix += iincx; 48 | iy += iincy; 49 | } 50 | } 51 | } 52 | 53 | return stemp; 54 | } /* ddot_ */ 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /HighClock.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | LARGE_INTEGER TimerStart(); 4 | LARGE_INTEGER TimerEnd(); 5 | LARGE_INTEGER GetTime(LARGE_INTEGER start,LARGE_INTEGER end); 6 | 7 | 8 | LARGE_INTEGER TimerStart() 9 | { 10 | LARGE_INTEGER start; 11 | QueryPerformanceCounter(&start); 12 | return start; 13 | } 14 | 15 | LARGE_INTEGER TimerEnd() 16 | { 17 | LARGE_INTEGER end; 18 | QueryPerformanceCounter(&end); 19 | return end; 20 | } 21 | 22 | LARGE_INTEGER GetTime(LARGE_INTEGER start,LARGE_INTEGER end) 23 | { 24 | LARGE_INTEGER Freq; 25 | QueryPerformanceFrequency(&Freq); 26 | LARGE_INTEGER use; 27 | use.QuadPart=( end.QuadPart - start.QuadPart)*1000/ Freq.QuadPart; 28 | return use; 29 | } 30 | 31 | //! High-resolution clock (In fraction of seconds, as milliseconds) 32 | //单位:秒 33 | class HighClock 34 | { 35 | public: 36 | 37 | HighClock() 38 | { 39 | // Setup the high-resolution timer 40 | QueryPerformanceFrequency(&TicksPerSec); 41 | 42 | // High-resolution timers, iniitalized timer 43 | QueryPerformanceCounter(&startTime); 44 | 45 | // Start off the timer 46 | Start(); Stop(); 47 | } 48 | 49 | void Stop() 50 | { 51 | QueryPerformanceCounter(&endTime); 52 | } 53 | 54 | // In seconds 55 | float GetTime() 56 | { 57 | // Measure the cycle time 58 | cpuTime.QuadPart = endTime.QuadPart - startTime.QuadPart; 59 | return (float)cpuTime.QuadPart / (float)TicksPerSec.QuadPart; 60 | } 61 | 62 | void Start() 63 | { 64 | QueryPerformanceCounter(&startTime); 65 | } 66 | 67 | private: 68 | LARGE_INTEGER TicksPerSec; 69 | LARGE_INTEGER startTime, endTime, cpuTime; 70 | }; 71 | -------------------------------------------------------------------------------- /dnrm2.c: -------------------------------------------------------------------------------- 1 | #include /* Needed for fabs() and sqrt() */ 2 | #include "blas.h" 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | float dnrm2_(int *n, float *x, int *incx) 9 | { 10 | long int ix, nn, iincx; 11 | float norm, scale, absxi, ssq, temp; 12 | 13 | /* DNRM2 returns the euclidean norm of a vector via the function 14 | name, so that 15 | 16 | DNRM2 := sqrt( x'*x ) 17 | 18 | -- This version written on 25-October-1982. 19 | Modified on 14-October-1993 to inline the call to SLASSQ. 20 | Sven Hammarling, Nag Ltd. */ 21 | 22 | /* Dereference inputs */ 23 | nn = *n; 24 | iincx = *incx; 25 | 26 | if( nn > 0 && iincx > 0 ) 27 | { 28 | if (nn == 1) 29 | { 30 | norm = fabs(x[0]); 31 | } 32 | else 33 | { 34 | scale = 0.0; 35 | ssq = 1.0; 36 | 37 | /* The following loop is equivalent to this call to the LAPACK 38 | auxiliary routine: CALL SLASSQ( N, X, INCX, SCALE, SSQ ) */ 39 | 40 | for (ix=(nn-1)*iincx; ix>=0; ix-=iincx) 41 | { 42 | if (x[ix] != 0.0) 43 | { 44 | absxi = fabs(x[ix]); 45 | if (scale < absxi) 46 | { 47 | temp = scale / absxi; 48 | ssq = ssq * (temp * temp) + 1.0; 49 | scale = absxi; 50 | } 51 | else 52 | { 53 | temp = absxi / scale; 54 | ssq += temp * temp; 55 | } 56 | } 57 | } 58 | norm = scale * sqrt(ssq); 59 | } 60 | } 61 | else 62 | norm = 0.0; 63 | 64 | return norm; 65 | 66 | } /* dnrm2_ */ 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif 71 | -------------------------------------------------------------------------------- /randomforest.h: -------------------------------------------------------------------------------- 1 | // 2 | // RandomForest.h 3 | // myopencv 4 | // 5 | // Created by lequan on 1/24/15. 6 | // Copyright (c) 2015 lequan. All rights reserved. 7 | // 8 | 9 | #ifndef __myopencv__RandomForest__ 10 | #define __myopencv__RandomForest__ 11 | 12 | #include "Tree.h" 13 | 14 | class RandomForest{ 15 | public: 16 | std::vector > rfs_; 17 | int max_numtrees_; 18 | int num_landmark_; 19 | int max_depth_; 20 | int stages_; 21 | float overlap_ratio_; 22 | 23 | 24 | RandomForest(){ 25 | max_numtrees_ = global_params.max_numtrees; 26 | num_landmark_ = global_params.landmark_num; 27 | max_depth_ = global_params.max_depth; 28 | overlap_ratio_ = global_params.bagging_overlap; 29 | 30 | // resize the trees 31 | rfs_.resize(num_landmark_); 32 | for (int i=0;i >& images, 37 | std::vector& augmented_images, 38 | std::vector >& ground_truth_shapes, 39 | std::vector& ground_truth_faces, 40 | std::vector >& current_shapes, 41 | std::vector& current_fi, 42 | std::vector& current_weight, 43 | std::vector & bounding_boxs, 44 | const cv::Mat_& mean_shape, 45 | std::vector >& shapes_residual, 46 | int stages, 47 | std::vector& RandomForest_, 48 | std::vector > Models_, 49 | int posLenth 50 | ); 51 | void Read(std::ifstream& fin); 52 | void Write(std::ofstream& fout); 53 | }; 54 | 55 | 56 | #endif /* defined(__myopencv__RandomForest__) */ 57 | -------------------------------------------------------------------------------- /linear.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIBLINEAR_H 2 | #define _LIBLINEAR_H 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | struct feature_node 10 | { 11 | int index; 12 | float value; 13 | }; 14 | 15 | struct problem 16 | { 17 | int l, n; 18 | float *y; 19 | struct feature_node **x; 20 | float bias; /* < 0 if no bias term */ 21 | }; 22 | 23 | enum { L2R_LR, L2R_L2LOSS_SVC_DUAL, L2R_L2LOSS_SVC, L2R_L1LOSS_SVC_DUAL, MCSVM_CS, L1R_L2LOSS_SVC, L1R_LR, L2R_LR_DUAL, L2R_L2LOSS_SVR = 11, L2R_L2LOSS_SVR_DUAL, L2R_L1LOSS_SVR_DUAL }; /* solver_type */ 24 | 25 | struct parameter 26 | { 27 | int solver_type; 28 | 29 | /* these are for training only */ 30 | float eps; /* stopping criteria */ 31 | float C; 32 | int nr_weight; 33 | int *weight_label; 34 | float* weight; 35 | float p; 36 | }; 37 | 38 | struct model 39 | { 40 | struct parameter param; 41 | int nr_class; /* number of classes */ 42 | int nr_feature; 43 | float *w; 44 | int *label; /* label of each class */ 45 | float bias; 46 | }; 47 | 48 | struct model* train(const struct problem *prob, const struct parameter *param); 49 | void cross_validation(const struct problem *prob, const struct parameter *param, int nr_fold, float *target); 50 | 51 | float predict_values(const struct model *model_, const struct feature_node *x, float* dec_values); 52 | float predict(const struct model *model_, const struct feature_node *x); 53 | float predict_probability(const struct model *model_, const struct feature_node *x, float* prob_estimates); 54 | 55 | int save_model(const char *model_file_name, const struct model *model_); 56 | struct model *load_model(const char *model_file_name); 57 | /* add my own save and load model*/ 58 | int save_model_bin(std::ofstream& fout, const struct model *model_); 59 | struct model *load_model_bin(std::ifstream& fin); 60 | /*********************************/ 61 | 62 | int get_nr_feature(const struct model *model_); 63 | int get_nr_class(const struct model *model_); 64 | void get_labels(const struct model *model_, int* label); 65 | float get_decfun_coef(const struct model *model_, int feat_idx, int label_idx); 66 | float get_decfun_bias(const struct model *model_, int label_idx); 67 | 68 | void free_model_content(struct model *model_ptr); 69 | void free_and_destroy_model(struct model **model_ptr_ptr); 70 | void destroy_param(struct parameter *param); 71 | 72 | const char *check_parameter(const struct problem *prob, const struct parameter *param); 73 | int check_probability_model(const struct model *model); 74 | int check_regression_model(const struct model *model); 75 | void set_print_string_function(void (*print_func) (const char*)); 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* _LIBLINEAR_H */ 82 | 83 | -------------------------------------------------------------------------------- /LBF.h: -------------------------------------------------------------------------------- 1 | #ifndef FACE_ALIGNMENT_H 2 | #define FACE_ALIGNMENT_H 3 | #include "opencv2/objdetect/objdetect.hpp" 4 | #include "opencv2/highgui/highgui.hpp" 5 | #include "opencv2/imgproc/imgproc.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "cv.hpp" 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | using namespace std; 26 | using namespace cv; 27 | 28 | #define SAVEBIN (0) 29 | #define MAXHEIGHT_POS (128) 30 | #define MAXHEIGHT_NEG (320) 31 | #define MINHEIGHT (16) 32 | #define CROP (0.1) 33 | #define FRAC (0.0) 34 | struct Params{ 35 | 36 | float bagging_overlap; 37 | int max_numtrees; 38 | int max_depth; 39 | int landmark_num;// to be decided 40 | int initial_num; 41 | 42 | int max_numstage; 43 | float max_radio_radius[10]; 44 | int max_numfeats[10]; // number of pixel pairs 45 | int max_numthreshs; 46 | float max_probility[10]; 47 | }; 48 | extern Params global_params; 49 | extern std::string modelPath; 50 | extern std::string dataPath; 51 | class BoundingBox{ 52 | public: 53 | float start_x; 54 | float start_y; 55 | float width; 56 | float height; 57 | float centroid_x; 58 | float centroid_y; 59 | BoundingBox(){ 60 | start_x = 0; 61 | start_y = 0; 62 | width = 0; 63 | height = 0; 64 | centroid_x = 0; 65 | centroid_y = 0; 66 | }; 67 | }; 68 | 69 | void InitializeGlobalParam(); 70 | 71 | Mat_ GetMeanShape(const vector >& shapes, 72 | const vector& bounding_box); 73 | Mat_ GetMeanShape2(const vector >& shapes, 74 | const vector& bounding_box,const vector& ground_truth_faces); 75 | 76 | void GetShapeResidual(const vector >& ground_truth_shapes, 77 | const vector >& current_shapes, 78 | const vector& bounding_boxs, 79 | const Mat_& mean_shape, 80 | vector >& shape_residuals); 81 | void GetShapeResidual2(vector shape_index, 82 | const vector >& ground_truth_shapes, 83 | const vector >& current_shapes, 84 | const vector& bounding_boxs, 85 | const Mat_& mean_shape, 86 | vector >& shape_residuals); 87 | 88 | cv::Mat_ ProjectShape(const cv::Mat_& shape, const BoundingBox& bounding_box); 89 | cv::Mat_ ReProjectShape(const cv::Mat_& shape, const BoundingBox& bounding_box); 90 | void SimilarityTransform(const cv::Mat_& shape1, const cv::Mat_& shape2, 91 | cv::Mat_& rotation,float& scale); 92 | float calculate_covariance(const std::vector& v_1, 93 | const std::vector& v_2); 94 | float CalculateError(const cv::Mat_& ground_truth_shape, const cv::Mat_& predicted_shape); 95 | 96 | BoundingBox CalculateBoundingBox(Mat_& img, cv::Mat_& shape); 97 | void adjustImage(Mat_& img, Mat_& ground_truth_shape, BoundingBox& bounding_box); 98 | void getRandomBox(const cv::Mat_& image, const BoundingBox& old_box, BoundingBox& new_box); 99 | void cropBoundingBox(Mat_& img, BoundingBox box, BoundingBox& newbox/*, Mat_ shapeMat_, & newshape*/); 100 | 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /tree.h: -------------------------------------------------------------------------------- 1 | #ifndef __myopencv__Tree__ 2 | #define __myopencv__Tree__ 3 | 4 | #include "LBF.h" 5 | 6 | class Node { 7 | public: 8 | //data 9 | bool issplit; 10 | int pnode; 11 | int depth; 12 | int cnodes[2]; 13 | bool isleafnode; 14 | float thresh; 15 | float feat[6]; 16 | //int landmarkId[2]; 17 | std::vector ind_samples; 18 | float score; 19 | 20 | //Constructors 21 | Node(){ 22 | ind_samples.clear(); 23 | issplit = 0; 24 | pnode = 0; 25 | depth = 0; 26 | cnodes[0] = 0; 27 | cnodes[1] = 0; 28 | isleafnode = 0; 29 | thresh = 0; 30 | feat[0] = 0; 31 | feat[1] = 0; 32 | feat[2] = 0; 33 | feat[3] = 0; 34 | feat[4] = 0; 35 | feat[5] = 0; 36 | /*landmarkId[0] = 0; 37 | landmarkId[1] = 0;*/ 38 | score = 0; 39 | } 40 | void Write(std::ofstream& fout){ 41 | fout << issplit<<" "<< pnode <<" "<> issplit >> pnode >> depth >> cnodes[0] >> cnodes[1] >> isleafnode 60 | >> thresh >> feat[0] >> feat[1] >> feat[2] >> feat[3] >> feat[4] >> feat[5] >> score; 61 | } 62 | }; 63 | 64 | class Tree{ 65 | public: 66 | 67 | // id of the landmark 68 | int landmarkID_; 69 | // depth of the tree: 70 | int max_depth_; 71 | // number of maximum nodes: 72 | int max_numnodes_; 73 | //number of leaf nodes and nodes 74 | int num_leafnodes_; 75 | int num_nodes_; 76 | 77 | // sample pixel featurs' number, use when training RF 78 | int max_numfeats_; 79 | float max_radio_radius_; 80 | float overlap_ration_; 81 | 82 | float max_probility_; 83 | float threshold; 84 | 85 | // leafnodes id 86 | std::vector id_leafnodes_; 87 | // tree nodes 88 | std::vector nodes_; 89 | 90 | 91 | Tree(){ 92 | overlap_ration_ = global_params.bagging_overlap; 93 | max_depth_ = global_params.max_depth; 94 | max_numnodes_ = pow(2.0, max_depth_)-1; 95 | nodes_.resize(max_numnodes_); 96 | 97 | max_probility_=1; 98 | threshold = 0; 99 | } 100 | void Train(const std::vector >& images, 101 | const std::vector& augmented_images, 102 | const std::vector >& ground_truth_shapes, 103 | const std::vector& ground_truth_faces, 104 | const std::vector >& current_shapes, 105 | const std::vector& current_fi, 106 | const std::vector& current_weight, 107 | const std::vector & bounding_boxs, 108 | const cv::Mat_& mean_shape, 109 | const std::vector >& regression_targets, 110 | const std::vector index, 111 | int stages, 112 | int landmarkID 113 | ); 114 | 115 | //Splite the node 116 | void Splitnode(const std::vector >& images, 117 | const std::vector& augmented_images, 118 | const std::vector >& ground_truth_shapes, 119 | const std::vector& ground_truth_faces, 120 | const std::vector >& current_shapes, 121 | const std::vector& current_fi, 122 | const std::vector& current_weight, 123 | const std::vector & bounding_box, 124 | const cv::Mat_& mean_shape, 125 | const cv::Mat_& shapes_residual, 126 | const std::vector &ind_samples, 127 | // output 128 | float& thresh, 129 | float* feat, 130 | int landmarkID, 131 | bool& isvaild, 132 | std::vector& lcind, 133 | std::vector& rcind, 134 | int stage 135 | ); 136 | 137 | //Predict 138 | void Predict(); 139 | 140 | // Read/ write 141 | void Read(std::ifstream& fin); 142 | void Write(std:: ofstream& fout); 143 | 144 | }; 145 | 146 | 147 | 148 | 149 | 150 | #endif /* defined(__myopencv__Tree__) */ 151 | -------------------------------------------------------------------------------- /LBFRegressor.h: -------------------------------------------------------------------------------- 1 | #ifndef __myopencv__LBFRegressor__ 2 | #define __myopencv__LBFRegressor__ 3 | 4 | #include "RandomForest.h" 5 | #include "liblinear/linear.h" 6 | class LBFRegressor{ 7 | public: 8 | std::vector RandomForest_; 9 | std::vector > Models_; 10 | cv::Mat_ mean_shape_; 11 | std::vector > shapes_residual_; 12 | int max_numstage_; 13 | public: 14 | LBFRegressor(){ 15 | max_numstage_ = global_params.max_numstage; 16 | RandomForest_.resize(max_numstage_); 17 | Models_.resize(max_numstage_); 18 | } 19 | ~LBFRegressor(){ 20 | 21 | } 22 | void Read(std::ifstream& fin); 23 | void Write(std::ofstream& fout); 24 | void Load(std::string path); 25 | void Save(std::string path); 26 | struct feature_node ** DeriveBinaryFeat(const RandomForest& randf, 27 | const std::vector >& images, 28 | const std::vector& augmented_images, 29 | const std::vector >& current_shapes, 30 | const std::vector & bounding_boxs); 31 | struct feature_node ** DeriveBinaryFeat3(const RandomForest& randf, 32 | const std::vector >& images, 33 | const std::vector& augmented_images, 34 | const std::vector >& current_shapes, 35 | const std::vector& ground_truth_faces, 36 | const std::vector & bounding_boxs); 37 | struct feature_node ** DeriveBinaryFeat2(const RandomForest& randf, 38 | const std::vector >& images, 39 | const std::vector& augmented_images, 40 | const std::vector >& current_shapes, 41 | const std::vector & bounding_boxs,std::vector & result_face,float& score,int& fcount,bool& fface); 42 | void ReleaseFeatureSpace(struct feature_node ** binfeatures, 43 | int num_train_sample); 44 | int GetCodefromTree(const Tree& tree, 45 | const cv::Mat_& image, 46 | const cv::Mat_& shapes, 47 | const BoundingBox& bounding_box, 48 | const cv::Mat_& rotation, 49 | const float scale); 50 | void GetCodefromRandomForest(struct feature_node *binfeature, 51 | const int index, 52 | const std::vector & rand_forest, 53 | const cv::Mat_& image, 54 | const cv::Mat_& shape, 55 | const BoundingBox& bounding_box, 56 | const cv::Mat_& rotation, 57 | const float scale); 58 | bool GetCodefromRandomForest2(struct feature_node *binfeature, 59 | const int index, 60 | const std::vector& rand_forest, 61 | const cv::Mat_& image, 62 | const cv::Mat_& shape, 63 | const BoundingBox& bounding_box, 64 | const cv::Mat_& rotation, 65 | const float scale,float& score,int& fcount,bool& fface); 66 | void GlobalRegression(struct feature_node **binfeatures, 67 | const std::vector >& shapes_residual, 68 | std::vector >& current_shapes, 69 | const std::vector & bounding_boxs, 70 | const cv::Mat_& mean_shape, 71 | //Mat_& W, 72 | std::vector& models, 73 | int num_feature, 74 | int num_train_sample, 75 | int stage); 76 | void GlobalRegression2(struct feature_node **binfeatures, 77 | const std::vector >& shapes_residual, 78 | std::vector >& current_shapes, 79 | const std::vector & bounding_boxs, 80 | const cv::Mat_& mean_shape, 81 | //Mat_& W, 82 | std::vector& models, 83 | int num_feature, 84 | const std::vector & augmented_images, 85 | const std::vector & ground_truth_faces, 86 | int stage); 87 | 88 | void GlobalPrediction(struct feature_node**, 89 | std::vector >& current_shapes, 90 | const std::vector & bounding_boxs, 91 | int stage); 92 | 93 | void Train( std::vector >& images, 94 | std::vector >& ground_truth_shapes, 95 | std::vector& ground_truth_faces, 96 | std::vector & bounding_boxs, int posLenth); 97 | 98 | std::vector > Predict( const std::vector >& images, 99 | const std::vector& bounding_boxs, 100 | const std::vector >& ground_truth_shapes, 101 | int initial_num,std::vector& result_face); 102 | cv::Mat_ Predict(const cv::Mat_& image, 103 | const BoundingBox& bounding_box, 104 | int initial_num, bool& isface,int& fcount); 105 | void WriteGlobalParam(std::ofstream& fout); 106 | void ReadGlobalParam(std::ifstream& fin); 107 | void WriteRegressor(std::ofstream& fout); 108 | void ReadRegressor(std::ifstream& fin); 109 | 110 | 111 | }; 112 | 113 | void GetResultfromTree(const Tree& tree, 114 | const cv::Mat_& image, 115 | const cv::Mat_& shapes, 116 | const BoundingBox& bounding_box, 117 | const cv::Mat_& rotation, 118 | const float scale,int* bincode,float* score); 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /tron.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "tron.h" 6 | 7 | #ifndef min 8 | template static inline T min(T x,T y) { return (x static inline T max(T x,T y) { return (x>y)?x:y; } 13 | #endif 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | extern float dnrm2_(int *, float *, int *); 20 | extern float ddot_(int *, float *, int *, float *, int *); 21 | extern int daxpy_(int *, float *, float *, int *, float *, int *); 22 | extern int dscal_(int *, float *, float *, int *); 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | 28 | static void default_print(const char *buf) 29 | { 30 | fputs(buf,stdout); 31 | fflush(stdout); 32 | } 33 | 34 | void TRON::info(const char *fmt,...) 35 | { 36 | char buf[BUFSIZ]; 37 | va_list ap; 38 | va_start(ap,fmt); 39 | vsprintf(buf,fmt,ap); 40 | va_end(ap); 41 | (*tron_print_string)(buf); 42 | } 43 | 44 | TRON::TRON(const function *fun_obj, float eps, int max_iter) 45 | { 46 | this->fun_obj=const_cast(fun_obj); 47 | this->eps=eps; 48 | this->max_iter=max_iter; 49 | tron_print_string = default_print; 50 | } 51 | 52 | TRON::~TRON() 53 | { 54 | } 55 | 56 | void TRON::tron(float *w) 57 | { 58 | // Parameters for updating the iterates. 59 | float eta0 = 1e-4, eta1 = 0.25, eta2 = 0.75; 60 | 61 | // Parameters for updating the trust region size delta. 62 | float sigma1 = 0.25, sigma2 = 0.5, sigma3 = 4; 63 | 64 | int n = fun_obj->get_nr_variable(); 65 | int i, cg_iter; 66 | float delta, snorm, one=1.0; 67 | float alpha, f, fnew, prered, actred, gs; 68 | int search = 1, iter = 1, inc = 1; 69 | float *s = new float[n]; 70 | float *r = new float[n]; 71 | float *w_new = new float[n]; 72 | float *g = new float[n]; 73 | 74 | for (i=0; ifun(w); 78 | fun_obj->grad(w, g); 79 | delta = dnrm2_(&n, g, &inc); 80 | float gnorm1 = delta; 81 | float gnorm = gnorm1; 82 | 83 | if (gnorm <= eps*gnorm1) 84 | search = 0; 85 | 86 | iter = 1; 87 | 88 | while (iter <= max_iter && search) 89 | { 90 | cg_iter = trcg(delta, g, s, r); 91 | 92 | memcpy(w_new, w, sizeof(float)*n); 93 | daxpy_(&n, &one, s, &inc, w_new, &inc); 94 | 95 | gs = ddot_(&n, g, &inc, s, &inc); 96 | prered = -0.5*(gs-ddot_(&n, s, &inc, r, &inc)); 97 | fnew = fun_obj->fun(w_new); 98 | 99 | // Compute the actual reduction. 100 | actred = f - fnew; 101 | 102 | // On the first iteration, adjust the initial step bound. 103 | snorm = dnrm2_(&n, s, &inc); 104 | if (iter == 1) 105 | delta = min(delta, snorm); 106 | 107 | // Compute prediction alpha*snorm of the step. 108 | if (fnew - f - gs <= 0) 109 | alpha = sigma3; 110 | else 111 | alpha = max((double)sigma1, -0.5*(gs/(fnew - f - gs))); 112 | 113 | // Update the trust region bound according to the ratio of actual to predicted reduction. 114 | if (actred < eta0*prered) 115 | delta = min(max(alpha, sigma1)*snorm, sigma2*delta); 116 | else if (actred < eta1*prered) 117 | delta = max(sigma1*delta, min(alpha*snorm, sigma2*delta)); 118 | else if (actred < eta2*prered) 119 | delta = max(sigma1*delta, min(alpha*snorm, sigma3*delta)); 120 | else 121 | delta = max(delta, min(alpha*snorm, sigma3*delta)); 122 | 123 | info("iter %2d act %5.3e pre %5.3e delta %5.3e f %5.3e |g| %5.3e CG %3d\n", iter, actred, prered, delta, f, gnorm, cg_iter); 124 | 125 | if (actred > eta0*prered) 126 | { 127 | iter++; 128 | memcpy(w, w_new, sizeof(float)*n); 129 | f = fnew; 130 | fun_obj->grad(w, g); 131 | 132 | gnorm = dnrm2_(&n, g, &inc); 133 | if (gnorm <= eps*gnorm1) 134 | break; 135 | } 136 | if (f < -1.0e+32) 137 | { 138 | info("WARNING: f < -1.0e+32\n"); 139 | break; 140 | } 141 | if (fabs(actred) <= 0 && prered <= 0) 142 | { 143 | info("WARNING: actred and prered <= 0\n"); 144 | break; 145 | } 146 | if (fabs(actred) <= 1.0e-12*fabs(f) && 147 | fabs(prered) <= 1.0e-12*fabs(f)) 148 | { 149 | info("WARNING: actred and prered too small\n"); 150 | break; 151 | } 152 | } 153 | 154 | delete[] g; 155 | delete[] r; 156 | delete[] w_new; 157 | delete[] s; 158 | } 159 | 160 | int TRON::trcg(float delta, float *g, float *s, float *r) 161 | { 162 | int i, inc = 1; 163 | int n = fun_obj->get_nr_variable(); 164 | float one = 1; 165 | float *d = new float[n]; 166 | float *Hd = new float[n]; 167 | float rTr, rnewTrnew, alpha, beta, cgtol; 168 | 169 | for (i=0; iHv(d, Hd); 185 | 186 | alpha = rTr/ddot_(&n, d, &inc, Hd, &inc); 187 | daxpy_(&n, &alpha, d, &inc, s, &inc); 188 | if (dnrm2_(&n, s, &inc) > delta) 189 | { 190 | info("cg reaches trust region boundary\n"); 191 | alpha = -alpha; 192 | daxpy_(&n, &alpha, d, &inc, s, &inc); 193 | 194 | float std = ddot_(&n, s, &inc, d, &inc); 195 | float sts = ddot_(&n, s, &inc, s, &inc); 196 | float dtd = ddot_(&n, d, &inc, d, &inc); 197 | float dsq = delta*delta; 198 | float rad = sqrt(std*std + dtd*(dsq-sts)); 199 | if (std >= 0) 200 | alpha = (dsq - sts)/(std + rad); 201 | else 202 | alpha = (rad - std)/dtd; 203 | daxpy_(&n, &alpha, d, &inc, s, &inc); 204 | alpha = -alpha; 205 | daxpy_(&n, &alpha, Hd, &inc, r, &inc); 206 | break; 207 | } 208 | alpha = -alpha; 209 | daxpy_(&n, &alpha, Hd, &inc, r, &inc); 210 | rnewTrnew = ddot_(&n, r, &inc, r, &inc); 211 | beta = rnewTrnew/rTr; 212 | dscal_(&n, &beta, d, &inc); 213 | daxpy_(&n, &one, r, &inc, d, &inc); 214 | rTr = rnewTrnew; 215 | } 216 | 217 | delete[] d; 218 | delete[] Hd; 219 | 220 | return(cg_iter); 221 | } 222 | 223 | float TRON::norm_inf(int n, float *x) 224 | { 225 | float dmax = fabs(x[0]); 226 | for (int i=1; i= dmax) 228 | dmax = fabs(x[i]); 229 | return(dmax); 230 | } 231 | 232 | void TRON::set_print_string(void (*print_string) (const char *buf)) 233 | { 234 | tron_print_string = print_string; 235 | } 236 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "LBF.h" 2 | #include "LBFRegressor.h" 3 | using namespace std; 4 | using namespace cv; 5 | 6 | // parameters 7 | Params global_params; 8 | string modelPath = "model"; 9 | string dataPath = "regress"; 10 | 11 | int main( int argc, const char** argv ){ 12 | 13 | InitializeGlobalParam(); 14 | omp_set_num_threads(16); 15 | 16 | string listT="list1.txt"; 17 | string listF="list2.txt"; 18 | 19 | vector< Mat_ > images_train; 20 | vector< Mat_ > ground_truth_shapes_train; 21 | vector ground_truth_faces_train; 22 | vector bounding_boxs_train; 23 | 24 | ifstream fin;locale::global(locale(""));fin.open(listT);locale::global(locale("C")); 25 | string line; 26 | int sample_freq=0; 27 | while(getline(fin,line)){ 28 | sample_freq++; 29 | printf("loading train:%d\r",sample_freq); 30 | istringstream stream(line); 31 | string name; 32 | stream >> name; 33 | Mat_ image = imread(name,0); 34 | if (image.rows ground_truth_shape(28,2); 42 | for (int i=0,j=0;i<95;++i){ 43 | if ( (i+1) == shape28Index[j]){ 44 | stream >> ground_truth_shape(j,0); 45 | stream >> ground_truth_shape(j,1); 46 | if (ground_truth_shape(j, 0)<0 || 47 | ground_truth_shape(j, 1)<0 || 48 | ground_truth_shape(j, 0)>=image.cols || 49 | ground_truth_shape(j, 1)>=image.rows) 50 | badshape = true; 51 | ++j; 52 | }else{ 53 | float tmp1,tmp2; 54 | stream >> tmp1; 55 | stream >> tmp2; 56 | /*if (tmp1 < 0 || tmp2 < 0 || tmp1 >= image.cols || tmp2 >= image.rows) 57 | badshape = true;*/ 58 | } 59 | } 60 | if (badshape) 61 | continue; 62 | // Read Bounding box 63 | BoundingBox bbx = CalculateBoundingBox(image, ground_truth_shape); 64 | adjustImage(image, ground_truth_shape, bbx); 65 | 66 | images_train.push_back(image); 67 | ground_truth_shapes_train.push_back(ground_truth_shape); 68 | ground_truth_faces_train.push_back(1); 69 | bounding_boxs_train.push_back(bbx); 70 | } 71 | fin.close(); 72 | cout<> name; 79 | FILE* imgFile;imgFile=fopen(name.c_str(),"rb"); 80 | if (imgFile==NULL) 81 | cout<<"error in read data\n"; 82 | else 83 | { 84 | while (1) 85 | { 86 | sample_freq++; 87 | printf("loading test:%d\r",sample_freq); 88 | int jWidth; 89 | int jHeight; 90 | fread(&jWidth,4,1,imgFile); 91 | fread(&jHeight,4,1,imgFile); 92 | uchar* jData = new uchar[jWidth*jHeight]; 93 | fread(jData,1,jWidth*jHeight,imgFile); 94 | 95 | if (feof(imgFile)){ 96 | delete[] jData; 97 | break; 98 | } 99 | if( jWidth image(jHeight,jWidth); 103 | for (int k=0;k image.cols){ 109 | if (image.rows > MAXHEIGHT_NEG){ 110 | float scale = 1.0*MAXHEIGHT_NEG / image.rows; 111 | int new_width = image.cols*scale; 112 | int new_height = image.rows*scale; 113 | resize(image, image, Size(new_width, new_height)); 114 | } 115 | }else 116 | if (image.cols > MAXHEIGHT_NEG){ 117 | float scale = 1.0*MAXHEIGHT_NEG / image.cols; 118 | int new_width = image.cols*scale; 119 | int new_height = image.rows*scale; 120 | resize(image, image, Size(new_width, new_height)); 121 | } 122 | BoundingBox new_box; 123 | RNG random_generator(getTickCount()); 124 | int random_idx = random_generator.uniform(0, posLenth - 1); 125 | getRandomBox(image, bounding_boxs_train[random_idx], new_box); 126 | Mat_ temp = ProjectShape(ground_truth_shapes_train[random_idx], bounding_boxs_train[random_idx]); 127 | Mat_ ground_truth_shape = ReProjectShape(temp, new_box); 128 | images_train.push_back(image); 129 | ground_truth_shapes_train.push_back(ground_truth_shape); 130 | ground_truth_faces_train.push_back(-1); 131 | bounding_boxs_train.push_back(new_box); 132 | } 133 | } 134 | fclose(imgFile); 135 | } 136 | fin2.close(); 137 | cout<<"\ntrain num:"< testImg=imread("img\\3.jpg",0); 148 | Mat_ forshow = testImg.clone(); 149 | float scale=1.1; 150 | int minSize=40/scale; 151 | float shuffle=0.1; 152 | int ccc=0; 153 | int ttt=0; 154 | for (int i=0;i<15;++i) 155 | { 156 | minSize*=scale; 157 | for (int j=0;j tmp=testImg.rowRange((int)top_y,(int)bottom_y).colRange((int)left_x,(int)right_x).clone(); 168 | 169 | BoundingBox bx; 170 | bx.start_x=0.3*minSize; 171 | bx.start_y=0.3*minSize; 172 | bx.width=(right_x-left_x)/1.6; 173 | bx.height=(bottom_y-top_y)/1.6; 174 | bx.centroid_x=(right_x-left_x)/2.0; 175 | bx.centroid_y=(bottom_y-top_y)/2.0; 176 | 177 | int count=0; 178 | bool result_face=true; 179 | Mat_shapes = regressor.Predict(tmp,bx,1,result_face,count); 180 | if (result_face) 181 | { 182 | for (int m=0;m> current_shapes; 202 | //vector> real_shapes; 203 | //vector real_idx; 204 | //int count=0; 205 | //for (int i=0;ishapes = regressor.Predict(images_test[i],bounding_boxs_test[i],1,result_face,fcount); 210 | // if (!result_face) 211 | // { 212 | // count+=fcount; 213 | // } 214 | // 215 | // if (1==ground_truth_faces_test[i] && result_face==true) 216 | // { 217 | // right_num_pos++; 218 | // } 219 | // if (-1==ground_truth_faces_test[i] && result_face==false) 220 | // { 221 | // right_num_neg++; 222 | // } 223 | // if (ground_truth_faces_test[i]==1 && result_face==true) 224 | // { 225 | // current_shapes.push_back(shapes); 226 | // real_shapes.push_back(ground_truth_shapes_test[i]); 227 | // real_idx.push_back(i); 228 | // } 229 | // if (ground_truth_faces_test[i]==1) 230 | // { 231 | // pos_num++; 232 | // } 233 | // else 234 | // { 235 | // neg_num++; 236 | // } 237 | // /*if(ground_truth_faces_test[i]==1 && result_face==false) 238 | // { 239 | // Mat_ tmp=images_test[i].clone(); 240 | // for (int j=0;j tmp2=images_test[i].clone(); 248 | // for (int j=0;j tmp=images_test[i].clone(); 258 | // for (int j=0;j tmp2=images_test[i].clone(); 266 | // for (int j=0;j tmp=images_test[real_idx[i]].clone(); 285 | // for (int j=0;j tmp2=images_test[real_idx[i]].clone(); 293 | // for (int j=0;j> global_params.bagging_overlap; 337 | fin >> global_params.max_numtrees; 338 | fin >> global_params.max_depth; 339 | fin >> global_params.max_numthreshs; 340 | fin >> global_params.landmark_num; 341 | fin >> global_params.initial_num; 342 | fin >> global_params.max_numstage; 343 | 344 | for (int i = 0; i< global_params.max_numstage; i++){ 345 | fin >> global_params.max_radio_radius[i]; 346 | } 347 | for (int i = 0; i < global_params.max_numstage; i++){ 348 | fin >> global_params.max_numfeats[i]; 349 | } 350 | cout << "Loading GlobalParam end"< GetMeanShape(const vector >& shapes, 7 | const vector& bounding_box){ 8 | Mat_ result = Mat::zeros(shapes[0].rows,2,CV_32FC1); 9 | for(int i = 0;i < shapes.size();i++){ 10 | 11 | result = result + ProjectShape(shapes[i],bounding_box[i]); 12 | } 13 | result = 1.0 / shapes.size() * result; 14 | return result; 15 | } 16 | 17 | Mat_ GetMeanShape2(const vector >& shapes, 18 | const vector& bounding_box, const vector& ground_truth_faces){ 19 | Mat_ result = Mat::zeros(shapes[0].rows,2,CV_32FC1); 20 | int tmp=0; 21 | for(int i = 0;i < shapes.size();i++){ 22 | if (ground_truth_faces[i]==1) 23 | { 24 | result = result + ProjectShape(shapes[i],bounding_box[i]); 25 | tmp++; 26 | } 27 | } 28 | result = 1.0 / tmp * result; 29 | return result; 30 | } 31 | 32 | void GetShapeResidual(const vector >& ground_truth_shapes, 33 | const vector >& current_shapes, 34 | const vector& bounding_boxs, 35 | const Mat_& mean_shape, 36 | vector >& shape_residuals) { 37 | 38 | Mat_ rotation; 39 | float scale; 40 | shape_residuals.resize(bounding_boxs.size()); 41 | for (int i = 0; i < bounding_boxs.size(); i++) { 42 | shape_residuals[i] = ProjectShape(ground_truth_shapes[i], bounding_boxs[i]) 43 | - ProjectShape(current_shapes[i], bounding_boxs[i]); 44 | SimilarityTransform(mean_shape, ProjectShape(current_shapes[i], bounding_boxs[i]), rotation, scale); 45 | transpose(rotation, rotation); 46 | shape_residuals[i] = scale * shape_residuals[i] * rotation; 47 | } 48 | } 49 | 50 | void GetShapeResidual2(vector shape_index, 51 | const vector >& ground_truth_shapes, 52 | const vector >& current_shapes, 53 | const vector& bounding_boxs, 54 | const Mat_& mean_shape, 55 | vector >& shape_residuals){ 56 | Mat_ rotation; 57 | float scale; 58 | shape_residuals.resize(shape_index.size()); 59 | for (int i = 0;i < shape_index.size(); i++){ 60 | shape_residuals[i] = ProjectShape(ground_truth_shapes[shape_index[i]], bounding_boxs[shape_index[i]]) 61 | - ProjectShape(current_shapes[shape_index[i]], bounding_boxs[shape_index[i]]); 62 | SimilarityTransform(mean_shape, ProjectShape(current_shapes[shape_index[i]],bounding_boxs[shape_index[i]]),rotation,scale); 63 | transpose(rotation,rotation); 64 | shape_residuals[i] = scale * shape_residuals[i] * rotation; 65 | } 66 | } 67 | 68 | 69 | Mat_ ProjectShape(const Mat_& shape, const BoundingBox& bounding_box){ 70 | Mat_ temp(shape.rows,2); 71 | for(int j = 0;j < shape.rows;j++){ 72 | temp(j,0) = (shape(j,0)-bounding_box.centroid_x) / (bounding_box.width / 2.0); 73 | temp(j,1) = (shape(j,1)-bounding_box.centroid_y) / (bounding_box.height / 2.0); 74 | } 75 | return temp; 76 | } 77 | 78 | Mat_ ReProjectShape(const Mat_& shape, const BoundingBox& bounding_box){ 79 | Mat_ temp(shape.rows,2); 80 | for(int j = 0;j < shape.rows;j++){ 81 | temp(j,0) = (shape(j,0) * bounding_box.width / 2.0 + bounding_box.centroid_x); 82 | temp(j,1) = (shape(j,1) * bounding_box.height / 2.0 + bounding_box.centroid_y); 83 | } 84 | return temp; 85 | } 86 | 87 | 88 | void SimilarityTransform(const Mat_& shape1, const Mat_& shape2, 89 | Mat_& rotation,float& scale){ 90 | rotation = Mat::zeros(2,2,CV_32FC1); 91 | scale = 0; 92 | 93 | // center the data 94 | float center_x_1 = 0; 95 | float center_y_1 = 0; 96 | float center_x_2 = 0; 97 | float center_y_2 = 0; 98 | for(int i = 0;i < shape1.rows;i++){ 99 | center_x_1 += shape1(i,0); 100 | center_y_1 += shape1(i,1); 101 | center_x_2 += shape2(i,0); 102 | center_y_2 += shape2(i,1); 103 | } 104 | center_x_1 /= shape1.rows; 105 | center_y_1 /= shape1.rows; 106 | center_x_2 /= shape2.rows; 107 | center_y_2 /= shape2.rows; 108 | 109 | Mat_ temp1 = shape1.clone(); 110 | Mat_ temp2 = shape2.clone(); 111 | for(int i = 0;i < shape1.rows;i++){ 112 | temp1(i,0) -= center_x_1; 113 | temp1(i,1) -= center_y_1; 114 | temp2(i,0) -= center_x_2; 115 | temp2(i,1) -= center_y_2; 116 | } 117 | Mat_ covariance1, covariance2; 118 | Mat_ mean1,mean2; 119 | // calculate covariance matrix 120 | calcCovarMatrix(temp1,covariance1,mean1,CV_COVAR_SCALE|CV_COVAR_ROWS|CV_COVAR_NORMAL,CV_32F); 121 | calcCovarMatrix(temp2,covariance2,mean2,CV_COVAR_SCALE|CV_COVAR_ROWS|CV_COVAR_NORMAL,CV_32F); 122 | //cout<& v_1, 145 | const vector& v_2){ 146 | Mat_ v1(v_1); 147 | Mat_ v2(v_2); 148 | float mean_1 = mean(v1)[0]; 149 | float mean_2 = mean(v2)[0]; 150 | v1 = v1 - mean_1; 151 | v2 = v2 - mean_2; 152 | return mean(v1.mul(v2))[0]; 153 | } 154 | 155 | BoundingBox CalculateBoundingBox(Mat_& img, Mat_& shape){ 156 | BoundingBox bbx; 157 | float left_x = 10000; 158 | float right_x = 0; 159 | float top_y = 10000; 160 | float bottom_y = 0; 161 | for (int i=0; i < shape.rows;i++){ 162 | if (shape(i,0) < left_x) 163 | left_x = shape(i,0); 164 | if (shape(i,0) > right_x) 165 | right_x = shape(i,0); 166 | if (shape(i,1) < top_y) 167 | top_y = shape(i,1); 168 | if (shape(i,1) > bottom_y) 169 | bottom_y = shape(i,1); 170 | } 171 | //bbx.centroid_x = shape(15,0); 172 | //bbx.centroid_y = shape(15,1); 173 | ///*circle(img, Point(bbx.centroid_x, bbx.centroid_y), 3, Scalar(255)); 174 | //imshow("test2", img); 175 | //waitKey(0);*/ 176 | ///*float maxw = min(right_x - bbx.centroid_x, bbx.centroid_x - left_x); 177 | //float maxh = min(bottom_y - bbx.centroid_y, bbx.centroid_y - top_y);*/ 178 | // bbx.start_x = min(img.cols - 1.0f, max(0.f, bbx.centroid_x - (right_x - left_x))); 179 | // bbx.start_y = min(img.rows - 1.0f, max(0.f, bbx.centroid_y - (bottom_y - top_y))); 180 | //float tmp1 = min(img.cols - 1.0f, max(0.f, bbx.centroid_x + (right_x - left_x))); 181 | //float tmp2 = min(img.rows - 1.0f, max(0.f, bbx.centroid_y + (bottom_y - top_y))); 182 | // bbx.width = 2 * (bbx.centroid_x - bbx.start_x); 183 | // bbx.height = 2 * (bbx.centroid_y - bbx.start_y); 184 | bbx.start_x = left_x; 185 | bbx.start_y = top_y; 186 | bbx.height = bottom_y - top_y; 187 | bbx.width = right_x - left_x; 188 | bbx.centroid_x = bbx.start_x + bbx.width / 2.0; 189 | bbx.centroid_y = bbx.start_y + bbx.height / 2.0; 190 | return bbx; 191 | } 192 | void cropBoundingBox(Mat_& img, BoundingBox box, BoundingBox& newbox/*, Mat_ shape, Mat_& newshape*/) { 193 | RNG random_generator(getTickCount()); 194 | do{ 195 | float step1 = random_generator.uniform(-CROP, CROP); 196 | float step2 = random_generator.uniform(-CROP, CROP); 197 | newbox.centroid_x = box.centroid_x - box.width*step1; 198 | newbox.centroid_y = box.centroid_y - box.height*step2; 199 | newbox.start_x = newbox.centroid_x - box.width/2; 200 | newbox.start_y = newbox.centroid_y - box.height/2; 201 | newbox.height = box.height; 202 | newbox.width = box.width; 203 | } while (newbox.start_x<0 || newbox.start_x>=img.cols|| 204 | newbox.start_y<0 || newbox.start_y>=img.rows|| 205 | (newbox.start_x + newbox.width) < 0 || (newbox.start_x + newbox.width) >= img.cols || 206 | (newbox.start_y + newbox.height)< 0 || (newbox.start_y + newbox.height) >=img.rows); 207 | /*float offsetx = newbox.centroid_x - box.centroid_x; 208 | float offsety = newbox.centroid_y - box.centroid_y; 209 | for (int i=0;i<28;++i) 210 | { 211 | newshape(i, 0) = shape(i, 0) + offsetx; 212 | newshape(i, 1) = shape(i, 1) + offsety; 213 | }*/ 214 | } 215 | void adjustImage(Mat_& img, 216 | Mat_& ground_truth_shape, 217 | BoundingBox& bounding_box){ 218 | /*imshow("test",img); 219 | waitKey(0);*/ 220 | float left_x = max(1.0, (double)bounding_box.centroid_x - bounding_box.width*0.8); 221 | float top_y = max(1.0, (double)bounding_box.centroid_y - bounding_box.height*0.8); 222 | float right_x = min(img.cols-1.0,(double)bounding_box.centroid_x+bounding_box.width*0.8); 223 | float bottom_y= min(img.rows-1.0,(double)bounding_box.centroid_y+bounding_box.height*0.8); 224 | 225 | img = img.rowRange((int)top_y,(int)bottom_y).colRange((int)left_x,(int)right_x).clone(); 226 | 227 | 228 | 229 | 230 | bounding_box.start_x = ((int)right_x - (int)left_x)*CROP; 231 | bounding_box.start_y = ((int)bottom_y - (int)top_y)*CROP; 232 | bounding_box.width = ((int)right_x - (int)left_x)*(1-2*CROP)-1; 233 | bounding_box.height = ((int)bottom_y - (int)top_y)*(1-2*CROP)-1; 234 | bounding_box.centroid_x = bounding_box.start_x + bounding_box.width / 2.0; 235 | bounding_box.centroid_y = bounding_box.start_y + bounding_box.height / 2.0; 236 | 237 | for(int i=0;iMAXHEIGHT_POS) 247 | { 248 | float scale=MAXHEIGHT_POS/ori_height; 249 | resize(img,img,Size(ori_weight*scale,ori_height*scale)); 250 | bounding_box.start_x*=scale; 251 | bounding_box.start_y*=scale; 252 | bounding_box.centroid_x*=scale; 253 | bounding_box.centroid_y*=scale; 254 | bounding_box.width*=scale; 255 | bounding_box.height*=scale; 256 | for(int i=0;i& image, const BoundingBox& old_box, BoundingBox& new_box){ 270 | RNG random_generator(getTickCount()); 271 | do{ 272 | new_box.start_x = random_generator.uniform(0, image.cols - 1); 273 | new_box.start_y = random_generator.uniform(0, image.rows - 1); 274 | new_box.height = random_generator.uniform(MINHEIGHT, image.rows - 1); 275 | new_box.width = (int)(new_box.height*old_box.width / old_box.height); 276 | } while (new_box.start_x+ new_box.width>=image.cols|| 277 | new_box.start_y + new_box.height>=image.rows); 278 | 279 | new_box.centroid_x = new_box.start_x + new_box.width /2.0; 280 | new_box.centroid_y = new_box.start_y + new_box.height /2.0; 281 | } 282 | 283 | float CalculateError(const Mat_& ground_truth_shape, const Mat_& predicted_shape) { 284 | Mat_ temp; 285 | //temp = ground_truth_shape.rowRange(36, 37)-ground_truth_shape.rowRange(45, 46); 286 | temp = ground_truth_shape.rowRange(1, 2) - ground_truth_shape.rowRange(6, 7); 287 | float x = mean(temp.col(0))[0]; 288 | float y = mean(temp.col(1))[1]; 289 | float interocular_distance = sqrt(x*x + y*y); 290 | float sum = 0; 291 | for (int i = 0; i < ground_truth_shape.rows; i++) { 292 | sum += norm(ground_truth_shape.row(i) - predicted_shape.row(i)); 293 | } 294 | return sum / (ground_truth_shape.rows*interocular_distance); 295 | } 296 | -------------------------------------------------------------------------------- /randomforest.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // RandomForest.cpp 3 | // myopencv 4 | // 5 | // Created by lequan on 1/24/15. 6 | // Copyright (c) 2015 lequan. All rights reserved. 7 | // 8 | 9 | #include "RandomForest.h" 10 | #include "LBFRegressor.h" 11 | using namespace std; 12 | using namespace cv; 13 | #define max(a,b) (((a) > (b)) ? (a) : (b)) 14 | #define min(a,b) (((a) < (b)) ? (a) : (b)) 15 | int perfomtimes = 0; 16 | void GetCodefromRandomForestOnlyOnce(struct feature_node *binfeature, 17 | const int index, 18 | const vector& rand_forest, 19 | const Mat_& image, 20 | const Mat_& shape, 21 | const BoundingBox& bounding_box, 22 | const Mat_& rotation, 23 | const float scale){ 24 | 25 | int leafnode_per_tree = pow(2.0,rand_forest[0].max_depth_-1); 26 | 27 | for (int iter = 0;iter& current_shapes, 79 | BoundingBox& bounding_boxs, 80 | const Mat_& mean_shape, 81 | vector& models 82 | ){ 83 | float tmp; 84 | float scale; 85 | Mat_rotation; 86 | int num_residual = current_shapes.rows*2; 87 | Mat_ deltashape_bar(num_residual/2,2); 88 | Mat_ deltashape_bar1(num_residual/2,2); 89 | 90 | #pragma omp parallel for 91 | for (int j=0;j p1, pair p2) 109 | { 110 | return p1.first < p2.first; 111 | }; 112 | 113 | void RandomForest::Train(vector >& images, 114 | vector& augmented_images, 115 | vector >& ground_truth_shapes, 116 | vector& ground_truth_faces, 117 | vector >& current_shapes, 118 | vector& current_fi, 119 | vector& current_weight, 120 | vector & bounding_boxs, 121 | const Mat_& mean_shape, 122 | vector >& shapes_residual, 123 | int stages, 124 | vector& RandomForest_, 125 | vector > Models_, int posLenth) { 126 | stages_ = stages; 127 | // all training samples 128 | vector index; 129 | for (int k = 0; k < augmented_images.size(); k++) 130 | index.push_back(k); 131 | 132 | for (int i = 0; i < num_landmark_; i++) 133 | { 134 | clock_t tt_clk = clock(); 135 | for (int j = 0; j < max_numtrees_; j++) 136 | { 137 | clock_t ss_clk = clock(); 138 | // update weight 139 | double totalWeight = 0; 140 | for (int k = 0; k < current_weight.size(); ++k) { 141 | current_weight[k] = min(100, exp(0.0 - ground_truth_faces[k] * current_fi[k])); 142 | totalWeight += current_weight[k]; 143 | } 144 | for (int k = 0; k < current_weight.size(); ++k) 145 | { 146 | current_weight[k] /= totalWeight; 147 | } 148 | 149 | // build RF 150 | rfs_[i][j].Train(images, augmented_images, ground_truth_shapes, ground_truth_faces, current_shapes, current_fi, current_weight, bounding_boxs, mean_shape, shapes_residual, index, stages_, i); 151 | 152 | // compute all samples's fi 153 | #pragma omp parallel for 154 | for (int n = 0; n < augmented_images.size(); ++n) 155 | { 156 | Mat_ rotation; 157 | float scale; 158 | SimilarityTransform(ProjectShape(current_shapes[n], bounding_boxs[n]), mean_shape, rotation, scale); 159 | int bincode = 0; 160 | float score = 0; 161 | GetResultfromTree(rfs_[i][j], images[augmented_images[n]], current_shapes[n], bounding_boxs[n], rotation, scale, &bincode, &score); 162 | current_fi[n] = current_fi[n] + score; 163 | } 164 | float fiT = 0, fiF = 0; 165 | double weightT = 0, weigthF = 0; 166 | int numT = 0, numF = 0; 167 | double maxF = DBL_MIN, minF = DBL_MAX; 168 | double maxW = DBL_MIN, minW = DBL_MAX; 169 | int maxImgIdx = 0; 170 | for (int n = 0; n < current_fi.size(); ++n) 171 | { 172 | if (ground_truth_faces[n] == 1) { 173 | fiT += current_fi[n]; 174 | weightT += current_weight[n]; 175 | ++numT; 176 | } 177 | else { 178 | fiF += current_fi[n]; 179 | weigthF += current_weight[n]; 180 | ++numF; 181 | } 182 | if (current_fi[n] > maxF) { 183 | maxF = current_fi[n]; 184 | } 185 | if (current_fi[n] < minF) { 186 | minF = current_fi[n]; 187 | } 188 | if (current_weight[n] > maxW) { 189 | maxW = current_weight[n]; 190 | maxImgIdx = n; 191 | } 192 | if (current_weight[n] < minW) { 193 | minW = current_weight[n]; 194 | } 195 | } 196 | cout << "fiTsum:" << fiT << " fiFsum:" << fiF << endl; 197 | cout << "weightTsum:" << weightT << " weightFsum:" << weigthF << endl; 198 | cout << "max fi:" << maxF << "\t\tmin fi:" << minF << endl; 199 | cout << "max weight:" << maxW << "\t\tmin weight:" << minW << endl; 200 | cout << "avg fiT:" << fiT / numT << "\t\tavg fiF:" << fiF / numF << endl; 201 | cout << "avg weightT:" << weightT / numT << "\t\tavg weightF:" << weigthF / numF << endl; 202 | if (1) 203 | { 204 | Mat_tmpimg = images[augmented_images[maxImgIdx]].clone(); 205 | for (int k = 0; k < current_shapes[maxImgIdx].rows; k++) { 206 | circle(tmpimg, Point(current_shapes[maxImgIdx](k, 0), current_shapes[maxImgIdx](k, 1)), 3, Scalar(255)); 207 | } 208 | rectangle(tmpimg, Point((int)bounding_boxs[maxImgIdx].start_x, (int)bounding_boxs[maxImgIdx].start_y), 209 | Point((int)bounding_boxs[maxImgIdx].start_x + bounding_boxs[maxImgIdx].width, 210 | (int)bounding_boxs[maxImgIdx].start_y + bounding_boxs[maxImgIdx].height), Scalar(255)); 211 | char tmpname[512]; 212 | sprintf(tmpname, "%d_%d_%d_%d_%f.jpg", stages_, i, j, ground_truth_faces[maxImgIdx], current_weight[maxImgIdx]); 213 | imwrite(tmpname, tmpimg); 214 | } 215 | // sort fi with index 216 | vector > fiSort; 217 | fiSort.clear(); 218 | for (int n = 0; n < current_fi.size(); ++n) 219 | fiSort.push_back(pair(current_fi[n], n)); 220 | sort(fiSort.begin(), fiSort.end(), my_cmp); 221 | // compute recall set threshold 222 | float max_recall = 0, min_error = 1; 223 | int idx_tmp = -1; 224 | vector > precise_recall; 225 | for (int n = 0; n < fiSort.size(); ++n) 226 | { 227 | int true_pos = 0; int false_neg = 0; 228 | int true_neg = 0; int false_pos = 0; 229 | for (int m = 0; m < fiSort.size(); ++m) 230 | { 231 | int isFace = ground_truth_faces[fiSort[m].second]; 232 | // below the threshold as non-face 233 | if (m < n) { 234 | if (isFace == 1) { 235 | false_neg++; 236 | } 237 | else { 238 | true_neg++; 239 | } 240 | } 241 | else { 242 | if (isFace == 1) { 243 | true_pos++; 244 | } 245 | else { 246 | false_pos++; 247 | } 248 | } 249 | } 250 | if (true_pos / (true_pos + false_neg + FLT_MIN) >= max_recall) { 251 | max_recall = true_pos / (true_pos + false_neg + FLT_MIN); 252 | precise_recall.push_back(pair(true_pos / (true_pos + false_neg + FLT_MIN), false_pos / (false_pos + true_neg + FLT_MIN))); 253 | rfs_[i][j].threshold = fiSort[n].first; 254 | } 255 | else 256 | break; 257 | } 258 | cout << "pre_recall in tree:" << precise_recall[precise_recall.size() - 1].first << " " << precise_recall[precise_recall.size() - 1].second << endl; 259 | ///////////////////////////////////////////////////////////////////////////// 260 | if (precise_recall[precise_recall.size() - 1].second < 0.5) 261 | { 262 | perfomtimes++; 263 | cout << "perform hard negative mining...." << perfomtimes << endl; 264 | int nn = posLenth*global_params.initial_num; 265 | int findtimes = 0; 266 | bool stop = false; 267 | #pragma omp parallel 268 | { 269 | while (!stop) 270 | { 271 | // if (current_fi[nn] >= rfs_[i][j].threshold) 272 | // { 273 | //#pragma omp critical { 274 | // nn++; 275 | // continue; 276 | // } 277 | // 278 | // } 279 | findtimes++; 280 | 281 | RNG random_generator(getTickCount()); 282 | int idx = random_generator.uniform(posLenth, images.size() - 1); 283 | int idx2 = random_generator.uniform(0, posLenth - 1); 284 | BoundingBox new_box; 285 | getRandomBox(images[idx], bounding_boxs[idx2], new_box); 286 | Mat_ temp2 = ProjectShape(ground_truth_shapes[idx2], bounding_boxs[idx2]); 287 | Mat_ tmp_current_shapes = ReProjectShape(temp2, new_box); 288 | 289 | bool tmp_isface = true; 290 | float tmp_fi = 0; 291 | 292 | for (int s = 0; s <= stages; ++s) 293 | { 294 | int iRange = RandomForest_[s].rfs_.size() - 1; 295 | if (s == stages) { 296 | iRange = i; 297 | } 298 | for (int r = 0; r <= iRange; ++r) { 299 | int jRange = RandomForest_[s].rfs_[r].size() - 1; 300 | if (r == i && s == stages) { 301 | jRange = j; 302 | } 303 | for (int t = 0; t <= jRange; ++t) { 304 | Mat_ rotation; 305 | float scale; 306 | SimilarityTransform(ProjectShape(tmp_current_shapes, new_box), mean_shape, rotation, scale); 307 | int bincode = 0; 308 | float score = 0; 309 | GetResultfromTree(RandomForest_[s].rfs_[r][t], images[idx], tmp_current_shapes, new_box, rotation, scale, &bincode, &score); 310 | tmp_fi += score; 311 | if (tmp_fi < RandomForest_[s].rfs_[r][t].threshold) { 312 | tmp_isface = false; 313 | break; 314 | } 315 | } 316 | if (!tmp_isface)break; 317 | } 318 | if (!tmp_isface)break; 319 | if ((s - 1) >= 0) 320 | { 321 | struct feature_node **binfeatures = new struct feature_node*[1]; 322 | binfeatures[0] = new struct feature_node[RandomForest_[s - 1].max_numtrees_*RandomForest_[s - 1].num_landmark_ + 1]; 323 | Mat_ rotation; 324 | float scale; 325 | SimilarityTransform(ProjectShape(tmp_current_shapes, new_box), mean_shape, rotation, scale); 326 | for (int j1 = 0; j1 < RandomForest_[s - 1].num_landmark_; j1++) { 327 | GetCodefromRandomForestOnlyOnce(binfeatures[0], j1*RandomForest_[s - 1].max_numtrees_, 328 | RandomForest_[s - 1].rfs_[j1], images[idx], tmp_current_shapes, 329 | new_box, rotation, scale); 330 | } 331 | binfeatures[0][RandomForest_[s - 1].num_landmark_ * RandomForest_[s - 1].max_numtrees_].index = -1; 332 | binfeatures[0][RandomForest_[s - 1].num_landmark_ * RandomForest_[s - 1].max_numtrees_].value = -1; 333 | GlobalRegressionOnlyOnce(binfeatures, tmp_current_shapes, new_box, mean_shape, Models_[s - 1]); 334 | delete[] binfeatures[0]; 335 | delete[] binfeatures; 336 | } 337 | } 338 | if (tmp_isface) { 339 | #pragma omp critical 340 | { 341 | if (nn < current_fi.size()) { 342 | augmented_images[nn] = idx; 343 | current_shapes[nn] = tmp_current_shapes; 344 | bounding_boxs[nn] = new_box; 345 | current_fi[nn] = tmp_fi; 346 | nn++; 347 | } 348 | else 349 | stop = true; 350 | } 351 | } 352 | /*if (findtimes > 1000000) 353 | { 354 | break; 355 | }*/ 356 | } 357 | } 358 | } 359 | float time = float(clock() - ss_clk) / CLOCKS_PER_SEC; 360 | cout << "stage: " << stages << " landmark: " << i << " tree: " << j << " time:" << time << endl; 361 | } 362 | float time = float(clock() - tt_clk) / CLOCKS_PER_SEC; 363 | cout << "the train rf of " << i << "th landmark cost " << time << "s" << endl; 364 | } 365 | } 366 | void RandomForest::Write(std::ofstream& fout){ 367 | fout << stages_ <> stages_; 380 | fin >> max_numtrees_; 381 | fin >> num_landmark_; 382 | fin >> max_depth_; 383 | fin >> overlap_ratio_; 384 | for (int i=0; i< num_landmark_;i++){ 385 | for (int j = 0; j < max_numtrees_; j++){ 386 | rfs_[i][j].Read(fin); 387 | } 388 | } 389 | } 390 | 391 | -------------------------------------------------------------------------------- /blasp.h: -------------------------------------------------------------------------------- 1 | /* blasp.h -- C prototypes for BLAS Ver 1.0 */ 2 | /* Jesse Bennett March 23, 2000 */ 3 | 4 | /* Functions listed in alphabetical order */ 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | #ifdef F2C_COMPAT 11 | 12 | void cdotc_(fcomplex *dotval, int *n, fcomplex *cx, int *incx, 13 | fcomplex *cy, int *incy); 14 | 15 | void cdotu_(fcomplex *dotval, int *n, fcomplex *cx, int *incx, 16 | fcomplex *cy, int *incy); 17 | 18 | float sasum_(int *n, float *sx, int *incx); 19 | 20 | float scasum_(int *n, fcomplex *cx, int *incx); 21 | 22 | float scnrm2_(int *n, fcomplex *x, int *incx); 23 | 24 | float sdot_(int *n, float *sx, int *incx, float *sy, int *incy); 25 | 26 | float snrm2_(int *n, float *x, int *incx); 27 | 28 | void zdotc_(dcomplex *dotval, int *n, dcomplex *cx, int *incx, 29 | dcomplex *cy, int *incy); 30 | 31 | void zdotu_(dcomplex *dotval, int *n, dcomplex *cx, int *incx, 32 | dcomplex *cy, int *incy); 33 | 34 | #else 35 | 36 | fcomplex cdotc_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy); 37 | 38 | fcomplex cdotu_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy); 39 | 40 | float sasum_(int *n, float *sx, int *incx); 41 | 42 | float scasum_(int *n, fcomplex *cx, int *incx); 43 | 44 | float scnrm2_(int *n, fcomplex *x, int *incx); 45 | 46 | float sdot_(int *n, float *sx, int *incx, float *sy, int *incy); 47 | 48 | float snrm2_(int *n, float *x, int *incx); 49 | 50 | dcomplex zdotc_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy); 51 | 52 | dcomplex zdotu_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy); 53 | 54 | #endif 55 | 56 | /* Remaining functions listed in alphabetical order */ 57 | 58 | int caxpy_(int *n, fcomplex *ca, fcomplex *cx, int *incx, fcomplex *cy, 59 | int *incy); 60 | 61 | int ccopy_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy); 62 | 63 | int cgbmv_(char *trans, int *m, int *n, int *kl, int *ku, 64 | fcomplex *alpha, fcomplex *a, int *lda, fcomplex *x, int *incx, 65 | fcomplex *beta, fcomplex *y, int *incy); 66 | 67 | int cgemm_(char *transa, char *transb, int *m, int *n, int *k, 68 | fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b, int *ldb, 69 | fcomplex *beta, fcomplex *c, int *ldc); 70 | 71 | int cgemv_(char *trans, int *m, int *n, fcomplex *alpha, fcomplex *a, 72 | int *lda, fcomplex *x, int *incx, fcomplex *beta, fcomplex *y, 73 | int *incy); 74 | 75 | int cgerc_(int *m, int *n, fcomplex *alpha, fcomplex *x, int *incx, 76 | fcomplex *y, int *incy, fcomplex *a, int *lda); 77 | 78 | int cgeru_(int *m, int *n, fcomplex *alpha, fcomplex *x, int *incx, 79 | fcomplex *y, int *incy, fcomplex *a, int *lda); 80 | 81 | int chbmv_(char *uplo, int *n, int *k, fcomplex *alpha, fcomplex *a, 82 | int *lda, fcomplex *x, int *incx, fcomplex *beta, fcomplex *y, 83 | int *incy); 84 | 85 | int chemm_(char *side, char *uplo, int *m, int *n, fcomplex *alpha, 86 | fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta, 87 | fcomplex *c, int *ldc); 88 | 89 | int chemv_(char *uplo, int *n, fcomplex *alpha, fcomplex *a, int *lda, 90 | fcomplex *x, int *incx, fcomplex *beta, fcomplex *y, int *incy); 91 | 92 | int cher_(char *uplo, int *n, float *alpha, fcomplex *x, int *incx, 93 | fcomplex *a, int *lda); 94 | 95 | int cher2_(char *uplo, int *n, fcomplex *alpha, fcomplex *x, int *incx, 96 | fcomplex *y, int *incy, fcomplex *a, int *lda); 97 | 98 | int cher2k_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha, 99 | fcomplex *a, int *lda, fcomplex *b, int *ldb, float *beta, 100 | fcomplex *c, int *ldc); 101 | 102 | int cherk_(char *uplo, char *trans, int *n, int *k, float *alpha, 103 | fcomplex *a, int *lda, float *beta, fcomplex *c, int *ldc); 104 | 105 | int chpmv_(char *uplo, int *n, fcomplex *alpha, fcomplex *ap, fcomplex *x, 106 | int *incx, fcomplex *beta, fcomplex *y, int *incy); 107 | 108 | int chpr_(char *uplo, int *n, float *alpha, fcomplex *x, int *incx, 109 | fcomplex *ap); 110 | 111 | int chpr2_(char *uplo, int *n, fcomplex *alpha, fcomplex *x, int *incx, 112 | fcomplex *y, int *incy, fcomplex *ap); 113 | 114 | int crotg_(fcomplex *ca, fcomplex *cb, float *c, fcomplex *s); 115 | 116 | int cscal_(int *n, fcomplex *ca, fcomplex *cx, int *incx); 117 | 118 | int csscal_(int *n, float *sa, fcomplex *cx, int *incx); 119 | 120 | int cswap_(int *n, fcomplex *cx, int *incx, fcomplex *cy, int *incy); 121 | 122 | int csymm_(char *side, char *uplo, int *m, int *n, fcomplex *alpha, 123 | fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta, 124 | fcomplex *c, int *ldc); 125 | 126 | int csyr2k_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha, 127 | fcomplex *a, int *lda, fcomplex *b, int *ldb, fcomplex *beta, 128 | fcomplex *c, int *ldc); 129 | 130 | int csyrk_(char *uplo, char *trans, int *n, int *k, fcomplex *alpha, 131 | fcomplex *a, int *lda, fcomplex *beta, fcomplex *c, int *ldc); 132 | 133 | int ctbmv_(char *uplo, char *trans, char *diag, int *n, int *k, 134 | fcomplex *a, int *lda, fcomplex *x, int *incx); 135 | 136 | int ctbsv_(char *uplo, char *trans, char *diag, int *n, int *k, 137 | fcomplex *a, int *lda, fcomplex *x, int *incx); 138 | 139 | int ctpmv_(char *uplo, char *trans, char *diag, int *n, fcomplex *ap, 140 | fcomplex *x, int *incx); 141 | 142 | int ctpsv_(char *uplo, char *trans, char *diag, int *n, fcomplex *ap, 143 | fcomplex *x, int *incx); 144 | 145 | int ctrmm_(char *side, char *uplo, char *transa, char *diag, int *m, 146 | int *n, fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b, 147 | int *ldb); 148 | 149 | int ctrmv_(char *uplo, char *trans, char *diag, int *n, fcomplex *a, 150 | int *lda, fcomplex *x, int *incx); 151 | 152 | int ctrsm_(char *side, char *uplo, char *transa, char *diag, int *m, 153 | int *n, fcomplex *alpha, fcomplex *a, int *lda, fcomplex *b, 154 | int *ldb); 155 | 156 | int ctrsv_(char *uplo, char *trans, char *diag, int *n, fcomplex *a, 157 | int *lda, fcomplex *x, int *incx); 158 | 159 | int daxpy_(int *n, float *sa, float *sx, int *incx, float *sy, 160 | int *incy); 161 | 162 | int dcopy_(int *n, float *sx, int *incx, float *sy, int *incy); 163 | 164 | int dgbmv_(char *trans, int *m, int *n, int *kl, int *ku, 165 | float *alpha, float *a, int *lda, float *x, int *incx, 166 | float *beta, float *y, int *incy); 167 | 168 | int dgemm_(char *transa, char *transb, int *m, int *n, int *k, 169 | float *alpha, float *a, int *lda, float *b, int *ldb, 170 | float *beta, float *c, int *ldc); 171 | 172 | int dgemv_(char *trans, int *m, int *n, float *alpha, float *a, 173 | int *lda, float *x, int *incx, float *beta, float *y, 174 | int *incy); 175 | 176 | int dger_(int *m, int *n, float *alpha, float *x, int *incx, 177 | float *y, int *incy, float *a, int *lda); 178 | 179 | int drot_(int *n, float *sx, int *incx, float *sy, int *incy, 180 | float *c, float *s); 181 | 182 | int drotg_(float *sa, float *sb, float *c, float *s); 183 | 184 | int dsbmv_(char *uplo, int *n, int *k, float *alpha, float *a, 185 | int *lda, float *x, int *incx, float *beta, float *y, 186 | int *incy); 187 | 188 | int dscal_(int *n, float *sa, float *sx, int *incx); 189 | 190 | int dspmv_(char *uplo, int *n, float *alpha, float *ap, float *x, 191 | int *incx, float *beta, float *y, int *incy); 192 | 193 | int dspr_(char *uplo, int *n, float *alpha, float *x, int *incx, 194 | float *ap); 195 | 196 | int dspr2_(char *uplo, int *n, float *alpha, float *x, int *incx, 197 | float *y, int *incy, float *ap); 198 | 199 | int dswap_(int *n, float *sx, int *incx, float *sy, int *incy); 200 | 201 | int dsymm_(char *side, char *uplo, int *m, int *n, float *alpha, 202 | float *a, int *lda, float *b, int *ldb, float *beta, 203 | float *c, int *ldc); 204 | 205 | int dsymv_(char *uplo, int *n, float *alpha, float *a, int *lda, 206 | float *x, int *incx, float *beta, float *y, int *incy); 207 | 208 | int dsyr_(char *uplo, int *n, float *alpha, float *x, int *incx, 209 | float *a, int *lda); 210 | 211 | int dsyr2_(char *uplo, int *n, float *alpha, float *x, int *incx, 212 | float *y, int *incy, float *a, int *lda); 213 | 214 | int dsyr2k_(char *uplo, char *trans, int *n, int *k, float *alpha, 215 | float *a, int *lda, float *b, int *ldb, float *beta, 216 | float *c, int *ldc); 217 | 218 | int dsyrk_(char *uplo, char *trans, int *n, int *k, float *alpha, 219 | float *a, int *lda, float *beta, float *c, int *ldc); 220 | 221 | int dtbmv_(char *uplo, char *trans, char *diag, int *n, int *k, 222 | float *a, int *lda, float *x, int *incx); 223 | 224 | int dtbsv_(char *uplo, char *trans, char *diag, int *n, int *k, 225 | float *a, int *lda, float *x, int *incx); 226 | 227 | int dtpmv_(char *uplo, char *trans, char *diag, int *n, float *ap, 228 | float *x, int *incx); 229 | 230 | int dtpsv_(char *uplo, char *trans, char *diag, int *n, float *ap, 231 | float *x, int *incx); 232 | 233 | int dtrmm_(char *side, char *uplo, char *transa, char *diag, int *m, 234 | int *n, float *alpha, float *a, int *lda, float *b, 235 | int *ldb); 236 | 237 | int dtrmv_(char *uplo, char *trans, char *diag, int *n, float *a, 238 | int *lda, float *x, int *incx); 239 | 240 | int dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, 241 | int *n, float *alpha, float *a, int *lda, float *b, 242 | int *ldb); 243 | 244 | int dtrsv_(char *uplo, char *trans, char *diag, int *n, float *a, 245 | int *lda, float *x, int *incx); 246 | 247 | 248 | int saxpy_(int *n, float *sa, float *sx, int *incx, float *sy, int *incy); 249 | 250 | int scopy_(int *n, float *sx, int *incx, float *sy, int *incy); 251 | 252 | int sgbmv_(char *trans, int *m, int *n, int *kl, int *ku, 253 | float *alpha, float *a, int *lda, float *x, int *incx, 254 | float *beta, float *y, int *incy); 255 | 256 | int sgemm_(char *transa, char *transb, int *m, int *n, int *k, 257 | float *alpha, float *a, int *lda, float *b, int *ldb, 258 | float *beta, float *c, int *ldc); 259 | 260 | int sgemv_(char *trans, int *m, int *n, float *alpha, float *a, 261 | int *lda, float *x, int *incx, float *beta, float *y, 262 | int *incy); 263 | 264 | int sger_(int *m, int *n, float *alpha, float *x, int *incx, 265 | float *y, int *incy, float *a, int *lda); 266 | 267 | int srot_(int *n, float *sx, int *incx, float *sy, int *incy, 268 | float *c, float *s); 269 | 270 | int srotg_(float *sa, float *sb, float *c, float *s); 271 | 272 | int ssbmv_(char *uplo, int *n, int *k, float *alpha, float *a, 273 | int *lda, float *x, int *incx, float *beta, float *y, 274 | int *incy); 275 | 276 | int sscal_(int *n, float *sa, float *sx, int *incx); 277 | 278 | int sspmv_(char *uplo, int *n, float *alpha, float *ap, float *x, 279 | int *incx, float *beta, float *y, int *incy); 280 | 281 | int sspr_(char *uplo, int *n, float *alpha, float *x, int *incx, 282 | float *ap); 283 | 284 | int sspr2_(char *uplo, int *n, float *alpha, float *x, int *incx, 285 | float *y, int *incy, float *ap); 286 | 287 | int sswap_(int *n, float *sx, int *incx, float *sy, int *incy); 288 | 289 | int ssymm_(char *side, char *uplo, int *m, int *n, float *alpha, 290 | float *a, int *lda, float *b, int *ldb, float *beta, 291 | float *c, int *ldc); 292 | 293 | int ssymv_(char *uplo, int *n, float *alpha, float *a, int *lda, 294 | float *x, int *incx, float *beta, float *y, int *incy); 295 | 296 | int ssyr_(char *uplo, int *n, float *alpha, float *x, int *incx, 297 | float *a, int *lda); 298 | 299 | int ssyr2_(char *uplo, int *n, float *alpha, float *x, int *incx, 300 | float *y, int *incy, float *a, int *lda); 301 | 302 | int ssyr2k_(char *uplo, char *trans, int *n, int *k, float *alpha, 303 | float *a, int *lda, float *b, int *ldb, float *beta, 304 | float *c, int *ldc); 305 | 306 | int ssyrk_(char *uplo, char *trans, int *n, int *k, float *alpha, 307 | float *a, int *lda, float *beta, float *c, int *ldc); 308 | 309 | int stbmv_(char *uplo, char *trans, char *diag, int *n, int *k, 310 | float *a, int *lda, float *x, int *incx); 311 | 312 | int stbsv_(char *uplo, char *trans, char *diag, int *n, int *k, 313 | float *a, int *lda, float *x, int *incx); 314 | 315 | int stpmv_(char *uplo, char *trans, char *diag, int *n, float *ap, 316 | float *x, int *incx); 317 | 318 | int stpsv_(char *uplo, char *trans, char *diag, int *n, float *ap, 319 | float *x, int *incx); 320 | 321 | int strmm_(char *side, char *uplo, char *transa, char *diag, int *m, 322 | int *n, float *alpha, float *a, int *lda, float *b, 323 | int *ldb); 324 | 325 | int strmv_(char *uplo, char *trans, char *diag, int *n, float *a, 326 | int *lda, float *x, int *incx); 327 | 328 | int strsm_(char *side, char *uplo, char *transa, char *diag, int *m, 329 | int *n, float *alpha, float *a, int *lda, float *b, 330 | int *ldb); 331 | 332 | int strsv_(char *uplo, char *trans, char *diag, int *n, float *a, 333 | int *lda, float *x, int *incx); 334 | 335 | int zaxpy_(int *n, dcomplex *ca, dcomplex *cx, int *incx, dcomplex *cy, 336 | int *incy); 337 | 338 | int zcopy_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy); 339 | 340 | int zdscal_(int *n, float *sa, dcomplex *cx, int *incx); 341 | 342 | int zgbmv_(char *trans, int *m, int *n, int *kl, int *ku, 343 | dcomplex *alpha, dcomplex *a, int *lda, dcomplex *x, int *incx, 344 | dcomplex *beta, dcomplex *y, int *incy); 345 | 346 | int zgemm_(char *transa, char *transb, int *m, int *n, int *k, 347 | dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b, int *ldb, 348 | dcomplex *beta, dcomplex *c, int *ldc); 349 | 350 | int zgemv_(char *trans, int *m, int *n, dcomplex *alpha, dcomplex *a, 351 | int *lda, dcomplex *x, int *incx, dcomplex *beta, dcomplex *y, 352 | int *incy); 353 | 354 | int zgerc_(int *m, int *n, dcomplex *alpha, dcomplex *x, int *incx, 355 | dcomplex *y, int *incy, dcomplex *a, int *lda); 356 | 357 | int zgeru_(int *m, int *n, dcomplex *alpha, dcomplex *x, int *incx, 358 | dcomplex *y, int *incy, dcomplex *a, int *lda); 359 | 360 | int zhbmv_(char *uplo, int *n, int *k, dcomplex *alpha, dcomplex *a, 361 | int *lda, dcomplex *x, int *incx, dcomplex *beta, dcomplex *y, 362 | int *incy); 363 | 364 | int zhemm_(char *side, char *uplo, int *m, int *n, dcomplex *alpha, 365 | dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta, 366 | dcomplex *c, int *ldc); 367 | 368 | int zhemv_(char *uplo, int *n, dcomplex *alpha, dcomplex *a, int *lda, 369 | dcomplex *x, int *incx, dcomplex *beta, dcomplex *y, int *incy); 370 | 371 | int zher_(char *uplo, int *n, float *alpha, dcomplex *x, int *incx, 372 | dcomplex *a, int *lda); 373 | 374 | int zher2_(char *uplo, int *n, dcomplex *alpha, dcomplex *x, int *incx, 375 | dcomplex *y, int *incy, dcomplex *a, int *lda); 376 | 377 | int zher2k_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha, 378 | dcomplex *a, int *lda, dcomplex *b, int *ldb, float *beta, 379 | dcomplex *c, int *ldc); 380 | 381 | int zherk_(char *uplo, char *trans, int *n, int *k, float *alpha, 382 | dcomplex *a, int *lda, float *beta, dcomplex *c, int *ldc); 383 | 384 | int zhpmv_(char *uplo, int *n, dcomplex *alpha, dcomplex *ap, dcomplex *x, 385 | int *incx, dcomplex *beta, dcomplex *y, int *incy); 386 | 387 | int zhpr_(char *uplo, int *n, float *alpha, dcomplex *x, int *incx, 388 | dcomplex *ap); 389 | 390 | int zhpr2_(char *uplo, int *n, dcomplex *alpha, dcomplex *x, int *incx, 391 | dcomplex *y, int *incy, dcomplex *ap); 392 | 393 | int zrotg_(dcomplex *ca, dcomplex *cb, float *c, dcomplex *s); 394 | 395 | int zscal_(int *n, dcomplex *ca, dcomplex *cx, int *incx); 396 | 397 | int zswap_(int *n, dcomplex *cx, int *incx, dcomplex *cy, int *incy); 398 | 399 | int zsymm_(char *side, char *uplo, int *m, int *n, dcomplex *alpha, 400 | dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta, 401 | dcomplex *c, int *ldc); 402 | 403 | int zsyr2k_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha, 404 | dcomplex *a, int *lda, dcomplex *b, int *ldb, dcomplex *beta, 405 | dcomplex *c, int *ldc); 406 | 407 | int zsyrk_(char *uplo, char *trans, int *n, int *k, dcomplex *alpha, 408 | dcomplex *a, int *lda, dcomplex *beta, dcomplex *c, int *ldc); 409 | 410 | int ztbmv_(char *uplo, char *trans, char *diag, int *n, int *k, 411 | dcomplex *a, int *lda, dcomplex *x, int *incx); 412 | 413 | int ztbsv_(char *uplo, char *trans, char *diag, int *n, int *k, 414 | dcomplex *a, int *lda, dcomplex *x, int *incx); 415 | 416 | int ztpmv_(char *uplo, char *trans, char *diag, int *n, dcomplex *ap, 417 | dcomplex *x, int *incx); 418 | 419 | int ztpsv_(char *uplo, char *trans, char *diag, int *n, dcomplex *ap, 420 | dcomplex *x, int *incx); 421 | 422 | int ztrmm_(char *side, char *uplo, char *transa, char *diag, int *m, 423 | int *n, dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b, 424 | int *ldb); 425 | 426 | int ztrmv_(char *uplo, char *trans, char *diag, int *n, dcomplex *a, 427 | int *lda, dcomplex *x, int *incx); 428 | 429 | int ztrsm_(char *side, char *uplo, char *transa, char *diag, int *m, 430 | int *n, dcomplex *alpha, dcomplex *a, int *lda, dcomplex *b, 431 | int *ldb); 432 | 433 | int ztrsv_(char *uplo, char *trans, char *diag, int *n, dcomplex *a, 434 | int *lda, dcomplex *x, int *incx); 435 | 436 | #ifdef __cplusplus 437 | } 438 | #endif 439 | -------------------------------------------------------------------------------- /tree.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Tree.cpp 3 | // myopencv 4 | // 5 | // Created by lequan on 1/23/15. 6 | // Copyright (c) 2015 lequan. All rights reserved. 7 | // 8 | 9 | #include "Tree.h" 10 | using namespace std; 11 | using namespace cv; 12 | 13 | inline float calculate_var(const vector& v_1 ){ 14 | if (v_1.size() == 0) 15 | return 0; 16 | Mat_ v1(v_1); 17 | float mean_1 = mean(v1)[0]; 18 | float mean_2 = mean(v1.mul(v1))[0]; 19 | return mean_2 - mean_1*mean_1; 20 | 21 | } 22 | inline float calculate_var(const Mat_& v1){ 23 | if (v1.rows==0) 24 | { 25 | return 0; 26 | } 27 | float mean_1 = mean(v1)[0]; 28 | float mean_2 = mean(v1.mul(v1))[0]; 29 | return mean_2 - mean_1*mean_1; 30 | 31 | } 32 | 33 | void Tree::Train(const vector >& images, 34 | const vector& augmented_images, 35 | const vector >& ground_truth_shapes, 36 | const vector& ground_truth_faces, 37 | const vector >& current_shapes, 38 | const vector& current_fi, 39 | const vector& current_weight, 40 | const vector & bounding_boxs, 41 | const Mat_& mean_shape, 42 | const vector >& regression_targets, 43 | const vector index, 44 | int stages, 45 | int landmarkID 46 | ){ 47 | // set the parameter 48 | landmarkID_ = landmarkID; // start from 0 49 | max_numfeats_ = global_params.max_numfeats[stages]; 50 | max_radio_radius_ = global_params.max_radio_radius[stages]; 51 | max_probility_ = global_params.max_probility[stages]; 52 | num_nodes_ = 1; 53 | num_leafnodes_ = 1; 54 | // index: indicate the training samples id in images 55 | int num_nodes_iter; 56 | int num_split; 57 | Mat_ shapes_residual((int)regression_targets.size(),2); 58 | // calculate regression targets: the difference between ground truth shapes and current shapes 59 | for(int i = 0;i < regression_targets.size();i++){ 60 | shapes_residual(i,0) = regression_targets[i](landmarkID_,0); 61 | shapes_residual(i,1) = regression_targets[i](landmarkID_,1); 62 | } 63 | // initialize the root 64 | nodes_[0].issplit = false; 65 | nodes_[0].pnode = 0; 66 | nodes_[0].depth = 1; 67 | nodes_[0].cnodes[0] = 0; 68 | nodes_[0].cnodes[1] = 0; 69 | nodes_[0].isleafnode = 1; 70 | nodes_[0].thresh = 0; 71 | for (int i=0; i < 6;i++){ 72 | nodes_[0].feat[i] = 1; 73 | } 74 | nodes_[0].ind_samples = index; 75 | nodes_[0].score=0; 76 | 77 | bool stop = 0; 78 | int num_nodes = 1; 79 | int num_leafnodes = 1; 80 | float thresh; 81 | float feat[6]; 82 | bool isvaild; 83 | vector lcind,rcind; 84 | lcind.reserve(index.size()); 85 | rcind.reserve(index.size()); 86 | while(!stop){ 87 | num_nodes_iter = num_nodes_; 88 | num_split = 0; 89 | for (int n = 0; n < num_nodes_iter; n++ ){ 90 | if (!nodes_[n].issplit){ 91 | if (nodes_[n].depth == max_depth_) { 92 | if (nodes_[n].depth == 1){ 93 | nodes_[n].depth = 1; 94 | } 95 | nodes_[n].issplit = true; 96 | } 97 | else { 98 | // separate the samples into left and right path 99 | Splitnode(images,augmented_images,ground_truth_shapes,ground_truth_faces, 100 | current_shapes,current_fi,current_weight,bounding_boxs,mean_shape,shapes_residual, 101 | nodes_[n].ind_samples,thresh, feat, landmarkID_, isvaild,lcind,rcind,stages); 102 | // set the threshold and featture for current node 103 | nodes_[n].feat[0] = feat[0]; 104 | nodes_[n].feat[1] = feat[1]; 105 | nodes_[n].feat[2] = feat[2]; 106 | nodes_[n].feat[3] = feat[3]; 107 | nodes_[n].feat[4] = feat[4]; 108 | nodes_[n].feat[5] = feat[5]; 109 | nodes_[n].thresh = thresh; 110 | nodes_[n].issplit = true; 111 | nodes_[n].isleafnode = false; 112 | nodes_[n].cnodes[0] = num_nodes ; 113 | nodes_[n].cnodes[1] = num_nodes +1; 114 | //add left and right child nodes into the random tree 115 | nodes_[num_nodes].ind_samples = lcind; 116 | nodes_[num_nodes].issplit = false; 117 | nodes_[num_nodes].pnode = n; 118 | nodes_[num_nodes].depth = nodes_[n].depth + 1; 119 | nodes_[num_nodes].cnodes[0] = 0; 120 | nodes_[num_nodes].cnodes[1] = 0; 121 | nodes_[num_nodes].isleafnode = true; 122 | nodes_[num_nodes +1].ind_samples = rcind; 123 | nodes_[num_nodes +1].issplit = false; 124 | nodes_[num_nodes +1].pnode = n; 125 | nodes_[num_nodes +1].depth = nodes_[n].depth + 1; 126 | nodes_[num_nodes +1].cnodes[0] = 0; 127 | nodes_[num_nodes +1].cnodes[1] = 0; 128 | nodes_[num_nodes +1].isleafnode = true; 129 | num_split++; 130 | num_leafnodes++; 131 | num_nodes +=2; 132 | } 133 | } 134 | } 135 | if (num_split == 0){ 136 | stop = 1; 137 | } 138 | else{ 139 | num_nodes_ = num_nodes; 140 | num_leafnodes_ = num_leafnodes; 141 | } 142 | } 143 | id_leafnodes_.clear(); 144 | 145 | for (int i=0;i < num_nodes_;i++){ 146 | if (nodes_[i].isleafnode == 1){ 147 | // compute leaf node's score 148 | float leafy_pos_weight=0; 149 | float leafy_neg_weight=0; 150 | for (int j=0;j DBL_EPSILON && (leafy_neg_weight - 0.0) > DBL_EPSILON) 178 | { 179 | nodes_[i].score = 0.5*log(leafy_pos_weight/ leafy_neg_weight) / log(2.0f); 180 | } 181 | id_leafnodes_.push_back(i); 182 | } 183 | } 184 | } 185 | 186 | void Tree::Splitnode(const vector >& images, 187 | const vector& augmented_images, 188 | const vector >& ground_truth_shapes, 189 | const vector& ground_truth_faces, 190 | const vector >& current_shapes, 191 | const vector& current_fi, 192 | const vector& current_weight, 193 | const vector & bounding_box, 194 | const Mat_& mean_shape, 195 | const Mat_& shapes_residual, 196 | const vector &ind_samples_ori, 197 | // output 198 | float& thresh, 199 | float* feat, 200 | int landmarkID, 201 | bool& isvaild, 202 | vector& lcind, 203 | vector& rcind, 204 | int stage 205 | ){ 206 | vector ind_samples; 207 | for (int i=0;i candidate_pixel_locations(max_numfeats_,6); 227 | for(unsigned int i = 0;i < max_numfeats_;i++){ 228 | float x1 = random_generator.uniform(-1.0,1.0); 229 | float y1 = random_generator.uniform(-1.0,1.0); 230 | float x2 = random_generator.uniform(-1.0,1.0); 231 | float y2 = random_generator.uniform(-1.0,1.0); 232 | if((x1*x1 + y1*y1 > 1.0)||(x2*x2 + y2*y2 > 1.0)){ 233 | i--;continue; 234 | } 235 | candidate_pixel_locations(i,0) = x1 * max_radio_radius_; 236 | candidate_pixel_locations(i,1) = y1 * max_radio_radius_; 237 | candidate_pixel_locations(i,2) = x2 * max_radio_radius_; 238 | candidate_pixel_locations(i,3) = y2 * max_radio_radius_; 239 | /*int tmp_idx=(int)random_generator.uniform(0,global_params.landmark_num-1); 240 | candidate_pixel_locations(i,4) = tmp_idx; 241 | candidate_pixel_locations(i,5) = tmp_idx;*/ 242 | candidate_pixel_locations(i, 4) = landmarkID; 243 | candidate_pixel_locations(i, 5) = landmarkID; 244 | } 245 | // get pixel difference feature 246 | Mat_ densities(max_numfeats_,(int)ind_samples.size()); 247 | #pragma omp parallel for 248 | for (int i = 0;i < ind_samples.size();i++){ 249 | Mat_ rotation; 250 | float scale; 251 | Mat_ temp = ProjectShape(current_shapes[ind_samples[i]],bounding_box[ind_samples[i]]); 252 | SimilarityTransform(temp,mean_shape,rotation,scale); 253 | for(int j = 0;j < max_numfeats_;j++) 254 | { 255 | float project_x1 = rotation(0,0) * candidate_pixel_locations(j,0) + rotation(0,1) * candidate_pixel_locations(j,1); 256 | float project_y1 = rotation(1,0) * candidate_pixel_locations(j,0) + rotation(1,1) * candidate_pixel_locations(j,1); 257 | project_x1 = scale * project_x1 * bounding_box[ind_samples[i]].width / 2.0; 258 | project_y1 = scale * project_y1 * bounding_box[ind_samples[i]].height / 2.0; 259 | int real_x1 = project_x1 + current_shapes[ind_samples[i]](candidate_pixel_locations(j,4),0); 260 | int real_y1 = project_y1 + current_shapes[ind_samples[i]](candidate_pixel_locations(j,4),1); 261 | real_x1 = max(0.0,min((double)real_x1,images[augmented_images[ind_samples[i]]].cols-1.0)); 262 | real_y1 = max(0.0,min((double)real_y1,images[augmented_images[ind_samples[i]]].rows-1.0)); 263 | float project_x2 = rotation(0,0) * candidate_pixel_locations(j,2) + rotation(0,1) * candidate_pixel_locations(j,3); 264 | float project_y2 = rotation(1,0) * candidate_pixel_locations(j,2) + rotation(1,1) * candidate_pixel_locations(j,3); 265 | project_x2 = scale * project_x2 * bounding_box[ind_samples[i]].width / 2.0; 266 | project_y2 = scale * project_y2 * bounding_box[ind_samples[i]].height / 2.0; 267 | int real_x2 = project_x2 + current_shapes[ind_samples[i]](candidate_pixel_locations(j,5),0); 268 | int real_y2 = project_y2 + current_shapes[ind_samples[i]](candidate_pixel_locations(j,5),1); 269 | real_x2 = max(0.0,min((double)real_x2,images[augmented_images[ind_samples[i]]].cols-1.0)); 270 | real_y2 = max(0.0,min((double)real_y2,images[augmented_images[ind_samples[i]]].rows-1.0)); 271 | densities(j,i) = ((int)(images[augmented_images[ind_samples[i]]](real_y1,real_x1))-(int)(images[augmented_images[ind_samples[i]]](real_y2,real_x2))); 272 | } 273 | } 274 | // pick the feature 275 | Mat_ densities_sorted = densities.clone(); 276 | cv::sort(densities, densities_sorted, CV_SORT_ASCENDING); 277 | //separate shape samples 278 | vector ind_samples_shape; 279 | for(int n=0;n shapes_residual_shape(ind_samples_shape.size(),2); 287 | for(int n=0,m=0;n cache_shape(max_numfeats_,2); 300 | Mat_ cache_face(max_numfeats_,2); 301 | #pragma omp parallel for 302 | for (int i = 0;i lc1_shape,lc2_shape; 304 | vector rc1_shape,rc2_shape; 305 | lc1_shape.reserve(ind_samples.size()); 306 | lc2_shape.reserve(ind_samples.size()); 307 | rc1_shape.reserve(ind_samples.size()); 308 | rc2_shape.reserve(ind_samples.size()); 309 | 310 | vector lc_pos_weight,lc_neg_weight; 311 | vector rc_pos_weight,rc_neg_weight; 312 | lc_pos_weight.reserve(ind_samples.size()); 313 | lc_neg_weight.reserve(ind_samples.size()); 314 | rc_pos_weight.reserve(ind_samples.size()); 315 | rc_neg_weight.reserve(ind_samples.size()); 316 | 317 | lc1_shape.clear(); 318 | lc2_shape.clear(); 319 | rc1_shape.clear(); 320 | rc2_shape.clear(); 321 | lc_pos_weight.clear(); 322 | lc_neg_weight.clear(); 323 | rc_pos_weight.clear(); 324 | rc_neg_weight.clear(); 325 | 326 | double total_lc_pos_weight=0,total_lc_neg_weight=0; 327 | double total_rc_pos_weight=0,total_rc_neg_weight=0; 328 | 329 | RNG random_generator2(getTickCount()); 330 | int ind =(int)(ind_samples.size() * random_generator2.uniform(0.05,0.95)); 331 | float threshold = densities_sorted(i,ind); 332 | for (int j=0;j < ind_samples.size();j++){ 333 | if (densities(i,j) < threshold){ 334 | if(ground_truth_faces[ind_samples[j]]==1) 335 | { 336 | lc1_shape.push_back(shapes_residual(ind_samples[j],0)); 337 | lc2_shape.push_back(shapes_residual(ind_samples[j],1)); 338 | if (current_weight[ind_samples[j]] > FRAC) 339 | { 340 | lc_pos_weight.push_back(current_weight[ind_samples[j]]); 341 | total_lc_pos_weight += current_weight[ind_samples[j]]; 342 | } 343 | } 344 | else 345 | { 346 | if (current_weight[ind_samples[j]] > FRAC) 347 | { 348 | lc_neg_weight.push_back(current_weight[ind_samples[j]]); 349 | total_lc_neg_weight += current_weight[ind_samples[j]]; 350 | } 351 | } 352 | } 353 | else{ 354 | if(ground_truth_faces[ind_samples[j]]==1) 355 | { 356 | rc1_shape.push_back(shapes_residual(ind_samples[j],0)); 357 | rc2_shape.push_back(shapes_residual(ind_samples[j],1)); 358 | 359 | if (current_weight[ind_samples[j]] > FRAC) 360 | { 361 | rc_pos_weight.push_back(current_weight[ind_samples[j]]); 362 | total_rc_pos_weight += current_weight[ind_samples[j]]; 363 | } 364 | } 365 | else 366 | { 367 | if (current_weight[ind_samples[j]] > FRAC) 368 | { 369 | rc_neg_weight.push_back(current_weight[ind_samples[j]]); 370 | total_rc_neg_weight += current_weight[ind_samples[j]]; 371 | } 372 | } 373 | } 374 | } 375 | // about shape 376 | float var_lc = (calculate_var(lc1_shape)+calculate_var(lc2_shape)) * lc1_shape.size(); 377 | float var_rc = (calculate_var(rc1_shape)+calculate_var(rc2_shape)) * rc1_shape.size(); 378 | float var_reduce = var_overall - var_lc - var_rc; 379 | cache_shape(i,0)=var_reduce; 380 | cache_shape(i,1)=threshold; 381 | 382 | // about face 383 | int total_sample_num = lc_pos_weight.size()+lc_neg_weight.size()+rc_pos_weight.size()+rc_neg_weight.size(); 384 | int left_sample_num = lc_pos_weight.size()+lc_neg_weight.size(); 385 | int right_sample_num = rc_pos_weight.size()+rc_neg_weight.size(); 386 | 387 | double total_weight = total_lc_pos_weight + total_lc_neg_weight + total_rc_pos_weight + total_rc_neg_weight; 388 | double total_lc_weight = total_lc_pos_weight + total_lc_neg_weight; 389 | double total_rc_weight = total_rc_pos_weight + total_rc_neg_weight; 390 | 391 | double entropy=0; 392 | double lc_entropy=0; 393 | double rc_entropy=0; 394 | 395 | if (total_sample_num==0) 396 | { 397 | lc_entropy= FLT_MAX; 398 | rc_entropy= FLT_MAX; 399 | } 400 | else 401 | { 402 | if (left_sample_num==0) 403 | { 404 | lc_entropy= 0; 405 | } 406 | else 407 | { 408 | float entropy_tmp = total_lc_pos_weight / (total_lc_weight + DBL_MIN); 409 | if ((entropy_tmp-0.0) max_var_reductions){ 449 | max_var_reductions = cache_shape(i,0); 450 | thresh_shape = cache_shape(i,1); 451 | max_id_shape = i; 452 | } 453 | } 454 | for (int i=0;i> landmarkID_; 519 | fin >> max_depth_; 520 | fin >> max_numnodes_; 521 | fin >> num_leafnodes_; 522 | fin >> num_nodes_; 523 | fin >> max_numfeats_; 524 | fin >> max_radio_radius_; 525 | fin >> overlap_ration_; 526 | fin >> max_probility_; 527 | fin >> threshold; 528 | int num ; 529 | fin >> num; 530 | id_leafnodes_.resize(num); 531 | for (int i=0;i> id_leafnodes_[i]; 533 | } 534 | 535 | for (int i=0; i >& images, 7 | vector >& ground_truth_shapes, 8 | vector& ground_truth_faces, 9 | vector & bounding_boxs, int posLenth){ 10 | // data augmentation and multiple initialization 11 | vector augmented_images; 12 | vector augmented_bounding_boxs; 13 | vector > augmented_ground_truth_shapes; 14 | vector augmented_ground_truth_faces; 15 | vector > current_shapes; 16 | vector current_fi; 17 | vector current_weight; 18 | // get mean shape from training shapes(only origin train images) 19 | mean_shape_ = GetMeanShape2(ground_truth_shapes,bounding_boxs,ground_truth_faces); 20 | cout << mean_shape_< temp1 = ProjectShape(ground_truth_shapes[tmp_idx], bounding_boxs[tmp_idx]); 34 | Mat_ temp2 = ReProjectShape(temp1, newbox); 35 | // 1. Select ground truth shapes of other images as initial shapes 36 | augmented_images.push_back(i); 37 | augmented_ground_truth_shapes.push_back(temp2); 38 | augmented_ground_truth_faces.push_back(ground_truth_faces[i]); 39 | augmented_bounding_boxs.push_back(newbox); 40 | // 2. Project current shape to bounding box of ground truth shapes 41 | current_shapes.push_back(temp2); 42 | current_fi.push_back(0); 43 | current_weight.push_back(1); 44 | 45 | /*Mat_ ttttttt = images[i].clone(); 46 | for (int k = 0; k < mean_shape_.rows; k++) { 47 | circle(ttttttt, Point(current_shapes[current_shapes.size()-1](k, 0), current_shapes[current_shapes.size() - 1](k, 1)), 3, Scalar(255)); 48 | } 49 | rectangle(ttttttt, Point(newbox.start_x, newbox.start_y), 50 | Point(newbox.start_x + newbox.width, newbox.start_y + newbox.height), Scalar(255)); 51 | imshow("test3", ttttttt); 52 | waitKey(0);*/ 53 | } 54 | else 55 | { 56 | 57 | // 1. Select ground truth shapes of other images as initial shapes 58 | augmented_images.push_back(i); 59 | augmented_ground_truth_faces.push_back(ground_truth_faces[i]); 60 | augmented_ground_truth_shapes.push_back(ground_truth_shapes[i].clone()); 61 | 62 | int index = 0; 63 | do { 64 | // index = (i+j+1) % (images.size()); 65 | index = random_generator.uniform(0, (int)images.size()-1); 66 | } while (index == i); 67 | 68 | // 2. Project current shape to bounding box of ground truth shapes 69 | Mat_ temp2 = ProjectShape(ground_truth_shapes[index], bounding_boxs[index]); 70 | temp2 = ReProjectShape(temp2, bounding_boxs[i]); 71 | current_shapes.push_back(temp2); 72 | augmented_bounding_boxs.push_back(bounding_boxs[i]); 73 | current_fi.push_back(0); 74 | current_weight.push_back(1); 75 | 76 | /*Mat_ ttttttt=images[i].clone(); 77 | for(int k=0;k shape_index; 88 | for (int i=0;i isface;isface.push_back(true); 115 | binfeatures = DeriveBinaryFeat3(RandomForest_[stage], images, augmented_images, current_shapes,augmented_ground_truth_faces, augmented_bounding_boxs); 116 | float t3 = (float)cvGetTickCount(); 117 | cout << "derive binary features of "<< stage<<" stage has been trained, cost "<< (t3-t2)/((float)cvGetTickFrequency()*1000*1000) <<" s"< >& images, 134 | const vector& augmented_images, 135 | const vector >& current_shapes, 136 | const vector & bounding_boxs) { 137 | // initilaize the memory for binfeatures 138 | struct feature_node **binfeatures; 139 | binfeatures = new struct feature_node*[augmented_images.size()]; 140 | for (int i = 0; i rotation; 149 | float scale; 150 | 151 | // extract feature for each samples 152 | // #pragma omp parallel for 153 | 154 | for (int i = 0; i < augmented_images.size(); i++) { 155 | SimilarityTransform(ProjectShape(current_shapes[i], bounding_boxs[i]), mean_shape_, rotation, scale); 156 | //cout< >& images, 179 | const vector& augmented_images, 180 | const vector >& current_shapes, 181 | const vector& ground_truth_faces, 182 | const vector & bounding_boxs) { 183 | 184 | vector index; 185 | for (int i = 0; i rotation; 206 | float scale; 207 | 208 | // extract feature for each samples 209 | // #pragma omp parallel for 210 | 211 | for (int i = 0; i < index.size(); i++) { 212 | SimilarityTransform(ProjectShape(current_shapes[index[i]], bounding_boxs[index[i]]), mean_shape_, rotation, scale); 213 | //cout< >& images, 236 | const vector& augmented_images, 237 | const vector >& current_shapes, 238 | const vector& bounding_boxs, vector& result_face, float& score, int& fcount, bool& fface) { 239 | 240 | // initilaize the memory for binfeatures 241 | struct feature_node **binfeatures; 242 | binfeatures = new struct feature_node*[augmented_images.size()]; 243 | for (int i = 0; i rotation; 252 | float scale; 253 | 254 | // extract feature for each samples 255 | // #pragma omp parallel for 256 | 257 | for (int i = 0; i < augmented_images.size(); i++) { 258 | SimilarityTransform(ProjectShape(current_shapes[i], bounding_boxs[i]), mean_shape_, rotation, scale); 259 | //cout<& rand_forest, 284 | const Mat_& image, 285 | const Mat_& shape, 286 | const BoundingBox& bounding_box, 287 | const Mat_& rotation, 288 | const float scale) { 289 | 290 | int leafnode_per_tree = pow(2.0, rand_forest[0].max_depth_ - 1); 291 | /*float landmark_x = shape(rand_forest[0].landmarkID_,0); 292 | float landmark_y = shape(rand_forest[0].landmarkID_,1);*/ 293 | 294 | for (int iter = 0; iter& rand_forest, 348 | const Mat_& image, 349 | const Mat_& shape, 350 | const BoundingBox& bounding_box, 351 | const Mat_& rotation, 352 | const float scale, float& score, int& fcount, bool& fface) { 353 | 354 | int leafnode_per_tree = pow(2.0, rand_forest[0].max_depth_ - 1); 355 | float landmark_x = shape(rand_forest[0].landmarkID_, 0); 356 | float landmark_y = shape(rand_forest[0].landmarkID_, 1); 357 | bool isface = true; 358 | 359 | for (int iter = 0; iter& image, 426 | const Mat_& shape, 427 | const BoundingBox& bounding_box, 428 | const Mat_& rotation, 429 | const float scale) { 430 | int currnode = 0; 431 | int bincode = 1; 432 | for (int i = 0; i& image, 479 | const Mat_& shape, 480 | const BoundingBox& bounding_box, 481 | const Mat_& rotation, 482 | const float scale, int* bincode, float* score) { 483 | int currnode = 0; 484 | *bincode = 1; 485 | for (int i = 0; i >& shapes_residual, 533 | vector >& current_shapes, 534 | const vector & bounding_boxs, 535 | const Mat_& mean_shape, 536 | //Mat_& W, 537 | vector& models, 538 | int num_feature, 539 | int num_train_sample, 540 | int stage 541 | ) { 542 | // shapes_residual: n*(l*2) 543 | // construct the problem(expect y) 544 | struct problem* prob = new struct problem; 545 | prob->l = num_train_sample; 546 | prob->n = num_feature; 547 | prob->x = binfeatures; 548 | prob->bias = -1; 549 | 550 | // construct the parameter 551 | struct parameter* param = new struct parameter; 552 | param->solver_type = L2R_L2LOSS_SVR_DUAL; 553 | // param-> solver_type = L2R_L2LOSS_SVR; 554 | param->C = 1.0 / num_train_sample; 555 | param->p = 0; 556 | param->eps = 0.00001; 557 | //param->eps = 0.001; 558 | 559 | // initialize the y 560 | int num_residual = shapes_residual[0].rows * 2; 561 | float** yy = new float*[num_residual]; 562 | 563 | for (int i = 0; iy = yy[i]; 585 | check_parameter(prob, param); 586 | struct model* lbfmodel = train(prob, param); 587 | models[i] = lbfmodel; 588 | float time = float(clock() - t1) / CLOCKS_PER_SEC; 589 | cout << "linear regression of one landmark cost " << time << "s" << endl; 590 | } 591 | // update the current shape and shapes_residual 592 | float tmp; 593 | float scale; 594 | Mat_rotation; 595 | Mat_ deltashape_bar(num_residual / 2, 2); 596 | Mat_ deltashape_bar1(num_residual / 2, 2); 597 | for (int i = 0; i >& shapes_residual, 622 | vector >& current_shapes, 623 | const vector & bounding_boxs, 624 | const Mat_& mean_shape, 625 | //Mat_& W, 626 | vector& models, 627 | int num_feature, 628 | const vector& augmented_images, 629 | const vector& ground_truth_faces, 630 | int stage 631 | ) { 632 | vector index; 633 | for (int i = 0; il = index.size(); 645 | prob->n = num_feature; 646 | prob->x = binfeatures; 647 | prob->bias = -1; 648 | 649 | // construct the parameter 650 | struct parameter* param = new struct parameter; 651 | param->solver_type = L2R_L2LOSS_SVR_DUAL; 652 | // param-> solver_type = L2R_L2LOSS_SVR; 653 | param->C = 1.0 / index.size(); 654 | param->p = 0; 655 | param->eps = 0.00001; 656 | //param->eps = 0.001; 657 | 658 | // initialize the y 659 | int num_residual = shapes_residual[index[0]].rows * 2; 660 | float** yy = new float*[num_residual]; 661 | 662 | for (int i = 0; iy = yy[i]; 684 | check_parameter(prob, param); 685 | struct model* lbfmodel = train(prob, param); 686 | models[i] = lbfmodel; 687 | float time = float(clock() - t1) / CLOCKS_PER_SEC; 688 | cout << "linear regression of one landmark cost " << time << "s" << endl; 689 | } 690 | // update the current shape and shapes_residual 691 | float tmp; 692 | float scale; 693 | Mat_rotation; 694 | Mat_ deltashape_bar(num_residual / 2, 2); 695 | Mat_ deltashape_bar1(num_residual / 2, 2); 696 | for (int i = 0; i >& current_shapes, 721 | const vector & bounding_boxs, 722 | int stage) { 723 | int num_train_sample = (int)current_shapes.size(); 724 | int num_residual = current_shapes[0].rows * 2; 725 | float tmp; 726 | float scale; 727 | Mat_rotation; 728 | Mat_ deltashape_bar(num_residual / 2, 2); 729 | // #pragma omp parallel for 730 | for (int i = 0; i > LBFRegressor::Predict(const vector >& images, 763 | const vector& bounding_boxs, 764 | const vector >& ground_truth_shapes, 765 | int initial_num,vector& result_face){ 766 | vector image_index; 767 | for (int i=0;i > current_shapes; 773 | //HighClock* timer1=new HighClock();timer1->Start(); 774 | for (int i=0; i current_shape = ReProjectShape(mean_shape_, bounding_boxs[i]); 776 | current_shapes.push_back(current_shape); 777 | //cout<Start();*/float totaltime=0; 786 | float score=0; 787 | 788 | int stage1 =0; 789 | for ( int stage = 0; stage < global_params.max_numstage; stage++){ 790 | if(stageStart(); 797 | struct feature_node ** binfeatures ; 798 | //HighClock* timer2=new HighClock();timer2->Start(); 799 | //binfeatures = DeriveBinaryFeat2(RandomForest_[stage1],images,image_index,current_shapes,bounding_boxs,result_face,score); 800 | //timer2->Stop();cout<<"total time2:"<GetTime()<Start(); 803 | GlobalPrediction(binfeatures, current_shapes,bounding_boxs,stage1); 804 | //cout<Stop();cout<<"total time3:"<GetTime()<Stop();totaltime+=timer1->GetTime(); 807 | ReleaseFeatureSpace(binfeatures,images.size()); 808 | 809 | //HighClock* timer4=new HighClock();timer4->Start(); 810 | /*float MRSE_sum = 0; 811 | for (int i =0; iStop();cout<<"total time4:"<GetTime()<Stop();cout<<"total time:"< LBFRegressor::Predict(const cv::Mat_& image, 822 | const BoundingBox& bounding_box, 823 | int initial_num,bool& isface,int& fcount){ 824 | vector > images; 825 | vector image_index; 826 | image_index.push_back(0); 827 | vector > current_shapes; 828 | vector bounding_boxs; 829 | 830 | 831 | images.push_back(image); 832 | bounding_boxs.push_back(bounding_box); 833 | current_shapes.push_back(ReProjectShape(mean_shape_, bounding_box)); 834 | 835 | float score=0; 836 | // Mat img = imread("/Users/lequan/workspace/LBF/Datasets/lfpw/testset/image_0078.png"); 837 | // // draw result :: red 838 | // for(int j = 0;j < global_params.landmark_num;j++){ 839 | // circle(img,Point2d(current_shapes[0](j,0),current_shapes[0](j,1)),1,Scalar(255,255,255),-1,8,0); 840 | // } 841 | // imshow("result", img); 842 | // waitKey(0); 843 | // string name = "example mean.jpg"; 844 | // imwrite(name,img); 845 | bool fface=true; 846 | for ( int stage = 0; stage < global_params.max_numstage; stage++){ 847 | struct feature_node ** binfeatures ; 848 | vector face; 849 | face.clear(); 850 | double t1 = (double)cvGetTickCount(); 851 | binfeatures = DeriveBinaryFeat2(RandomForest_[stage],images,image_index,current_shapes,bounding_boxs,face,score,fcount,fface); 852 | double t2 = (double)cvGetTickCount(); 853 | //cout << "the DeriveBinaryFeat2 cost "<< (t2-t1)/((double)cvGetTickFrequency()) <<" us"<> global_params.bagging_overlap; 957 | fin >> global_params.max_numtrees; 958 | fin >> global_params.max_depth; 959 | fin >> global_params.max_numthreshs; 960 | fin >> global_params.landmark_num; 961 | fin >> global_params.initial_num; 962 | fin >> global_params.max_numstage; 963 | 964 | for (int i = 0; i< global_params.max_numstage; i++){ 965 | fin >> global_params.max_radio_radius[i]; 966 | } 967 | 968 | for (int i = 0; i < global_params.max_numstage; i++){ 969 | fin >> global_params.max_numfeats[i]; 970 | } 971 | } 972 | 973 | void LBFRegressor::ReadRegressor(ifstream& fin){ 974 | mean_shape_ = Mat::zeros(global_params.landmark_num,2,CV_32FC1); 975 | for(int i = 0;i < global_params.landmark_num;i++){ 976 | fin >> mean_shape_(i,0) >> mean_shape_(i,1); 977 | } 978 | ifstream fin_reg; 979 | locale::global(locale("")); 980 | fin_reg.open(dataPath.c_str(),ios::binary); 981 | locale::global(locale("C")); 982 | //cout<<"111:"<> num; 987 | //cout<<"i:"<