AI人工智能分析-人脸识别和分析(人脸检测跟踪、获取特征长度、提取用于人脸特征、比较相似度)
人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。
人工智能可以对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。
人工智能是一门极富挑战性的科学,从事这项工作的人必须懂得计算机知识,心理学和哲学。人工智能是包括十分广泛的科学,它由不同的领域组成,如机器学习,计算机视觉等等,总的说来,人工智能研究的一个主要目标是使机器能够胜任一些通常需要人类智能才能完成的复杂工作。但不同的时代、不同的人对这种“复杂工作”的理解是不同的。
可以模拟分析大部分物体,识别率在97%左右,下面简单粘贴下头文件和使用方式,如果感兴趣的朋友可以联系我拿库和demo使用。提供的接口包含了:人脸检测跟踪接口、获取特征长度、提取用于人脸特征、比较相似度
头文件:
#ifndef ADFACESDK_H
#define ADFACESDK_H
#ifdef __cplusplus
extern "C" {
#endif
#define AD_FACE_API __attribute__((visibility("default")))
// 通用错误码
typedef enum ad_errcode
{
AD_OK = 0, // 成功 or 合法
AD_EMPTY_FRAME_ERR = 20000, // 空图像
AD_UNSUPPORT_FORMAT_ERR, // 图像格式不支持
AD_ROI_ERR, // ROI设置失败
AD_MINMAX_ERR, // 最小最大人脸设置失败
AD_OUTOF_RANGE_ERR, // 数据范围错误
AD_UNAUTHORIZED_ERR, // 未授权
AD_UNINITIALIZED_ERR, // 尚未初始化
AD_BUILDIN_MODEL_ABSENCE, // 没有内置模型
AD_PARAM_INVALID, // 参数无效
AD_DETECT_MODEL_ERR, // 加载检测模型失败
AD_KEYPT_MODEL_ERR, // 加载关键点模型失败
AD_QUALITY_MODEL_ERR, // 加载质量评估模型失败
AD_EXCEEDMAXHANDLE_ERR, // 超过授权最大句柄数
AD_DET_ERR, // 检测失败
AD_TRACK_ERR, // 跟踪失败
AD_KEYPT_ERR, // 提取关键点失败
AD_ALIGN_ERR, // 对齐人脸失败
AD_QUALITY_ERR, // 质量评估失败
AD_RECOG_FEATURE_MODEL_ERR, // 加载特征识别模型失败
AD_RECOG_ALIGNEDFACE_ERR, // 对齐图片数据错误
AD_RECOG_MALLOCMEMORY_ERR, // 预分配特征空间不足
AD_RECOG_FILEDDATA_ERR, // 用于注册的特征数据错误
AD_RECOG_PROBEDATA_ERR, // 用于检索的特征数据错误
AD_RECOG_EXCEEDMAXFEASPEED, // 超过授权最大提特征速度
AD_RECOG_EXCEEDMAXCOMSPEED, // 超过授权最大比对速度
AD_ATTRI_AGEGENDER_MODEL_ERR, // 加载年龄性别模型失败
AD_ATTRI_EVAL_AGEGENDER_ERR, // 年龄性别识别失败
AD_ATTRI_NATIONALITY_MODEL_ERR, // 加载国籍年龄段模型失败
AD_ATTRI_EVAL_NATIONALITY_ERR, // 国籍年龄段识别失败
} ad_errcode_t;
// 图像
typedef struct
{
char* data; // 图像数据
int width; // 宽, JPG等二进制图可不设
int height; // 高, JPG等二进制图可不设
} ad_img_t;
// 人脸框
typedef struct
{
int x;
int y;
int width;
int height;
} ad_facepos_rect_t;
// 对齐人脸
#define AD_ALIGNED_SIZE 128
typedef struct
{
char data[AD_ALIGNED_SIZE * AD_ALIGNED_SIZE]; // 图像数据
int width; // 宽
int height; // 高
int nChannels; // 图像通道
} ad_aligned_face_t;
// 关键点
#define AD_MAX_KEYPT_NUM 5
typedef struct
{
float x;
float y;
} ad_point_t;
typedef struct
{
ad_point_t points[AD_MAX_KEYPT_NUM]; // 关键点
int nkeypt; // 关键点个数
} ad_keypt_t;
// 人脸综合结构
typedef struct AD_face_res
{
int trackId; // 人脸ID(ID<0表示没有进入跟踪)
ad_facepos_rect_t faceRect; // 人脸框
ad_keypt_t keypt; // 关键点
ad_aligned_face_t faceAligned; // 对齐人脸
float score;
} ad_face_res_t;
// 接口参数
typedef struct
{
int roiX; // roi, 默认整帧图像0, 0, 0, 0
int roiY;
int roiWidth;
int roiHeight;
int maxFaceNumPerImg; // 每帧最大人脸数,默认20
int minSize; // 人脸尺寸范围, pc端默认(30 ~ 1000);移动端默认(100 ~ 400)
int maxSize;
int nMinNeighbors; // 一般1-10,越大检出率越低,但误检越小,默认3
int globleDetFreq; // 全局检测频率, 默认10
int b_track; // 是否开启单目标跟踪, 默认开启. 0关闭,非0开启
int det_frame_for_new; // 预跟踪帧数,默认3
int max_frame_since_lost; // 跟丢到退出跟踪的帧数,默认150
}ad_det_param_t;
/**
* 功能:从模型文件创建检测器
* 输入:
* pFaceModelFile - 人脸检测模型文件
* pLicence - 授权码
* 输出:
* errCode - 成功返回AD_OK,失败返回其他
* 返回值:
* 检测器句柄 - 成功返回句柄,失败返回0
*/
AD_FACE_API
void* adCreateFaceHandle(ad_errcode_t* errCode,
const char* pFaceModelFile,
const char* pLicence,
int bGpu);
/**
* 功能:释放检测器
* 输入:
* pDetector - 检测器句柄
* 输出:
* 无
* 返回值:
* 无
*/
AD_FACE_API
void adReleaseFaceHandle(void* pDetector);
/**
* 功能:获取检测器参数
* 输入:
* pDetector - 检测器句柄
* 输出:
* param - 检测器参数
* 返回值:
* ad_errcode_t - 成功返回AD_OK,失败返回其他
*/
AD_FACE_API
ad_errcode_t adGetFaceParam(void* pDetector, ad_det_param_t* param);
/**
* 功能:设置检测器参数(必须先调用ADGetFaceParam再使用此函数)
* 输入:
* pDetector - 检测器句柄
* param - 参数
* 输出:
* 无
* 返回值:
* ad_errcode_t - 成功返回AD_OK,失败返回其他
*/
AD_FACE_API
ad_errcode_t adSetFaceParam(void* pDetector, const ad_det_param_t* param);
/**
* 功能:人脸检测跟踪接口
* 输入:
* pDetector - 检测器句柄
* filePath - 图片路径
* pFrameImg - ad_img_t 信息,内存需要外部释放
* 输出:
* pFaceBuffer - 存放检测结果的数组
* nFaceNum - 实际被检测到的人脸数
* 返回值:
* ad_errcode_t - 成功返回AD_OK,失败返回其他
*/
AD_FACE_API
ad_errcode_t adParseImage(void* pDetector,
char * filePath,
ad_img_t* pFrameImg);
AD_FACE_API
ad_errcode_t adReleaseImage(void* pDetector,
ad_img_t* pFrameImg);
/**
* 功能:人脸检测跟踪接口
* 输入:
* pDetector - 检测器句柄
* pFrameImg - 被检测图像
* iBuffLen - 存放检测结果pFaceBuffer数组的元素个数
* 输出:
* pFaceBuffer - 存放检测结果的数组
* nFaceNum - 实际被检测到的人脸数
* 返回值:
* ad_errcode_t - 成功返回AD_OK,失败返回其他
*/
AD_FACE_API
ad_errcode_t adFaceDetection(void* pDetector,
ad_img_t* pFrameImg,
ad_face_res_t* pFaceBuffer,
int iBuffLen,
int* nFaceNum);
/**
* 功能:获取特征长度
* 输入:
* pRecogHandle - 识别句柄
* 输出:
* 无
* 返回值:
* int - 特征长度
*/
AD_FACE_API
int adGetFeatureLength(void* pDetector);
/**
* 功能:提取用于人脸特征
* 输入:
* pRecogHandle - 识别句柄
* alignedFaces - 对齐的人脸数组
* iAlignFaceNum - 对齐的人脸数组个数
* 输出:
* pFeatueData - 返回的特征数据,需要预先分配足够空间
* nFeatureLength - 传入pFeatueData的长度,输出实际使用的长度
* 返回值:
* ad_errcode_t - 成功返回AD_OK,失败返回其他
*/
AD_FACE_API
ad_errcode_t adGetFeature(void* pDetector,
ad_aligned_face_t* alignedFace,
void* pFeatueData,
int nFeatureLength);
/**
* 功能:比较相似度
* 输入:
* pRecogHandle - 识别句柄
* pFirstFeature - 第一个特征
* pSecondFeature - 第二个特征
* nFeatureLength - 用于注册的特征长度
* 输出:
* pScores - 返回的相似度分数
* 返回值:
* ad_errcode_t - 成功返回AD_OK,失败返回其他
*/
AD_FACE_API
ad_errcode_t adComputeMatchScore(void* pDetector,
const void* pFirstFeature,
const void* pSecondFeature,
int nFeatureLength,
float* pScores);
#ifdef __cplusplus
}
#endif
#endif // ADFACESDK_H
使用方法:
#include <iostream>
#include <stdlib.h>
#include <assert.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <time.h>
#include "adfacesdk.h"
using namespace std;
#define MAX_FACES 200
#define DGB printf
int unit_test(int argc,char *argv[])
{
ad_errcode_t errCode;
ad_img_t stFrameImg;
ad_face_res_t FaceBuffer[MAX_FACES];
int nFaceNum=0;
float Scores;
if(argc!=4)
{
printf("%s modelfile image1 image2\n",argv[0]);
return -1;
}
int off=0;
int counter=0;
while(true)
{
if(off>1)
off=0;
void* pDetector=adCreateFaceHandle(&errCode,argv[1],NULL,off++);
assert(pDetector);
int nFeatureLength=adGetFeatureLength(pDetector);
assert(nFeatureLength>0);
char *pFeatueData[2]={new char[nFeatureLength],new char[nFeatureLength]};
DGB("nFeatureLength:%d\n",nFeatureLength);
clock_t start,finish;
double totaltime;
start=clock();
assert(AD_OK==adParseImage(pDetector,argv[2],&stFrameImg));
assert(AD_OK==adFaceDetection(pDetector,
&stFrameImg,
FaceBuffer,
MAX_FACES,
&nFaceNum));
free(stFrameImg.data);
assert(nFaceNum==1);
assert(AD_OK==adGetFeature(pDetector,&FaceBuffer[0].faceAligned,pFeatueData[0],nFeatureLength));
assert(AD_OK==adParseImage(pDetector,argv[3],&stFrameImg));
assert(AD_OK==adFaceDetection(pDetector,
&stFrameImg,
FaceBuffer,
MAX_FACES,
&nFaceNum));
free(stFrameImg.data);
assert(nFaceNum==1);
assert(AD_OK==adGetFeature(pDetector,&FaceBuffer[0].faceAligned,pFeatueData[1],nFeatureLength));
assert(AD_OK==adComputeMatchScore(pDetector,pFeatueData[0],pFeatueData[1],nFeatureLength,&Scores));
DGB("Scores:%0.2f\n",Scores);
finish=clock();
totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
DGB("%d usetime:%f (sec)\n",counter,totaltime);
adReleaseFaceHandle(pDetector);
if(counter++%100==0)
printf("counter:%d\n",counter);
break;
}
return 0;
}
int unit_test_list(int argc,char *argv[])
{
if(argc!=2)
{
printf("%s modelfile\n",argv[0]);
return -1;
}
ad_errcode_t errCode;
ad_img_t stFrameImg;
ad_face_res_t FaceBuffer[MAX_FACES];
int nFaceNum=0;
void* pDetector=adCreateFaceHandle(&errCode,argv[1],NULL,1);
assert(pDetector);
int nFeatureLength=adGetFeatureLength(pDetector);
assert(nFeatureLength>0);
char *pFeatueData[2]={new char[nFeatureLength],new char[nFeatureLength]};
DGB("nFeatureLength:%d\n",nFeatureLength);
std::ifstream fin("test_images_list.txt", std::ios::in);
char line[8192] = { 0 };
int counter=0;
while (fin.getline(line, sizeof(line)))
{
nFaceNum=0;
clock_t start,finish;
double totaltime;
start=clock();
assert(AD_OK==adParseImage(pDetector,line,&stFrameImg));
assert(AD_OK==adFaceDetection(pDetector,
&stFrameImg,
FaceBuffer,
MAX_FACES,
&nFaceNum));
free(stFrameImg.data);
for(int i=0;i<nFaceNum;i++)
{
assert(AD_OK==adGetFeature(pDetector,&FaceBuffer[i].faceAligned,pFeatueData[0],nFeatureLength));
}
finish=clock();
totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
DGB("[%08d] Count:%04d usetime:%0.2f (sec) %s\n",counter++,nFaceNum,totaltime,line);
}
fin.clear();
fin.close();
return true;
}
int main(int argc,char *argv[])
{
unit_test(argc,argv);
//unit_test_list(argc,argv);
}