环境
linux x64
刚开始是将人脸特征数据全部加载到内存,然后遍历内存,进行比较。
后面偶尔看到了 mysql UDF(Userdefined function)的开发,用户自定义函数
#include <mysql.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include "udf_face_comparison.h"
#include "arcsoft_face_sdk.h"
#include "amcomdef.h"
#include "asvloffscreen.h"
#include "merror.h"
using namespace std;
#define APPID "HnS2rSQq1ewRDDLsdz5KuTNvyoTbMm8rX2jFqZkpd4Fa"
#define SDKKEY "CmEstwumE52p5zGSBt8CJtkQtk5fSpqGm8M8ZxZFFuXt"
#define ACTIVEKEY "8281-1111-M125-XXKM"
#define NSCALE 16
#define FACENUM 5
#define SafeFree(p) { if ((p)) free(p); (p) = NULL; }
#define SafeArrayDelete(p) { if ((p)) delete [] (p); (p) = NULL; }
#define SafeDelete(p) { if ((p)) delete (p); (p) = NULL; }
MHandle faceHandle = 0;
const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int base64_decode( const char * base64, unsigned char * bindata )
{
int i, j;
unsigned char k;
unsigned char temp[4];
for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )
{
memset( temp, 0xFF, sizeof(temp) );
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i] )
temp[0]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+1] )
temp[1]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+2] )
temp[2]= k;
}
for ( k = 0 ; k < 64 ; k ++ )
{
if ( base64char[k] == base64[i+3] )
temp[3]= k;
}
bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |
((unsigned char)((unsigned char)(temp[1]>>4)&0x03));
if ( base64[i+2] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |
((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));
if ( base64[i+3] == '=' )
break;
bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |
((unsigned char)(temp[3]&0x3F));
}
return j;
}
extern "C" double face_comparison(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
MRESULT res = MOK;
if(faceHandle == 0){
return -1.0;
}
unsigned char bindata[2048];
int iRet = base64_decode(args->args[0], bindata);
ASF_FaceFeature feature1 = {0}, feature2 = {0};
feature1.feature = (MByte *)malloc(iRet);
feature1.featureSize = iRet;
memcpy(feature1.feature, bindata, feature1.featureSize);
feature2.feature = (MByte *)malloc(args->lengths[1]);
feature2.featureSize = args->lengths[1];
memcpy(feature2.feature, args->args[1], feature2.featureSize);
MFloat confidenceLevel = 0.0f;
res = ASFFaceFeatureCompare(faceHandle, &feature1, &feature2, &confidenceLevel);
printf("dqist_face_comparison_init_init");
SafeFree(feature1.feature); //释放内存
SafeFree(feature2.feature); //释放内存
return confidenceLevel;
}
extern "C" my_bool face_comparison_init(UDF_INIT *inited, UDF_ARGS *args, char*message)
{
inited->decimals = 2;
MRESULT res = MOK;
res = ASFOnlineActivation(APPID,SDKKEY);
MInt32 mask = ASF_FACERECOGNITION;
res = ASFInitEngine(ASF_DETECT_MODE_IMAGE, ASF_OP_0_ONLY, NSCALE, FACENUM, mask, &faceHandle);
return 0;
}
extern "C" void face_comparison_deinit(UDF_INIT *inited)
{
printf("face_comparison_init_init");
}
int test()
{
printf("hello worlod");
return 3;
}
drop FUNCTION face_comparison;
CREATE FUNCTION face_comparison RETURNS REAL SONAME 'libudf_face_comparison.so';
SELECT face_comparison('base64', feature_data) from face.face
这样就可以将模型比较放在sql 语句本身的执行里。