sampleDetectLandmarksvideo.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include "opencv2/face.hpp"
  2. #include "opencv2/highgui.hpp"
  3. #include "opencv2/imgcodecs.hpp"
  4. #include "opencv2/imgproc.hpp"
  5. #include "opencv2/videoio.hpp"
  6. #include "opencv2/objdetect.hpp"
  7. #include <iostream>
  8. #include <vector>
  9. #include <string>
  10. using namespace std;
  11. using namespace cv;
  12. using namespace cv::face;
  13. static bool myDetector(InputArray image, OutputArray faces, CascadeClassifier *face_cascade)
  14. {
  15. Mat gray;
  16. if (image.channels() > 1)
  17. cvtColor(image, gray, COLOR_BGR2GRAY);
  18. else
  19. gray = image.getMat().clone();
  20. equalizeHist(gray, gray);
  21. std::vector<Rect> faces_;
  22. face_cascade->detectMultiScale(gray, faces_, 1.4, 2, CASCADE_SCALE_IMAGE, Size(30, 30));
  23. Mat(faces_).copyTo(faces);
  24. return true;
  25. }
  26. int main(int argc,char** argv){
  27. //Give the path to the directory containing all the files containing data
  28. CommandLineParser parser(argc, argv,
  29. "{ help h usage ? | | give the following arguments in following format }"
  30. "{ model_filename f | | (required) path to binary file storing the trained model which is to be loaded [example - /data/file.dat]}"
  31. "{ video v | | (required) path to video in which face landmarks have to be detected.[example - /data/video.avi] }"
  32. "{ face_cascade c | | Path to the face cascade xml file which you want to use as a detector}"
  33. );
  34. // Read in the input arguments
  35. if (parser.has("help")){
  36. parser.printMessage();
  37. cerr << "TIP: Use absolute paths to avoid any problems with the software!" << endl;
  38. return 0;
  39. }
  40. string filename(parser.get<string>("model_filename"));
  41. if (filename.empty()){
  42. parser.printMessage();
  43. cerr << "The name of the model file to be loaded for detecting landmarks is not found" << endl;
  44. return -1;
  45. }
  46. string video(parser.get<string>("video"));
  47. if (video.empty()){
  48. parser.printMessage();
  49. cerr << "The name of the video file in which landmarks have to be detected is not found" << endl;
  50. return -1;
  51. }
  52. string cascade_name(parser.get<string>("face_cascade"));
  53. if (cascade_name.empty()){
  54. parser.printMessage();
  55. cerr << "The name of the cascade classifier to be loaded to detect faces is not found" << endl;
  56. return -1;
  57. }
  58. VideoCapture cap(video);
  59. if(!cap.isOpened()){
  60. cerr<<"Video cannot be loaded. Give correct path"<<endl;
  61. return -1;
  62. }
  63. //pass the face cascade xml file which you want to pass as a detector
  64. CascadeClassifier face_cascade;
  65. face_cascade.load(cascade_name);
  66. FacemarkKazemi::Params params;
  67. Ptr<FacemarkKazemi> facemark = FacemarkKazemi::create(params);
  68. facemark->setFaceDetector((FN_FaceDetector)myDetector, &face_cascade);
  69. facemark->loadModel(filename);
  70. cout<<"Loaded model"<<endl;
  71. //vector to store the faces detected in the image
  72. vector<Rect> faces;
  73. vector< vector<Point2f> > shapes;
  74. Mat img;
  75. while(1){
  76. faces.clear();
  77. shapes.clear();
  78. cap>>img;
  79. //Detect faces in the current image
  80. resize(img,img,Size(600,600), 0, 0, INTER_LINEAR_EXACT);
  81. facemark->getFaces(img,faces);
  82. if(faces.size()==0){
  83. cout<<"No faces found in this frame"<<endl;
  84. }
  85. else{
  86. for( size_t i = 0; i < faces.size(); i++ )
  87. {
  88. cv::rectangle(img,faces[i],Scalar( 255, 0, 0 ));
  89. }
  90. //vector to store the landmarks of all the faces in the image
  91. if(facemark->fit(img,faces,shapes))
  92. {
  93. for(unsigned long i=0;i<faces.size();i++){
  94. for(unsigned long k=0;k<shapes[i].size();k++)
  95. cv::circle(img,shapes[i][k],3,cv::Scalar(0,0,255),FILLED);
  96. }
  97. }
  98. }
  99. namedWindow("Detected_shape");
  100. imshow("Detected_shape",img);
  101. if(waitKey(1) >= 0) break;
  102. }
  103. return 0;
  104. }