环境
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 语句本身的执行里。