pans
2016-12-20 0034d2bcd5408c55feff6d46428df78a0df32008
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#include <iostream>
#include <vector>
#include <stdio.h>
#include <cv_face.h>
#include "time_helper.h"
 
#include <opencv2/opencv.hpp>
#define DEFAULT_THRESHOLD (0.5)
 
using namespace std;
using namespace cv;
 
//ÈËÁ³ÑéÖ¤
static cv_handle_t handle_verify = NULL;
//Êý¾Ý¿â²Ù×÷
static cv_handle_t handle_db = NULL;
//¾²Ì¬ÈËÁ³Ê¶±ð
static cv_handle_t handle_detect = NULL;
 
#define _MAX_PATH 260
 
//ÌáÈ¡Í¼Æ¬ÌØÕ÷Öµ
cv_feature_t *extract_feature(Mat image_color) {
 
    Mat image_color_color;
    //    cvtColor(image_color, image_color_color, CV_BGR2BGRA);    // CV_PIX_FMT_BGRA8888
    image_color_color = image_color;                          // CV_PIX_FMT_BGR888
 
    cv_feature_t *p_feature = NULL;
    cv_face_t *p_face = NULL;
    int face_count = 0;
    cv_result_t st_result = CV_OK;
    //¼ì²âÈËÁ³
    st_result = cv_face_detect(handle_detect, image_color_color.data, CV_PIX_FMT_BGR888,
        image_color_color.cols, image_color_color.rows, image_color_color.step,
        CV_FACE_UP, &p_face, &face_count);
    if (face_count >= 1) {
        //»ñÈ¡ÈËÁ³ÌØÕ÷
        st_result = cv_verify_get_feature(handle_verify,
            (unsigned char *)image_color_color.data, CV_PIX_FMT_BGR888,
            image_color_color.cols, image_color_color.rows, image_color_color.step,
            p_face, &p_feature, NULL);
        if (st_result != CV_OK) {
            fprintf(stderr, "cv_verify_get_feature failed, error code %d\n", st_result);
        }
    } else {
        fprintf(stderr, "can't find face in ");
    }
    // ÊÍ·ÅÄÚ´æ
    cv_face_release_detector_result(p_face, face_count);
    return p_feature;
}
 
//Êý¾Ý¿âÌí¼ÓÊý¾Ý£¬²¢·µ»Ø¼Ç¼µÃid
int db_add(cv_feature_t *p_feature) {
    /*cv_feature_t *p_feature = extract_feature(image_color);
    if (!p_feature) {
    return -1;
    }*/
    int idx;
    cv_result_t cv_result = cv_verify_add_face(handle_db, p_feature, &idx);
    if (cv_result != CV_OK) {
        fprintf(stderr, "cv_verify_add_face failed, error code %d\n", cv_result);
    }
    cv_verify_release_feature(p_feature);
    return idx;
}
 
//¸ù¾Ýidɾ³ý¼Ç¼
bool db_del(int idx) {
    if (idx < 0) {
        fprintf(stderr, "invalid idx!\n");
        return false;
    }
    cv_result_t cv_result = CV_OK;
    cv_result = cv_verify_delete_face(handle_db, idx);
    if (cv_result != CV_OK) {
        fprintf(stderr, "cv_verify_delete_face failed, error code %d\n", cv_result);
    } else {
        fprintf(stderr, "delete succeed\n");
    }
}
 
//Êý¾Ý¿â±£´æ
bool db_save(char *db_path) {
    cv_result_t cv_result = CV_OK;
    cv_result = cv_verify_save_db(handle_db, db_path);
    if (cv_result != CV_OK) {
        fprintf(stderr, "cv_verify_save_db failed, error code %d\n", cv_result);
        return false;
    } else {
        fprintf(stderr, "save done!\n");
    }
 
    return true;
}
 
//Êý¾Ý¿â¼ÓÔØ
bool db_load(char *db_path) {
    cv_result_t cv_result = CV_OK;
    cv_result = cv_verify_load_db(handle_db, db_path);
 
    if (cv_result != CV_OK) {
        fprintf(stderr, "cv_verify_load_db failed, error code %d\n", cv_result);
        return false;
    } else {
        fprintf(stderr, "load done!\n");
    }
 
    return true;
}
 
//ËÑË÷Êý¾Ý¿â
bool search_db(Mat image_color,char *db_path) {
 
    cv_feature_t *p_feature = extract_feature(image_color);
    if (p_feature == NULL) {
        fprintf(stderr, "extract failed !\n");
        return false;
    }
    db_load(db_path);
    //²éѯǰ10Ìõ
    int top_k = 10;
    int *top_idxs = new int[top_k];
    float *top_scores = new float[top_k];
    unsigned int result_length = 0;
    cv_result_t cv_result = cv_verify_search_face(handle_verify, handle_db,
        p_feature, top_k,
        top_idxs, top_scores, &result_length);
    if (cv_result == CV_OK) {
        //Êä³ö¼ì²é½á¹û
        for (unsigned int t = 0; t < result_length; t++) {
            // const cv_feature_t item = result[t].item;
            fprintf(stderr, "%d\t", top_idxs[t]);
            fprintf(stderr, "%0.2f\n", top_scores[t]);
        }
    } else {
        fprintf(stderr, "cv_verify_search_face failed, error code %d\n", cv_result);
    }
    if (top_idxs) {
        delete[]top_idxs;
    }
    if (top_scores) {
        delete[]top_scores;
    }
    cv_verify_release_feature(p_feature);
    return true;
}
 
//ÅúÁ¿µ¼ÈëͼƬ½øÐзÖÎö
bool db_gen(char *image_list, char *db_path) {
    bool bresult = true;
    //¶ÁȡͼƬÁбí
    FILE *fp_path = fopen(image_list, "r");
    if(!fp_path) {
        fprintf(stderr, "failed to load %s\n", image_list);
        return false;
    }
 
    //ÈËÁ³ÌØÕ÷ÐÅÏ¢  Êý¾Ý½á¹¹
    std::vector<cv_feature_t *> list_feature;
    list_feature.clear();
 
    for (;;) {
        char image_path[1024];
        int num = fscanf(fp_path, "%s", image_path);
        if (num != 1) {
            bresult = false;
            break;
        }
        fprintf(stderr, "extracting %s\n", image_path);
 
 
        // get the face feature
        Mat image_color = imread(image_path);
        if (!image_color.data) {
            return NULL;
        }
 
        cv_feature_t *p_feature = extract_feature(image_color);
        if (!p_feature) {
            fprintf(stderr, "failed to extract image: %s\n", image_path);
            continue;
        }
        list_feature.push_back(p_feature);
    }
    fclose(fp_path);
 
 
    cv_verify_destroy_db(handle_db);
    cv_result_t cv_result = CV_OK;
    cv_verify_create_db(&handle_db);
    //´´½¨ÐµÄÊý¾Ý¿â£¬Ó¦¸Ã¸ÄΪÅжϣ¬Èç¹ûÊý¾Ý¿â´æÔÚÔò½øÐвåÈ룬·ñÔòн¨¡£
    if(db_load(db_path)){
        for (int x = 0; x < list_feature.size(); x++) {
            db_add(list_feature[x]);
        }
    }else{
        cv_result = cv_verify_build_db(handle_db, &list_feature[0], list_feature.size());
        if (cv_result != CV_OK) {
            fprintf(stderr, "cv_verify_build_db failed, error code %d\n", cv_result);
            bresult = false;
        }
        for (int i = 0; i < list_feature.size(); i++) {
            cv_verify_release_feature(list_feature[i]);
        }
    }
    cv_verify_save_db(handle_db, db_path);
 
 
    return bresult;
}
 
int main(int argc, char *argv[]) {
 
    //Îļþ·¾¶
    char *db_path = "./out1.db";
    char *image_path = "../../test_image/face_08.jpg";
    char *image_list = "../../test_image/imglist";
 
    //´´½¨¾²Ì¬ÈËÁ³Ê¶±ð¾ä±ú£¬Í¬Ê±´´½¨×´Ì¬±êÁ¿
    cv_result_t cv_result = cv_face_create_detector(&handle_detect, NULL, CV_DETECT_ENABLE_ALIGN_21);
    if (cv_result != CV_OK){
        fprintf(stderr, "create detect handle failed, error code %d\n", cv_result);
    }
    //´´½¨ÈËÁ³ÑéÖ¤¾ä±ú²¢³õʼ»¯
    cv_result = cv_verify_create_handle(&handle_verify, "../../../models/verify.model");
    if (cv_result != CV_OK){
        fprintf(stderr, "create verify handle failed, error code %d\n", cv_result);
    }
    // ´´½¨ÈËÁ³Êý¾Ý¿â¾ä±ú
    cv_result = cv_verify_create_db(&handle_db);
    if (cv_result != CV_OK){
        fprintf(stderr, "create db handle failed, error code %d\n", cv_result);
    }
 
    //ÅúÁ¿²åÈëÊý¾Ý¿â
    db_gen(image_list,db_path);
 
    //´ýËÑË÷µÄͼÏñ
    Mat image_color = imread(image_path);
    if (!image_color.data) {
        return NULL;
    }
    //ËÑË÷Êý¾Ý¿â
    if(search_db(image_color,db_path)){
        cout<<"search db"<<endl;
    }
 
    //»ØÊÕÄÚ´æ
    cv_face_destroy_detector(handle_detect);
    cv_verify_destroy_db(handle_db);
    cv_verify_destroy_handle(handle_verify);
    return 0;
}