File: mace_webcam.cpp

package info (click to toggle)
opencv 4.5.1%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 268,248 kB
  • sloc: cpp: 969,170; xml: 682,525; python: 36,732; lisp: 30,170; java: 25,155; ansic: 7,927; javascript: 5,643; objc: 2,041; sh: 935; cs: 601; perl: 494; makefile: 145
file content (137 lines) | stat: -rw-r--r-- 4,435 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// This file is part of the 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 "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/objdetect.hpp"
#include "opencv2/face/mace.hpp"
#include <iostream>
using namespace cv;
using namespace cv::face;
using namespace std;


enum STATE {
    NEUTRAL,
    RECORD,
    PREDICT
};

const char *help =
        "press 'r' to record images. once N trainimages were recorded, train the mace filter\n"
        "press 'p' to predict (twofactor mode will switch back to neutral after each prediction attempt)\n"
        "press 's' to save a trained model\n"
        "press 'esc' to return\n"
        "any other key will reset to neutral state\n";

int main(int argc, char **argv) {
    CommandLineParser parser(argc, argv,
        "{ help h usage ? ||     show this help message }"
        "{ cascade c      ||     (required) path to a cascade file for face detection }"
        "{ pre p          ||     load a pretrained mace filter file, saved from previous session  (e.g. my.xml.gz) }"
        "{ num n          |50|   num train images }"
        "{ size s         |64|   image size }"
        "{ twofactor t    ||     pass phrase(text) for 2 factor authentification.\n"
        "                     (random convolute images seeded with the crc of this)\n"
        "                     users will get prompted to guess the secrect, additional to the image. }"
    );
    String cascade = parser.get<String>("cascade");
    if (parser.has("help") || cascade.empty()) {
        parser.printMessage();
        return 1;
    } else {
        cout << help << endl;
    }
    String defname = "mace.xml.gz";
    String pre = parser.get<String>("pre");
    String two = parser.get<String>("twofactor");
    int N = parser.get<int>("num");
    int Z = parser.get<int>("size");
    int state = NEUTRAL;

    Ptr<MACE> mace;
    if (! pre.empty()) { // load pretrained model, if available
        mace = MACE::load(pre);
        if (mace->empty()) {
            cerr << "loading the MACE failed !" << endl;
            return -1;
        }
        state = PREDICT;
    } else {
        mace  = MACE::create(Z);
        if (! two.empty()) {
            cout << "'" << two << "' initial passphrase" << endl;
            mace->salt(two);
        }
    }


    CascadeClassifier head(cascade);
    if (head.empty()) {
        cerr << "loading the cascade failed !" << endl;
        return -2;
    }

    VideoCapture cap(0);
    if (! cap.isOpened()) {
        cerr << "VideoCapture could not be opened !" << endl;
        return -3;
    }

    vector<Mat> train_img;
    while(1) {
        Mat frame;
        cap >> frame;

        vector<Rect> rects;
        head.detectMultiScale(frame,rects);
        if (rects.size()>0) {
            Scalar col = Scalar(0,120,0);

            if (state == RECORD) {
                if (train_img.size() >= size_t(N)) {
                    mace->train(train_img);
                    train_img.clear();
                    state = PREDICT;
                } else {
                    train_img.push_back(frame(rects[0]).clone());
                }
                col = Scalar(200,0,0);
            }

            if (state == PREDICT) {
                if (! two.empty()) { // prompt for secret on console
                    cout << "enter passphrase: ";
                    string pass;
                    getline(cin, pass);
                    mace->salt(pass);
                    state = NEUTRAL;
                    cout << "'" << pass << "' : ";
                }
                bool same = mace->same(frame(rects[0]));
                if (same) col = Scalar(0,220,220);
                else      col = Scalar(60,60,60);
                if (! two.empty()) {
                    cout << (same ? "accepted." : "denied.") << endl;
                }
            }

            rectangle(frame, rects[0], col, 2);
        }

        imshow("MACE",frame);
        int k = waitKey(10);
        switch (k) {
            case -1 : break;
            case 27 : return 0;
            default : state = NEUTRAL; break;
            case 'r': state = RECORD;  break;
            case 'p': state = PREDICT; break;
            case 's': mace->save(defname); break;
        }
    }

    return 0;
}