// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. #include "precomp.hpp" #include "face_alignmentimpl.hpp" #include #include using namespace std; namespace cv{ namespace face{ bool FacemarkKazemiImpl :: findNearestLandmarks( vector< vector >& nearest){ if(meanshape.empty()||loaded_pixel_coordinates.empty()){ String error_message = "Model not loaded properly.Aborting..."; CV_Error(Error::StsBadArg, error_message); return false; } nearest.resize(loaded_pixel_coordinates.size()); for(unsigned long i=0 ; i< loaded_pixel_coordinates.size(); i++){ for(unsigned long j = 0;j &leaf) { uint64_t size; is.read((char*)&size, sizeof(size)); leaf.resize((size_t)size); is.read((char*)&leaf[0], leaf.size() * sizeof(Point2f)); } void FacemarkKazemiImpl :: readPixels(ifstream& is,uint64_t index) { is.read((char*)&loaded_pixel_coordinates[(unsigned long)index][0], loaded_pixel_coordinates[(unsigned long)index].size() * sizeof(Point2f)); } void FacemarkKazemiImpl :: loadModel(String filename){ if(filename.empty()){ String error_message = "No filename found.Aborting...."; CV_Error(Error::StsBadArg, error_message); return ; } ifstream f(filename.c_str(),ios::binary); if(!f.is_open()){ String error_message = "No file with given name found.Aborting...."; CV_Error(Error::StsBadArg, error_message); return ; } uint64_t len; f.read((char*)&len, sizeof(len)); char* temp = new char[(size_t)len+1]; f.read(temp, len); temp[len] = '\0'; string s(temp); delete [] temp; if(s.compare("cascade_depth")!=0){ String error_message = "Data not saved properly.Aborting....."; CV_Error(Error::StsBadArg, error_message); return ; } uint64_t cascade_size; f.read((char*)&cascade_size,sizeof(cascade_size)); loaded_forests.resize((unsigned long)cascade_size); f.read((char*)&len, sizeof(len)); temp = new char[(unsigned long)len+1]; f.read(temp, len); temp[len] = '\0'; s = string(temp); delete [] temp; if(s.compare("pixel_coordinates")!=0){ String error_message = "Data not saved properly.Aborting....."; CV_Error(Error::StsBadArg, error_message); return ; } loaded_pixel_coordinates.resize((unsigned long)cascade_size); uint64_t num_pixels; f.read((char*)&num_pixels,sizeof(num_pixels)); for(unsigned long i=0 ; i < cascade_size ; i++){ loaded_pixel_coordinates[i].resize((unsigned long)num_pixels); readPixels(f,i); } f.read((char*)&len, sizeof(len)); temp = new char[(unsigned long)len+1]; f.read(temp, len); temp[len] = '\0'; s = string(temp); delete [] temp; if(s.compare("mean_shape")!=0){ String error_message = "Data not saved properly.Aborting....."; CV_Error(Error::StsBadArg, error_message); return ; } uint64_t mean_shape_size; f.read((char*)&mean_shape_size,sizeof(mean_shape_size)); meanshape.resize((unsigned long)mean_shape_size); f.read((char*)&meanshape[0], meanshape.size() * sizeof(Point2f)); if(!setMeanExtreme()) exit(0); f.read((char*)&len, sizeof(len)); temp = new char[(unsigned long)len+1]; f.read(temp, len); temp[len] = '\0'; s = string(temp); delete [] temp; if(s.compare("num_trees")!=0){ String error_message = "Data not saved properly.Aborting....."; CV_Error(Error::StsBadArg, error_message); return ; } uint64_t num_trees; f.read((char*)&num_trees,sizeof(num_trees)); for(unsigned long i=0;i leaf; readLeaf(f,leaf); node.leaf = leaf; } else{ String error_message = "Data not saved properly.Aborting....."; CV_Error(Error::StsBadArg, error_message); return ; } tree.nodes[k]=node; } loaded_forests[i].push_back(tree); } } f.close(); isModelLoaded = true; } /** * @brief Copy the contents of a corners vector to an OutputArray, settings its size. */ static void _copyVector2Output(std::vector< std::vector< Point2f > > &vec, OutputArrayOfArrays out) { out.create((int)vec.size(), 1, CV_32FC2); if (out.isMatVector()) { for (unsigned int i = 0; i < vec.size(); i++) { out.create(68, 1, CV_32FC2, i); Mat &m = out.getMatRef(i); Mat(Mat(vec[i]).t()).copyTo(m); } } else if (out.isUMatVector()) { for (unsigned int i = 0; i < vec.size(); i++) { out.create(68, 1, CV_32FC2, i); UMat &m = out.getUMatRef(i); Mat(Mat(vec[i]).t()).copyTo(m); } } else if (out.kind() == _OutputArray::STD_VECTOR_VECTOR) { for (unsigned int i = 0; i < vec.size(); i++) { out.create(68, 1, CV_32FC2, i); Mat m = out.getMat(i); Mat(Mat(vec[i]).t()).copyTo(m); } } else { CV_Error(cv::Error::StsNotImplemented, "Only Mat vector, UMat vector, and vector OutputArrays are currently supported."); } } bool FacemarkKazemiImpl::fit(InputArray img, InputArray roi, OutputArrayOfArrays _landmarks) { if(!isModelLoaded){ String error_message = "No model loaded. Aborting...."; CV_Error(Error::StsBadArg, error_message); return false; } Mat image = img.getMat(); Mat roimat = roi.getMat(); std::vector faces = roimat.reshape(4, roimat.rows); std::vector > shapes; shapes.resize(faces.size()); if(image.empty()){ String error_message = "No image found.Aborting.."; CV_Error(Error::StsBadArg, error_message); return false; } if(faces.empty()){ String error_message = "No faces found.Aborting.."; CV_Error(Error::StsBadArg, error_message); return false; } if(meanshape.empty()||loaded_forests.empty()||loaded_pixel_coordinates.empty()){ String error_message = "Model not loaded properly.Aborting..."; CV_Error(Error::StsBadArg, error_message); return false; } if(loaded_forests.size()==0){ String error_message = "Model not loaded properly.Aboerting..."; CV_Error(Error::StsBadArg, error_message); return false; } if(loaded_pixel_coordinates.size()==0){ String error_message = "Model not loaded properly.Aboerting..."; CV_Error(Error::StsBadArg, error_message); return false; } vector< vector > nearest_landmarks; findNearestLandmarks(nearest_landmarks); tree_node curr_node; vector pixel_relative; vector pixel_intensity; Mat warp_mat; for(size_t e=0;e curr_node.split.thresh) { curr_node_index=left(curr_node_index); } else curr_node_index=right(curr_node_index); curr_node = tree.nodes[curr_node_index]; } for(size_t p=0;p(3,1) << shapes[e][j].x, shapes[e][j].y, 1); Mat D = warp_mat*C; shapes[e][j].x=float(D.at(0,0)); shapes[e][j].y=float(D.at(1,0)); } } _copyVector2Output(shapes, _landmarks); return true; } }//cv }//face