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.pswp.cn/diannao/37183.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/37183.shtml
英文地址,請注明出處:http://en.pswp.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…