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.mfbz.cn/a/753169.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【干货】一文讲清楚社群裂变的主要模式和SOP流程

一、社群裂变的主要模式 社群裂变是一种依赖于现有成员的推广以吸引新成员的增长策略。以下是几种主要的社群裂变模式&#xff1a; 老带新裂变 定义&#xff1a;通过老用户带动新用户&#xff0c;同时给予某一方或双方奖励的一种裂变形式。 示例&#xff1a;任务宝活动&…

【精选】数据治理项目实施(合集)06——数据标准在数据治理中的落地实践

导读 本文对数据标准管理进行了深入探讨。重点介绍了数据标准的定义&#xff0c;实施路线和具体标准定义的内容&#xff0c;并总结了企业开展数据标准管理面临的常见问题&#xff0c;由于编写的水平和时间有限&#xff0c; 难免有所纸漏&#xff0c; 欢迎大家批评指正。 在现实…

填报高考志愿时,学校、专业和城市怎么选择呢?

我的观点是&#xff1a; 专业>城市>学校 专业是兴趣导向&#xff0c;符合自己的价值观&#xff0c;失去了这种驱动力的专业学习&#xff0c;会变得非常艰难的&#xff0c;而且没有竞争力&#xff0c;所以我的排序第一位是专业。 其次是城市&#xff0c;最好是一线城市&…

OpenAI发布新模型CriticGPT:利用GPT优化GPT训练,RLHF实现超越人类能力!

目录 01 基于GPT-4&#xff0c;改进GPT-4 02 CriticGPT取得了哪些成果呢&#xff1f; 03 RLHF的上限不再是人类 近日&#xff0c;OpenAI突然发布了一个新模型&#xff01;这个模型基于GPT-4训练&#xff0c;旨在帮助下一代GPT的训练。 CriticGPT能够在代码挑错中找到超过75%…

golang生成RSA公钥和密钥

目录 场景 场景一&#xff1a;加密、解密 场景二&#xff1a;微信退款 场景三&#xff1a;SSL证书 为什么是.key和.pem格式的文件 生成密钥、公钥 密钥、公钥保存到文件中 第一个&#xff1a;保存密钥到文件里 第二个&#xff1a;保存公钥到文件里 场景 场景一&#…

ForkJoinPool浅析

一,概述 相比传统的线程池ExecuteService,ForkJoinPool的优势在于能采用分治算法、工作窃取算法高效利用CPU资源,如下图 Fork即拆分,Join即合并, 通过将大任务拆分成多个小任务,在多个线程中执行后,合并结果即可得到大任务的结果,经典的例子有归并排序、超大数组求和…

如何保护应用?可快速部署的WAF服务器分享

Web应用攻击是安全事件和数据泄露的主要原因。相关统计表明&#xff0c;超过四分之三的网络犯罪直指应用及其漏洞。为保护数量日益增长的应用安全&#xff0c;Web应用防火墙(WAF)因此而生。本文则聚焦于WAF服务器&#xff0c;了解它的性能与具体的实践应用。   新加坡网络安全…

Linux应急响应靶机 2

一、靶机介绍 应急响应靶机-Linux2 前景需要&#xff1a;看监控的时候发现webshell告警&#xff0c;领导让你上机检查你可以救救安服仔吗&#xff01;&#xff01; 1,提交攻击者IP 2,提交攻击者修改的管理员密码(明文) 3,提交第一次Webshell的连接URL(http://xxx.xxx.xxx.…

变“回锅肉”专场的《歌手2024》,是不是高开低走了?

《歌手2024》播出已经过半&#xff0c;似乎出现了高开低走的不妙趋势。 6月26日&#xff0c;《歌手》节目组官宣第八期节目的补位歌手为谭维维&#xff0c;曾主动“请战”的她再次回到了《歌手》舞台&#xff0c;实力歌手加入节目按理说是件好事&#xff0c;却意外并未受到观众…

每天写java到期末考试--复习集合与泛型--6.28

1、定义一个Student类,具有name、sex、age属性,具有getName、setName、getSex、setSex、 getAge、setAge方法和三个参数的构造方法 2、编写一个类,名字为ListDemo,在main方法中做以下工作: 定义一个可以保存Student类型对象的List类型对象list1,然后向list1中放入2个学生:new S…

Web渗透:php反序列化漏洞

反序列化漏洞&#xff08;Deserialization Vulnerability&#xff09;是一种在应用程序处理数据的过程中&#xff0c;因不安全的反序列化操作引发的安全漏洞&#xff1b;反序列化是指将序列化的数据&#xff08;通常是字节流或字符串&#xff09;转换回对象的过程&#xff0c;如…

松下的台灯值得入手吗?书客、飞利浦真实横评大分享!

我们都知道&#xff0c;无论是学习还是工作&#xff0c;都需要一个良好的照明环境&#xff0c;而台灯就是我们日常生活中非常重要的照明工具。它不仅能够提供额外的光线&#xff0c;还能减少眼睛疲劳&#xff0c;提高我们的工作和学习效率。 所以&#xff0c;选购一款合适的台…

240622_昇思学习打卡-Day4-ResNet50迁移学习

240622_昇思学习打卡-Day4-ResNet50迁移学习 我们对事物的认知都是一点一点积累出来的&#xff0c;往往借助已经认识过的东西&#xff0c;可以更好地理解和认识新的有关联的东西。比如一个人会骑自行车&#xff0c;我们让他去骑摩托车他也很快就能学会&#xff0c;比如已经学会…

电脑提醒事项怎么显示在桌面

在繁忙的工作节奏中&#xff0c;我们经常会面临多项任务同时进行的情况。为了确保不遗漏任何重要事务&#xff0c;设置电脑提醒事项就显得尤为重要。想象一下&#xff0c;当你正忙于一个项目时&#xff0c;电脑屏幕突然弹出一个提醒&#xff0c;告诉你接下来的会议时间&#xf…

梦想CAD二次开发

1.mxdraw简介 mxdraw是一个HTML5 Canvas JavaScript框架&#xff0c;它在THREE.js的基础上扩展开发&#xff0c;为用户提供了一套在前端绘图更为方便&#xff0c;快捷&#xff0c;高效率的解决方案&#xff0c;mxdraw的实质为一个前端二维绘图平台。你可以使用mxdraw在画布上绘…

实力认可!安全狗受聘成为福建省网信系统2024年度网络安全技术支撑单位

6月6日&#xff0c;福建省委网信办组织召开福建省网信系统2024年度网络安全技术支撑单位座谈会。 作为国内云原生安全领导厂商&#xff0c;安全狗也受邀出席此次活动。 省委宣传部副部长、省委网信办主任、省互联网信息办公室主任张远出席会议并颁发支撑单位证书。安全狗凭借出…

如何用Vue3和Plotly.js绘制动态3D图表?

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Plotly.js: 使用Vue.js动态加载数据并绘制图表 应用场景 在数据可视化应用中&#xff0c;需要将数据动态加载到图表中并进行实时更新。本文将展示如何使用Plotly.js和Vue.js实现这一功能&#xff0c;从加载外…

java基于ssm+jsp 电子商城系统

1管理员功能模块 管理员登录&#xff0c;通过填写用户名、密码进行登录&#xff0c;如图1所示。 图1管理员登录界面图 管理员登录进入电子商城系统可以查看个人中心、用户管理、医生管理、药品信息管理、线上诊疗管理、医生信息管理、管理员管理、论坛管理、系统管理、订单管…

snowflake 不再是个数据仓库公司了

标题先上结论&#xff0c;为啥这么认为&#xff0c;且听接下来道来。 snowflake 非常成功&#xff0c;开创了云数仓先河&#xff0c;至今在数仓架构上也是相对比较先进的&#xff0c;国内一堆模仿的公司&#xff0c;传统上我们会认为 snowflake 肯定是一家数据仓库公司。不过最…

智能工业网络,需要何种工业以太网交换机作为支撑?

随着工业企业数字化及信息化的进一步深化升级&#xff0c;工业领域相关控制及信息系统的业务类型不断增加、复杂性不断提升&#xff0c;工业控制网络与工业信息网络也呈现融合趋势&#xff0c;具备支持多业务、多协议、多厂商设备和数据的互联互通、共网承载以及高质量传输能力…