0%

ArcFaceSDK3.0 PythonDemo

做服务外包项目需要是用虹软的人脸对比SDK,项目使用Python进行开发,但是网上以及官方社区没有基于Python的3.0版本项目,所以自己根据社区里大佬1.1和2.0的Demo写了一个

face_class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from ctypes import *


# 人脸框
class MRECT(Structure):
_fields_ = [(u'left1', c_int32), (u'top1', c_int32),
(u'right1', c_int32), (u'bottom1', c_int32)]


# 版本信息 版本号,构建日期,版权说明
class ASF_VERSION(Structure):
_fields_ = [('Version', c_char_p), ('BuildDate',
c_char_p), ('CopyRight', c_char_p)]


# 单人人脸信息 人脸狂,人脸角度
class ASF_SingleFaceInfo(Structure):
_fields_ = [('faceRect', MRECT), ('faceOrient', c_int32)]


# 多人人脸信息 人脸框数组,人脸角度数组,人脸数
class ASF_MultiFaceInfo(Structure):
# _fields_=[('faceRect',POINTER(MRECT)),('faceOrient',POINTER( c_int32)),('faceNum',c_int32)]
_fields_ = [(u'faceRect', POINTER(MRECT)), (u'faceOrient',
POINTER(c_int32)), (u'faceNum', c_int32)]
# _fields_=[(u'faceRect',MRECT*50),(u'faceOrient',c_int32*50),(u'faceNum',c_int32)]


# 人脸特征 人脸特征,人脸特征长度
class ASF_FaceFeature(Structure):
_fields_ = [('feature', c_void_p), ('featureSize', c_int32)]


# 自定义图片类face_dll
class IM:
def __init__(self):
self.filepath = None
self.date = None
self.width = 0
self.height = 0

face_dll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

wuyongdll = CDLL('/media/psf/Home/code/fwwb/face/so/libarcsoft_face.so')
dll = CDLL('/media/psf/Home/code/fwwb/face/so/libarcsoft_face_engine.so')
libc = CDLL('libc.so.6')
#这里不同操作系统使用的动态库链接文件是不同的,我使用的是linux用了libc.so

ASF_DETECT_MODE_VIDEO = 0x00000000
ASF_DETECT_MODE_IMAGE = 0xFFFFFFFF
c_ubyte_p = POINTER(c_ubyte)

# 激活
jihuo = dll.ASFActivation
jihuo.restype = c_int32
jihuo.argtypes = (c_char_p, c_char_p)

# 初始化
chushihua = dll.ASFInitEngine
chushihua.restype = c_int32
chushihua.argtypes = (
c_long,
c_int32,
c_int32,
c_int32,
c_int32,
POINTER(c_void_p))

# 人脸识别
shibie = dll.ASFDetectFaces
shibie.restype = c_int32
shibie.argtypes = (
c_void_p,
c_int32,
c_int32,
c_int32,
POINTER(c_ubyte),
POINTER(ASF_MultiFaceInfo))

# 特征提取
tezheng = dll.ASFFaceFeatureExtract
tezheng.restype = c_int32
tezheng.argtypes = (
c_void_p,
c_int32,
c_int32,
c_int32,
POINTER(c_ubyte),
POINTER(ASF_SingleFaceInfo),
POINTER(ASF_FaceFeature))

# 特征比对
bidui = dll.ASFFaceFeatureCompare
bidui.restype = c_int32
bidui.argtypes = (
c_void_p,
POINTER(ASF_FaceFeature),
POINTER(ASF_FaceFeature),
POINTER(c_float))

# 内存控制
malloc = libc.malloc
free = libc.free
memcpy = libc.memcpy
malloc.restype = c_void_p
malloc.argtypes = (c_size_t, )
free.restype = None
free.argtypes = (c_void_p, )
memcpy.restype = c_void_p
memcpy.argtypes = (c_void_p, c_void_p, c_size_t)

face_function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
from . import face_dll
from . import face_class
from ctypes import *
import cv2
from io import BytesIO

Handle = c_void_p()
c_ubyte_p = POINTER(c_ubyte)


# 激活函数
def JH(appkey, sdkey):
ret = face_dll.jihuo(appkey, sdkey)
return ret


# 初始化函数
def CSH(): # 1:视频或图片模式,2角度,3最小人脸尺寸推荐16,4最多人脸数最大50,5功能,6返回激活句柄
ret = face_dll.chushihua(0xFFFFFFFF, 0x1, 16, 50, 5, byref(Handle))
# Main.Handle=Handle
return ret, Handle


# cv2记载图片并处理
def LoadImg(im):
img = cv2.imread(im.filepath)
sp = img.shape
img = cv2.resize(img, (sp[1] // 4 * 4, sp[0] // 4 * 4))
sp = img.shape
im.data = img
im.width = sp[1]
im.height = sp[0]
return im

def LoadWebImg(img):
print(img)
sp = img.shape
im = cv2.resize(img, (sp[1] // 4 * 4, sp[0] // 4 * 4))
sp = im.shape
img.data = im
img.width = sp[1]
img.height = sp[0]
return img

def RLSB(im):
faces = face_class.ASF_MultiFaceInfo()
img = im.data
imgby = bytes(im.data)
imgcuby = cast(imgby, c_ubyte_p)
ret = face_dll.shibie(
Handle,
im.width,
im.height,
0x201,
imgcuby,
byref(faces))
return ret, faces


# 显示人脸识别图片**unfinish
def showimg(im, faces):
print('facenum is:', faces.faceNum)
for i in range(0, faces.faceNum):
ra = faces.faceRect[i]
cv2.rectangle(im.data, (ra.left1, ra.top1),
(ra.right1, ra.bottom1), (255, 0, 0,), 2)
cv2.imshow('faces', im.data)
cv2.waitKey(0)


# 提取人脸特征
def RLTZ(im, ft):
detectedFaces = face_class.ASF_FaceFeature()
img = im.data
imgby = bytes(im.data)
imgcuby = cast(imgby, c_ubyte_p)
ret = face_dll.tezheng(
Handle,
im.width,
im.height,
0x201,
imgcuby,
ft,
byref(detectedFaces))
if ret == 0:
retz = face_class.ASF_FaceFeature()
retz.featureSize = detectedFaces.featureSize
# 必须操作内存来保留特征值,因为c++会在过程结束后自动释放内存
retz.feature = face_dll.malloc(detectedFaces.featureSize)
face_dll.memcpy(
retz.feature,
detectedFaces.feature,
detectedFaces.featureSize)
#print('提取特征成功:', detectedFaces.featureSize, mem)
return ret, retz
else:
return ret


# 特征值比对,返回比对结果
def BD(tz1, tz2):
jg = c_float()
ret = face_dll.bidui(Handle, tz1, tz2, byref(jg))
return ret, jg.value


# 单人特征写入文件
def writeFTFile(feature, filepath):
f = BytesIO(string_at(feature.feature, feature.featureSize))
a = open(filepath, 'wb')
a.write(f.getvalue())
a.close()


# 从多人中提取单人数据
def getsingleface(singleface, index):
ft = face_class.ASF_SingleFaceInfo()
ra = singleface.faceRect[index]
ft.faceRect.left1 = ra.left1
ft.faceRect.right1 = ra.right1
ft.faceRect.top1 = ra.top1
ft.faceRect.bottom1 = ra.bottom1
ft.faceOrient = singleface.faceOrient[index]
return ft


# 从文件获取特征值
def ftfromfile(filepath):
fas = face_class.ASF_FaceFeature()
f = open('./1.dat', 'rb')
b = f.read()
f.close()
fas.featureSize = b.__len__()
fas.feature = face_dll.malloc(fas.featureSize)
face_dll.memcpy(fas.feature, b, fas.featureSize)
return fas


关于ctypes类型转换

C类型 Python类型 ctypes 类型
char 1-character/string c_char
wchar_t 1-character/Unicode、string c_wchar
char int/long c_byte
char int/long c_ubyte
short int/long c_short
unsigned short int/long c_ushort
int int/long c_int
unsigned int int/long c_uint
long int/long c_long
unsigned long int/long c_ulong
long long int/long c_longlong
unsigned long long int/long c_ulonglong
float float c_float
double float c_double
char *(NULL terminated) string or none c_char_p
wchar_t *(NULL terminated) unicode or none c_wchar_p
void * int/long or none c_void_p

当一个函数期望一个指针作为参数时,可以像这样调用

1
function_main(byref(parameter))

struct例子
下面的例子是定义一个结构
C语言例子

1
2
3
4
5
struct beer_recipe
{
int amt_barley;
int amt_water;
};

Python例子

1
2
3
4
5
class beer_recipe(Structure):
_fields_ = [
("amt_barley", c_int),
("amt_water", c_int),
]

写在后面

ArcFaceSDK3.0还加入了很多新功能 比如说1:N的识别等 如果后期继续做相关应该会继续补到function里面