float CalculateError(const Mat_<float>& ground_truth_shape, const Mat_<float>& predicted_shape) { Mat_<float> temp; //temp = ground_truth_shape.rowRange(36, 37)-ground_truth_shape.rowRange(45, 46); temp = ground_truth_shape.rowRange(1, 2) - ground_truth_shape.rowRange(6, 7); float x = mean(temp.col(0))[0]; float y = mean(temp.col(1))[1]; float interocular_distance = sqrt(x*x + y*y); float sum = 0; for (int i = 0; i < ground_truth_shape.rows; i++) { sum += norm(ground_truth_shape.row(i) - predicted_shape.row(i)); } return sum / (ground_truth_shape.rows*interocular_distance); }
Point3f GetPupilPosition(Mat_<double> eyeLdmks3d){ eyeLdmks3d = eyeLdmks3d.t(); Mat_<double> irisLdmks3d = eyeLdmks3d.rowRange(0,8); Point3f p (mean(irisLdmks3d.col(0))[0], mean(irisLdmks3d.col(1))[0], mean(irisLdmks3d.col(2))[0]); return p; }
void adjustImage(Mat_<uchar>& img, Mat_<float>& ground_truth_shape, BoundingBox& bounding_box){ /*imshow("test",img); waitKey(0);*/ float left_x = max(1.0, (double)bounding_box.centroid_x - bounding_box.width*0.8); float top_y = max(1.0, (double)bounding_box.centroid_y - bounding_box.height*0.8); float right_x = min(img.cols-1.0,(double)bounding_box.centroid_x+bounding_box.width*0.8); float bottom_y= min(img.rows-1.0,(double)bounding_box.centroid_y+bounding_box.height*0.8); img = img.rowRange((int)top_y,(int)bottom_y).colRange((int)left_x,(int)right_x).clone(); bounding_box.start_x = ((int)right_x - (int)left_x)*CROP; bounding_box.start_y = ((int)bottom_y - (int)top_y)*CROP; bounding_box.width = ((int)right_x - (int)left_x)*(1-2*CROP)-1; bounding_box.height = ((int)bottom_y - (int)top_y)*(1-2*CROP)-1; bounding_box.centroid_x = bounding_box.start_x + bounding_box.width / 2.0; bounding_box.centroid_y = bounding_box.start_y + bounding_box.height / 2.0; for(int i=0;i<ground_truth_shape.rows;i++){ ground_truth_shape(i,0) = ground_truth_shape(i,0)-left_x; ground_truth_shape(i,1) = ground_truth_shape(i,1)-top_y; } //imshow("test1",img); //waitKey(0); float ori_height=img.rows; float ori_weight=img.cols; if (ori_height>MAXHEIGHT_POS) { float scale=MAXHEIGHT_POS/ori_height; resize(img,img,Size(ori_weight*scale,ori_height*scale)); bounding_box.start_x*=scale; bounding_box.start_y*=scale; bounding_box.centroid_x*=scale; bounding_box.centroid_y*=scale; bounding_box.width*=scale; bounding_box.height*=scale; for(int i=0;i<ground_truth_shape.rows;i++){ ground_truth_shape(i,0) *= scale; ground_truth_shape(i,1) *= scale; } } /*rectangle(img,Point(bounding_box.start_x,bounding_box.start_y),Point(bounding_box.start_x+bounding_box.width,bounding_box.start_y+bounding_box.height),Scalar(255)); for(int i=0;i<ground_truth_shape.rows;i++){ circle(img,Point(ground_truth_shape(i,0),ground_truth_shape(i,1)),3,Scalar(255)); } imshow("test2",img); waitKey(0);*/ }
int MultipleGraphsClassifier::predict(DisjointSetForest &segmentation, const Mat_<Vec3b> &image, const Mat_<float> &mask) { int maxGraphSize = max(segmentation.getNumberOfComponents(), this->maxTrainingGraphSize); int minGraphSize = min(segmentation.getNumberOfComponents(), this->minTrainingGraphSize); if (minGraphSize <= this->k) { cout<<"the smallest graph has size "<<minGraphSize<<", cannot compute "<<this->k<<" eigenvectors"<<endl; exit(EXIT_FAILURE); } // compute each feature graph for the test sample vector<WeightedGraph> featureGraphs; featureGraphs.reserve(this->features.size()); for (int i = 0; i < (int)this->features.size(); i++) { featureGraphs.push_back(this->computeFeatureGraph(i, segmentation, image, mask)); } // order graphs by feature, to compute pattern vectors feature by // feature. vector<vector<WeightedGraph> > graphsByFeatures(this->features.size()); // add feature graphs for the test sample at index 0 for (int i = 0; i < (int)this->features.size(); i++) { graphsByFeatures[i].reserve(this->trainingFeatureGraphs.size() + 1); graphsByFeatures[i].push_back(featureGraphs[i]); } // add feature graphs for each training sample for (int i = 0; i < (int)this->trainingFeatureGraphs.size(); i++) { for (int j = 0; j < (int)this->features.size(); j++) { graphsByFeatures[j].push_back(get<0>(this->trainingFeatureGraphs[i])[j]); } } // compute the corresponding pattern vectors vector<vector<VectorXd> > patternsByFeatures(this->features.size()); for (int i = 0; i < (int)this->features.size(); i++) { patternsByFeatures[i] = patternVectors(graphsByFeatures[i], this->k, maxGraphSize); } // concatenate pattern vectors by image, converting to opencv format // to work with cv's ML module. Mat_<float> longPatterns = Mat_<float>::zeros(this->trainingFeatureGraphs.size() + 1, maxGraphSize * k * this->features.size()); for (int i = 0; i < (int)this->trainingFeatureGraphs.size() + 1; i++) { VectorXd longPattern(maxGraphSize * k * this->features.size()); for (int j = 0; j < this->features.size(); j++) { longPattern.block(j * maxGraphSize * k, 0, maxGraphSize * k, 1) = patternsByFeatures[j][i]; } Mat_<double> cvLongPattern; eigenToCv(longPattern, cvLongPattern); Mat_<float> castLongPattern = Mat_<float>(cvLongPattern); castLongPattern.copyTo(longPatterns.row(i)); } // classification of long patterns using SVM CvKNearest svmClassifier; Mat_<int> classes(this->trainingFeatureGraphs.size(), 1); for (int i = 0; i < (int)this->trainingFeatureGraphs.size(); i++) { classes(i,0) = get<1>(this->trainingFeatureGraphs[i]); } svmClassifier.train(longPatterns.rowRange(1, longPatterns.rows), classes); return (int)svmClassifier.find_nearest(longPatterns.row(0), 1); }