python3调用虹软3.0人脸识别

2023-10-28 17:30

本文主要是介绍python3调用虹软3.0人脸识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

python3调用虹软3.0人脸识别

    • 说明
    • 代码结构

说明

平台 windows,linux没试过应该也可以只需将虹软sdk换成linux版本即可。
软件依赖 cv2、flask、虹软sdk3版本(2版本的也可以)
main_flask是以图片的方式在浏览器上实时浏览,
main_client是一个窗口的形式展现实时监测视频数据。
代码结构
虹软的sdk怎么搞就不多说了,自己看官网。

代码结构

  1. flask程序主入口 main_flask.py
import face_dll
import face_class
from ctypes import *
import cv2
import face_function as fun
import face_feature_extract
import video_camera
from flask import Flask, abort, request, jsonify, Responseapp = Flask(__name__)Appkey = b''
SDKey = b'''''
存放人脸库的信息,key为对应的图片名即为1.jpg或者2.jpg
'''
faceInfos = {'1':{'name':'Ju Jingyi','gender':'girl','age':'25','image':'images/1.jpg'},'2':{'name':'Ju Jingyi','gender':'girl','age':'25','image':'images/2.jpg'}}'''
激活sdk,激活一次即可
'''def active():ret = fun.active(Appkey, SDKey)if ret == 0 or ret == 90114:print('激活成功:', ret)else:print('激活失败:', ret)passdef init():# 初始化 1 视频(0x00000000)或图片(0xFFFFFFFF)模式,ret = fun.init(0x00000000)if ret[0] == 0:print('初始化成功:', ret, '句柄', fun.Handle)else:print('初始化失败:', ret)def gen():videoCamera = video_camera.VideoCamera(faceFeatures, faceInfos)while True:ret, frame = videoCamera.get_frame()if ret:yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame.tobytes() + b'\r\n\r\n')'''
返回图片流
'''
@app.route('/video_feed/')
def video_feed():return Response(gen(),mimetype='multipart/x-mixed-replace; boundary=frame')if __name__ == "__main__":#active()# 加载人脸资源faceFeatures = face_feature_extract.load_face_feature(faceInfos)init()app.run(host="0.0.0.0", port=8080, debug=True, threaded=True, processes=True)
  1. 摄像头类 video_camera.py
import cv2
import face_function as fun
import face_feature_extract
import face_class'''
摄像头类
'''class VideoCamera(object):def __init__(self, faceFeatures, faceInfos):# 通过opencv获取实时视频流self.videoCapture = cv2.VideoCapture(0, cv2.CAP_DSHOW)self.frame_width = int(self.videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH))self.frame_height = int(self.videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT))self.faceFeatures = faceFeaturesself.faceInfos = faceInfosdef __del__(self):self.videoCapture.release()'''将视频帧转换为字节流返回'''def get_frame(self):ret, frame = self.videoCapture.read()if ret:# 加载图片imageData = face_class.ImageData(frame, self.frame_width, self.frame_height)ret, faces = fun.detectFaces(fun.deal_image_data(imageData))if ret == 0:frame = fun.deal_frame(imageData, faces, self.faceFeatures, self.faceInfos)img_fps = 80img_param = [int(cv2.IMWRITE_JPEG_QUALITY), img_fps]# 转化ret, frame = cv2.imencode('.jpg', frame, img_param)return ret, frame
  1. 人脸识别相关函数 face_function.py
import face_dll
import face_class
from ctypes import *
import cv2
from io import BytesIO# from Main import *
Handle = c_void_p()
c_ubyte_p = POINTER(c_ubyte)# 激活函数def active(appkey, sdkey):ret = face_dll.active(appkey, sdkey)return ret# 初始化函数def init(model):'''1 视频(0x00000000)或图片(0xFFFFFFFF)模式,2 角度(),3 识别的最小人脸比例 = 图片长边 / 人脸框长边的比值 默认推荐值:VIDEO模式推荐16;IMAGE模式推荐324 最大需要检测的人脸个数,取值范围[1,50],5 需要启用的功能组合,可多选ASF_FACE_DETECT 0x00000001 //人脸检测 SF_FACERECOGNITION 0x00000004 //人脸特征 ASF_AGE 0x00000008 //年龄 ASF_GENDER 0x00000010 //性别ASF_FACE3DANGLE 0x00000020 //3D角度 ASF_LIVENESS 0x00000080 //RGB活体 ASF_IR_LIVENESS 0x00000400 //IR活体 这些属性均是以常量值进行定义,可通过 | 位运算符进行组合使用。例如 MInt32 combinedMask = ASF_FACE_DETECT | ASF_FACERECOGNITION | ASF_LIVENESS;6 返回激活句柄'''ret = face_dll.initEngine(model, 0x1, 16, 10, 5, byref(Handle))return ret, Handle# cv2记载图片并处理def LoadImg(imageData):img = cv2.imread(imageData.filepath)sp = img.shapeimg = cv2.resize(img, (sp[1]//4*4, sp[0]//4*4))sp = img.shapeimageData.image = imgimageData.width = sp[1]imageData.height = sp[0]return imageData'''
处理图片改变大小
'''def deal_image_data(imageData):shape = imageData.image.shapeimage = cv2.resize(imageData.image, (shape[1]//4*4, shape[0]//4*4))shape = image.shapeimageData.image = imageimageData.width = shape[1]imageData.height = shape[0]return imageDatadef detectFaces(imageData):faces = face_class.ASF_MultiFaceInfo()imgby = bytes(imageData.image)imgcuby = cast(imgby, c_ubyte_p)ret = face_dll.detectFaces(Handle, imageData.width, imageData.height, 0x201, imgcuby, byref(faces))return ret, faces# 显示人脸识别图片def showimg(im, faces):for i in range(0, faces.faceNum):ra = faces.faceRect[i]cv2.rectangle(im.image, (ra.left, ra.top),(ra.right, ra.bottom), (255, 0, 0,), 2)cv2.imshow('faces', im.image)cv2.waitKey(0)# 显示人脸识别图片def showimg2(imageData, faces, faceFeatures, faceInfos):for i in range(0, faces.faceNum):# 画出人脸框ra = faces.faceRect[i]cv2.rectangle(imageData.image, (ra.left, ra.top),(ra.right, ra.bottom), (255, 0, 0,), 2)peopleName = 'unknown'res = 0.5# 提取单人1特征ft = getsingleface(faces, i)ret, faceFeature = faceFeatureExtract(imageData, ft)if ret == 0:for item in faceFeatures:ret, result = faceFeatureCompare(faceFeature, item['faceFeature'])if ret == 0:if result > res:res = resultpeopleName = faceInfos[item['id']]['name']cv2.putText(imageData.image, peopleName, (ra.left, ra.top - 5),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0,), 1, cv2.LINE_AA)cv2.imshow('faces', imageData.image)def deal_frame(imageData, faces, faceFeatures, faceInfos):for i in range(0, faces.faceNum):# 画出人脸框ra = faces.faceRect[i]cv2.rectangle(imageData.image, (ra.left, ra.top),(ra.right, ra.bottom), (255, 0, 0,), 2)peopleName = 'unknown'res = 0.5# 提取单人1特征ft = getsingleface(faces, i)ret, faceFeature = faceFeatureExtract(imageData, ft)if ret == 0:for item in faceFeatures:ret, result = faceFeatureCompare(faceFeature, item['faceFeature'])if ret == 0:if result > res:res = resultpeopleName = faceInfos[item['id']]['name']cv2.putText(imageData.image, peopleName, (ra.left, ra.top - 5),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0,), 1, cv2.LINE_AA)return imageData.image
# 提取人脸特征def faceFeatureExtract(im, ft):detectedFaces = face_class.ASF_FaceFeature()img = im.imageimgby = bytes(im.image)imgcuby = cast(imgby, c_ubyte_p)ret = face_dll.faceFeatureExtract(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)return ret, retzelse:return ret, None# 特征值比对,返回比对结果def faceFeatureCompare(faceFeature1, FaceFeature2):result = c_float()ret = face_dll.faceFeatureCompare(Handle, faceFeature1, FaceFeature2, byref(result))return ret, result.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.left = ra.leftft.faceRect.right = ra.rightft.faceRect.top = ra.topft.faceRect.bottom = ra.bottomft.faceOrient = singleface.faceOrient[index]return ft# 从文件获取特征值def ftfromfile(filepath):fas = face_class.ASF_FaceFeature()f = open(filepath, '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
  1. 人脸特征值提取face_feature_extract.py
import face_dll
import face_class
import cv2
import face_function as fun
import os
from ctypes import string_at'''
存放人脸特征值的集合
'''
faceFeatures = []'''
初始化sdk设置为图片模式以加载更为精确的特征值集合
'''def init():# 初始化ret = fun.init(0xFFFFFFFF)if ret[0] == 0:print('初始化成功:', ret, '句柄', fun.Handle)else:print('初始化失败:', ret)'''
提取图片文件里面的人脸特征值
'''def face_feature_extract(filepath):imageData = face_class.ImageLoadData(filepath)imageData = fun.LoadImg(imageData)ret, faces = fun.detectFaces(imageData)if ret == 0:# 提取单人1特征ft = fun.getsingleface(faces, 0)ret, faceFeature = fun.faceFeatureExtract(imageData, ft)return ret, faceFeature'''
读取人脸资源库所有的图片
'''def read_images(filePath):for i, j, files in os.walk(filePath):return filesdef load_face_feature(faceInfos):init()for info in faceInfos:imagePath = faceInfos[info]['image']if imagePath.find('.jpg'):ret, faceFeature = face_feature_extract(imagePath)if ret == 0:print("add faceFeature", info)faceFeatures.append({'id': info, 'faceFeature': faceFeature})return faceFeaturesif __name__ == "__main__":faceInfos = {'1':{'name':'Ju Jingyi','gender':'girl','age':'25','image':'images/1.jpg'},'2':{'name':'Ju Jingyi','gender':'girl','age':'25','image':'images/2.jpg'}}load_face_feature(faceInfos)
  1. 特征值对比 face_feature_compare.py
import face_dll
import face_class
import face_function as fun
import face_feature_extract'''
本地图片提取的特征值与内存的特征值对比
'''def face_feature_compare(faceFeature):# 结果比对faceFeatures = face_feature_extract.loadFaceFeature('images/')for item in faceFeatures:ret, result = fun.faceFeatureCompare(faceFeature, item['faceFeature'])if ret == 0:print('name %s similarity %s' % (item['name'], result))if __name__ == "__main__":ret, faceFeature = face_feature_extract.faceFeatureExtract('images/JuJingyi.jpg')if ret == 0:face_feature_compare(faceFeature)
  1. c++中的结构体python封装 face_class.py
from ctypes import c_int32, c_char_p, Structure, POINTER, c_void_p# 人脸框class MRECT(Structure):_fields_ = [(u'left', c_int32), (u'top', c_int32),(u'right', c_int32), (u'bottom', 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_ = [(u'faceRect', POINTER(MRECT)), (u'faceOrient',POINTER(c_int32)), (u'faceNum', c_int32)]# 人脸特征 人脸特征,人脸特征长度class ASF_FaceFeature(Structure):_fields_ = [('feature', c_void_p), ('featureSize', c_int32)]# 自定义图片类class ImageData:def __init__(self, image, width, height):self.image = imageself.width = widthself.height = height# 自定义图片类class ImageLoadData:def __init__(self, filepath):self.filepath = filepathself.image = Noneself.width = 0self.height = 0
  1. sdk库pyhton接口封装 face_dll.py
from ctypes import c_int32, c_char_p, c_void_p, c_float, c_size_t, c_ubyte, c_long, cdll, POINTER, CDLL
from face_class import ASF_MultiFaceInfo, ASF_SingleFaceInfo, ASF_FaceFeaturewuyongdll = CDLL('libarcsoft/libarcsoft_face.dll')
dll = CDLL('libarcsoft/libarcsoft_face_engine.dll')
dllc = cdll.msvcrt
ASF_DETECT_MODE_VIDEO = 0x00000000
ASF_DETECT_MODE_IMAGE = 0xFFFFFFFF
c_ubyte_p = POINTER(c_ubyte)# 激活
active = dll.ASFActivation
active.restype = c_int32
active.argtypes = (c_char_p, c_char_p)# 初始化
initEngine = dll.ASFInitEngine
initEngine.restype = c_int32
initEngine.argtypes = (c_long, c_int32, c_int32,c_int32, c_int32, POINTER(c_void_p))# 人脸识别
detectFaces = dll.ASFDetectFaces
detectFaces.restype = c_int32
detectFaces.argtypes = (c_void_p, c_int32, c_int32,c_int32, POINTER(c_ubyte), POINTER(ASF_MultiFaceInfo))# 特征提取
faceFeatureExtract = dll.ASFFaceFeatureExtract
faceFeatureExtract.restype = c_int32
faceFeatureExtract.argtypes = (c_void_p, c_int32, c_int32, c_int32, POINTER(c_ubyte), POINTER(ASF_SingleFaceInfo), POINTER(ASF_FaceFeature))# 特征比对
faceFeatureCompare = dll.ASFFaceFeatureCompare
faceFeatureCompare.restype = c_int32
faceFeatureCompare.argtypes = (c_void_p, POINTER(ASF_FaceFeature), POINTER(ASF_FaceFeature), POINTER(c_float))
malloc = dllc.malloc
free = dllc.free
memcpy = dllc.memcpymalloc.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)
  1. 窗口的形式展现 main_client.py
import face_dll
import face_class
from ctypes import *
import cv2
import face_function as fun
import face_feature_extractAppkey = b''
SDKey = b'''''
存放人脸库的信息,key为对应的图片名即为1.jpg或者2.jpg
'''
faceInfos = {'1':{'name':'Ju Jingyi','gender':'girl','age':'25','image':'images/1.jpg'},'2':{'name':'Ju Jingyi','gender':'girl','age':'25','image':'images/2.jpg'}}'''
激活sdk,激活一次即可
'''def active():ret = fun.active(Appkey, SDKey)if ret == 0 or ret == 90114:print('激活成功:', ret)else:print('激活失败:', ret)passdef init():# 初始化 1 视频(0x00000000)或图片(0xFFFFFFFF)模式,ret = fun.init(0x00000000)if ret[0] == 0:print('初始化成功:', ret, '句柄', fun.Handle)else:print('初始化失败:', ret)def start(faceFeatures):cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))while True:# get a frameret, frame = cap.read()if ret:# 加载图片imageData = face_class.ImageData(frame, frame_width, frame_height)ret, faces = fun.detectFaces(fun.deal_image_data(imageData))if ret == 0:fun.showimg2(imageData, faces, faceFeatures, faceInfos)else:pass# show a frameif cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()if __name__ == "__main__":#active()# 加载人脸资源faceFeatures = face_feature_extract.load_face_feature(faceInfos)init()start(faceFeatures)

代码地址:码云仓库代码

这篇关于python3调用虹软3.0人脸识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/294808

相关文章

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性

python3 pip终端出现错误解决的方法详解

《python3pip终端出现错误解决的方法详解》这篇文章主要为大家详细介绍了python3pip如果在终端出现错误该如何解决,文中的示例方法讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下... 目录前言一、查看是否已安装pip二、查看是否添加至环境变量1.查看环境变量是http://www.cppcns

使用Python实现调用API获取图片存储到本地的方法

《使用Python实现调用API获取图片存储到本地的方法》开发一个自动化工具,用于从JSON数据源中提取图像ID,通过调用指定API获取未经压缩的原始图像文件,并确保下载结果与Postman等工具直接... 目录使用python实现调用API获取图片存储到本地1、项目概述2、核心功能3、环境准备4、代码实现

使用@Cacheable注解Redis时Redis宕机或其他原因连不上继续调用原方法的解决方案

《使用@Cacheable注解Redis时Redis宕机或其他原因连不上继续调用原方法的解决方案》在SpringBoot应用中,我们经常使用​​@Cacheable​​注解来缓存数据,以提高应用的性能... 目录@Cacheable注解Redis时,Redis宕机或其他原因连不上,继续调用原方法的解决方案1

C#通过进程调用外部应用的实现示例

《C#通过进程调用外部应用的实现示例》本文主要介绍了C#通过进程调用外部应用的实现示例,以WINFORM应用程序为例,在C#应用程序中调用PYTHON程序,具有一定的参考价值,感兴趣的可以了解一下... 目录窗口程序类进程信息类 系统设置类 以WINFORM应用程序为例,在C#应用程序中调用python程序

Java调用Python的四种方法小结

《Java调用Python的四种方法小结》在现代开发中,结合不同编程语言的优势往往能达到事半功倍的效果,本文将详细介绍四种在Java中调用Python的方法,并推荐一种最常用且实用的方法,希望对大家有... 目录一、在Java类中直接执行python语句二、在Java中直接调用Python脚本三、使用Run

Python如何调用指定路径的模块

《Python如何调用指定路径的模块》要在Python中调用指定路径的模块,可以使用sys.path.append,importlib.util.spec_from_file_location和exe... 目录一、sys.path.append() 方法1. 方法简介2. 使用示例3. 注意事项二、imp

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

python3 gunicorn配置文件的用法解读

《python3gunicorn配置文件的用法解读》:本文主要介绍python3gunicorn配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python3 gunicorn配置文件配置文件服务启动、重启、关闭启动重启关闭总结python3 gun