日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python调用sdk的文章_如何使用 python 接入虹软 ArcFace SDK

發布時間:2023/12/13 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python调用sdk的文章_如何使用 python 接入虹软 ArcFace SDK 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

公司需要在項目中使用人臉識別SDK,并且對信息安全的要求非常高,在詳細了解市場上幾個主流人臉識別SDK后,綜合來看虹軟的Arcface SDK比較符合我們的需求,它提供了免費版本,并且可以在離線環境下使用,這一點非常符合我們對安全性的要求。但有個遺憾的事情,我們的項目主要使用了Python語言,虹軟官方并沒有提供Python版本的SDK,因此我自己使用Python封裝了Arcface C++ SDK,便于在項目中使用,這里將主要過程寫出來供大家探討下。

1.環境說明

a.注意Win64環境的Python必須使用ArcFace C++(Win64) SDK,如果平臺不一致, 否則可能會出現以下錯誤。

OSError: [WinError 193] %1 不是有效的 Win32 應用程序

b.由于SDK中涉及到內存操作,本文使用了ctypes包和cdll包提供的以下幾種方式

c_ubyte_p = POINTER(c_ubyte)

memcpy = cdll.msvcrt.memcpy

malloc = cdll.msvcrt.malloc

malloc.restype = c_void_p

free = cdll.msvcrt.free

2.Arcface SDK基本數據結構封裝

在封裝數據結構時,一定要注意參數類型,否則可能會導致程序出錯。

class MRECT(Structure): # 人臉框

_fields_ = [(u'left', c_int32),

(u'top', c_int32),

(u'right', c_int32),

(u'bottom', c_int32)]

class ASFVersion(Structure): # 版本信息 版本號 構建日期 版權說明

_fields_ = [

('Version', c_char_p),

('BuildDate', c_char_p),

('CopyRight', c_char_p)]

class ASFSingleFaceInfo(Structure): # 單人臉信息 人臉框 人臉角度

_fields_ = [

('faceRect', MRECT),

('faceOrient', c_int32)]

class ASFMultiFaceInfo(Structure): # 多人臉信息 人臉框數組 人臉角度數組 人臉數

_fields_ = [

(u'faceRect', POINTER(MRECT)),

(u'faceOrient', POINTER(c_int32)),

(u'faceNum', c_int32)]

class ASFFaceFeature(Structure): # 人臉特征 人臉特征 人臉特征長度

_fields_ = [

('feature', c_void_p),

('featureSize', c_int32)]

class ASFFace3DAngle(Structure): # 人臉角度信息

_fields_ = [

('roll', c_void_p),

('yaw', c_void_p),

('pitch', c_void_p),

('status', c_void_p),

('num', c_int32)]

class ASFAgeInfo(Structure): # 年齡

_fields_ = [

(u'ageArray', c_void_p),

(u'num', c_int32)]

class ASFGenderInfo(Structure): # 性別

_fields_ = [

(u'genderArray', c_void_p),

(u'num', c_int32)]

class ASFLivenessThreshold(Structure): # 活體閾值

_fields_ = [

(u'thresholdmodel_BGR', c_float),

(u'thresholdmodel_IR', c_int32)]

class ASFLivenessInfo(Structure): # 活體信息

_fields_ = [

(u'isLive', c_void_p),

(u'num', c_int32)]

3.Arcface SDK接口封裝

a.接口封裝之前需要加載dll庫,Arcface SDK 提供的dll都需要加載。

b.本文中圖片格式使用了ASVL_PAF_RGB24_B8G8R8。

c.每個接口都需要定義返回值以及參數類型,某些參數類型依賴前文所述的基本數據結構。

from arcsoft_face_struct import *

from ctypes import *

from enum import Enum

face_dll = CDLL("libarcsoft_face.dll")

face_engine_dll = CDLL("libarcsoft_face_engine.dll")

ASF_DETECT_MODE_VIDEO = 0x00000000

ASF_DETECT_MODE_IMAGE = 0xFFFFFFFF

ASF_NONE = 0x00000000

ASF_FACE_DETECT = 0x00000001

ASF_FACE_RECOGNITION = 0x00000004

ASF_AGE = 0x00000008

ASF_GENDER = 0x00000010

ASF_FACE3DANGLE = 0x00000020

ASF_LIVENESS = 0x00000080

ASF_IR_LIVENESS = 0x00000400

ASVL_PAF_RGB24_B8G8R8 = 0x201

class ArcSoftFaceOrientPriority(Enum):

ASF_OP_0_ONLY = 0x1,

ASF_OP_90_ONLY = 0x2,

ASF_OP_270_ONLY = 0x3,

ASF_OP_180_ONLY = 0x4,

ASF_OP_0_HIGHER_EXT = 0x5,

activate = face_engine_dll.ASFActivation

activate.restype = c_int32

activate.argtypes = (c_char_p, c_char_p)

init_engine = face_engine_dll.ASFInitEngine

init_engine.restype = c_int32

init_engine.argtypes = (c_long, c_int32, c_int32, c_int32, c_int32, POINTER(c_void_p))

detect_face = face_engine_dll.ASFDetectFaces

detect_face.restype = c_int32

detect_face.argtypes = (c_void_p, c_int32, c_int32, c_int32, POINTER(c_ubyte), POINTER(ASFMultiFaceInfo))

extract_feature = face_engine_dll.ASFFaceFeatureExtract

extract_feature.restype = c_int32

extract_feature.argtypes = (c_void_p, c_int32, c_int32, c_int32, POINTER(c_ubyte),

POINTER(ASFSingleFaceInfo), POINTER(ASFFaceFeature))

compare_feature = face_engine_dll.ASFFaceFeatureCompare

compare_feature.restype = c_int32

compare_feature.argtypes = (c_void_p, POINTER(ASFFaceFeature),

POINTER(ASFFaceFeature), POINTER(c_float))

set_liveness_param = face_engine_dll.ASFSetLivenessParam

set_liveness_param.restype = c_int32

set_liveness_param.argtypes = (c_void_p, POINTER(ASFLivenessThreshold))

process = face_engine_dll.ASFProcess

process.restype = c_int32

process.argtypes = (c_void_p, c_int32, c_int32, c_int32, POINTER(c_ubyte),

POINTER(ASFMultiFaceInfo), c_int32)

get_age = face_engine_dll.ASFGetAge

get_age.restype = c_int32

get_age.argtypes = (c_void_p, POINTER(ASFAgeInfo))

get_gender = face_engine_dll.ASFGetGender

get_gender.restype = c_int32

get_gender.argtypes = (c_void_p, POINTER(ASFGenderInfo))

get_3d_angle = face_engine_dll.ASFGetFace3DAngle

get_3d_angle.restype = c_int32

get_3d_angle.argtypes = (c_void_p, POINTER(ASFFace3DAngle))

get_liveness_info = face_engine_dll.ASFGetLivenessScore

get_liveness_info.restype = c_int32

get_liveness_info.argtypes = (c_void_p, POINTER(ASFLivenessInfo))

4.封裝接口調用

接下來按照下面的流程圖介紹接口調用(此圖使用 Microsoft Visio 2016自動生成)。

下圖是按照此流程處理得到的效果圖,由于畫面有限,只顯示了年齡、性別、活體信息。

a.激活

需要注意app_id和sdk_key需要使用字節類型。

app_id = b""

sdk_key = b""

ret = arcsoft_face_func.activate(app_id, sdk_key) # 激活

if ret == 0 or ret == 90114:

print("激活成功")

else:

print("激活失敗:", ret)

b.初始化

初始化需要將所有需要的功能參數一次性傳入,本文使用了人臉檢測、特征提取等功能。

mask = arcsoft_face_func.ASF_FACE_DETECT | \

arcsoft_face_func.ASF_FACE_RECOGNITION | \

arcsoft_face_func.ASF_AGE | \

arcsoft_face_func.ASF_GENDER | \

arcsoft_face_func.ASF_FACE3DANGLE |\

arcsoft_face_func.ASF_LIVENESS

engine = c_void_p()

ret = arcsoft_face_func.init_engine(arcsoft_face_func.ASF_DETECT_MODE_IMAGE,

arcsoft_face_func.ArcSoftFaceOrientPriority.ASF_OP_0_ONLY.value[0],

30, 10, mask, byref(engine))

if ret == 0:

print("初始化成功")

else:

print("初始化失敗:", ret)

c.人臉檢測

本文使用了opencv讀圖,兼容性更好,并且自定義的數據結構記錄圖片信息,注意 ArcFace C++ SDK 要求傳入的圖像寬度需要是4的倍數,下面做了裁剪。

class Image:

def __init__(self):

self.width = 0

self.height = 0

self.imageData = None

def load_image(file_path):

img = cv2.imread(file_path)

sp = img.shape

img = cv2.resize(img, (sp[1]//4*4, sp[0]))# 四字節對齊

image = Image()

image.width = img.shape[1]

image.height = img.shape[0]

image.imageData = img

return image

###################### 人臉檢測 ##################################

image1 = load_image(r"1.jpg")

image_bytes = bytes(image1.imageData)

image_ubytes = cast(image_bytes, c_ubyte_p)

detect_faces = ASFMultiFaceInfo()

ret = arcsoft_face_func.detect_face(

engine,

image1.width,

image1.height,

arcsoft_face_func.ASVL_PAF_RGB24_B8G8R8,

image_ubytes,

byref(detect_faces)

)

if ret == 0:

print("檢測人臉成功")

else:

print("檢測人臉失敗:", ret)

d.特征提取

特征提取只支持單人臉,因此做了人臉處理操作,并且需要及時將提取的人臉特征拷貝一份,否則會被覆蓋。

single_face1 = ASFSingleFaceInfo()

single_face1.faceRect = detect_faces.faceRect[0]

single_face1.faceOrient = detect_faces.faceOrient[0]

face_feature = ASFFaceFeature()

ret = arcsoft_face_func.extract_feature(

engine,

image1.width,

image1.height,

arcsoft_face_func.ASVL_PAF_RGB24_B8G8R8,

image_ubytes,

single_face1,

byref(face_feature)

)

if ret == 0:

print("提取特征1成功")

else:

print("提取特征1失敗:", ret)

feature1 = ASFFaceFeature()

feature1.featureSize = face_feature.featureSize

feature1.feature = malloc(feature1.featureSize)

memcpy(c_void_p(feature1.feature),

c_void_p(face_feature.feature),

feature1.featureSize)

e.特征比對

按照前文所述再提取一張人臉的特征,即可以進行下面的人臉特征比對操作

compare_threshold = c_float()

ret = arcsoft_face_func.compare_feature(

engine, feature1, feature2, compare_threshold

)

free(c_void_p(feature1.feature))

free(c_void_p(feature2.feature))

if ret == 0:

print("特征比對成功,相似度:", compare_threshold.value)

else:

print("特征比對失敗:", ret)

f.年齡、性別、3D Angle

process接口目前提供了 年齡、性別、3D Angle、活體檢測, 但年齡、性別、3D Angle支持多人臉,而活體只支持單人臉,因此下面分別處理。

process_mask = arcsoft_face_func.ASF_AGE | \

arcsoft_face_func.ASF_GENDER | \

arcsoft_face_func.ASF_FACE3DANGLE

ret = arcsoft_face_func.process(

engine,

image1.width,

image1.height,

arcsoft_face_func.ASVL_PAF_RGB24_B8G8R8,

image_ubytes,

byref(detect_faces),

c_int32(process_mask)

)

if ret == 0:

print("process成功")

else:

print("process失敗:", ret)

######################## Age ################################

age_info = ASFAgeInfo()

ret = arcsoft_face_func.get_age(engine, byref(age_info))

if ret == 0:

print("get_age 成功")

age_ptr = cast(age_info.ageArray, POINTER(c_int))

for i in range(age_info.num):

print("face", i, "age:", age_ptr[i])

else:

print("get_age 失敗:", ret)

####################### Gender #################################

gender_info = ASFGenderInfo()

ret = arcsoft_face_func.get_gender(engine, byref(gender_info))

if ret == 0:

print("get_gender 成功")

gender_ptr = cast(gender_info.genderArray, POINTER(c_int))

for i in range(gender_info.num):

print("face", i, "gender:",

"女性" if (gender_ptr[i] == 1) else (

"男性" if (gender_ptr[i] == 0) else "未知"

))

else:

print("get_gender 失敗:", ret)

####################### 3D Angle #################################

angle_info = ASFFace3DAngle()

ret = arcsoft_face_func.get_3d_angle(engine, byref(angle_info))

if ret == 0:

print("get_3d_angle 成功")

roll_ptr = cast(angle_info.roll, POINTER(c_float))

yaw_ptr = cast(angle_info.yaw, POINTER(c_float))

pitch_ptr = cast(angle_info.pitch, POINTER(c_float))

status_ptr = cast(angle_info.status, POINTER(c_int32))

for i in range(angle_info.num):

print("face", i,

"roll:", roll_ptr[i],

"yaw:", yaw_ptr[i],

"pitch:", pitch_ptr[i],

"status:", "正常" if status_ptr[i] == 0 else "出錯")

else:

print("get_3d_angle 失敗:", ret)

g.RGB活體

在活體檢測之前建議按照實際場景設置活體閾值,不設置即使用默認閾值,這里設置了RGB活體的閾值為0.75。并將檢測的多人臉分別轉為單張人臉的參數傳到接口中。

######################### 活體閾值設置 ###############################

threshold_param = ASFLivenessThreshold()

threshold_param.thresholdmodel_BGR = 0.75

ret = arcsoft_face_func.set_liveness_param(engine,threshold_param)

if ret == 0:

print("set_liveness_param成功")

else:

print("set_liveness_param 失敗:", ret)

temp_face_info = ASFMultiFaceInfo()

temp_face_info.faceNum = 1

LP_MRECT = POINTER(MRECT)

temp_face_info.faceRect = LP_MRECT(MRECT(malloc(sizeof(MRECT))))

LP_c_long = POINTER(c_long)

temp_face_info.faceOrient = LP_c_long(c_long(malloc(sizeof(c_long))))

for i in range(detect_faces.faceNum):

temp_face_info.faceRect[0] = detect_faces.faceRect[i]

temp_face_info.faceOrient[0] = detect_faces.faceOrient[i]

ret = arcsoft_face_func.process(

engine,

image1.width,

image1.height,

arcsoft_face_func.ASVL_PAF_RGB24_B8G8R8,

image_ubytes,

byref(temp_face_info),

c_int32(arcsoft_face_func.ASF_LIVENESS)

)

if ret == 0:

print("process成功")

else:

print("process失敗:", ret)

## RGB活體檢測

ret = arcsoft_face_func.process(

engine,

image1.width,

image1.height,

arcsoft_face_func.ASVL_PAF_RGB24_B8G8R8,

image_ubytes,

byref(temp_face_info),

c_int32(arcsoft_face_func.ASF_LIVENESS)

)

if ret == 0:

print("process成功")

else:

print("process失敗:", ret)

liveness_info = ASFLivenessInfo()

ret = arcsoft_face_func.get_liveness_info(engine, byref(liveness_info))

if ret == 0:

print("get_liveness_info 成功")

liveness_ptr = cast(liveness_info.isLive, POINTER(c_int))

print("face", i, "liveness:",

"非真人" if (liveness_ptr[0] == 0) else (

"真人" if (liveness_ptr[0] == 1) else (

"不確定" if (liveness_ptr[0] == -1) else (

"傳入人臉數>1" if (liveness_ptr[0] == -2) else

(liveness_ptr[0])

)

)

))

else:

print("get_liveness_info 失敗:", ret)

總結

以上是生活随笔為你收集整理的python调用sdk的文章_如何使用 python 接入虹软 ArcFace SDK的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。