赞
踩
由于本地有一大批数据需要处理,虽然百度开放了在线人脸识别接口,但实际测试,10个QPS+50M上行带宽,仅仅三十多万张图就花了40小时左右, 后面还有大量的视频,抽帧检测更是难搞,因此申请离线识别SDK走起。。。。
狗血的是,百度的人脸识别SDK分为两种,离线采集(仅支持移动端)和离线识别,还有单设备90天和5台设备的限制,(吐槽归吐槽,后面还是得掏钱买的,还TM一百个授权码起购。。。)
到下载页面一看,傻眼了,没有python版本的,只有Java和C++.
我的java就是入了门,直接搞kotlin+Android(当然也是非常烂); C++就更不用说了,就会写个hello world
于是我萌生了一个大胆的想法——python调用Java!!!
python3.7
依赖库:pyjnius
jdk18
亲测此版本可用
不要问我为什么用这么新的jdk,因为我找不到当时的安装路径了,懒得找了,直接现场下。
python 仅仅需要 pip install pyjnius
即可食用。
理论上,应该下载C++版本的,直接编译成dll与python供python调用是最完美的方案,无奈我看不懂。
因此调用流程就是:python 调用 java , java在调用dll,然后再通过java传递给python。
jnius用法很简单,但有点小坑,因此我直接简单封装了个jvm
包,方便以后使用。
如果要修改jvm的封装,请注意: 导入顺序千万不能错,先配置环境变量,再调用jnius_config
, 最后再导入autoclass
,因为autoclass导入后,虚拟机已经启动了,再配置jnius_config
就不生效了(当然也有解决方案,但不做赘述,能跑就行)
# jvm.__init__.py
import os
import jnius_config
env = []
jar2classPaths = []
def run():
os.environ['path'] = ';'.join(env)
jnius_config.add_classpath(*jar2classPaths)
# jvm.com.py # 可以在这个文件中定义一些常用的Java类的映射与类型标注,方便IDE进行代码提示。 from jnius import autoclass class __System: @staticmethod def getProperty(key: str) -> str: ... @staticmethod def loadLibrary(name: str) -> str: ... @staticmethod def load(path: str) -> str: ... class out: def println(self, *args): ... System: __System = autoclass("java.lang.System")
# main.py # 运行测试 import jvm # --- jvm初始化 --- jvm.env.extend([ r"C:\Program Files\Java\jdk-18\bin\server", # jvm地址 # 各种dll路径,我将相关的dll全部复制到这个目录了,也可以直接填百度SDK的主目录 r"E:\projects\Python\tempitem\mada_emotion\lib"]) jvm.jar2classPaths.extend([ r"E:\projects\kotlin\BaiduFaceSDK\bin", # java编译后的目录 # jar包, 如果有其他依赖,继续往这儿加,本质上都是.class文件 r"E:\projects\Python\tempitem\mada_emotion\lib\opencv-320"]) jvm.run() # --- jvm初始化完成 --- # 尝试初始化百度SDK的Face类 api = autoclass("com.jni.face.Face")() print(api.sdkInit("xxxxx")) # 初始化成功返回0
至此,就可以勉强使用了
可是,作为有强迫症的我,没有代码提示简直没法下手敲,因此,肝了一小时,拿去用吧各位,不用谢。共三个文件,封装成了baiduFaceSDK,后面打包整理传github再更新。
# baiduFaceSDK.__init__.py from jnius import autoclass from result import * class Api: def __new__(cls, **kwargs): return autoclass("com.jni.face.Face")() def __init__(self): ... def readImage(self, f: Union[bytes, bytearray]) -> Mat: ... def sdkInit(self, modelPath) -> int: ... def sdkDestroy(self): ... def isAuth(self) -> bool: ... def getDeviceId(self) -> str: ... def sdkVersion(self) -> str: ... def detect(self, addr: int, _type: int) -> detectResult: ... def track(self, addr: int, _type: int) -> trackResult: ... def clearTrackHistory(self) -> int: def faceAttr(self, addr: int) -> faceAttrResult: ... def faceEyeClose(self, addr: int) -> faceEyeCloseResult: ... def faceGaze(self, addr: int) -> faceGazeResult: ... def faceHeadPose(self, addr: int) -> faceHeadPoseResult: ... def faceIllumination(self, addr: int) -> List[int]: ... def faceBlur(self, addr: int) -> List[float]: ... def faceMouthClose(self, addr: int) -> List[float]: ... def faceMouthMask(self, addr: int) -> List[float]: ... def faceOcclusion(self, addr: int) -> faceOcclusionResult: ... def darkEnhance(self, in_addr: int, out_addr: int) -> int: ... def faceCrop(self, in_addr: int, out_addr: int) -> int: ... def faceBest(self, addr: int) -> List[float]: ... def faceLandmark(self, addr: int) -> faceLandmarkResult: ... def faceActionLive(self, addr: int, actionType: int, actionResult: List[int]) -> faceActionLiveResult: ... def clearActionLiveHistory(self) -> int: ... def faceFeature(self, addr: int, _type: int) -> faceFeatureResult: ... def livenessFeature(self, addr: int, _type: int) -> livenessFeatureResult: ... def match(self, addr1: int, addr2: int, _type: int) -> int: ... def compareFeature(self, f1: Feature, f2: Feature, _type: int) -> float: ... def rgbLiveness(self, addr: int) -> rgbLivenessResult: ... def userAddByMat(self, addr: int, userId: str, groupId: str, userInfo: str) -> str: ... def userAdd(self, fea: Feature, userId: str, groupId: str, userInfo: str) -> str: ... def userUpdate(self, addr: int, userId: str, groupId: str, userInfo: str) -> str: ... def userDelete(self, userId: str, groupId: str) -> str: ... def groupAdd(self, groupId: str) -> str: ... def groupDelete(self, groupId: str) -> str: ... def getUserInfo(self, userId: str, groupId: str) -> str: ... def getUserImage(self, out_addr: int, userId: str, groupId: str) -> int: ... def getUserList(self, groupId: str, start: int, length: int) -> str: ... def getGroupList(self, start: int, length: int) -> str: ... def dbFaceCount(self, groupId: str) -> int: ... def identifyByMat(self, addr: int, groupIdList: str, userId: str, _type: int)-> str: ... def identify(self, fea: Feature, groupIdList: str, userId: str, _type: int) -> str: ... def identifyWithAllByMat(self, addr: int, _type: int) -> str: ... def identifyWithAll(self, fea: Feature, _type: int) -> str: ... def loadDbFace(self) -> bool: ...
# baiduFaceSDK.result.py # 定义接口的返回值,并做类型标注,即使是列表遍历之后Pycharm也会提示关键字,舒服!!! from structs import * class Mat: def release(self): ... def getNativeObjAddr(self) -> float: ... class detectResult(list): def __getitem__(self, i) -> FaceBox: ... def __iter__(self) -> List[FaceBox]: ... class trackResult(list): def __getitem__(self, i) -> TrackFaceInfo: ... def __iter__(self) -> List[TrackFaceInfo]: ... class faceAttrResult(list): def __getitem__(self, i) -> Attribute: ... def __iter__(self) -> List[Attribute]: ... class faceEyeCloseResult(list): def __getitem__(self, i) -> EyeClose: ... def __iter__(self) -> List[EyeClose]: ... class faceGazeResult(list): def __getitem__(self, item) -> GazeInfo: ... def __iter__(self) -> List[GazeInfo]: ... class faceHeadPoseResult(list): def __getitem__(self, item) -> HeadPose: ... def __iter__(self) -> List[HeadPose]: ... class faceOcclusionResult(list): def __getitem__(self, item) -> Occlusion: ... def __iter__(self) -> List[Occlusion]: ... class faceLandmarkResult(list): def __getitem__(self, item) -> Landmarks: ... def __iter__(self) -> List[Landmarks]: ... class faceActionLiveResult(list): def __getitem__(self, item) -> FaceBox: ... def __iter__(self) -> List[FaceBox]: ... class faceFeatureResult(list): def __getitem__(self, item) -> FeatureInfo: ... def __iter__(self) -> List[FeatureInfo]: ... class livenessFeatureResult(list): def __getitem__(self, item) -> LiveFeatureInfo: ... def __iter__(self) -> List[LiveFeatureInfo]: ... class rgbLivenessResult(list): def __getitem__(self, item) -> LivenessInfo: ... def __iter__(self) -> List[LivenessInfo]: ...
# baiduFaceSDK.structs.py # 定义的结构体 from typing import List class Attribute: age: int race: int # 0:黄种人 1:白种人 2:黑种人 3:印第安人 emotion: int # 0:皱眉 1:笑 2:平静 glasses: int # 0:无眼镜 1:有眼镜 2:墨镜 gender: int # 0:女性 1:男性 class CropFaceConf: isFlat: int # 是否镜像 cropSize: int # 抠图大小 enlargeRatio: int # 抠图倍数 class EyeClose: # 双眼闭合置信度 leftEyeCloseConf: float rightEyeCloseConf: float class FaceBox: index: int centerx: float centery: float width: float height: float angle: float score: float class Feature: size: int data: bytes class FeatureInfo: feature: Feature face: FaceBox class GazeInfo: # 注意力信息 leftEyeDirection: int # 左眼凝视方向 0:向上看 1:向下看 2:向右看 3:向左看 4:向前看 5:闭眼 leftEyeConf: float # 置信度 rightEyeDirection: int # 右眼凝视方向 0:向上看 1:向下看 2:向右看 3:向左看 4:向前看 5:闭眼 rightEyeConf: float # 置信度 class HeadPose: yaw: float # 水平转动 roll: float # 左右倾斜 pitch: float # 抬头低头 class Landmarks: index: int # 关键点索引 size: int data: List[float] # 关键点数据,144个点,72个x,y坐标 score: float # 关键点分值 class LiveFeatureInfo: feature: Feature # 特征值 box: FaceBox # 人脸框 score: float # 活体分值 class TrackFaceInfo: faceId: int box: FaceBox land: Landmarks class LivenessInfo: trackinfo: TrackFaceInfo livescore: float class Occlusion: leftEye: float rightEye: float nose: float mouth: float leftCheek: float rightCheek: float chin: float class RgbDepthInfo: trackinfo: TrackFaceInfo rgbscore: float depthscore: float
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。