java调用海康威视SDK实现车牌识别

我采用的是 报警布防方式  SDK版本为 CH-HCNetSDKV6.1.9.48_build20230410_win32

如何引用dll 我用的是jna 就不描述了  SDK在官网自行下载  以下代码亲测可用 自行参考~

1.1接口调用流程

虚线框的内容是可选的,设备事先安装配置好,能力集和配置接口可不调用,不会影响其他接口功能的使用。

  • 初始化NET_DVR_Init接口在程序开始是调用,只需要调用一次。
  • 用户注册即登录设备,调用NET_DVR_Login_V40接口,每一台设备只需要登录一次。
  • 登录设备之后,可以通过NET_DVR_GetDeviceAbility获取智能交通能力集可以判断设备是否支持相关功能,能力集类型:DEVICE_ABILITY_INFO,能力集:ITDeviceAbility,节点:<ITCAbility>。
  • 车牌识别包括IO触发、虚拟线圈触发等自动触发抓拍模式和网络触发等手动抓拍模式。
    如果是自动触发模式,一般建议通过WEB网页登录设备进行配置调试,也可以通过SDK接口进行配置,相关接口:NET_DVR_GetDVRConfig(命令:NET_ITC_GET_TRIGGERCFG)、NET_DVR_SetDVRConfig(命令:NET_ITC_SET_TRIGGERCFG)、NET_DVR_GetDeviceConfig(命令:NET_DVR_GET_TRIGGEREX_CFG)、NET_DVR_SetDeviceConfig(命令:NET_DVR_SET_TRIGGEREX_CFG)等。
    如果是手动抓拍,有两种方式:1)通过NET_DVR_ManualSnap可以在接口直接返回结果信息;2)通过NET_DVR_ContinuousShoot发送网络触发连拍命令,抓拍结果跟自动触发模式一样,通过报警布防方式在报警回调函数里面返回。
  • 配置好设备相关参数,车辆通过时进行抓拍和识别,结果信息通过报警布防方式获取,具体实现方法:
    1) 先调用NET_DVR_SetDVRMessageCallBack_V50设置报警回调函数(V31、V30接口也支持,新接口兼容老接口),在SDK初始化之后即可以调用,多台设备对接时也只需要调用一次设置一个回调函数,回调函数里面接收数据之后可以通过报警设备信息(NET_DVR_ALARMER)中lUserID等参数判断区分设备。
    2) 每台设备分别登录,分别调用NET_DVR_SetupAlarmChan_V41进行布防,布防即建立设备跟客户端之间报警上传的连接通道,这样设备发生报警之后通过该连接上传报警信息,SDK在报警回调函数中接收和处理报警信息数据即可。对接智能交通摄像机,布防时可以选择布防等级,一级布防(byLevel为0)最大连接数为1个,二级布防(byLevel为1)最大连接数为3个,如果已经达到上限了,再布防就会失败,SDK将返回28的错误号。
    3) 程序退出前或者不需要接收报警信息时调用NET_DVR_CloseAlarmChan_V30进行撤防,释放资源,此时连接断开,设备将不再上传报警信息。
  • 车牌识别的报警信息类型为COMM_ITS_PLATE_RESULT(新报警信息)和COMM_UPLOAD_PLATE_RESULT(老报警信息),分别对应接口NET_DVR_SetupAlarmChan_V41中布防参数byAlarmInfoType=1和byAlarmInfoType=0。建议使用新的报警信息类型。
    1)设备是否支持新报警信息可从注册返回的能力获知,详见NET_DVR_DEVICEINFO_V30结构中bySupport1&0x80(表示是否支持车牌新报警信息),如果注册返回能力不支持,设备仅支持老报警信息上传。
    2)COMM_UPLOAD_PLATE_RESULT:兼容旧型号(976/986/966等)抓拍机,一次回调只上传一张图片信息,对应报警信息结构体:NET_DVR_PLATE_RESULT
    3)COMM_ITS_PLATE_RESULT:应用于违章图片组一次性上传以及合成图片上传等新功能,对应报警信息结构体:NET_ITS_PLATE_RESULT
  • 退出程序时调用NET_DVR_Logout注销设备,每一台设备调用一次。最后调用NET_DVR_Cleanup释放SDK所有资源。

1.2示例代码

初始化+登录

    private boolean init(String ip, int port, String userName, String password) {/**加载日志*/if (!NET_DVR_Init()) {logger.error("摄像头初始化失败!错误码为" + hCNetSDK.NET_DVR_GetLastError());return false;}hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false);userId = NET_DVR_Login_V30(ip, port, userName, password);if (userId > -1) {isinitialized = true;}return isinitialized;}

 设置回调+布防

 public boolean licensePlateRecognition(CarNumRecognizerConfig carNumRecognizerConfig) {logger.debug("*********************licensePlateRecognition**************************");String ip = carNumRecognizerConfig.getCarNumRecognizerIP();int port = carNumRecognizerConfig.getPort();String userName = carNumRecognizerConfig.getUserName();String password = carNumRecognizerConfig.getPassword();if (StringUtil.isNotBlank(carNumRecognizerConfig.getEncoding())) {encode = carNumRecognizerConfig.getEncoding();}if (StringUtil.isNotBlank(carNumRecognizerConfig.getImageDir())) {imageDirPath = carNumRecognizerConfig.getImageDir();}if (!init(ip, port, userName, password)) {logger.error("摄像头初始化失败!");return false;}carNumRecognizerDevices = deviceManager.getCarNumRecognizerDevices();//设置连接时间与重连时间hCNetSDK.NET_DVR_SetConnectTime(2000, 1);hCNetSDK.NET_DVR_SetReconnect(100000, true);
//设备信息, 输出参数//设置报警回调函数if (fMSFCallBack_V31 == null) {fMSFCallBack_V31 = new FMSGCallBack_V31();String UserData = "UserData";HCNetSDK.BYTE_ARRAY UserDataByte = new HCNetSDK.BYTE_ARRAY(25);UserDataByte.read();UserDataByte.byValue = UserData.getBytes();UserDataByte.write();Pointer pUserDataByte = UserDataByte.getPointer();if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(fMSFCallBack_V31, pUserDataByte)) {logger.error("设置回调函数失败!+" + hCNetSDK.NET_DVR_GetLastError());return false;} else {logger.info("设置回调函数成功!");}}HCNetSDK.NET_DVR_LOCAL_GENERAL_CFG struNET_DVR_LOCAL_GENERAL_CFG = new HCNetSDK.NET_DVR_LOCAL_GENERAL_CFG();struNET_DVR_LOCAL_GENERAL_CFG.byAlarmJsonPictureSeparate = 1;   //设置JSON透传报警数据和图片分离struNET_DVR_LOCAL_GENERAL_CFG.write();Pointer pStrNET_DVR_LOCAL_GENERAL_CFG = struNET_DVR_LOCAL_GENERAL_CFG.getPointer();hCNetSDK.NET_DVR_SetSDKLocalCfg(17, pStrNET_DVR_LOCAL_GENERAL_CFG);
//尚未布防,需要布防if (lAlarmHandle < 0) {//报警布防参数设置HCNetSDK.NET_DVR_SETUPALARM_PARAM m_strAlarmInfo = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();m_strAlarmInfo.dwSize = m_strAlarmInfo.size();m_strAlarmInfo.byLevel = 0;  //布防等级m_strAlarmInfo.byAlarmInfoType = 1;   // 智能交通报警信息上传类型:0- 老报警信息(NET_DVR_PLATE_RESULT),1- 新报警信息(NET_ITS_PLATE_RESULT)m_strAlarmInfo.byDeployType = 1;   //布防类型:0-客户端布防,1-实时布防m_strAlarmInfo.write();lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(Integer.valueOf(userId + ""), m_strAlarmInfo);logger.info("lAlarmHandle: " + lAlarmHandle);if (lAlarmHandle == -1) {logger.info("布防失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());return false;} else {logger.info("布防成功");}} else {logger.info("设备已经布防,请先撤防!");}return true;}

回调

public class FMSGCallBack_V31 implements HCNetSDK.FMSGCallBack_V31 {//报警信息回调函数public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {logger.info("报警事件类型: lCommand:" + Integer.toHexString(lCommand));//lCommand是传的报警类型switch (lCommand) {case 3058:logger.info("报警事件类型: 0x3058 车辆黑白名单数据需要同步报警上传");case HCNetSDK.COMM_UPLOAD_PLATE_RESULT:logger.info("报警事件类型: COMM_UPLOAD_PLATE_RESULT");case HCNetSDK.COMM_ITS_PLATE_RESULT://交通抓拍结果(新报警信息)logger.info("报警事件类型: COMM_ITS_PLATE_RESULT");HCNetSDK.NET_ITS_PLATE_RESULT strItsPlateResult = new HCNetSDK.NET_ITS_PLATE_RESULT();strItsPlateResult.write();Pointer pItsPlateInfo = strItsPlateResult.getPointer();pItsPlateInfo.write(0, pAlarmInfo.getByteArray(0, strItsPlateResult.size()), 0, strItsPlateResult.size());strItsPlateResult.read();try {String sLicense = new String(strItsPlateResult.struPlateInfo.sLicense, encode);String carNum = StringUtil.extractTheLicensePlateNumber(sLicense);//这个方法是提取车牌号 因为我接收到的车牌号会带颜色在前面 比如 蓝京A---- 这样子logger.info("识别车号:{},提取车号:{}",sLicense,carNum);CarNumRecognizerResult carNumRecognizerResult = new CarNumRecognizerResult();carNumRecognizerResult.setCarNum(carNum);boolean isOK = carNumRecognizerDevices.notifyCarNumResult(carNumRecognizerResult);logger.info("isOK:::" + isOK);} catch (UnsupportedEncodingException e1) {e1.printStackTrace();logger.error(e1.getMessage(),e1);} catch (IOException e) {e.printStackTrace();logger.error(e.getMessage(),e);}/*** 报警图片保存,车牌,车辆图片*/if (StringUtil.isNotBlank(imageDirPath)){File imageDir = new File(imageDirPath);if(!imageDir.exists() || !imageDir.isDirectory()){imageDir.mkdirs();}for (int i = 0; i < strItsPlateResult.dwPicNum; i++) {if (strItsPlateResult.struPicInfo[i].dwDataLen > 0) {String baseName = DateUtil.getTimeStr((int)(System.currentTimeMillis()/1000), "yyyyMMddHHmmss");File imageFile = getImageFilePath(i+"", baseName, imageDir);FileOutputStream fout;try {fout = new FileOutputStream(imageFile);//将字节写入文件long offset = 0;ByteBuffer buffers = strItsPlateResult.struPicInfo[i].pBuffer.getByteBuffer(offset, strItsPlateResult.struPicInfo[i].dwDataLen);byte[] bytes = new byte[strItsPlateResult.struPicInfo[i].dwDataLen];buffers.rewind();buffers.get(bytes);fout.write(bytes);fout.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}}break;default:logger.info("报警类型:" + Integer.toHexString(lCommand));break;}return true;}}

重点是这里  我起初选择0  就不起作用  可能是客户端没配置好?不懂

m_strAlarmInfo.byDeployType = 1;   //布防类型:0-客户端布防,1-实时布防

总结两点:

1 确认摄像机客户端中可以识别到车号!!!

2 确认使用哪种布防!!!

再提一嘴 我个人认为海康的车牌识别做的不好,因为我开发其他车牌识别产品 例如文通、VM、大华  这些设备的车牌识别都是采用自动识别 主动推送的方式到http接口 更好处理 还不占资源。

海康也有监听方法 但我没研究明白 不会用..

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

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

相关文章

Linux高级编程——线程

pthread 线程 概念 &#xff1a;线程是轻量级进程&#xff0c;一般是一个进程中的多个任务。 进程是系统中最小的资源分配单位. 线程是系统中最小的执行单位。 优点&#xff1a; 比多进程节省资源&#xff0c;可以共享变量 进程会占用&am…

【高考】选专业时,应避免的误区

【高考】选专业时&#xff0c;应避免的误区-CSDN博客 【高考】选专业时以什么为主&#xff1f;-CSDN博客 分数限制下&#xff0c;选好专业还是选好学校&#xff1f;-CSDN博客 分数限制下&#xff0c;选好专业还是选好学校&#xff1f;-CSDN博客 在选专业时&#xff0c;考生…

解析 ThreadLocal 原理

ThreadLocal用于线程局部变量的一个工具类。 原理是为每个线程创建独立的变量副本&#xff0c;从而实现线程数据的隔离。具体来说&#xff0c;ThreadLocal 通过一个 ThreadLocalMap来实现&#xff0c;这个 ThreadLocalMap 是一个自定义的哈希表&#xff0c;用于存储线程和对应的…

Qt creator实现一个简单计算器

目录 1 界面设计 2 思路简介 3 代码 目录 1 界面设计 ​2 思路简介 3 代码 3.1 widget.h 3.2 widget.c 4 完整代码 在这里主要记载了如何使用Qt creator完成一个计算器的功能。该计算器可以实现正常的加减乘除以及括号操作&#xff0c;能实现简单的计算器功能。 1 界…

Hadoop版本演变、分布式集群搭建

Hadoop版本演变历史 Hadoop发行版非常的多&#xff0c;有华为发行版、Intel发行版、Cloudera Hadoop(CDH)、Hortonworks Hadoop(HDP)&#xff0c;这些发行版都是基于Apache Hadoop衍生出来的。 目前Hadoop经历了三个大的版本。 hadoop1.x&#xff1a;HDFSMapReduce hadoop2.x…

MySQL学习_python操作MySQL

用python连接数据库分为以下几个步骤 1.首先下载pymysql pip install pymysql2.创建数据 # 1.导入pymysql import pymysql # 2.连接MySQL conn pymysql.connect(host127.0.0.1,port3306,userroot,charsetutf8,dbunicom) cursor conn.cursor(cursorpymysql.cursors.DicCurso…

uniapp开发企业微信内部应用

最近一直忙着开发项目&#xff0c;终于1.0版本开发完成&#xff0c;抽时间自己总结下在项目开发中遇到的技术点。此次项目属于自研产品&#xff0c;公司扩展业务&#xff0c;需要在企业微信中开发内部应用。因为工作中使用的是钉钉&#xff0c;很少使用企业微信&#xff0c;对于…

重新记录做事的方向和内容(2024年6月28日19:50:38)

感觉自己没必要这么焦虑&#xff0c;最后的结果无非就是自己又开始恢复到自己抽烟&#xff0c;喝酒&#xff0c;说脏话的一个状态&#xff0c;自己那么糟糕自己都已经通过实事求是走出来了&#xff0c;现在难道自己还害怕什么&#xff1f; 如果顺着这种封闭和没有断舍离的状态…

【Qt C++实现绘制仪表盘】

要在Qt C中绘制仪表盘&#xff0c;您可以使用QChart、QSeries、QBarSeries、QPointSeries等类。以下是一个简单的示例&#xff0c;演示如何使用这些类创建一个绘图仪表盘&#xff1a; #include <QApplication> #include <QChart> #include <QChartView> #in…

06 Shell编程实战——案例1

脚本编程步骤&#xff1a; 脚本编程一般分为4个步骤&#xff0c;即先确定需求&#xff0c;然后再确定你所要用到的语句&#xff0c; 需求分析&#xff1a;根据系统管理的需求&#xff0c;分析脚本要实现的功能、功能实现的层次、实现的命令与语句等&#xff1b;命令测试&…

Windows11下安装多个JDK版本,并切换

Windows11下安装多个JDK版本,并切换 前言步骤1、前期准备2、版本切换思考前言 一台电脑可以同时安装多个版本 jdk,建议两个,最多不超三个。安装多个JDK版本可能会占用较多的磁盘空间。此外,同时运行多个 JDK 版本可能会对系统性能产生一定的影响。   切换 JDK 有两种方式…

ios swift5 视频播放 播放视频失败 无法播放HEVC (H.265) 格式的视频 H.264格式的可以播放

文章目录 1.问题2.原因&#xff1a;iOS swift AVPlayerViewController无法播放HEVC (H.265) 格式的视频3.解决方法用第三方框架MobileVLCKit来播放4.用MobileVLCKit写的播放器4.1 两个oc版本的4.2 两个swiftUI版本的5.苹果是支持HEVC (H.265) 格式的视频&#xff0c;是硬件那边…

css做旋转星球可举一反三

<!DOCTYPE html> <html lang"en"><head> <meta charset"UTF-8" /> <title>旋转的星球</title> <style type"text/css">.box {/*position: relative;*/position: absolute;width: 139px;height: 139p…

计算文本相似度的几种方法

计算文本相似度的几种方法 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨一下计算文本相似度的几种方法。文本相似度在自然语言处理&#xff08…

算法训练 | 动态规划Part10 | 300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组

目录 300.最长递增子序列 动态规划法 674.最长连续递增序列 动态规划法 718.最长重复子数组 动态规划法 300.最长递增子序列 题目链接&#xff1a;300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 动态规划法 “子序列是…

基于java语言+springboot技术架构开发的 互联网智能3D导诊系统源码支持微信小程序、APP 医院AI智能导诊系统源码

基于java语言springboot技术架构开发的 互联网智能3D导诊系统源码支持微信小程序、APP 医院AI智能导诊系统源码 一、智慧导诊系统开发原理 导诊系统从原理上大致可分为基于规则模板和基于数据模型两类。 1、基于规则推理的方法通过人工建立症状、疾病和科室之间的对应规则实现…

Java反射API详解与应用场景

一、Java反射API简介: 一、什么是反射: 反射是一种强大的工具,它允许我们在运行时检查类、方法和字段的信息,甚至允许我们动态的调用特定类的方法或改变字段的值。编程语言中的反射机制通常用于从类、对象或方法中检索元数据,或者更特别的说,从代码本身中获取信息。这就…

【51单片机入门】点亮数码管

文章目录 前言仿真图如何去绘制一个数字示例代码选择某个数码管显示某个数字 示例代码总结 前言 在嵌入式系统的世界中&#xff0c;单片机扮演着至关重要的角色。51单片机&#xff0c;作为最早的微控制器之一&#xff0c;至今仍被广泛应用在各种设备中。本文将介绍如何使用51单…

几种linux开机自启脚本的方法

几种linux开机自启脚本的方法 1. 脚本添加到init.d目录中2. 创建服务service&#xff08;推荐&#xff09;3. /etc/profile & /etc/profile.d&#xff08;不推荐&#xff09;4. /etc/rc.local 本文以启动jenkins节点为例&#xff0c;需要持久连接&#xff0c;实现开机自启 …

js或ts中对象如何循环遍历获取名字和值

数组循环有多种方法&#xff0c;但是对象循环还是会遇到一些问题 分开获取key或value let names{name:kaka,age:12}获取key值代码&#xff1a; Object.keys(names).forEach(name>{console.log(name) })结果&#xff1a; 获取value值代码&#xff1a; Object.values(name…