2023年没有封闭的网站有哪些广告投放这个工作难不难做
2023年没有封闭的网站有哪些,广告投放这个工作难不难做,济南软件优化网站建设,wordpress的登陆地址修改密码本文基于虹软人脸服务器版SDK(Linux Pro和ARM Pro)(后续称人脸SDK)#xff0c;就视频和图片2种模式#xff0c;对人脸多线程应用框架进行了讨论#xff0c;并对SDK接入过程中的一些开发注意项以及性能优化点做了总结分析#xff0c;旨在交流讨论服务器环境下#xff0c;常…本文基于虹软人脸服务器版SDK(Linux Pro和ARM Pro)(后续称人脸SDK)就视频和图片2种模式对人脸多线程应用框架进行了讨论并对SDK接入过程中的一些开发注意项以及性能优化点做了总结分析旨在交流讨论服务器环境下常见人脸开发业务的处理流程和设计思想。虹软人脸SDK服务器版本提供了人脸检测、人脸识别、人脸跟踪、人脸比对、人脸属性、人脸质量检测、RGB/IR活体等功能提供了C/C/Java版本接口能够满足众多场景下的人脸业务需求。本文主要参考的链接为官方服务器版本源码链接开发者中心-虹软视觉开放平台知乎博文参考链接(31 封私信 / 6 条消息) 在Spring Boot项目中集成虹软Linux Pro SDK实现人脸1N对比服务极简版快速上手 - 知乎一、不同场景下人脸业务多线程架构服务器版的人脸SDK根据场景功能需求分为图片和视频流两种模式具体选择哪种方式需要综合前端硬件能力、网络情况、业务需求等来决定。1.1 图片模式下人脸业务多线程架构对于使用图片的场景一般满足以下一些特征之一前端设备具备图片上传能力、业务并发程度相对较高环境网络相对不稳定、实时性要求不高。常见的场景有考勤、门禁、VIP客户精准识别等。以门禁考勤场景为例前端设备是抓拍相机整体框架结构如下图 1-1图片模式人脸业务框架在上图中网络协议常见的有http/tcp等报文内容根据实际业务内容自定义。数据流形式是前端设备上传人脸照片服务器接收照片完成人脸检测业务通常服务器要处理来自N个设备的并发请求。1.2 视频流模式下人脸业务多线程架构对于使用视频流的场景一般前端设备是网络相机并且这些设备不具备抓拍能力需要依赖服务器来完成人脸检测、识别等流程。另外在视频模式下对网络要求相对较高因为需要接入多路视频流。输入视频流常见的场景有园区老旧摄像头改造接入人脸识别能力、服务器端需要人脸跟踪显示等。以安防监控场景为例前端是IPC相机整体框架结构如下图 1-2视频模式人脸业务框架在上图中不同于输入为图片的情况框架中增加了RTSP取流和推流线程推流线程中的视频流一般会自定义加入一些OSD信息显示例如人脸框等。人员操作任务通常处理前端的人员操作请求人脸增删改查使用方法同上面的图片模式。在视频流模式下可以根据业务功能需求设计2个引擎池FT(人脸跟踪)引擎池、通用引擎池(完成人脸识别、属性获取等)。这里设计2个引擎池的目的是降低内存消耗人脸SDK初始化掩码不同内存会存在差异后面会详细提到。1.3 小结从人脸SDK多线程使用角度图片和视频模式两者差异不是很大前者处理的是一张张来自不同前端设备的单独图片每个任务是独立的后者接收的是来自多台相机的码流数据需要额外关注的是人脸跟踪以及视频流图片抽帧(因为服务器处理的能力有限)。但是对于SDK来说最终期望处理的都是一张质量相对较高的人脸图片。因此这里结合2种模式下实际接入过程中经验给出人脸SDK接入过程的一些注意点1多线程调用SDK时需要考虑资源竞争和同步问题对于同一个引擎句柄目前的人脸SDK暂不支持在不同线程中同时调用同一个人脸处理接口(例如人脸特征提取)2人脸SDK支持创建多个引擎句柄来加快业务处理速度但是不同引擎句柄之间特征数据是不共享的多引擎加速需要注意引擎之间数据同步3为简化特征管理加快人脸1VN比对速度人脸SDK中提供了特征管理接口但是SDK特征是存储在内存中特征操作时需要注意同步到本地数据库中图 1-3不同句柄中人脸特征数据和本地数据库关系上述的注意项大致可以总结为多线程下人脸SDK引擎管理、以及特征数据管理问题。本文将在后续章节针对这些点给出自己的处理思路并针对现有的SDK接口结合实际业务给出一些性能优化技巧(人脸注册和人脸识别业务性能优化)二、SDK接口安全调用及资源管理2.1 如何安全管理SDK引擎在实际的人脸业务中为加速业务处理速度会使用多引擎的方式来并行处理业务。安全的管理多引擎句柄最方便的方法就是使用引擎池。引擎池提供了线程安全的方法来保证引擎句柄的独占解决竞争问题。本文这里仅给出java里面现成的方法类GenericObjectPool后续将基于这个来描述引擎管理。2.1.1 引擎创建在人脸SDK中创建引擎时可以按需初始化对应功能的掩码初始化不同的掩码对应引擎所占用的内存也会存在差异。例如视频模式下在人脸检测线程中对应的引擎只需要初始化ASF_FACE_DETECT掩码。下表给出了初始化全部掩码子功能和只初始化FD的内存占用情况对比可以发现掩码初始化和内存占用有强相关。表 2-1不同初始化掩码内存占用对比模块内存ASF_FACE_DETECT/ASF_FACERECOGNITION/ASF_AGE/ASF_GENDER/ASF_LIVENESS/ASF_IR_LIVENESS/ASF_MASKDETECT/ASF_IMAGEQUALITY192MBASF_FACE_DETECT66MB如下代码给出了输入为视频流模式下的引擎初始化过程。privatevoidinit(){GenericObjectPoolConfigFaceEnginedetectPoolConfignewGenericObjectPoolConfig();detectPoolConfig.setMaxIdle(detectPoolSize);detectPoolConfig.setMaxTotal(detectPoolSize);detectPoolConfig.setMinIdle(detectPoolSize);detectPoolConfig.setLifo(false);EngineConfigurationdetectCfgnewEngineConfiguration();FunctionConfigurationdetectFunctionCfgnewFunctionConfiguration();detectFunctionCfg.setSupportFaceDetect(true);//开启人脸检测功能detectFunctionCfg.setSupportAge(true);//开启年龄检测功能detectFunctionCfg.setSupportGender(true);//开启性别检测功能detectFunctionCfg.setSupportLiveness(true);//开启活体检测功能detectCfg.setFunctionConfiguration(detectFunctionCfg);detectCfg.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);//图片检测模式如果是连续帧的视频流图片那么改成VIDEO模式detectCfg.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);//人脸旋转角度detectCfg.setFaceModel(faceModel);generalPoolnewGenericObjectPool(newFaceEngineFactory(appId,sdkKey,activeKey,activeFile,detectCfg),detectPoolConfig);//底层库算法对象池GenericObjectPoolConfigFaceEnginedetectFtPoolConfignewGenericObjectPoolConfig();detectFtPoolConfig.setMaxIdle(detectPoolSize);detectFtPoolConfig.setMaxTotal(detectPoolSize);detectFtPoolConfig.setMinIdle(detectPoolSize);detectFtPoolConfig.setLifo(false);EngineConfigurationdetectFtCfgnewEngineConfiguration();FunctionConfigurationdetectFtFunctionCfgnewFunctionConfiguration();detectFtFunctionCfg.setSupportFaceDetect(true);//开启人脸检测功能detectFtCfg.setFunctionConfiguration(detectFtFunctionCfg);detectFtCfg.setDetectMode(DetectMode.ASF_DETECT_MODE_VIDEO);//视频检测模式detectFtCfg.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);//人脸旋转角度detectFtCfg.setFaceModel(faceModel);//底层库算法对象池ftPoolnewGenericObjectPool(newFaceEngineFactory(appId,sdkKey,activeKey,activeFile,detectFtCfg),detectFtPoolConfig);}2.1.2 引擎使用Java类GenericObjectPool中提供了borrowObject和returnObject接口来实现引擎资源的独占和释放具体调用方法示例如下publicUserCompareInfofaceRecognition(byte[]faceFeature,floatpassRate){FaceEnginefaceEnginenull;try{faceEnginefaceEngineComparePool.borrowObject();FaceFeaturesearchfaceFeaturenewFaceFeature();SearchResultsearchResultnewSearchResult();searchfaceFeature.setFeatureData(faceFeature);interrorCodefaceEngine.searchFaceFeature(searchfaceFeature,searchResult);if(errorCode0){if(searchResult.getMaxSimilar()passRate){UserCompareInfouserCompareInfonewUserCompareInfo();userCompareInfo.setId(searchResult.getFaceFeatureInfo().getSearchId());userCompareInfo.setSimilar(searchResult.getMaxSimilar());userCompareInfo.setName(searchResult.getFaceFeatureInfo().getFaceTag());returnuserCompareInfo;}}}catch(Exceptione){log.error(,e);}finally{if(faceEngine!null){faceEngineComparePool.returnObject(faceEngine);}}returnnull;}为便于理解下面给出了2种模式下引擎的使用流程框图。图片模式在图片模式下以人脸注册业务为例引擎使用流程如下。图 2-1图片模式引擎调用流程视频模式在视频模式下这里创建了2个引擎池来处理不同的业务分别是通用引擎池和FT引擎池。FT引擎池用于实现多路视频流的人脸跟踪输出人脸框信息通用引擎池用于人脸比对识别等通用业务。特别说明下由于服务器的性能有限对取流到的视频帧需要按需抽帧降低服务器压力。图 2-1视频模式引擎调用流程2.1.3 引擎销毁本文使用引擎池对所用到的引擎进行统一管理销毁时使用getObject安全拿到引擎对象。此时引擎池其它接口无法拿到该对象保证销毁对象时是线程安全的。关于销毁时机可以是用户程序主动销毁引擎池中引擎也可以是引擎池根据设置的最大/最小引擎数量动态销毁空闲对象。但无论哪种方式上层必须要通过引擎池提供的线程安全接口才能够拿到引擎对象。下面代码是引擎销毁的代码destroyObject为BasePooledObjectFactory类的重载函数会在引擎池对象销毁时自动调用。OverridepublicvoiddestroyObject(PooledObjectFaceEnginep)throwsException{allObjects.remove(p);FaceEnginefaceEnginep.getObject();intresultfaceEngine.unInit();super.destroyObject(p);}2.2 人脸特征数据管理实际业务中人脸特征数据会被持久化存储在服务器的数据库中而人脸SDK中的特征位于内存中因此需要注意数据库中特征值和人脸SDK中特征值之间的同步、多引擎句柄之间的数据同步。人脸数据库和SDK之间数据同步数据库和SDK之间的特征数据同步过程发生在以下几种情况1、应用程序起来之后数据库中人脸特征数据需要同步到人脸SDK中2、SDK发生人脸注册、删除、更新事件时对应特征需要同步到数据库中下面是应用程序起来之后读取数据库人脸信息调用SDK注册接口将本地数据库中的特征数据注册到内存中参考代码。//初始化注册人脸注册到本地内存publicvoidinitSystemFace(){PathMatchingResourcePatternResolverresolvernewPathMatchingResourcePatternResolver();try{org.springframework.core.io.Resource[]resourcesresolver.getResources(classpath*:static/images/*);// 递归获取 static 目录下的所有文件for(org.springframework.core.io.Resourceresource:resources){InputStreaminputStreamresource.getInputStream();register(resource.getFilename(),null,inputStream);}}catch(IOExceptione){log.error(,e);}}多引擎数据同步多引擎句柄特征数据是独立的因此当使用某个引擎调用人脸注册、更新和删除接口时特征数据需要同步到引擎池所有引擎中。另外人脸SDK中人员操作接口(注册、删除、更新)是内部线程安全的。这里给出注册和删除函数的代码。publicvoidregisterFaceFeature2Engine(intsearchId,Stringtag,byte[]faceFeature){FaceEngineFactoryfactory(FaceEngineFactory)faceEngineComparePool.getFactory();ListFaceEngineallObjectsfactory.getAllObjects();FaceFeatureInfofaceFeatureInfonewFaceFeatureInfo();faceFeatureInfo.setSearchId(searchId);faceFeatureInfo.setFaceTag(tag);faceFeatureInfo.setFeatureData(faceFeature);log.info(Register:JSON.toJSONString(faceFeatureInfo));for(FaceEngineallObject:allObjects){intresallObject.registerFaceFeature(faceFeatureInfo);}}publicvoidremoveFaceFeature2Engine(intsearchId){FaceEngineFactoryfactory(FaceEngineFactory)faceEngineComparePool.getFactory();ListFaceEngineallObjectsfactory.getAllObjects();for(FaceEngineallObject:allObjects){allObject.removeFaceFeature(searchId);}}三、性能优化在使用人脸SDK开发时考虑到服务器的性能结合实际业务个人认为在人脸注册、人脸识别两方面可以针对性做一些优化提升优化的角度是低质量人脸过滤、人脸分组提高识别效率。3.1 低质量人脸过滤在SDK中提供了imageQualityDetect人脸质量接口用于判断当前的人脸信息是否满足质量阈值。如果不满足可以取消后续的操作。在人脸SDK中人脸特征提取接口相对耗时较长对于人脸注册和识别业务如果不做人脸质量筛查会导致大量的图片停留在特征提取过程中。在个人设备(Intel i7-10700CPU2.9GHZ)上测试特征提取接口耗时数据如下表 3-1人脸SDK特征提取耗时证件照大模型均值(ms)注册照大模型548识别照大模型269注册照中模型130识别照中模型77因此在人脸注册和识别业务中应该加上人脸质量检测接口过滤掉一些人脸质量较差的照片减少服务器性能消耗。对于人脸质量评分阈值人脸SDK中建议RGB识别照人脸质量分阈值为0.49注册照质量阈值为0.63。3.2 人脸识别业务性能优化目前官方提供的SDK有3种人脸比对接口compareFaceFeature、searchFaceFeature具体接口用法可以参考官方文档。在大模型中自测在1万人脸底库下searchFaceFeature和compareFaceFeature性能数据如下(Intel i7-10700CPU2.9GHZ)表 3-2人脸识别接口1万底库耗时对比接口均值(ms)searchFaceFeature2.473compareFaceFeature10可见在1万底库下人脸SDK提供的searchFaceFeature接口的性能已经是很好了对于1万以下的人脸底库场景接口性能绰绰有余compareFaceFeature接口性能相对较差因为该接口通常用于1:1场景的人脸比对不太适合1:N场景的人脸比对。而对于更大的人脸底库场景比如几十万人脸底库场景searchFaceFeature接口的耗时会相应增加。如果希望性能有更大的提升建议对人脸底库进行分组以公司场景为例可以按照部门分组将不同部门的人脸特征注册在不同的人脸句柄中然后多线程调用多个引擎句柄并发调用searchFaceFeature接口然后排序输出最大的人脸识别分数。图 3-1人脸分组比对调用流程四、总结本文基于虹软服务器版SDK(Linux/ARM Pro)就接入过程中的一些注意点和思考点进行了分享包括1、探讨了图片和视频模式下服务器程序的多线程框架2、提出使用GenericObjectPool构建引擎池增强对人脸引擎的多线程管理避免多线程调用过程中由于竞争导致的数据不同步和异常crash问题3、就人脸SDK的特征管理方式给出了人脸特征管理方法4、对人脸SDK的部分接口做了性能测试推荐使用SDK提供的人脸质量检测接口过滤低质量图片降低服务器性能消耗5、提出使用人脸分组的策略加速人脸比对速度人脸服务器业务远不止文章中提到的这些多线程程序设计时应该充分考虑线程资源竞争和同步。