2026/4/17 20:23:43
网站建设
项目流程
潮州市住房和城乡建设局网站,桌面软件开发跟网站开发那个,wordpress 回复 楼中楼,霍邱网站设计公司一.本章节介绍本章节将讲解如何使用rockx提取人脸图像特征值#xff0c;并将其存储到sqlite3数据库中。在实际开发中#xff0c;人脸特征值通常都会存入数据库#xff0c;常见的选择包括sqlite3、MySQL等。#xff08;注#xff1a;本项目不会深入讲解数据库知识#xff…一.本章节介绍本章节将讲解如何使用rockx提取人脸图像特征值并将其存储到sqlite3数据库中。在实际开发中人脸特征值通常都会存入数据库常见的选择包括sqlite3、MySQL等。注本项目不会深入讲解数据库知识而是带大家完成基础的增删改查操作。二.rockx读取人脸特征值保存数据库大体框图上图展示了将人脸特征和图片数据写入数据库的处理流程连接并读取人脸SQLite3数据库初始化三个Rockx句柄人脸检测句柄(face_det_handle)人脸识别句柄(face_recognize_handle)人脸关键点句柄(face_5landmarks_handle)使用rockx_image_read读取人脸图片通过FILE API获取图片长度和二进制数据使用rockx_face_align进行人脸图片对齐调用rockx_face_recognize提取人脸特征值将人脸特征值和图片二进制数据存入SQLite3数据库三.rockx读取人脸特征值保存数据库的代码3.1.Connection_sqlite3DataBase连接数据库printf(Start Connection sqlite3......................\n); Connection_sqlite3DataBase(); printf(End Connection_sqlite3DataBase......................\n);这里封装了一个了SQLITE3连接数据库的函数Connection_sqlite3Database这个函数的实现如下int Connection_sqlite3DataBase() { rc sqlite3_open(/userdata/face.db, db); if (rc ! SQLITE_OK) { fprintf(stderr, Cant open database: %s\n, sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } else { printf(You have opened a sqlite3 database named bind.db successfully!\nCongratulation! Have fun!\n); } return 0; }这个函数直接调用了sqlite3的api sqlite3_open来初始化人脸数据库若返回值不等于SQLITE_OK则初始化数据库失败否则就初始化成功。3.2.创建三个rockx句柄// 1. 创建人脸检测句柄 ret rockx_create(face_det_handle, ROCKX_MODULE_FACE_DETECTION_V2, config, 0); if (ret ! ROCKX_RET_SUCCESS) { printf(init rockx module ROCKX_MODULE_FACE_DETECTION error %d\n, ret); return -1; } // 2. 创建人脸5关键点句柄 ret rockx_create(face_5landmarks_handle, ROCKX_MODULE_FACE_LANDMARK_5, config, 0); if (ret ! ROCKX_RET_SUCCESS) { printf(init rockx module ROCKX_MODULE_FACE_LANDMARK_68 error %d\n, ret); return -1; } // 3. 创建人脸特征提取句柄 ret rockx_create(face_recognize_handle, ROCKX_MODULE_FACE_RECOGNIZE, config, 0); if (ret ! ROCKX_RET_SUCCESS) { printf(init rockx module ROCKX_MODULE_FACE_LANDMARK_68 error %d\n, ret); return -1; }我们需要创建三个人脸处理句柄来实现完整功能人脸检测句柄ROCKX_MODULE_FACE_DETECTION_V2人脸识别句柄ROCKX_MODULE_FACE_RECOGNIZE人脸关键点检测句柄ROCKX_MODULE_FACE_LANDMARK_5这些句柄都通过rockx_create函数进行初始化。3.3.读取人脸图片rockx_image_t input_image1; rockx_image_read(image_path, input_image1, 1); //读取图片文件到rockx_image_t第二个参数1表示按RGB格式读取上图是读取人脸的图片这里使用的是rockx_image_read来读取人脸图片其中input_image是需要从命令行输入的。3.4.使用FILE读取图片的二进制数据和长度FILE *imageFile fopen(image_path, rb); // 打开名为image.jpg的图片文件二进制模式 if (!imageFile) { printf(无法打开图片文件.\n); return -1; } fseek(imageFile, 0L, SEEK_END); // 定位到文件尾部 long fileSize ftell(imageFile); // 获取文件大小 rewind(imageFile); // 重新定位到文件起始位置 printf(fileSize %ld\n, fileSize); unsigned char *buffer new unsigned char[fileSize]; // 分配足够大小的缓冲区 size_t bytesRead fread(buffer, sizeof(unsigned char), fileSize, imageFile); // 从文件中读取图像数据到缓冲区3.5.使用run_face_recognize检测人脸数据并找到最精确的人脸int run_face_recognize(const char *name, rockx_image_t *in_image, rockx_face_feature_t *out_feature, unsigned char * buffer, int buffer_size) { rockx_ret_t ret; /*************** FACE Detect ***************/ // create rockx_face_array_t for store result rockx_object_array_t face_array; memset(face_array, 0, sizeof(rockx_object_array_t)); // detect face ret rockx_face_detect(face_det_handle, in_image, face_array, NULL); if (ret ! ROCKX_RET_SUCCESS) { printf(rockx_face_detect error %d\n, ret); return -1; } // process result for (int i 0; i face_array.count; i) { int left face_array.object[i].box.left; int top face_array.object[i].box.top; int right face_array.object[i].box.right; int bottom face_array.object[i].box.bottom; float score face_array.object[i].score; printf(%d box(%d %d %d %d) score%f\n, i, left, top, right, bottom,score); } rockx_object_t *max_face get_max_face(face_array); if (max_face NULL) { printf(error no face detected\n); return -1; } // Face Align rockx_image_t out_img; memset(out_img, 0, sizeof(rockx_image_t)); /*************** 2. 人脸对齐 ***************/ ret rockx_face_align(face_5landmarks_handle, in_image, (max_face-box),NULL, out_img); if (ret ! ROCKX_RET_SUCCESS) { return -1; } /*************** 3. 人脸特征提取 ***************/ rockx_face_recognize(face_recognize_handle, out_img, out_feature); /*************** 4. 特征图片数据入库 ***************/ insert_face_data_toDataBase(name, out_feature-feature, FEATURE_SIZE, buffer, buffer_size); // Release Aligned Image rockx_image_release(out_img); return 0; } run_face_recognize(name, input_image1, out_feature1, buffer, bytesRead);rockx_object_t *get_max_face(rockx_object_array_t *face_array) { if (face_array-count 0) { return NULL; } rockx_object_t *max_face NULL;//存储人脸的最大指针 int i; for (i 0; i face_array-count; i) { rockx_object_t *cur_face (face_array-object[i]); if (max_face NULL) { max_face cur_face; continue; } int cur_face_box_area (cur_face-box.right - cur_face-box.left) * (cur_face-box.bottom - cur_face-box.top); int max_face_box_area (max_face-box.right - max_face-box.left) * (max_face-box.bottom - max_face-box.top); if (cur_face_box_area max_face_box_area) { max_face cur_face; } } printf(get_max_face %d\n, i - 1); return max_face; }get_max_face方法通过遍历所有人脸数据实现功能计算每个人脸区域面积(cur_face_box_area)并与当前最大面积(max_face_box_area)比较。当检测到更大的人脸区域时会更新最大面积值最终确定max_face为最精确的人脸数据。3.6. 把人脸特征值和图片数据保存到sqlite3数据库void insert_face_data_toDataBase(const char *name, float feature[512], int featureSize, uint8_t *image_data, int image_length) { printf(face_size %d\n, image_length); // 1. 预编译SQL并检查返回值 int ret sqlite3_prepare(db, insert into face_data_table(name,face_feature,feature_size,image_data,image_size) values (?,?,?,?,?);, -1, stmt, NULL); if (ret ! SQLITE_OK) { printf(sqlite3_prepare error: %s\n, sqlite3_errmsg(db)); return; } // 2. 绑定参数修正特征字节数 ret sqlite3_bind_text(stmt, 1, name, strlen(name), SQLITE_STATIC); // SQLITE_STATIC 等价于NULL表示不释放 if (ret ! SQLITE_OK) goto err; ret sqlite3_bind_blob(stmt, 2, feature, featureSize * sizeof(float), SQLITE_STATIC); if (ret ! SQLITE_OK) goto err; ret sqlite3_bind_int(stmt, 3, featureSize); if (ret ! SQLITE_OK) goto err; ret sqlite3_bind_blob(stmt, 4, image_data, image_length, SQLITE_STATIC); if (ret ! SQLITE_OK) goto err; ret sqlite3_bind_int(stmt, 5, image_length); if (ret ! SQLITE_OK) goto err; // 3. 打印调试 printf(insert face feature: ); for (int i 0; i 50; i) { printf(%f , feature[i]); } printf(\n); // 4. 执行插入并检查返回值 ret sqlite3_step(stmt); if (ret ! SQLITE_DONE) { printf(sqlite3_step error: %s\n, sqlite3_errmsg(db)); } err: // 5. 释放语句对象 sqlite3_finalize(stmt); }3.7.测试结果(图二)最后一步是将人脸特征值和图片数据存入SQLite3数据库。我们使用以下SQL插入语句INSERT INTO face_data_table(name, face_feature, feature_size, image_data, image_size) VALUES (?, ?, ?, ?, ?);其中face_data_table是存储人脸数据的数据表包含以下字段name人脸名称face_feature人脸特征值feature_size特征值长度image_data图片数据image_size图片长度通过sqlite3_prepare函数将SQL语句编译为可执行字节码支持查询、插入、更新和删除等操作。具体参数绑定如下sqlite3_bind_text(stmt, 1, name, strlen(name), NULL)绑定名称sqlite3_bind_blob(stmt, 2, feature, featureSize, NULL)绑定人脸特征值sqlite3_bind_int(stmt, 3, featureSize)绑定特征值长度sqlite3_bind_blob(stmt, 4, image_data, image_length, NULL)绑定图片数据sqlite3_bind_int(stmt, 5, image_length)绑定图片长度3.8.完整代码/* * ./sqlite3_operation_test name image_path */ #include rockx.h #include sqlite3_operation.h #define FEATURE_SIZE 512 rockx_handle_t face_det_handle; rockx_handle_t face_5landmarks_handle; rockx_handle_t face_recognize_handle; void insert_face_data_toDataBase(const char *name, float feature[512], int featureSize, uint8_t *image_data, int image_length) { printf(face_size %d\n, image_length); // 1. 预编译SQL并检查返回值 int ret sqlite3_prepare(db, insert into face_data_table(name,face_feature,feature_size,image_data,image_size) values (?,?,?,?,?);, -1, stmt, NULL); if (ret ! SQLITE_OK) { printf(sqlite3_prepare error: %s\n, sqlite3_errmsg(db)); return; } // 2. 绑定参数修正特征字节数 ret sqlite3_bind_text(stmt, 1, name, strlen(name), SQLITE_STATIC); // SQLITE_STATIC 等价于NULL表示不释放 if (ret ! SQLITE_OK) goto err; ret sqlite3_bind_blob(stmt, 2, feature, featureSize * sizeof(float), SQLITE_STATIC); if (ret ! SQLITE_OK) goto err; ret sqlite3_bind_int(stmt, 3, featureSize); if (ret ! SQLITE_OK) goto err; ret sqlite3_bind_blob(stmt, 4, image_data, image_length, SQLITE_STATIC); if (ret ! SQLITE_OK) goto err; ret sqlite3_bind_int(stmt, 5, image_length); if (ret ! SQLITE_OK) goto err; // 3. 打印调试 printf(insert face feature: ); for (int i 0; i 50; i) { printf(%f , feature[i]); } printf(\n); // 4. 执行插入并检查返回值 ret sqlite3_step(stmt); if (ret ! SQLITE_DONE) { printf(sqlite3_step error: %s\n, sqlite3_errmsg(db)); } err: // 5. 释放语句对象 sqlite3_finalize(stmt); } int Connection_sqlite3DataBase() { rc sqlite3_open(/userdata/face.db, db); if (rc ! SQLITE_OK) { fprintf(stderr, Cant open database: %s\n, sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } else { printf(You have opened a sqlite3 database named bind.db successfully!\nCongratulation! Have fun!\n); } return 0; } rockx_object_t *get_max_face(rockx_object_array_t *face_array) { if (face_array-count 0) { return NULL; } rockx_object_t *max_face NULL;//存储人脸的最大指针 int i; for (i 0; i face_array-count; i) { rockx_object_t *cur_face (face_array-object[i]); if (max_face NULL) { max_face cur_face; continue; } int cur_face_box_area (cur_face-box.right - cur_face-box.left) * (cur_face-box.bottom - cur_face-box.top); int max_face_box_area (max_face-box.right - max_face-box.left) * (max_face-box.bottom - max_face-box.top); if (cur_face_box_area max_face_box_area) { max_face cur_face; } } printf(get_max_face %d\n, i - 1); return max_face; } int run_face_recognize(const char *name, rockx_image_t *in_image, rockx_face_feature_t *out_feature, unsigned char * buffer, int buffer_size) { rockx_ret_t ret; /*************** FACE Detect ***************/ // create rockx_face_array_t for store result rockx_object_array_t face_array; memset(face_array, 0, sizeof(rockx_object_array_t)); // detect face ret rockx_face_detect(face_det_handle, in_image, face_array, NULL); if (ret ! ROCKX_RET_SUCCESS) { printf(rockx_face_detect error %d\n, ret); return -1; } // process result for (int i 0; i face_array.count; i) { int left face_array.object[i].box.left; int top face_array.object[i].box.top; int right face_array.object[i].box.right; int bottom face_array.object[i].box.bottom; float score face_array.object[i].score; printf(%d box(%d %d %d %d) score%f\n, i, left, top, right, bottom,score); } rockx_object_t *max_face get_max_face(face_array); if (max_face NULL) { printf(error no face detected\n); return -1; } // Face Align rockx_image_t out_img; memset(out_img, 0, sizeof(rockx_image_t)); /*************** 2. 人脸对齐 ***************/ ret rockx_face_align(face_5landmarks_handle, in_image, (max_face-box),NULL, out_img); if (ret ! ROCKX_RET_SUCCESS) { return -1; } /*************** 3. 人脸特征提取 ***************/ rockx_face_recognize(face_recognize_handle, out_img, out_feature); /*************** 4. 特征图片数据入库 ***************/ insert_face_data_toDataBase(name, out_feature-feature, FEATURE_SIZE, buffer, buffer_size); // Release Aligned Image rockx_image_release(out_img); return 0; } int main(int argc, char *argv[]) { rockx_ret_t ret; printf(----------------- main init ---------------------\n); #if 1 if (argc ! 3) { printf(Usage: Insert DataBase ./sqlite3_operation_test name image_path\n); return -1; } printf(Start Connection sqlite3......................\n); Connection_sqlite3DataBase(); printf(End Connection_sqlite3DataBase......................\n); // 创建rockx配置对象 rockx_config_t *config rockx_create_config(); // 设置rockx模型数据路径需提前放置模型文件 rockx_add_config(config, ROCKX_CONFIG_DATA_PATH, /userdata/rockx_data/); /*************** Creat Handle ***************/ // create a face detection handle // 1. 创建人脸检测句柄 ret rockx_create(face_det_handle, ROCKX_MODULE_FACE_DETECTION_V2, config, 0); if (ret ! ROCKX_RET_SUCCESS) { printf(init rockx module ROCKX_MODULE_FACE_DETECTION error %d\n, ret); return -1; } // 2. 创建人脸5关键点句柄 ret rockx_create(face_5landmarks_handle, ROCKX_MODULE_FACE_LANDMARK_5, config, 0); if (ret ! ROCKX_RET_SUCCESS) { printf(init rockx module ROCKX_MODULE_FACE_LANDMARK_68 error %d\n, ret); return -1; } // 3. 创建人脸特征提取句柄 ret rockx_create(face_recognize_handle, ROCKX_MODULE_FACE_RECOGNIZE, config, 0); if (ret ! ROCKX_RET_SUCCESS) { printf(init rockx module ROCKX_MODULE_FACE_LANDMARK_68 error %d\n, ret); return -1; } const char *name argv[1]; const char *image_path argv[2]; rockx_face_feature_t out_feature1; rockx_image_t input_image1; rockx_image_read(image_path, input_image1, 1); //读取图片文件到rockx_image_t第二个参数1表示按RGB格式读取 FILE *imageFile fopen(image_path, rb); // 打开名为image.jpg的图片文件二进制模式 if (!imageFile) { printf(无法打开图片文件.\n); return -1; } fseek(imageFile, 0L, SEEK_END); // 定位到文件尾部 long fileSize ftell(imageFile); // 获取文件大小 rewind(imageFile); // 重新定位到文件起始位置 printf(fileSize %ld\n, fileSize); unsigned char *buffer new unsigned char[fileSize]; // 分配足够大小的缓冲区 size_t bytesRead fread(buffer, sizeof(unsigned char), fileSize, imageFile); // 从文件中读取图像数据到缓冲区 /*************** 执行人脸处理入库 ***************/ run_face_recognize(name, input_image1, out_feature1, buffer, bytesRead); #endif return 0; }四.在板子上查询数据库的人脸数据4.1. 打开sqlite3数据库使用sqlite3 face.db打开人脸数据库4.2. 查询人脸的数据通过SQL查询语句检索人脸识别数据执行命令为SELECT * FROM face_data_table查询结果如上方截图所示。