人脸识别-人脸建库学习:Sqlite3 的基本使用

一.创建和调用: face_feature.db

1.测试参考和配置

调试:本次为方便调试,未使用参考工程中cmakelist搭建,选择qt5搭建测试工程,工程qmake.pro 配置:

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle
LIBS +=-lpthread \
       -fopenmp

You can make your code fail to compile if it uses deprecated APIs.

In order to do so, uncomment the following line.

#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

#add opencv
INCLUDEPATH += /usr/local/include/opencv \
               $$PWD/Include/ncnn/

LIBS += /usr/local/lib/libopencv_*

SOURCES += \
        src/main_sqlit3.cpp \
        Common/cJSON.cpp \
        src/TRetina.cpp \
        src/TArcface.cpp \
        src/TWarp.cpp \

HEADERS += \
           Common/cJSON.h \
           Common/CppSQLite3.h \
           Common/inifile.h  \
           Common/jsonp.h \
           Common/sqlite3.h \
           $$PWD/Include/featuredb.h  \
           $$PWD/Include/TRetina.h \
           $$PWD/Include/TArcface.h \
           $$PWD/Include/TWarp.h \

#LIBS += -L$$PWD/lib/sqlite -llualibsqlite.0

LIBS += $$PWD/lib/sqlite/libsqlite3.so \
        /home/xxx/sqlitefacedb/lib/libncnn.a \

Default rules for deployment.

qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

2.建库目标:

db 文件存储人脸模型输出的1×128维度特征;能够支持戴口罩、不带口罩;

db 数据table 类型如:

nameintNOMASKFEATUREMASKFEATUREXXX_00121X1281X128XXX_00121X1281X128

3.建库需要的工程搭建:

基于参考工程调用人脸检测+对其+特征提取:

TWarp Warp;   //调用对其
std::vector Faces;   //人脸检测数据结构
const int   RetinaWidth      = 320;
const int   RetinaHeight     = 240;

std::shared_ptr Rn(new TRetina(RetinaWidth, RetinaHeight, false));  //使用智能指针初始化和调用人脸检测
std::shared_ptr ArcFace(new TArcFace());//使用智能指针初始化和调用人脸特征提取

3.Sqlite3 建立人脸库的基本使用

3.1 创建人脸数据库:

//人脸特征建库前数据存储形式,以下仅参考,对于db文件table 表中的name 和blob 输入可多中方式,如json 也可
std::vector< std::pair > fcdata ; //这里用vector+:pair的形式存储模型输出后names 和人脸的1x128维度的特征;
//如果存储一个人多个人脸可用:
std::vector< std::pair> > mutilfcdata;

以文件夹下img/***1.jpg

img/***2.jpg 为例,遍历文件下所有图片使用检测+对其+特征提取fc,push进vector便于后续导入db 的table(这种方式,后续需要优化,大数据量情况不合理 )。

//创建脸部特征数据库
int getallimgfeature(string &image_dir,std::vector< std::pair > &tests)
{
    //获取图片数据
    vector NameFaces;
    cv::glob(image_dir, NameFaces);
    int FaceCnt=NameFaces.size();
    if(FaceCnt==0) {
        cout << "No image files[jpg] in database" << endl;
        return -1;
    }
    for(int i=0; i tempstring=split(temp, "/");
        std::vector tempstring2=split(tempstring[tempstring.size()-1], ".");

        Faces.clear();
        cv::Mat imgs=cv::imread(temp,1);
        cv::Mat result_cnn;
        cv::resize(imgs, result_cnn, cv::Size(RetinaWidth,RetinaHeight),cv::INTER_LINEAR);
        Rn->detect_retinaface(result_cnn,Faces);
        if(Faces[0].FaceProb>0.5){
           //get centre aligned image
           cv::Mat face_schipss = Warp.Process(result_cnn,Faces[0]);
           Faces[0].align_max=face_schipss;
        }
        else{
           cout<GetFeature(Faces[0].align_max); //得到人脸特征,这里仅做测试,没有去求真实的最大人脸
        cv::Mat prob;
        normalize(prob_fc,prob,1,0,CV_MINMAX);  //opencv 接口归一化
        string names=tempstring2[0];
        cout<

3.2 Sqlite3 db 创建

当我们已获取文件夹下图像的id_names和特征后就可以使用sqlite3相关接口创建人脸数据库了,首先要建立db问价和建立table:

    sqlite3 *db;
    char *zErrMsg = 0;
    int  rc;
    char *sql;
    sqlite3_stmt* stmt;

    //打开数据库文件
    rc = sqlite3_open("face_feature.db", &db);
    if( rc ){
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        exit(0);
    }else{
        fprintf(stdout, "Opened database successfully\n");
    }

    //创建脸部特征表
    sql = "CREATE TABLE FEATURES("  \
         "NAME           VARCHAR(256)    NOT NULL," \
         "NUMFEA         INT     NOT NULL," \
         "NOMASKFACE     BLOB    NOT NULL," \
         "MASKFACE       BLOB    NOT NULL);";
    rc = sqlite3_exec(db, sql, NULL, 0, &zErrMsg);
    if( rc != SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
       sqlite3_free(zErrMsg);
    }else{
       fprintf(stdout, "Table created successfully\n");
    }

当数据表建立后,我们就需要考虑按照自己table 格式导入我们用 std::vector< std::pair

//导入前的准备语句
sqlite3_prepare(db,"INSERT INTO FEATURES (NAME,NUMFEA,NOMASKFACE,MASKFACE)  VALUES(?,?,?,?);",-1,&stmt,NULL); // 导入

//导入已存结构中的id 名字 在tabel 列中
sqlite3_bind_text(stmt,1,entry[i].first.c_str(),-1,SQLITE_STATIC);
//导入已存结构中有几组特征 在tabel 列中 int ,这里只是作为后续扩展一个人脸多个底库特征类型的记录
sqlite3_bind_int(stmt,2,entry[i].second.size[1]);

//导入已存结构中的1x128 cv:Mat 特征 在tabel 列中NOMASKFACE--BLOB中

sqlite3_bind_blob(stmt,3,entry[i].second.data,entry[i].second.size[0]*entry[i].second.size[1]*4,SQLITE_TRANSIENT);

//导入已存结构中的1x128 cv:Mat 特征 在tabel 列中MASKFACE--BLOB中

sqlite3_bind_blob(stmt,4,entry[0].second.data,entry[i].second.size[0]*entry[i].second.size[1]*4,SQLITE_TRANSIENT);
rc = sqlite3_step(stmt);

3.2 Sqlite3 db 生成后调用

当建立face_feature.db后,对于人脸识别系统来说,我们需要遍历db数据table中存储的人脸特征与输入人脸特征做1:N比较,并返回最大pred 得分和对应id name

…. 梳理测中。。。

Original: https://blog.csdn.net/qq_37553011/article/details/123269073
Author: CodeAIF
Title: 人脸识别-人脸建库学习:Sqlite3 的基本使用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/815503/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球