用虹软SDK进行人脸对比

准备

建立文件夹,把要对比的图片放进去

face/samplecode/ASFTestDemo/build$ mkdir ../jpg_cmp

提取最大那个人脸的特征

int arcsorft_face_process2(int width, int height, MUInt8* rgb888_data, ASF_FaceFeature *pout_feature) {
	pthread_mutex_lock(&g_mutex);
	MRESULT res = MOK;

	ASVLOFFSCREEN offscreen = { 0 };
	ColorSpaceConversion(width, height, ASVL_PAF_RGB24_B8G8R8, rgb888_data, offscreen);
	
	ASF_MultiFaceInfo detectedFaces = { 0 };
	ASF_SingleFaceInfo SingleDetectedFaces = { 0 };
		
	res = ASFDetectFacesEx(handle, &offscreen, &detectedFaces);
	if (res != MOK) {
		printf("ASFDetectFaces fail: %ld\n", res);
		//getchar();
		pthread_mutex_unlock(&g_mutex);
		return -1;
	}
	//没有发现人脸,直接返回0
	else if(detectedFaces.faceNum == 0) {
		//printf("faceNum: %d, not 1\n", detectedFaces.faceNum);
		//getchar();
		pthread_mutex_unlock(&g_mutex);
		return 0;
	}
	//发现人脸
	else
	{
		int face_index = 0;
		int max_width = 0;
		int face_width = 0;
		int i = 0;
		//多个人脸的话,取他们脸最宽的那个
		if(detectedFaces.faceNum > 1) {
			for(i = 0; i < detectedFaces.faceNum; i++){
				/*
				printf("left: %d, top: %d, right: %d, bottom: %d \n",
				        detectedFaces.faceRect[i].left,
						detectedFaces.faceRect[i].top,
						detectedFaces.faceRect[i].right,
						detectedFaces.faceRect[i].bottom);
				*/
				face_width = detectedFaces.faceRect[i].right - detectedFaces.faceRect[i].left;
				if(face_width > max_width) {
					face_index = i;
					max_width = face_width;
				}
			}
		}
		
		SingleDetectedFaces.faceRect.left = detectedFaces.faceRect[face_index].left;
		SingleDetectedFaces.faceRect.top = detectedFaces.faceRect[face_index].top;
		SingleDetectedFaces.faceRect.right = detectedFaces.faceRect[face_index].right;
		SingleDetectedFaces.faceRect.bottom = detectedFaces.faceRect[face_index].bottom;
		SingleDetectedFaces.faceOrient = detectedFaces.faceOrient[face_index];
			
		// 单人脸特征提取
		res = ASFFaceFeatureExtractEx(handle, &offscreen, &SingleDetectedFaces, pout_feature);
		if (res != MOK)
		{
			printf("left: %d, top: %d, right: %d, bottom: %d ASFFaceFeatureExtractEx fail: 0x%lx\n", 
			        SingleDetectedFaces.faceRect.left,
					SingleDetectedFaces.faceRect.top, 
					SingleDetectedFaces.faceRect.right, 
					SingleDetectedFaces.faceRect.bottom,
					res);
			pthread_mutex_unlock(&g_mutex);
			return -1;
		}
		pthread_mutex_unlock(&g_mutex);
		return 	1;	
	}
	pthread_mutex_unlock(&g_mutex);
	return 0;
}

人脸对比

//人脸特征对比
float arcsorft_face_comp(LPASF_FaceFeature pfeature1,LPASF_FaceFeature pfeature2) {
	MRESULT res = MOK;
	MFloat confidenceLevel;

	pthread_mutex_lock(&g_mutex);

	res = ASFFaceFeatureCompare(handle, pfeature1, pfeature2, &confidenceLevel);

	pthread_mutex_unlock(&g_mutex);
	return confidenceLevel;
}

建立所有人脸数据内存

建立一个内存区域,里面能保存3000个人脸特征,名字,身份证号。

#define face_table_len 3000*(1032+255+19)
static unsigned char face_table[face_table_len] = {0}; 
static int face_count = 0;

数据库中所有的人脸特征

//get数据库的数据 SELECT * FROM face_data
//用于更新整个人脸数据表
//人脸数据为unsigned char[1032](blod 人脸特征数据)+char[255](名字)+char[19](身份证号) *3000
int database_get_data(void *dst, const int cnt)
{
    int ret = 0;
    char cmd[256];
    sqlite3_stmt *stat = NULL;
    int index = 0;
    const void *data;
    size_t size;

    pthread_mutex_lock(&g_mutex);
    snprintf(cmd, sizeof(cmd), "SELECT * FROM %s;", DATABASE_TABLE_FEATURE);
    if (sqlite3_prepare(g_db, cmd, -1, &stat, 0) != SQLITE_OK) {
        pthread_mutex_unlock(&g_mutex);
        return 0;
    }
    while (1) {
        ret = sqlite3_step(stat);
        if (ret != SQLITE_ROW)
            break;
        //人脸特征数据
        data = sqlite3_column_blob(stat, 1);
        size = sqlite3_column_bytes(stat, 1);        
        //复制到表中
        memcpy((unsigned char*)dst, data, size);
        dst += 1032;

        //名字
        data = sqlite3_column_text(stat, 2);
        size = sqlite3_column_bytes(stat, 2);        
        //复制到表中
        memcpy((unsigned char*)dst, data, size);
        dst += 255;

        //身份证号
        data = sqlite3_column_text(stat, 3);
        size = sqlite3_column_bytes(stat, 3);        
        //复制到表中
        memcpy((unsigned char*)dst, data, size);
        dst += 19;

        if (++index >= cnt)
            break;
    }
    sqlite3_finalize(stat);
    pthread_mutex_unlock(&g_mutex);

    return index;
}

主程序从数据库中读取到人脸的信息,放内存中,

//清内存
	memset(face_table, 0, face_table_len);
	//更新整个人脸数据表
	face_count = 0;
	face_count = database_get_data((unsigned char*)face_table, 3000);

读取文件夹里面的人脸,抽取人脸特征,和内存中的人脸数据进行比对

	//文件夹
	const char* jpg_cmp_path = "../jpg_cmp";
	//打开文件夹
	dirp = opendir(jpg_cmp_path);
	while ((dp = readdir(dirp)) != nullptr) {
        if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
            char jpg_name[300];	

			sprintf(jpg_name, "%s/%s", jpg_cmp_path, dp->d_name);

		    //打开文件
	        FILE* fpjpg = fopen(jpg_name, "rb");
	        //查文件的长度
	        fseek(fpjpg, 0, SEEK_END);
	        long file_length = ftell(fpjpg);
	        fseek(fpjpg, 0, SEEK_SET);

	        //分配内存
	        pjpg_data = (unsigned char*)malloc(file_length);
	        //读取数据
	        fread(pjpg_data, 1, file_length, fpjpg);	//jpeg文件数据
	        //关闭文件
	        fclose(fpjpg);

	        //把jpg图片解码成bgr数据
	        jpg2bgr(pjpg_data, file_length, &pbgr_data, &width, &height);
	        printf("pic %s width: %d, height: %d \n", jpg_name, width, height);

	        //抽取人脸特征
			ASF_FaceFeature feature;
	        ret = arcsorft_face_process2(width, height, pbgr_data, &feature);

			//如果发现了人脸, 人脸对比
		    if(ret == 1){
			    //人脸对比
			    ASF_FaceFeature feature1;
			    float confidenceLevel = 0.0;
			    float max_confidenceLevel = 0.0;
			    int max_similar_id = -1;
			    for(int i = 0; i < face_count; i++) {
				    feature1.feature = face_table + i * (1032 + 255 + 19);
				    feature1.featureSize = 1032;

					//printf("%s\n", face_table + i * (1032 + 255 + 19) + 1032);

				    confidenceLevel = arcsorft_face_comp(&feature1,&feature);
				    //置信度大于阈值, 并且阈值大于以前的
				    if(confidenceLevel > 0.8 && confidenceLevel > max_confidenceLevel) {
					    max_confidenceLevel = confidenceLevel;
					    max_similar_id = i;
				    }
			    }
			    //max_similar_id
			    if(max_similar_id != -1){
				    printf("%s is name: %s, id: %s, max_confidenceLevel: %f\n", dp->d_name,
				           &face_table[max_similar_id*(1032 + 255 + 19) +1032], 
					       &face_table[max_similar_id*(1032 + 255 + 19) +1032 + 255],
						   max_confidenceLevel);
				    //sleep(5);
			    }
			    else{
				    printf("not white table person!!!!!!!!!!!\n");
			    }
			    max_similar_id = -1;
		    } else {
				printf("process2 err \n");
				continue;
			}
        }
		
	}
	//释放内存
	free(pbgr_data);
	//关闭文件夹
    closedir(dirp);

编译运行测试

编译运行结果

face/samplecode/ASFTestDemo/build$ ./arcsoft_face_engine_test

************* ArcFace SDK Info *****************
startTime: 2024-09-09 00:00:00
endTime: 2025-09-09 00:00:00

Version:3.0.12402010101.3
BuildDate:07/29/2020
CopyRight:Copyright 2020 ArcSoft Corporation Limited. All rights reserved.

************* Face Recognition *****************
ASFInitEngine sucess: 0
face_count: 2322

pic ../jpg_cmp/111.jpg width: 640, height: 807
111.jpg is name: 200000000000000001, id: 200000000000000001, max_confidenceLevel: 0.962285
pic ../jpg_cmp/200000000000000001.jpg width: 376, height: 390
200000000000000001.jpg is name: 200000000000000001, id: 200000000000000001, max_confidenceLevel: 1.000000
pic ../jpg_cmp/ffff.jpg width: 1280, height: 1280
ffff.jpg is name: 100000000000000552, id: 100000000000000552, max_confidenceLevel: 0.989109
pic ../jpg_cmp/222.jpg width: 636, height: 609
not white table person!!!!!!!!!!!
pic ../jpg_cmp/333.jpg width: 492, height: 473
333.jpg is name: 200000000000000001, id: 200000000000000001, max_confidenceLevel: 0.917396

ASFUninitEngine sucess: 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值