mace_webcam.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // This file is part of the OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. #include "opencv2/videoio.hpp"
  5. #include "opencv2/highgui.hpp"
  6. #include "opencv2/imgproc.hpp"
  7. #include "opencv2/objdetect.hpp"
  8. #include "opencv2/face/mace.hpp"
  9. #include <iostream>
  10. using namespace cv;
  11. using namespace cv::face;
  12. using namespace std;
  13. enum STATE {
  14. NEUTRAL,
  15. RECORD,
  16. PREDICT
  17. };
  18. const char *help =
  19. "press 'r' to record images. once N trainimages were recorded, train the mace filter\n"
  20. "press 'p' to predict (twofactor mode will switch back to neutral after each prediction attempt)\n"
  21. "press 's' to save a trained model\n"
  22. "press 'esc' to return\n"
  23. "any other key will reset to neutral state\n";
  24. int main(int argc, char **argv) {
  25. CommandLineParser parser(argc, argv,
  26. "{ help h usage ? || show this help message }"
  27. "{ cascade c || (required) path to a cascade file for face detection }"
  28. "{ pre p || load a pretrained mace filter file, saved from previous session (e.g. my.xml.gz) }"
  29. "{ num n |50| num train images }"
  30. "{ size s |64| image size }"
  31. "{ twofactor t || pass phrase(text) for 2 factor authentification.\n"
  32. " (random convolute images seeded with the crc of this)\n"
  33. " users will get prompted to guess the secrect, additional to the image. }"
  34. );
  35. String cascade = parser.get<String>("cascade");
  36. if (parser.has("help") || cascade.empty()) {
  37. parser.printMessage();
  38. return 1;
  39. } else {
  40. cout << help << endl;
  41. }
  42. String defname = "mace.xml.gz";
  43. String pre = parser.get<String>("pre");
  44. String two = parser.get<String>("twofactor");
  45. int N = parser.get<int>("num");
  46. int Z = parser.get<int>("size");
  47. int state = NEUTRAL;
  48. Ptr<MACE> mace;
  49. if (! pre.empty()) { // load pretrained model, if available
  50. mace = MACE::load(pre);
  51. if (mace->empty()) {
  52. cerr << "loading the MACE failed !" << endl;
  53. return -1;
  54. }
  55. state = PREDICT;
  56. } else {
  57. mace = MACE::create(Z);
  58. if (! two.empty()) {
  59. cout << "'" << two << "' initial passphrase" << endl;
  60. mace->salt(two);
  61. }
  62. }
  63. CascadeClassifier head(cascade);
  64. if (head.empty()) {
  65. cerr << "loading the cascade failed !" << endl;
  66. return -2;
  67. }
  68. VideoCapture cap(0);
  69. if (! cap.isOpened()) {
  70. cerr << "VideoCapture could not be opened !" << endl;
  71. return -3;
  72. }
  73. vector<Mat> train_img;
  74. while(1) {
  75. Mat frame;
  76. cap >> frame;
  77. vector<Rect> rects;
  78. head.detectMultiScale(frame,rects);
  79. if (rects.size()>0) {
  80. Scalar col = Scalar(0,120,0);
  81. if (state == RECORD) {
  82. if (train_img.size() >= size_t(N)) {
  83. mace->train(train_img);
  84. train_img.clear();
  85. state = PREDICT;
  86. } else {
  87. train_img.push_back(frame(rects[0]).clone());
  88. }
  89. col = Scalar(200,0,0);
  90. }
  91. if (state == PREDICT) {
  92. if (! two.empty()) { // prompt for secret on console
  93. cout << "enter passphrase: ";
  94. string pass;
  95. getline(cin, pass);
  96. mace->salt(pass);
  97. state = NEUTRAL;
  98. cout << "'" << pass << "' : ";
  99. }
  100. bool same = mace->same(frame(rects[0]));
  101. if (same) col = Scalar(0,220,220);
  102. else col = Scalar(60,60,60);
  103. if (! two.empty()) {
  104. cout << (same ? "accepted." : "denied.") << endl;
  105. }
  106. }
  107. rectangle(frame, rects[0], col, 2);
  108. }
  109. imshow("MACE",frame);
  110. int k = waitKey(10);
  111. switch (k) {
  112. case -1 : break;
  113. case 27 : return 0;
  114. default : state = NEUTRAL; break;
  115. case 'r': state = RECORD; break;
  116. case 'p': state = PREDICT; break;
  117. case 's': mace->save(defname); break;
  118. }
  119. }
  120. return 0;
  121. }