1044 lines
29 KiB
C
1044 lines
29 KiB
C
#include "data_base.h"
|
|
|
|
static db_attr g_svp_db[MAX_DB_NUM] = { 0 };
|
|
|
|
/*
|
|
data:
|
|
argc: row_num
|
|
argv: col value
|
|
azColName: col name
|
|
*/
|
|
static xmedia_s32 name_callback(xmedia_void* data, xmedia_s32 argc, xmedia_char** argv, xmedia_char** azColName)
|
|
{
|
|
if (data == NULL) {
|
|
printf("callback func storage data is null\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
xmedia_char *result = (xmedia_char *)data;
|
|
if (argc > 0) {
|
|
if (argv[0]) {
|
|
memcpy((xmedia_char*)result, argv[0], NAME_LEN);
|
|
}
|
|
} else {
|
|
printf("can not match name from index\n");
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 index_callback(xmedia_void* data, xmedia_s32 argc, xmedia_char** argv, xmedia_char** azColName)
|
|
{
|
|
if (data == NULL) {
|
|
printf("callback func storage data is null\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
printf("come in to index_callback\n");
|
|
xmedia_s32 *result = (xmedia_s32 *)data;
|
|
if (argc > 0) {
|
|
if (argv[0]) {
|
|
*result = atoi(argv[0]);
|
|
printf("match index: %d\n", *result);
|
|
}
|
|
} else {
|
|
printf("can not match index from name\n");
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
xmedia_void printf_matrix(matrix_data *matrix) {
|
|
printf("o_matrix row: %d, col: %d\n", matrix->row_num, matrix->col_num);
|
|
|
|
for (xmedia_s32 i = 0; i < matrix->row_num; i++) {
|
|
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
|
|
printf("%lf ", matrix->data[i][j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
xmedia_void printf_t_matrix(t_matrix_data *matrix) {
|
|
printf("t_matrix row: %d, col: %d\n", matrix->row_num, matrix->col_num);
|
|
|
|
for (xmedia_s32 i = 0; i < matrix->row_num; i++) {
|
|
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
|
|
printf("%lf ", matrix->data[i][j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
xmedia_void printf_r_matrix(r_matrix_data *matrix) {
|
|
printf("r_matrix row: %d, col: %d\n", matrix->row_num, matrix->col_num);
|
|
|
|
for (int i = 0; i < matrix->row_num; i++) {
|
|
for (int j = 0; j < matrix->col_num; j++) {
|
|
printf("%lf ", matrix->data[i][j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
}
|
|
|
|
static xmedia_s32 create_table(sqlite3* sql3_db, xmedia_s32 col_num, xmedia_char *table_name)
|
|
{
|
|
xmedia_s32 ret;
|
|
|
|
xmedia_char create_table_cmd[1000];
|
|
sprintf(create_table_cmd, "CREATE TABLE IF NOT EXISTS %s (id TEXT, ", table_name);
|
|
for (xmedia_s32 i = 1; i <= col_num - 1; i++) {
|
|
xmedia_char columnName[20];
|
|
sprintf(columnName, "val%d REAL", i);
|
|
strcat(create_table_cmd, columnName);
|
|
if (i != (col_num - 1)) {
|
|
strcat(create_table_cmd, ", ");
|
|
}
|
|
}
|
|
strcat(create_table_cmd, ");");
|
|
|
|
printf("%s\n", create_table_cmd);
|
|
|
|
ret = sqlite3_exec(sql3_db, create_table_cmd, 0, 0, 0);
|
|
if (ret != SQLITE_OK) {
|
|
printf("can not exce SQL: %s\n", sqlite3_errmsg(sql3_db));
|
|
sqlite3_close(sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 table_insert_one_row(sqlite3* sql3_db, xmedia_char *name, xmedia_s32 index,
|
|
xmedia_s32 col_num, xmedia_char *table_name)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_char id[MAX_NAME_LEN];
|
|
xmedia_char table_insert_cmd[1000]; //保证能装完513个数据 512 * (8 + 4) + 30
|
|
|
|
sprintf(table_insert_cmd, "INSERT INTO %s (id, ", table_name);
|
|
for (xmedia_s32 j = 1; j <= col_num - 1; j++) {
|
|
xmedia_char col[10];
|
|
sprintf(col, "val%d", j);
|
|
strcat(table_insert_cmd, col);
|
|
if (j != col_num - 1) {
|
|
strcat(table_insert_cmd, ", ");
|
|
}
|
|
}
|
|
|
|
strcat(table_insert_cmd, ") VALUES ('");
|
|
|
|
sprintf(id, "%s", name);
|
|
strcat(table_insert_cmd, id);
|
|
strcat(table_insert_cmd, "', ");
|
|
for (xmedia_s32 j = 1; j <= col_num - 1; j++) { //这里还可以增加其他信息
|
|
xmedia_s32 value = index;
|
|
xmedia_char value_str[20];
|
|
sprintf(value_str, "%d", value);
|
|
strcat(table_insert_cmd, value_str);
|
|
if (j != col_num - 1) {
|
|
strcat(table_insert_cmd, ", ");
|
|
}
|
|
}
|
|
strcat(table_insert_cmd, ");");
|
|
|
|
printf("insert %d info :\n %s\n", index, table_insert_cmd);
|
|
|
|
ret = sqlite3_exec(sql3_db, table_insert_cmd, 0, 0, 0);
|
|
if (ret != SQLITE_OK) {
|
|
printf("can not insert SQL: %s\n", sqlite3_errmsg(sql3_db));
|
|
sqlite3_close(sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 search_id(sqlite3* sql3_db, xmedia_char *str, xmedia_s32 index)
|
|
{
|
|
xmedia_s32 ret;
|
|
|
|
if (str == NULL) {
|
|
printf("storage name space is null\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
// 外部数据
|
|
double extra_val[SQL_COL_NUM - 1];
|
|
for (xmedia_s32 i = 1; i <= SQL_COL_NUM - 1; i++) {
|
|
extra_val[i - 1] = index;
|
|
}
|
|
|
|
// 查询匹配的行
|
|
xmedia_char select_cmd[100];
|
|
sprintf(select_cmd, "SELECT id FROM my_table WHERE ");
|
|
for (xmedia_s32 i = 1; i <= SQL_COL_NUM - 1; i++) {
|
|
xmedia_char colName[10];
|
|
sprintf(colName, "val%d", i);
|
|
strcat(select_cmd, colName);
|
|
|
|
xmedia_char val_str[20];
|
|
sprintf(val_str, " = %f", extra_val[i - 1]);
|
|
strcat(select_cmd, val_str);
|
|
if (i != SQL_COL_NUM - 1) {
|
|
strcat(select_cmd, " AND ");
|
|
}
|
|
}
|
|
strcat(select_cmd, ";");
|
|
|
|
ret = sqlite3_exec(sql3_db, select_cmd, name_callback, str, 0);
|
|
if (ret != SQLITE_OK) {
|
|
printf("can not query SQL: %s\n", sqlite3_errmsg(sql3_db));
|
|
sqlite3_close(sql3_db);
|
|
return SQL_ERROR;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 search_index(sqlite3* sql3_db, xmedia_char *name_str, xmedia_s32 *index)
|
|
{
|
|
xmedia_s32 ret;
|
|
|
|
if (name_str == NULL) {
|
|
printf("name is invalid\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
if (index == NULL) {
|
|
printf("storage index space is null\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
// 查询匹配的行
|
|
xmedia_char select_cmd[100];
|
|
sprintf(select_cmd, "SELECT val1 FROM my_table WHERE id = '");
|
|
xmedia_char col_name[50];
|
|
sprintf(col_name, name_str);
|
|
strcat(select_cmd, col_name);
|
|
strcat(select_cmd, "';");
|
|
|
|
printf("find str is :\n %s \n", select_cmd);
|
|
ret = sqlite3_exec(sql3_db, select_cmd, index_callback, index, 0);
|
|
if (ret != SQLITE_OK) {
|
|
printf("can not query SQL: %s\n", sqlite3_errmsg(sql3_db));
|
|
//sqlite3_close(sql3_db);
|
|
return SQL_ERROR;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 insert_row(double row[], xmedia_s32 size, matrix_data *matri)
|
|
{
|
|
if (matri == NULL) {
|
|
printf("the matri is not exist\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
if (matri->row_num >= MAX_ROWS) {
|
|
printf("Database is full, can not insert more rows.\n");
|
|
return PUSH_FAILED;
|
|
}
|
|
|
|
if (size > MAX_COLS) {
|
|
printf("Row size exceeds maximum number of colums. can not insert rows.\n");
|
|
return PUSH_FAILED;
|
|
}
|
|
|
|
for (xmedia_s32 i = 0; i < size; i++) {
|
|
matri->data[matri->row_num][i] = row[i];
|
|
}
|
|
|
|
matri->row_num++;
|
|
matri->col_num = size;
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 delete_row(xmedia_s32 row_index, matrix_data *matri) {
|
|
if (row_index < 0 || row_index > matri->row_num) {
|
|
printf("Invalid row index. can not delete row.\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
for (xmedia_s32 i = row_index; i < matri->row_num - 1; i++) {
|
|
for (xmedia_s32 j = 0; j < matri->col_num; j++) {
|
|
matri->data[i][j] = matri->data[i + 1][j];
|
|
}
|
|
}
|
|
|
|
matri->row_num -= 1;
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 normalize_matrix(matrix_data *matrix)
|
|
{
|
|
if (matrix == NULL) {
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
// find the max value from matrix
|
|
for (xmedia_s32 i = 0; i < matrix->row_num; i++) {
|
|
double sum_of_square = 0.0;
|
|
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
|
|
sum_of_square += matrix->data[i][j] * matrix->data[i][j];
|
|
}
|
|
|
|
double model_len = sqrt(sum_of_square);
|
|
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
|
|
matrix->data[i][j] /= model_len;
|
|
}
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 matrix_transpose(matrix_data *matrix, t_matrix_data *t_matrix)
|
|
{
|
|
if (matrix == NULL || t_matrix == NULL) {
|
|
printf("can not transpose, matrix or t_matrix is null\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
for (xmedia_s32 i = 0; i < matrix->row_num; i++) {
|
|
for (xmedia_s32 j = 0; j < matrix->col_num; j++) {
|
|
t_matrix->data[j][i] = matrix->data[i][j];
|
|
}
|
|
}
|
|
|
|
t_matrix->row_num = matrix->col_num;
|
|
t_matrix->col_num = matrix->row_num;
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 check_dot_result(r_matrix_data *matrix, double similarity_thres, db_match_result *result)
|
|
{
|
|
double min = 1.0;
|
|
xmedia_s32 i, j;
|
|
|
|
if (matrix == NULL) {
|
|
printf("check dot result failed!\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// multi target, clear result firstly
|
|
result->face_num = 0;
|
|
result->match_num = 0;
|
|
memset(result->match_col, -1, sizeof(xmedia_s32) * MAX_MATCH_NUM);
|
|
for (i = 0; i < matrix->row_num; i++) {
|
|
for (j = 0; j < matrix->col_num; j++) {
|
|
if (matrix->data[i][j] <= similarity_thres) { // pick data from similarity_thres, data_value in [0, 1]
|
|
if (min > matrix->data[i][j]) { // get the samllest value in row
|
|
min = matrix->data[i][j];
|
|
result->match_col[i] = j;
|
|
}
|
|
}
|
|
}
|
|
|
|
min = 1.0;
|
|
}
|
|
|
|
result->face_num = matrix->row_num;
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 svp_matrix_dot(t_matrix_data *t_matrix, r_matrix_data *result_matrix,
|
|
xmedia_svp_fr_output *face_matrix)
|
|
{
|
|
if (face_matrix == NULL || t_matrix == NULL || result_matrix == NULL) {
|
|
printf("matrix handle is null\n");
|
|
return XMEDIA_NULL;
|
|
}
|
|
|
|
for (xmedia_s32 i = 0; i < face_matrix->face_num; i++) {
|
|
for (xmedia_s32 j = 0; j < t_matrix->col_num; j++) {
|
|
for (xmedia_s32 k = 0; k < MAX_COLS; k++) {
|
|
result_matrix->data[i][j] += face_matrix->fr_result[i].vector[k] * t_matrix->data[k][j];
|
|
}
|
|
|
|
// [-1, 1] --> [0, 1]
|
|
result_matrix->data[i][j] = 0.5 - 0.5 * result_matrix->data[i][j]; // 0.5 - 0.5*cosine
|
|
}
|
|
}
|
|
|
|
result_matrix->row_num = face_matrix->face_num;
|
|
result_matrix->col_num = t_matrix->col_num;
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 check_db_cfg_info(config_info *cfg)
|
|
{
|
|
if (cfg->file_name == NULL) {
|
|
printf("cfg file_name is NULL\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (cfg->match_thres > 1.0 || cfg->match_thres < 0.0) {
|
|
printf("cfg match_thres %f is invaild, recommend 0.0 ~ 1.0\n", cfg->match_thres);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 check_add_person_info(add_person_info *person_info)
|
|
{
|
|
xmedia_double sum = 0.0;
|
|
xmedia_s32 i = 0;
|
|
|
|
if (person_info->add_person_name == NULL) {
|
|
printf("add person name is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
for (; i < MAX_COLS; i++) {
|
|
sum += person_info->add_person_feature[i];
|
|
}
|
|
|
|
if (sum == 0.0 || i != MAX_COLS) {
|
|
printf("add person info is invalid\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 append_person_info_to_file(xmedia_char *file, add_person_info *person_info)
|
|
{
|
|
FILE *fp;
|
|
|
|
if (file == NULL) {
|
|
printf("file is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
fp = fopen(file, "a");
|
|
if (fp == NULL) {
|
|
printf("can not open file\n");
|
|
}
|
|
|
|
fprintf(fp, "\"%s\" #", person_info->add_person_name);
|
|
for (xmedia_s32 i = 0; i < MAX_COLS; i++) {
|
|
fprintf(fp, "%lf", person_info->add_person_feature[i]);
|
|
if (i != MAX_COLS - 1) {
|
|
fprintf(fp, ",");
|
|
}
|
|
}
|
|
fprintf(fp, "#\n");
|
|
|
|
printf("finish write data to file\n");
|
|
|
|
fclose(fp);
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
static xmedia_s32 delete_person_info_from_file(xmedia_char *file, xmedia_char *name)
|
|
{
|
|
FILE *read_fp;
|
|
FILE *clear_fp;
|
|
FILE *write_fp;
|
|
xmedia_char *tmp_buffer;
|
|
xmedia_char *delete_start;
|
|
xmedia_char *delete_end;
|
|
xmedia_s32 file_size;
|
|
|
|
if (file == NULL) {
|
|
printf("file is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// read origin data to buffer
|
|
read_fp = fopen(file, "r");
|
|
if (read_fp == NULL) {
|
|
printf("can not open file\n");
|
|
}
|
|
|
|
fseek(read_fp, 0, SEEK_END);
|
|
file_size = ftell(read_fp);
|
|
fseek(read_fp, 0, SEEK_SET);
|
|
|
|
tmp_buffer = (xmedia_char*)malloc(file_size);
|
|
if (tmp_buffer == NULL) {
|
|
printf("malloc tmp_buffer for data file failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
fread(tmp_buffer, sizeof(xmedia_char), file_size, read_fp);
|
|
fclose(read_fp);
|
|
|
|
// clear file
|
|
clear_fp = fopen(file, "w");
|
|
if (clear_fp == NULL) {
|
|
printf("can not open clear_fp_file\n");
|
|
goto OPEN_CLEAR_FAILED;
|
|
}
|
|
fclose(clear_fp);
|
|
|
|
// determine location
|
|
delete_start = strstr(tmp_buffer, name) - 1;
|
|
delete_end = strchr(delete_start + MAX_NAME_LEN + 3, '#');// " 空格 # 三个字符
|
|
|
|
write_fp = fopen(file, "w");
|
|
if (write_fp == NULL) {
|
|
printf("can not open write_fp_file, txt file is empty!!!\n");
|
|
free(tmp_buffer);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
fwrite(tmp_buffer, sizeof(xmedia_char), delete_start - tmp_buffer, write_fp);
|
|
fwrite(delete_end + 1, sizeof(xmedia_char), (tmp_buffer + file_size) - (delete_end + 1), write_fp);
|
|
|
|
fclose(write_fp);
|
|
free(tmp_buffer);
|
|
|
|
return XMEDIA_SUCCESS;
|
|
|
|
OPEN_CLEAR_FAILED:
|
|
free(tmp_buffer);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
xmedia_s32 svp_init_database(db_attr **fr_db_attr, config_info *cfg)
|
|
{
|
|
FILE *fp;
|
|
xmedia_s32 ret;
|
|
xmedia_s32 index;
|
|
xmedia_slong file_size;
|
|
xmedia_char *tmp_buffer;
|
|
xmedia_char* start;
|
|
xmedia_char *end;
|
|
xmedia_char *sql;
|
|
xmedia_char data[MAX_FEATURE_LEN];
|
|
xmedia_char* token;
|
|
xmedia_char* delimiter = ",";
|
|
xmedia_char *err_msg;
|
|
xmedia_s32 last_index = -1;
|
|
xmedia_s32 match_name_index;
|
|
xmedia_char name[MAX_NAME_LEN];
|
|
xmedia_char *info_table = "my_table";
|
|
|
|
if (fr_db_attr == NULL) {
|
|
printf("fr_db_attr is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (cfg == NULL) {
|
|
printf("database cfg is NULL\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// check cfg info
|
|
ret = check_db_cfg_info(cfg);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("database cfg param is invalid\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// find idle
|
|
for (index = 0; index < MAX_DB_NUM; index++) {
|
|
if (!g_svp_db[index].use_flag) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (index >= MAX_DB_NUM) {
|
|
printf("db num is out of range 2\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
g_svp_db[index].feature_db = malloc(sizeof(face_feature_db));
|
|
g_svp_db[index].feature_db->o_matrix = malloc(sizeof(matrix_data));
|
|
g_svp_db[index].feature_db->t_matrix = malloc(sizeof(t_matrix_data));
|
|
g_svp_db[index].feature_db->r_matrix = malloc(sizeof(r_matrix_data));
|
|
|
|
if (!g_svp_db[index].feature_db) {
|
|
printf("g_svp_db[index].feature_db malloc failed\n");
|
|
return MALLOC_FAILED;
|
|
}
|
|
|
|
if (!g_svp_db[index].feature_db->o_matrix) {
|
|
printf("o_matrix malloc failed\n");
|
|
free(g_svp_db[index].feature_db);
|
|
return MALLOC_FAILED;
|
|
}
|
|
|
|
if (!g_svp_db[index].feature_db->t_matrix) {
|
|
printf("t_matrix malloc failed\n");
|
|
free(g_svp_db[index].feature_db);
|
|
free(g_svp_db[index].feature_db->o_matrix);
|
|
return MALLOC_FAILED;
|
|
}
|
|
|
|
if (!g_svp_db[index].feature_db->r_matrix) {
|
|
printf("r_matrix malloc failed\n");
|
|
free(g_svp_db[index].feature_db);
|
|
free(g_svp_db[index].feature_db->o_matrix);
|
|
free(g_svp_db[index].feature_db->t_matrix);
|
|
return MALLOC_FAILED;
|
|
}
|
|
|
|
memset(g_svp_db[index].feature_db->o_matrix, 0x00, sizeof(matrix_data));
|
|
memset(g_svp_db[index].feature_db->t_matrix, 0x00, sizeof(t_matrix_data));
|
|
memset(g_svp_db[index].feature_db->r_matrix, 0x00, sizeof(r_matrix_data));
|
|
|
|
g_svp_db[index].match_thres = cfg->match_thres;
|
|
g_svp_db[index].filepath = cfg->file_name;
|
|
|
|
ret = sqlite3_open("./res/person_name_id", &g_svp_db[index].sql3_db);
|
|
if (ret != SQLITE_OK) {
|
|
printf("can not open SQL database: %s\n", sqlite3_errmsg(g_svp_db[index].sql3_db));
|
|
return 1;
|
|
}
|
|
|
|
ret = create_table(g_svp_db[index].sql3_db, SQL_COL_NUM, info_table);
|
|
if (ret != 0) {
|
|
printf("can not create table\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
fp = fopen(cfg->file_name, "r");
|
|
if (!fp) {
|
|
printf("open data file failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
fseek(fp, 0, SEEK_END);
|
|
file_size = ftell(fp);
|
|
fseek(fp, 0, SEEK_SET);
|
|
|
|
tmp_buffer = (xmedia_char*)malloc(file_size);
|
|
if (tmp_buffer == NULL) {
|
|
printf("malloc tmp_buffer for data file failed\n");
|
|
goto MALLOC_TMP_BUFF;
|
|
}
|
|
|
|
fread(tmp_buffer, sizeof(xmedia_char), file_size, fp);
|
|
|
|
start = strchr(tmp_buffer, '"');
|
|
while (start != NULL) {
|
|
end = strchr(start + 1, '"');
|
|
strncpy(name, start + 1, end - start - 1);
|
|
name[end - start - 1] = '\0';
|
|
printf("name: %s\n", name);
|
|
|
|
// 查找当前数据库中最大的index
|
|
sql = "SELECT MAX(val1) FROM my_table;";
|
|
ret = sqlite3_exec(g_svp_db[index].sql3_db, sql, index_callback, &last_index, &err_msg);
|
|
if (ret != SQLITE_OK) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(g_svp_db[index].sql3_db);
|
|
return 1;
|
|
}
|
|
printf("sql table max index %d\n", last_index);
|
|
|
|
// 判断数据库中是否有这个人
|
|
match_name_index = -1;
|
|
ret = search_index(g_svp_db[index].sql3_db, name, &match_name_index);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("can not search sql\n");
|
|
goto FAIL_INSERT;
|
|
}
|
|
|
|
if (match_name_index == -1) { // add new one
|
|
printf("sql db cann't find %s, add!!!\n", name);
|
|
ret = table_insert_one_row(g_svp_db[index].sql3_db, name, last_index + 1, SQL_COL_NUM, info_table);
|
|
if (ret != 0) {
|
|
printf("insert info data failed\n");
|
|
goto FAIL_INSERT;
|
|
}
|
|
}
|
|
|
|
// 提取##之间的数据
|
|
start = strchr(end + 1, '#');
|
|
end = strchr(start + 1, '#');
|
|
strncpy(data, start + 1, end - start - 1);
|
|
data[end - start - 1] = '\0';
|
|
|
|
token = strtok(data, delimiter);
|
|
xmedia_double row[MAX_COLS] = {0};
|
|
xmedia_s32 data_index = 0;
|
|
while (token != NULL) {
|
|
if (data_index > MAX_COLS) {
|
|
goto FAIL_INSERT;
|
|
}
|
|
|
|
row[data_index] = atof(token);
|
|
token = strtok(NULL, delimiter);
|
|
data_index++;
|
|
}
|
|
|
|
ret = insert_row(row, MAX_COLS, g_svp_db[index].feature_db->o_matrix);
|
|
if (ret != 0) {
|
|
printf("insert feature data failed\n");
|
|
goto FAIL_INSERT;
|
|
}
|
|
|
|
printf("finish one people\n");
|
|
|
|
start = strchr(end + 1, '"');
|
|
}
|
|
|
|
fclose(fp);
|
|
free(tmp_buffer);
|
|
|
|
// txt is empty
|
|
if (g_svp_db[index].feature_db->o_matrix->row_num == 0) {
|
|
printf("txt file is empty\n");
|
|
g_svp_db[index].db_empty_flag = XMEDIA_TRUE;
|
|
}
|
|
|
|
// normlize
|
|
ret = normalize_matrix(g_svp_db[index].feature_db->o_matrix);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("normlize failed\n");
|
|
goto FAIL_INSERT;
|
|
}
|
|
|
|
ret = matrix_transpose(g_svp_db[index].feature_db->o_matrix, g_svp_db[index].feature_db->t_matrix);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("matrix_transpose failed\n");
|
|
goto FAIL_INSERT;
|
|
}
|
|
|
|
g_svp_db[index].use_flag = XMEDIA_TRUE;
|
|
*fr_db_attr = &g_svp_db[index];
|
|
|
|
printf("database init successfully\n");
|
|
|
|
return XMEDIA_SUCCESS;
|
|
|
|
FAIL_INSERT:
|
|
free(tmp_buffer);
|
|
MALLOC_TMP_BUFF:
|
|
free(g_svp_db[index].feature_db->o_matrix);
|
|
free(g_svp_db[index].feature_db->t_matrix);
|
|
free(g_svp_db[index].feature_db->r_matrix);
|
|
free(g_svp_db[index].feature_db);
|
|
|
|
sqlite3_close(g_svp_db[index].sql3_db);
|
|
|
|
fclose(fp);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
xmedia_s32 svp_deinit_database(db_attr *fr_db_attr)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_s32 db_handle = 0;
|
|
|
|
if (fr_db_attr == NULL) {
|
|
printf("fr_db_attr is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
for (; db_handle < MAX_DB_NUM; db_handle++) {
|
|
if (fr_db_attr == &g_svp_db[db_handle]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (db_handle >= MAX_DB_NUM) {
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (!g_svp_db[db_handle].use_flag) {
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (g_svp_db[db_handle].feature_db->o_matrix) {
|
|
free(g_svp_db[db_handle].feature_db->o_matrix);
|
|
}
|
|
|
|
if (g_svp_db[db_handle].feature_db->t_matrix) {
|
|
free(g_svp_db[db_handle].feature_db->t_matrix);
|
|
}
|
|
|
|
if (g_svp_db[db_handle].feature_db->r_matrix) {
|
|
free(g_svp_db[db_handle].feature_db->r_matrix);
|
|
}
|
|
|
|
if (g_svp_db[db_handle].feature_db) {
|
|
free(g_svp_db[db_handle].feature_db);
|
|
}
|
|
|
|
if (g_svp_db[db_handle].sql3_db) {
|
|
ret = sqlite3_close(g_svp_db[db_handle].sql3_db);
|
|
if (ret != SQLITE_OK) {
|
|
printf("sql close failed\n");
|
|
}
|
|
}
|
|
|
|
g_svp_db[db_handle].use_flag = XMEDIA_FALSE;
|
|
|
|
printf("database deinit successfully\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
xmedia_s32 svp_get_match_result(db_attr *fr_db_attr, xmedia_svp_fr_output *face_matrix, db_match_result *result)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_s32 db_handle = 0;
|
|
|
|
if (result == NULL) {
|
|
printf("db_result is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (face_matrix == NULL) {
|
|
printf("face matrix is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (face_matrix->face_num == 0) {
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
if (fr_db_attr == NULL) {
|
|
printf("db handle is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
for (; db_handle < MAX_DB_NUM; db_handle++) {
|
|
if (fr_db_attr == &g_svp_db[db_handle]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (db_handle >= MAX_DB_NUM) {
|
|
printf("db_handle is invalid\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (fr_db_attr->db_empty_flag) {
|
|
printf("data_base is empty, please input data\n");
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
t_matrix_data *t_matrix = g_svp_db[db_handle].feature_db->t_matrix;
|
|
r_matrix_data *result_matrix = g_svp_db[db_handle].feature_db->r_matrix;
|
|
memset(result_matrix, 0x00, sizeof(r_matrix_data));
|
|
ret = svp_matrix_dot(t_matrix, result_matrix, face_matrix);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("matrix dot failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
// check result
|
|
memset(result->match_name, 0, sizeof(result->match_name));
|
|
check_dot_result(result_matrix, fr_db_attr->match_thres, result);
|
|
for (xmedia_s32 i = 0; i < result->face_num; i++) {
|
|
if (result->match_col[i] != -1) {
|
|
ret = search_id(fr_db_attr->sql3_db,result->match_name[i], result->match_col[i]);
|
|
if (ret != 0) { // got name
|
|
printf("DB can not search \n");
|
|
}
|
|
|
|
if (strcmp(result->match_name[i], "") != 0) { // got name
|
|
result->match_num++;
|
|
// printf("DB match %s\n", result->match_name[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
xmedia_s32 svp_add_someone_to_database(db_attr *fr_db_attr, add_person_info *person_info)
|
|
{
|
|
xmedia_s32 ret = 0;
|
|
xmedia_char *sql;
|
|
xmedia_char *err_msg;
|
|
xmedia_s32 last_index = -1;
|
|
xmedia_s32 match_name_index;
|
|
xmedia_char *info_table = "my_table";
|
|
xmedia_s32 db_handle = 0;
|
|
|
|
if (fr_db_attr == NULL) {
|
|
printf("fr_db_attr is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (person_info == NULL) {
|
|
printf("person info is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
for (; db_handle < MAX_DB_NUM; db_handle++) {
|
|
if (fr_db_attr == &g_svp_db[db_handle]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (db_handle >= MAX_DB_NUM) {
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// check person info
|
|
ret = check_add_person_info(person_info);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("person info invalid\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// find max index in sql
|
|
sql = "SELECT MAX(val1) FROM my_table;";
|
|
ret = sqlite3_exec(fr_db_attr->sql3_db, sql, index_callback, &last_index, &err_msg);
|
|
if (ret != SQLITE_OK) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(fr_db_attr->sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
printf("sql table max index %d\n", last_index);
|
|
|
|
// check if has add person
|
|
match_name_index = -1;
|
|
ret = search_index(fr_db_attr->sql3_db, person_info->add_person_name, &match_name_index);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("can not search sql\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// add to sql
|
|
if (match_name_index == -1) {
|
|
ret = table_insert_one_row(fr_db_attr->sql3_db, person_info->add_person_name,
|
|
last_index + 1, SQL_COL_NUM, info_table);
|
|
if (ret != 0) {
|
|
printf("insert info data failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// add to feature o_matrix
|
|
ret = insert_row(person_info->add_person_feature, MAX_COLS, fr_db_attr->feature_db->o_matrix);
|
|
if (ret != 0) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(fr_db_attr->sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
fr_db_attr->db_empty_flag = XMEDIA_FALSE;
|
|
|
|
ret = normalize_matrix(fr_db_attr->feature_db->o_matrix);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(fr_db_attr->sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
ret = matrix_transpose(fr_db_attr->feature_db->o_matrix, fr_db_attr->feature_db->t_matrix);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(fr_db_attr->sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// update info to txt file
|
|
ret = append_person_info_to_file(fr_db_attr->filepath, person_info);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("append_person_info_to_file\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
printf("add %s to database successfully, index is %d\n", person_info->add_person_name, last_index + 1);
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
printf("person already in database\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
xmedia_s32 svp_delete_someone_from_database(db_attr *fr_db_attr, xmedia_char *name)
|
|
{
|
|
xmedia_s32 ret;
|
|
xmedia_s32 match_name_index;
|
|
xmedia_char *err_msg;
|
|
xmedia_s32 db_handle = 0;
|
|
|
|
if (fr_db_attr == NULL) {
|
|
printf("db handle is null\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
for (; db_handle < MAX_DB_NUM; db_handle++) {
|
|
if (fr_db_attr == &g_svp_db[db_handle]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (db_handle >= MAX_DB_NUM) {
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
if (name == NULL) {
|
|
printf("delete name is invalid\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// find index by name
|
|
match_name_index = -1;
|
|
ret = search_index(fr_db_attr->sql3_db, name, &match_name_index);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("can not search sql\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// if index valid, go on
|
|
if (match_name_index != -1) {
|
|
// updata sql index
|
|
xmedia_char delete_table_cmd[100];
|
|
sprintf(delete_table_cmd, "DELETE FROM my_table WHERE val1 = %d;", match_name_index);
|
|
ret = sqlite3_exec(fr_db_attr->sql3_db, delete_table_cmd, NULL, 0, &err_msg);
|
|
if (ret != SQLITE_OK) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(fr_db_attr->sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
xmedia_char update_table_cmd[100];
|
|
sprintf(update_table_cmd, "UPDATE my_table SET val1 = val1 - 1 WHERE val1 > %d;", match_name_index);
|
|
ret = sqlite3_exec(fr_db_attr->sql3_db, update_table_cmd, NULL, 0, &err_msg);
|
|
if (ret != SQLITE_OK) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(fr_db_attr->sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// delete feature o_matrix row by index
|
|
ret = delete_row(match_name_index, fr_db_attr->feature_db->o_matrix);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("use name search index failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
ret = normalize_matrix(fr_db_attr->feature_db->o_matrix);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(fr_db_attr->sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
ret = matrix_transpose(fr_db_attr->feature_db->o_matrix, fr_db_attr->feature_db->t_matrix);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
sqlite3_free(err_msg);
|
|
sqlite3_close(fr_db_attr->sql3_db);
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
// delete person from txt file
|
|
ret = delete_person_info_from_file(fr_db_attr->filepath, name);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
printf("delete_person_info_from_file failed\n");
|
|
return XMEDIA_FAILURE;
|
|
}
|
|
|
|
printf("delete %s from database successfully,origin index is %d\n", name, match_name_index);
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
printf("%s not in database\n", name);
|
|
return XMEDIA_FAILURE;
|
|
}
|