ArcFaceSDK3.0 Python Demo

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

face_class

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


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

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

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

function_main(byref(parameter))

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

    struct beer_recipe
    {
    int amt_barley;
    int amt_water;
    };

Python例子

class beer_recipe(Structure):
    _fields_ = [
    ("amt_barley", c_int),
    ("amt_water", c_int),
    ]

写在后面

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

上一篇:python人工智能第二篇:人脸检测和图像识别


下一篇:人脸检测——基于Haar分类器方法