123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- /*
- This file was part of GSoC Project: Facemark API for OpenCV
- Final report: https://gist.github.com/kurnianggoro/74de9121e122ad0bd825176751d47ecc
- Student: Laksono Kurnianggoro
- Mentor: Delia Passalacqua
- */
- /*----------------------------------------------
- * Usage:
- * facemark_demo_lbf <face_cascade_model> <saved_model_filename> <training_images> <annotation_files> [test_files]
- *
- * Example:
- * facemark_demo_lbf ../face_cascade.xml ../LBF.model ../images_train.txt ../points_train.txt ../test.txt
- *
- * Notes:
- * the user should provides the list of training images_train
- * accompanied by their corresponding landmarks location in separated files.
- * example of contents for images_train.txt:
- * ../trainset/image_0001.png
- * ../trainset/image_0002.png
- * example of contents for points_train.txt:
- * ../trainset/image_0001.pts
- * ../trainset/image_0002.pts
- * where the image_xxxx.pts contains the position of each face landmark.
- * example of the contents:
- * version: 1
- * n_points: 68
- * {
- * 115.167660 220.807529
- * 116.164839 245.721357
- * 120.208690 270.389841
- * ...
- * }
- * example of the dataset is available at https://ibug.doc.ic.ac.uk/download/annotations/ibug.zip
- *--------------------------------------------------*/
- #include <stdio.h>
- #include <fstream>
- #include <sstream>
- #include <iostream>
- #include "opencv2/core.hpp"
- #include "opencv2/highgui.hpp"
- #include "opencv2/imgproc.hpp"
- #include "opencv2/face.hpp"
- using namespace std;
- using namespace cv;
- using namespace cv::face;
- static bool myDetector( InputArray image, OutputArray roi, CascadeClassifier *face_detector);
- static bool parseArguments(int argc, char** argv, String & cascade,
- String & model, String & images, String & annotations, String & testImages
- );
- int main(int argc, char** argv)
- {
- String cascade_path,model_path,images_path, annotations_path, test_images_path;
- if(!parseArguments(argc, argv, cascade_path,model_path,images_path, annotations_path, test_images_path))
- return -1;
- /*create the facemark instance*/
- FacemarkLBF::Params params;
- params.model_filename = model_path;
- params.cascade_face = cascade_path;
- Ptr<FacemarkLBF> facemark = FacemarkLBF::create(params);
- CascadeClassifier face_cascade;
- face_cascade.load(params.cascade_face.c_str());
- facemark->setFaceDetector((FN_FaceDetector)myDetector, &face_cascade);
- /*Loads the dataset*/
- std::vector<String> images_train;
- std::vector<String> landmarks_train;
- loadDatasetList(images_path,annotations_path,images_train,landmarks_train);
- Mat image;
- std::vector<Point2f> facial_points;
- for(size_t i=0;i<images_train.size();i++){
- printf("%i/%i :: %s\n", (int)(i+1), (int)images_train.size(),images_train[i].c_str());
- image = imread(images_train[i].c_str());
- loadFacePoints(landmarks_train[i],facial_points);
- facemark->addTrainingSample(image, facial_points);
- }
- /*train the Algorithm*/
- facemark->training();
- /*test using some images*/
- String testFiles(images_path), testPts(annotations_path);
- if(!test_images_path.empty()){
- testFiles = test_images_path;
- testPts = test_images_path; //unused
- }
- std::vector<String> images;
- std::vector<String> facePoints;
- loadDatasetList(testFiles, testPts, images, facePoints);
- std::vector<Rect> rects;
- CascadeClassifier cc(params.cascade_face.c_str());
- for(size_t i=0;i<images.size();i++){
- std::vector<std::vector<Point2f> > landmarks;
- cout<<images[i];
- Mat img = imread(images[i]);
- facemark->getFaces(img, rects);
- facemark->fit(img, rects, landmarks);
- for(size_t j=0;j<rects.size();j++){
- drawFacemarks(img, landmarks[j], Scalar(0,0,255));
- rectangle(img, rects[j], Scalar(255,0,255));
- }
- if(rects.size()>0){
- cout<<endl;
- imshow("result", img);
- waitKey(0);
- }else{
- cout<<"face not found"<<endl;
- }
- }
- }
- bool myDetector(InputArray image, OutputArray faces, CascadeClassifier *face_cascade)
- {
- Mat gray;
- if (image.channels() > 1)
- cvtColor(image, gray, COLOR_BGR2GRAY);
- else
- gray = image.getMat().clone();
- equalizeHist(gray, gray);
- std::vector<Rect> faces_;
- face_cascade->detectMultiScale(gray, faces_, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30));
- Mat(faces_).copyTo(faces);
- return true;
- }
- bool parseArguments(int argc, char** argv,
- String & cascade,
- String & model,
- String & images,
- String & annotations,
- String & test_images
- ){
- const String keys =
- "{ @c cascade | | (required) path to the face cascade xml file fo the face detector }"
- "{ @i images | | (required) path of a text file contains the list of paths to all training images}"
- "{ @a annotations | | (required) Path of a text file contains the list of paths to all annotations files}"
- "{ @m model | | (required) path to save the trained model }"
- "{ t test-images | | Path of a text file contains the list of paths to the test images}"
- "{ help h usage ? | | facemark_demo_lbf -cascade -images -annotations -model [-t] \n"
- " example: facemark_demo_lbf ../face_cascade.xml ../images_train.txt ../points_train.txt ../lbf.model}"
- ;
- CommandLineParser parser(argc, argv,keys);
- parser.about("hello");
- if (parser.has("help")){
- parser.printMessage();
- return false;
- }
- cascade = String(parser.get<String>("cascade"));
- model = String(parser.get<string>("model"));
- images = String(parser.get<string>("images"));
- annotations = String(parser.get<string>("annotations"));
- test_images = String(parser.get<string>("t"));
- cout<<"cascade : "<<cascade.c_str()<<endl;
- cout<<"model : "<<model.c_str()<<endl;
- cout<<"images : "<<images.c_str()<<endl;
- cout<<"annotations : "<<annotations.c_str()<<endl;
- if(cascade.empty() || model.empty() || images.empty() || annotations.empty()){
- std::cerr << "one or more required arguments are not found" << '\n';
- parser.printMessage();
- return false;
- }
- return true;
- }
|