欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

如何使用 python 接入虹軟 ArcFace SDK

系統 1830 0

公司需要在項目中使用人臉識別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自動生成)。
如何使用 python 接入虹軟 ArcFace SDK_第1張圖片

下圖是按照此流程處理得到的效果圖,由于畫面有限,只顯示了年齡、性別、活體信息。
如何使用 python 接入虹軟 ArcFace SDK_第2張圖片

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)



          

  寫在最后,歡迎大家交流指正,若有需要下載其他語言的SDK或demo,可至其官網下載~https://ai.arcsoft.com.cn/product/arcface.html?utm_source=cnblogs&utm_medium=referral


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 免费精品 | 亚洲伊人精品 | 91中文字幕在线观看 | A片扒开双腿猛进入免费观看 | 欧美在线视频一区二区三区 | 五月婷在线 | 亚洲偷图色综合色就色 | 五月激情综合婷婷 | 亚洲最大成人在线 | 91高清视频 | 亚洲入口 | 国产欧美日韩第一页 | 久久久高清免费视频 | 欧美永久精品 | 精品欧美日韩 | 看亚洲a级一级毛片 | 久久久久久久综合日本亚洲 | 色综合色综合色综合 | 欧美亚洲国产另类在线观看 | 欧美无遮挡一区二区三区 | 国产一区二区三区不卡在线观看 | 欧美日韩三区 | 国产精品毛片一区二区在线看 | 中文字幕免费在线观看视频 | 久草手机在线视频 | 免费成人av | 一区二区三区四区在线观看视频 | 91你懂的 | 精品三级国产精品经典三 | 黄色免费av | 国产精品久久久久影视青草 | 久久综合九色综合欧洲 | 污视频免费观看网站 | 日本喷潮 | 男人天堂中文字幕 | 99热热精品 | 免费成人福利视频 | 欧美日韩国产一区二区三区 | 老司机福利在线视频 | 亚洲精品一区二区三区在线观看 | 91免费视频版 |