C#海康車牌識別實戰指南帶源碼
前言
車牌識別技術在智能交通、停車場管理等領域有著廣泛的應用。海康威視作為國內領先的安防廠商,其車牌識別相機提供了豐富的SDK接口供開發者使用。本文將詳細介紹如何使用C#語言結合海康威視SDK實現車牌識別功能,并解析關鍵代碼實現。
一、環境準備
在開始之前,需要準備以下環境:
Visual Studio(推薦2017或更高版本)
海康威視網絡SDK(HCNetSDK.dll)
海康威視車牌識別相機設備
.NET Framework 4.0或更高版本
二、項目結構
本項目包含兩個核心類文件:
LicenseCameraGroup.cs
?- 管理多個車牌識別相機的組類LicenseCameraItem.cs
?- 單個車牌識別相機的實現類
三、核心代碼解析
1. LicenseCameraGroup類解析
LicenseCameraGroup
類負責管理多個車牌識別相機,主要功能包括初始化SDK、啟動監聽服務和處理識別結果。
初始化SDK
public bool Init(List<lpr_entity> dataList, List<PictureBox> licenseCameraPicList) {try{LprList = dataList;bool m_bInitSDK = CHCNetSDK.NET_DVR_Init();if (m_bInitSDK == false){return false;}else{// 設置SDK日志路徑CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);// 設置異常消息回調函數if (m_fExceptionCB == null){m_fExceptionCB = new CHCNetSDK.EXCEPYIONCALLBACK(cbExceptionCB);}CHCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, IntPtr.Zero, m_fExceptionCB, IntPtr.Zero);// 設置報警回調函數if (m_falarmData_V31 == null){m_falarmData_V31 = new CHCNetSDK.MSGCallBack_V31(MsgCallback_V31);}CHCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(m_falarmData_V31, IntPtr.Zero);}// 初始化每個車牌識別相機int a = 0;foreach (var item in dataList){LicenseCameraItem licenseCameraItem = new LicenseCameraItem();licenseCameraItem.Init(item.ip, item.port, item.serial_port, item.baud_rate, item.license_account, item.license_password, licenseCameraPicList[a], item.communication_mode);a++;}// 啟動監聽線程Thread thread = new Thread(StartListen);thread.IsBackground = true;thread.Start();return true;}catch (Exception ex){return false;} }
啟動監聽服務
public void StartListen() {sLocalIP = GetIpV4();ushort wLocalPort = 7200;if (m_falarmData == null){m_falarmData = new CHCNetSDK.MSGCallBack(MsgCallback);}iListenHandle = CHCNetSDK.NET_DVR_StartListen_V30(sLocalIP, wLocalPort, m_falarmData, IntPtr.Zero);if (iListenHandle < 0){iLastErr = CHCNetSDK.NET_DVR_GetLastError();strErr = "啟動監聽失敗,錯誤號:" + iLastErr;return;} }
處理車牌識別結果
private void ProcessCommAlarm_ITSPlate(ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser) {CHCNetSDK.NET_ITS_PLATE_RESULT struITSPlateResult = new CHCNetSDK.NET_ITS_PLATE_RESULT();uint dwSize = (uint)Marshal.SizeOf(struITSPlateResult);struITSPlateResult = (CHCNetSDK.NET_ITS_PLATE_RESULT)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_ITS_PLATE_RESULT));// 保存抓拍圖片for (int i = 0; i < struITSPlateResult.dwPicNum; i++){if (struITSPlateResult.struPicInfo[i].dwDataLen != 0){int iLen = (int)struITSPlateResult.struPicInfo[i].dwDataLen;byte[] by = new byte[iLen];Marshal.Copy(struITSPlateResult.struPicInfo[i].pBuffer, by, 0, iLen);if (isSavePic){// 保存圖片到指定路徑if (!System.IO.Directory.Exists(path)){System.IO.Directory.CreateDirectory(path);}string str = path + "\\[" + name + "]_Pictype_" + struITSPlateResult.struPicInfo[i].byType + "_PicNum[" + (i + 1) + "]_" + iFileNumber + ".jpg";FileStream fs = new FileStream(str, FileMode.Create);fs.Write(by, 0, iLen);fs.Close();iFileNumber++;}}}// 獲取識別到的車牌號碼string stringPlateLicense = System.Text.Encoding.GetEncoding("GBK").GetString(struITSPlateResult.struPlateInfo.sLicense).TrimEnd('\0');if (!CardIds.Contains(stringPlateLicense)){CardIds.Add(stringPlateLicense);}// 觸發車牌識別事件isFront = strIP == LprList[0].ip;GetNumberEvent(CardIds, isFront);CardIds.Clear(); }
2. LicenseCameraItem類解析
LicenseCameraItem
類負責單個車牌識別相機的管理,包括相機初始化、登錄、預覽和布防等功能。
相機初始化
public bool Init(string ip, string port, string account, string password) {try{_IP = ip;_Port = port;_Account = account;_Password = password;bool m_bInitSDK = CHCNetSDK.NET_DVR_Init();if (m_bInitSDK == false){return false;}return true;}catch (Exception ex){return false;} }
相機登錄
public bool CameraLogin1(out int num, string iP, string port, string account, string password) {try{//相機參數不能為空if (String.IsNullOrEmpty(iP) || String.IsNullOrEmpty(port) || String.IsNullOrEmpty(account) || String.IsNullOrEmpty(password)){num = 0;return false;}struLogInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();//登錄//設備IP地址或者域名byte[] byIP = System.Text.Encoding.Default.GetBytes(iP);struLogInfo.sDeviceAddress = new byte[129];byIP.CopyTo(struLogInfo.sDeviceAddress, 0);//設備用戶名byte[] byUserName = System.Text.Encoding.Default.GetBytes(account);struLogInfo.sUserName = new byte[64];byUserName.CopyTo(struLogInfo.sUserName, 0);//設備密碼byte[] byPassword = System.Text.Encoding.Default.GetBytes(password);struLogInfo.sPassword = new byte[64];byPassword.CopyTo(struLogInfo.sPassword, 0);struLogInfo.wPort = ushort.Parse(port);//設備服務端口號if (LoginCallBack == null){LoginCallBack = new CHCNetSDK.LOGINRESULTCALLBACK(cbLoginCallBack);//注冊回調函數 }struLogInfo.cbLoginResult = LoginCallBack;struLogInfo.bUseAsynLogin = false; //是否異步登錄:0- 否,1- 是 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();//登錄設備m_lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo);if (m_lUserID < 0){iLastErr = CHCNetSDK.NET_DVR_GetLastError();num = 0;return false;}num = m_lUserID;return true;}catch (Exception ex){num = 0;return false;} }
打開相機預覽
private bool OpenLicenseCamera(PictureBox LicenseCameraPic, string licenseIp, string licensePort, string licenseAccount, string licensePassword) {try{if (Init(licenseIp, licensePort, licenseAccount, licensePassword)){if (CameraLogin1(out int num, licenseIp, licensePort, licenseAccount, licensePassword)){m_lUserID = num;}else{return false;}//成功后打開攝像頭CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();lpPreviewInfo.hPlayWnd = LicenseCameraPic.Handle;//預覽窗口lpPreviewInfo.lChannel = 1;//預te覽的設備通道lpPreviewInfo.dwStreamType = 0;//碼流類型:0-主碼流,1-子碼流,2-碼流3,3-碼流4,以此類推lpPreviewInfo.dwLinkMode = 0;//連接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP lpPreviewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流lpPreviewInfo.dwDisplayBufNum = 1; //播放庫播放緩沖區最大緩沖幀數lpPreviewInfo.byProtoType = 0;lpPreviewInfo.byPreviewMode = 0;if (RealData == null){RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//預覽實時流回調函數}IntPtr pUser = new IntPtr();//用戶數據//打開預覽m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser);if (m_lRealHandle < 0){iLastErr = CHCNetSDK.NET_DVR_GetLastError();return false;}//監聽車牌線程Thread thread = new Thread(LicenseThread);thread.IsBackground = true;thread.Start();return true;}return false;}catch (Exception ex){return false;} }
四、使用示例
// 創建車牌識別組 LicenseCameraGroup licenseCameraGroup = new LicenseCameraGroup();// 訂閱車牌識別事件 licenseCameraGroup.GetNumberEvent += (cardIds, isFront) => {foreach (string cardId in cardIds){Console.WriteLine($"識別到車牌: {cardId}, 方向: {(isFront ? "前" : "后")}");} };// 初始化車牌識別相機 List<lpr_entity> lprList = new List<lpr_entity> {new lpr_entity { ip = "192.168.1.64", port = "8000", license_account = "admin", license_password = "12345" } };List<PictureBox> pictureBoxes = new List<PictureBox> { pictureBox1 }; licenseCameraGroup.Init(lprList, pictureBoxes);
五、注意事項
確保正確引用海康威視的SDK文件(HCNetSDK.dll)
需要先初始化SDK再調用其他功能
確保網絡通暢,相機設備可達
注意處理異常情況,如網絡斷開、設備離線等
合理管理資源,及時釋放不需要的連接
注意編碼問題,海康SDK通常使用GBK編碼
確保相機參數配置正確,包括IP、端口、用戶名和密碼
六、總結
本文詳細介紹了如何使用C#和海康威視SDK實現車牌識別功能。通過分析LicenseCameraGroup
和LicenseCameraItem
兩個核心類,我們了解了如何初始化SDK、登錄相機、啟動預覽、設置布防以及處理車牌識別結果。
關鍵點包括:
使用
NET_DVR_Init
初始化SDK使用
NET_DVR_Login_V40
登錄相機設備使用
NET_DVR_RealPlay_V40
開啟實時預覽使用
NET_DVR_SetupAlarmChan_V41
設置布防通過回調函數處理車牌識別結果
在實際應用中,還需要考慮異常處理、性能優化和資源管理等問題。希望本文對您實現車牌識別功能有所幫助,如有疑問歡迎在評論區留言討論。