大华相机接入web页面实现人脸识别

先看下效果,中间主视频流就是大华相机(视频编码H.264),海康相机(视屏编码H.265)

在这里插入图片描述

在这里插入图片描述
前端接入视屏流代码

  <!--视频流--><div id="col2"><div class="cell" style="flex: 7; background: none"><div class="cell-box" style="position: relative"><video autoplay muted id="video" class="video" /><div class="cell div-faces"><div class="cell-box"><!--人脸识别--><div class="faces-wrapper"><div v-for="i in 5" :key="i" class="face-wrapper"><div class="face-arrow"></div><divclass="face-image":style="{background: faceImages[i - 1]? `url(data:image/jpeg;base64,${faceImages[i - 1]}) 0 0 / 100% 100% no-repeat`: ''}"></div></div></div></div></div></div></div>
api.post('screen2/init').then((attach) => {const { streamerIp, streamerPort, cameraIp, cameraPort, cameraAdmin, cameraPsw } = attachwebRtcServer = new WebRtcStreamer('video', `${location.protocol}//${streamerIp}:${streamerPort}`)webRtcServer.connect(`rtsp://${cameraAdmin}:${cameraPsw}@${cameraIp}:${cameraPort}`)})

后台部署需要启动:webrtc-streamer.exe 用来解码视屏流,这样就能实现web页面接入视屏流。

主视屏流下面的相机抓拍图片和预警数据接口是怎么实现的呢?
1、需要把大华相机的sdk加载到项目中sdk下载
在这里插入图片描述
在maven的pom.xml中添加依赖,将上面jar包 依赖到项目中

        <!--外部依赖--><dependency><!--groupId和artifactId不知道随便写--><groupId>com.dahua.netsdk</groupId><artifactId>netsdk-api-main</artifactId><!--依赖范围,必须system--><scope>system</scope><version>1.0-SNAPSHOT</version><!--依赖所在位置--><systemPath>${project.basedir}/libs/netsdk-api-main-1.0.jar</systemPath></dependency><dependency><!--groupId和artifactId不知道随便写--><groupId>com.dahua.netsdk</groupId><artifactId>netsdk-dynamic</artifactId><!--依赖范围,必须system--><scope>system</scope><version>1.0-SNAPSHOT</version><!--依赖所在位置--><systemPath>${project.basedir}/libs/netsdk-dynamic-lib-main-1.0.jar</systemPath></dependency><dependency><!--groupId和artifactId不知道随便写--><groupId>com.dahua.netsdk</groupId><artifactId>netsdk-jna</artifactId><!--依赖范围,必须system--><scope>system</scope><version>1.0-SNAPSHOT</version><!--依赖所在位置--><systemPath>${project.basedir}/libs/jna.jar</systemPath></dependency>

然后写一个大华初始化,登录,订阅类 InitDahua

package ahpu.aip.controller.dahua;import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.ToolKits;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;@Component
public class InitDahua implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {//NetSDK 库初始化boolean bInit    = false;NetSDKLib netsdkApi = NetSDKLib.NETSDK_INSTANCE;// 智能订阅句柄NetSDKLib.LLong attachHandle = new NetSDKLib.LLong(0);//设备断线回调: 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK会调用该函数class DisConnect implements NetSDKLib.fDisConnect {public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);}}//网络连接恢复,设备重连成功回调// 通过 CLIENT_SetAutoReconnect 设置该回调函数,当已断线的设备重连成功时,SDK会调用该函数class HaveReConnect implements NetSDKLib.fHaveReConnect {public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);}}//登陆参数String m_strIp         = "192.168.1.108";int m_nPort        	   = 37777;String m_strUser       = "admin";String m_strPassword   = "admin123456";//设备信息NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex(); // 对应CLIENT_LoginEx2NetSDKLib.LLong m_hLoginHandle = new NetSDKLib.LLong(0);     // 登陆句柄NetSDKLib.LLong m_hAttachHandle = new NetSDKLib.LLong(0);    // 智能订阅句柄//        初始化bInit = netsdkApi.CLIENT_Init(new DisConnect(), null);if(!bInit) {System.out.println("Initialize SDK failed");}else{System.out.println("Initialize SDK Success");}// 登录int nSpecCap = NetSDKLib.EM_LOGIN_SPAC_CAP_TYPE.EM_LOGIN_SPEC_CAP_TCP; //=0IntByReference nError = new IntByReference(0);m_hLoginHandle = netsdkApi.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, nSpecCap, null, m_stDeviceInfo, nError);if(m_hLoginHandle.longValue() == 0) {System.err.printf("Login Device[%s] Port[%d]Failed.\n", m_strIp, m_nPort, ToolKits.getErrorCode());} else {System.out.println("Login Success [ " + m_strIp + " ]");}// 订阅int bNeedPicture = 1; // 是否需要图片m_hAttachHandle =  netsdkApi.CLIENT_RealLoadPictureEx(m_hLoginHandle, 0, NetSDKLib.EVENT_IVS_ALL, bNeedPicture, new AnalyzerDataCB(), null, null);if(m_hAttachHandle.longValue() == 0) {System.err.println("CLIENT_RealLoadPictureEx Failed, Error:" + ToolKits.getErrorCode());}else {System.out.println("订阅成功~");}}}

回调类,具体识别结果在回调中获取

package ahpu.aip.controller.dahua;import ahpu.aip.AiPlatformServerApplication;
import ahpu.aip.util.RedisUtils;
import ahpu.aip.util.StringUtils;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.ToolKits;
import com.sun.jna.Pointer;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;@Component
public class AnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack {private static final Logger log = LoggerFactory.getLogger(AnalyzerDataCB.class);public static HashMap<String, Object> temMap;private int bGlobalScenePic;					//全景图是否存在, 类型为BOOL, 取值为0或者1private NetSDKLib.NET_PIC_INFO stuGlobalScenePicInfo;     //全景图片信息private NetSDKLib.NET_PIC_INFO stPicInfo;	  			    // 人脸图private NetSDKLib.NET_FACE_DATA stuFaceData;			    // 人脸数据private int nCandidateNumEx;				    // 当前人脸匹配到的候选对象数量private NetSDKLib.CANDIDATE_INFOEX[] stuCandidatesEx;     // 当前人脸匹配到的候选对象信息扩展// 全景大图、人脸图、对比图private BufferedImage globalBufferedImage = null;private BufferedImage personBufferedImage = null;private BufferedImage candidateBufferedImage = null;String[] faceSexStr = {"未知", "男", "女"};// 用于保存对比图的图片缓存,用于多张图片显示private ArrayList<BufferedImage> arrayListBuffer = new ArrayList<BufferedImage>();@Overridepublic int invoke(NetSDKLib.LLong lAnalyzerHandle, int dwAlarmType,Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize,Pointer dwUser, int nSequence, Pointer reserved) {// 获取相关事件信息getObjectInfo(dwAlarmType, pAlarmInfo);/*if(dwAlarmType == NetSDKLib.EVENT_IVS_FACERECOGNITION) {   // 目标识别// 保存图片savePicture(pBuffer, dwBufSize, bGlobalScenePic, stuGlobalScenePicInfo, stPicInfo, nCandidateNumEx, stuCandidatesEx);// 刷新UI时,将目标识别事件抛出处理EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();if (eventQueue != null) {eventQueue.postEvent(new FaceRecognitionEvent(this,globalBufferedImage,personBufferedImage,stuFaceData,arrayListBuffer,nCandidateNumEx,stuCandidatesEx));}} else*/ if(dwAlarmType == NetSDKLib.EVENT_IVS_FACEDETECT) {  // 人脸检测// 保存图片savePicture(pBuffer, dwBufSize, stPicInfo);}return 0;}/*** 获取相关事件信息* @param dwAlarmType 事件类型* @param pAlarmInfo 事件信息指针*/public void getObjectInfo(int dwAlarmType, Pointer pAlarmInfo) {if(pAlarmInfo == null) {return;}switch(dwAlarmType){case NetSDKLib.EVENT_IVS_FACERECOGNITION:  ///< 目标识别事件{NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO msg = new NetSDKLib.DEV_EVENT_FACERECOGNITION_INFO();ToolKits.GetPointerData(pAlarmInfo, msg);bGlobalScenePic = msg.bGlobalScenePic;stuGlobalScenePicInfo = msg.stuGlobalScenePicInfo;stuFaceData = msg.stuFaceData;stPicInfo = msg.stuObject.stPicInfo;nCandidateNumEx = msg.nRetCandidatesExNum;stuCandidatesEx = msg.stuCandidatesEx;break;}case NetSDKLib.EVENT_IVS_FACEDETECT:   ///< 人脸检测{NetSDKLib.DEV_EVENT_FACEDETECT_INFO msg = new NetSDKLib.DEV_EVENT_FACEDETECT_INFO();ToolKits.GetPointerData(pAlarmInfo, msg);stPicInfo = msg.stuObject.stPicInfo;  // 检测到的人脸//                System.out.println("sex:" + faceSexStr[msg.emSex]);log.info("口罩状态(0-未知,1-未识别,2-没戴口罩,3-戴口罩了):" + msg.emMask);log.info("时间:"+msg.UTC);RedisUtils.set("mask",msg.emMask==3?"戴口罩":"未戴口罩");RedisUtils.set("time",msg.UTC+"");break;}default:break;}}/*** 保存目标识别事件图片* @param pBuffer 抓拍图片信息* @param dwBufSize 抓拍图片大小*//* public void savePicture(Pointer pBuffer, int dwBufSize,int bGlobalScenePic, NetSDKLib.NET_PIC_INFO stuGlobalScenePicInfo,NetSDKLib.NET_PIC_INFO stPicInfo,int nCandidateNum, NetSDKLib.CANDIDATE_INFOEX[] stuCandidatesEx) {File path = new File("./FaceRegonition/");if (!path.exists()) {path.mkdir();}if (pBuffer == null || dwBufSize <= 0) {return;}/// 保存全景图 ///if(bGlobalScenePic == 1 && stuGlobalScenePicInfo != null) {String strGlobalPicPathName = path + "\\" + System.currentTimeMillis() + "Global.jpg";byte[] bufferGlobal = pBuffer.getByteArray(stuGlobalScenePicInfo.dwOffSet, stuGlobalScenePicInfo.dwFileLenth);ByteArrayInputStream byteArrInputGlobal = new ByteArrayInputStream(bufferGlobal);try {globalBufferedImage = ImageIO.read(byteArrInputGlobal);if(globalBufferedImage == null) {return;}ImageIO.write(globalBufferedImage, "jpg", new File(strGlobalPicPathName));} catch (IOException e2) {e2.printStackTrace();}}/// 保存人脸图 /if(stPicInfo != null) {String strPersonPicPathName = path + "\\" + System.currentTimeMillis() + "Person.jpg";byte[] bufferPerson = pBuffer.getByteArray(stPicInfo.dwOffSet, stPicInfo.dwFileLenth);ByteArrayInputStream byteArrInputPerson = new ByteArrayInputStream(bufferPerson);try {personBufferedImage = ImageIO.read(byteArrInputPerson);if(personBufferedImage == null) {return;}ImageIO.write(personBufferedImage, "jpg", new File(strPersonPicPathName));} catch (IOException e2) {e2.printStackTrace();}}/ 保存对比图 //arrayListBuffer.clear();if(nCandidateNum > 0 && stuCandidatesEx != null) {for(int i = 0; i < nCandidateNum; i++) {String strCandidatePicPathName = path + "\\" + System.currentTimeMillis() + "Candidate.jpg";// 多张对比图for(int j = 0; j < stuCandidatesEx[i].stPersonInfo.wFacePicNum; j++) {byte[] bufferCandidate = pBuffer.getByteArray(stuCandidatesEx[i].stPersonInfo.szFacePicInfo[j].dwOffSet, stuCandidatesEx[i].stPersonInfo.szFacePicInfo[j].dwFileLenth);ByteArrayInputStream byteArrInputCandidate = new ByteArrayInputStream(bufferCandidate);try {candidateBufferedImage = ImageIO.read(byteArrInputCandidate);if(candidateBufferedImage == null) {return;}ImageIO.write(candidateBufferedImage, "jpg", new File(strCandidatePicPathName));} catch (IOException e2) {e2.printStackTrace();}arrayListBuffer.add(candidateBufferedImage);}}}}*//*** 保存人脸检测事件图片 ===* @param pBuffer 抓拍图片信息* @param dwBufSize 抓拍图片大小*/public void savePicture(Pointer pBuffer, int dwBufSize, NetSDKLib.NET_PIC_INFO stPicInfo) {File path = new File("./FaceDetected/");if (!path.exists()) {path.mkdir();}if (pBuffer == null || dwBufSize <= 0) {return;}/// 保存全景图 ////*  String strGlobalPicPathName = path + "\\" + System.currentTimeMillis() + "Global.jpg";byte[] bufferGlobal = pBuffer.getByteArray(0, dwBufSize);ByteArrayInputStream byteArrInputGlobal = new ByteArrayInputStream(bufferGlobal);try {globalBufferedImage = ImageIO.read(byteArrInputGlobal);if(globalBufferedImage == null) {return;}ImageIO.write(globalBufferedImage, "jpg", new File(strGlobalPicPathName));} catch (IOException e2) {e2.printStackTrace();}*//// 保存人脸图 /if(stPicInfo != null) {String strPersonPicPathName = path + "\\" + System.currentTimeMillis() + "Person.jpg";byte[] bufferPerson = pBuffer.getByteArray(stPicInfo.dwOffSet, stPicInfo.dwFileLenth);ByteArrayInputStream byteArrInputPerson = new ByteArrayInputStream(bufferPerson);try {personBufferedImage = ImageIO.read(byteArrInputPerson);if(personBufferedImage == null) {return;}ImageIO.write(personBufferedImage, "jpg", new File(strPersonPicPathName));//  把图片保存到resultMap中String base64 = Base64.encode(new File(strPersonPicPathName));log.info("base64图片:data:image/jpeg;base64,"+base64);RedisUtils.set("img","data:image/jpeg;base64,"+base64);String listStr = (String) RedisUtils.get("dahuaList");List<HashMap> list = JSONArray.parseArray(listStr,HashMap.class);HashMap<String,String> tmpResult = new HashMap<String,String>();tmpResult.put("img",(String) RedisUtils.get("img"));tmpResult.put("time",(String) RedisUtils.get("time"));tmpResult.put("mask",(String) RedisUtils.get("mask"));if(CollectionUtils.isEmpty(list)){list = new ArrayList<>();list.add(tmpResult);}else {list.add(tmpResult);}if(list.size()>5){RedisUtils.set("dahuaList",JSON.toJSONString(list.subList(list.size()-5,list.size())));}else {RedisUtils.set("dahuaList",JSON.toJSONString(list));}} catch (IOException e2) {e2.printStackTrace();}}}}

人脸识别事件类

package ahpu.aip.controller.dahua;import com.netsdk.lib.NetSDKLib;import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import org.springframework.stereotype.Component;public class FaceRecognitionEvent extends AWTEvent {private static final long serialVersionUID = 1L;public static final int EVENT_ID = AWTEvent.RESERVED_ID_MAX + 1;private BufferedImage globalImage = null;private BufferedImage personImage = null;private NetSDKLib.NET_FACE_DATA stuFaceData;private ArrayList<BufferedImage> arrayList = null;private int nCandidateNum;private ArrayList<String[]> candidateList;// 用于保存对比图的人脸库id、名称、人员名称、相似度private static String[] candidateStr = new String[4];private static final String encode = "UTF-8";public FaceRecognitionEvent(Object target,BufferedImage globalImage,BufferedImage personImage,NetSDKLib.NET_FACE_DATA stuFaceData,ArrayList<BufferedImage> arrayList,int nCandidateNum,NetSDKLib.CANDIDATE_INFOEX[] stuCandidatesEx) {super(target,EVENT_ID);this.globalImage = globalImage;this.personImage = personImage;this.stuFaceData = stuFaceData;this.arrayList = arrayList;this.nCandidateNum = nCandidateNum;this.candidateList = new ArrayList<String[]>();this.candidateList.clear();for(int i = 0; i < nCandidateNum; i++) {try {candidateStr[0] = new String(stuCandidatesEx[i].stPersonInfo.szGroupID, encode).trim();candidateStr[1] = new String(stuCandidatesEx[i].stPersonInfo.szGroupName, encode).trim();candidateStr[2] = new String(stuCandidatesEx[i].stPersonInfo.szPersonName, encode).trim();} catch (UnsupportedEncodingException e) {e.printStackTrace();}candidateStr[3] = String.valueOf(0xff & stuCandidatesEx[i].bySimilarity);this.candidateList.add(candidateStr);}}
}

获取结果接口类

@RestController
@Validated
@RequestMapping("dahua/")
public class DahuaController {@ApiOperation(value = "大华人脸",tags = "大华人脸")@GetMapping("getFaceList")public R face() {String dahuaList = (String) RedisUtils.get("dahuaList");List<HashMap> list = JSONArray.parseArray(dahuaList,HashMap.class);return R.succ().attach(list);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/23413.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud——分布式请求链路跟踪Sleuth

安装运行zipkin SpringCloud从F版已不需要自己构建Zipkin Server&#xff0c;只需要调用jar包即可 https://dl.bintray.com/oenzipkin/maven/io/zipkin/java/zipkin-server/ 下载&#xff1a;zipkin-server-2.12.9-exec.jar 运行&#xff1a;java -jar zipkin-server-2.12.9-e…

Word 插件实现读取excel自动填写

日常工作中碰到需要将EXCEL的对应数据记录填写到word文档对应的位置&#xff0c;人工操作的方式是&#xff1a; 打开exel表—>查找对应报告号的行—>逐列复制excel表列单元格内容到WORD对应的位置&#xff08;如下图标注所示&#xff09; 这种方法耗时且容易出错。实际上…

三菱PLC上位机测试

利用三菱的MX Component与三菱PLC进行以太网通信&#xff0c;我们可以用官方的dll编写C#代码&#xff0c;特别简单&#xff0c;最后附上整个源码下载。 1. 安装MX Component&#xff08;必须&#xff09;和GX WORKS3&#xff08;主要是仿真用&#xff0c;实际可以不装&#xf…

【USRP X310】如何将你的X310转化为USRP RIO 可以用于FPGA编程

X310 转化为USRP RIO X310产品X310和NI-USRP对应关系 简介第一步原理解释打开工具运行 Initialize Flash.vi可以去选择设备类型Hardware Current Version 如何选择 第二步创建工程运行校准程序 附录&#xff1a;射频子板的IDWBXSBXCBXUBXTwinRX X310产品 X310和NI-USRP对应关系…

Android Java代码与JNI交互 JNI访问Java类方法 (七)

🔥 Android Studio 版本 🔥 🔥 创建包含JNI的类 JNIAccessMethod.java 🔥 package com.cmake.ndk1.jni;import com.cmake.ndk1.model.Animal;public class JNIAccessMethod {static {System.loadLibrary("access-method-lib");}public native void access…

Meta提出全新参数高效微调方案,仅需一个RNN,Transformer模型GPU使用量减少84%!

近来&#xff0c;随着ChatGPT和GPT-4模型的不断发展&#xff0c;国内外互联网大厂纷纷推出了自家的大语言模型&#xff0c;例如谷歌的PaLM系列&#xff0c;MetaAI的LLaMA系列&#xff0c;还有国内公司和高校推出的一些大模型&#xff0c;例如百度的文心一言&#xff0c;清华的C…

【VTK】VTK 显示小球例子,在 Windows 上使用 Visual Studio 配合 Qt 构建 VTK

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 编号内容1【Visual Studio】在 Windows 上使用 Visual Studio 构建 VTK2【Visual Studio】在 Windows 上使用 Visual Studio 配合 Qt 构建 VTK3【VTK】VTK 显…

java导出pdf(纯代码实现)

java导出pdf 在项目开发中&#xff0c;产品的需求越来越奇葩啦&#xff0c;开始文件下载都是下载为excel的&#xff0c;做着做着需求竟然变了&#xff0c;要求能导出pdf。导出pdf倒也不是特别大的问题关键就是麻烦。 导出pdf我知道的一共有3中方法&#xff1a; 方法一&#xff…

如何通过CRM系统减低客户流失率并提高销售业绩?

销售人员如何提高业绩&#xff0c;减低客户流失率&#xff1f;通过CRM客户管理系统与客户建立良好的客户关系、提升客户体验助力销售人员业绩节节攀升&#xff0c;降低客户流失率。接下来我们就来说一说CRM系统如何实现的&#xff1f; 1.全渠道沟通提升客户体验 只有足够多的…

Picgo使用Gitee平台搭建图床照片无法显示

1.问题 使用Hexo框架搭建个人博客&#xff0c;发现博客中图片无法显示 2.问题分析 查看图床&#xff0c;发现相册中图片无法显示 查阅多方网站&#xff0c;发现Gitee与Picgo配合使用时&#xff0c;图片文件不能大于1M。 这主要因为Gitee查阅超过1M的文件需要登录的权限 。而…

10.25UEC++/小试牛刀(笨鸟先飞案例)

1.思路整理&#xff1a; 如何入手&#xff1f; 角色可能是每个游戏的最重要的部分&#xff0c;所以一般可以先从角色入手&#xff0c;如果游戏很复杂&#xff0c;可以进行拆分设计。 蓝图创建地图&#xff1a; 创建默认Pawn&#xff1a; 编写GameMode默认构造函数&#xff1a;…

提效工具:揭秘VS Code Copilot与Labs、Chat的完美结合

vscode相关插件 一、GitHub Copilot、中文说明 GitHub Copilot基于OpenAI的GPT-3.5模型进行训练&#xff0c;是一种基于机器学习的代码自动补全工具&#xff0c;由OpenAI和GitHub联合开发。&#xff08;可淘宝上搜索关键词“copilot”&#xff0c;20-30就行&#xff09; 使用…