C# 实现海康车牌识别一体机的高效语音播报与LED显示

324 阅读4分钟

前言

随着智能安防系统的快速发展,车牌识别技术在停车场管理、交通监控等领域得到了广泛应用。

本文将详细介绍如何使用C#语言实现对海康车牌识别一体机的控制,包括语音播报和LED显示屏的优化。通过本文的学习,可以掌握基于ISAPI协议进行设备通信的方法,并能够应用到实际项目中。

正文

一、海康ISAPI协议原理

海康ISAPI协议是基于HTTP/HTTPS的智能安防通信框架,专为安防设备设计的应用层通信协议。它采用RESTful架构风格,支持明文HTTP与加密HTTPS传输,确保通信安全。请求与响应数据以XML或JSON格式交互,并依赖签名机制(如摘要认证)保障每次调用的安全性。

核心功能

设备管理:设备状态查询、参数配置。

视频流控制:实时视频流获取、录像回放。

智能分析:人脸识别、行为分析等AI功能。

云台控制:摄像头方向、焦距远程调节。

事件管理:报警订阅、事件触发与响应。

热成像处理:热成像设备数据交互。

二、核心代码

LED显示

public static void LedShow(string ip, string userName, string userPwd, List<LedLineInfo> lines)
{
    string ISAPIUrl = "/ISAPI/Parking/channels/1/LEDConfigurationDz";
    string putXml = "<?xml version=\"1.0\"?>"
        + "<LEDConfigurationList xmlns=\"http://www.hikvision.com/ver20/XMLSchema\" version=\"2.0\">";
    
    foreach (var line in lines)
    {
        putXml += "<LEDConfiguration>";
        putXml += $"<information>{line.LedText}</information><displayMode>{line.DisplayMode}</displayMode><speedType>{line.SpeedType}</speedType><showTime>15</showTime><showPlate>false</showPlate><fontSize>16</fontSize><fontColor>1</fontColor>";
        putXml += "</LEDConfiguration>";
    }
    putXml += "</LEDConfigurationList>";
    string url = "http://" + ip + ISAPIUrl;
    DigestAuthUtil.PostResponse(url, ISAPIUrl, putXml, userName, userPwd);
}

语音播放

public static void SpeakText(string ip, string userName, string userPwd, string text)
{
    string ISAPIUrl = "/ISAPI/Parking/channels/1/voiceBroadcastInfo";
    string putXml = "<VoiceBroadcastInfo version=\"2.0\" xmlns=\"http://www.isapi.org/ver20/XMLSchema\"><information min=\"0\" max=\"128\">" + text + "</information></VoiceBroadcastInfo>";

    string url = "http://" + ip + ISAPIUrl;
    DigestAuthUtil.PostResponse(url, ISAPIUrl, putXml, userName, userPwd);
}

Digest 认证

Digest认证涉及到多个参数,例如WWW-Authentication用于定义认证方式,realm表示Web服务器中受保护文档的安全域,nonce作为服务端向客户端发送的质询随机数等。详细代码见下:

public class DigestAuthUtil
{
    public static string PostResponse(string url, string urlroute, string postData, string username, string password)
    {
        string realm = string.Empty;
        string qop = string.Empty;
        string nonce = string.Empty;
        string opaque = string.Empty;
        string nc = string.Empty;
        string cnonce = string.Empty;

        HttpContent httpContent = new StringContent(postData);
        httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/xml");

        HttpClient httpClient = new HttpClient();
        HttpResponseMessage response = httpClient.GetAsync(url).Result;

        if (response.StatusCode == HttpStatusCode.Unauthorized)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();

            foreach (var item in response.Headers.WwwAuthenticate)
            {
                if (item.Scheme.ToUpper() == "DIGEST")
                {
                    dic.Add(item.Scheme.ToUpper(), item.Parameter);
                }
            }

            foreach (string keyValuePair in dic["DIGEST"].Split(','))
            {
                int index = keyValuePair.IndexOf("=", System.StringComparison.Ordinal);
                string key = keyValuePair.Substring(0, index).Trim();
                string value = keyValuePair.Substring(index + 2, keyValuePair.Length - index - 3);

                switch (key)
                {
                    case "realm":
                        realm = value;
                        break;
                    case "nonce":
                        nonce = value;
                        break;
                    case "qop":
                        qop = value;
                        break;
                    case "opaque":
                        opaque = value;
                        break;
                }
            }

            nc = "00000001";
            cnonce = Guid.NewGuid().ToString();
        }

        string responseString = computeDigestResponse(username, password, realm, "PUT", nonce, urlroute, nc, cnonce, qop);

        // 注意各值的逗号后面一定要有空格隔开
        string headString1 = string.Format("Digest username=\"{0}\", realm=\"{1}\", nonce=\"{2}\", uri=\"{3}\", algorithm=\"MD5\", ", username, realm, nonce, urlroute);
        string headString2 = string.Format("qop={0}, nc={1}, cnonce=\"{2}\", response=\"{3}\" ", qop, nc, cnonce, responseString);
        string headString = headString1 + headString2;

        // HTTPS访问需要添加证书验证(可选)
        // ServicePointManager.ServerCertificateValidationCallback += CheckValidationResult;

        using (var http = new HttpClient())
        {
            http.DefaultRequestHeaders.Add("Authorization", headString);

            StringContent httpContent2 = new StringContent(postData, Encoding.UTF8, "application/xml");

            var response2 = http.PutAsync(url, httpContent2).Result;

            if (response2.IsSuccessStatusCode)
            {
                try
                {
                    var x = response2.Content.ReadAsStringAsync().Result;
                    return x;
                }
                catch (Exception)
                {
                    return null;
                }
            }
        }

        return null;
    }

    /// <summary>
    /// MD5 32位加密
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    private static string md5(string str)
    {
        return CalculateMd5Hash(str);
    }

    private static string CalculateMd5Hash(string input)
    {
        var inputBytes = Encoding.ASCII.GetBytes(input);
        var hash = MD5.Create().ComputeHash(inputBytes);
        var sb = new StringBuilder();

        foreach (var b in hash)
        {
            sb.Append(b.ToString("x2"));
        }

        return sb.ToString();
    }

    /// <summary>
    /// 生成摘要签名
    /// </summary>
    public static string computeDigestResponse(string username, string userpwd, string realm, string method, string nonce, string url, string nc, string cnonce, string qop)
    {
        string ha1 = md5(username + ":" + realm + ":" + userpwd);
        string ha2 = md5(method + ":" + url);
        string response = md5(ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2);
        return response;
    }
}

总结

本文介绍了如何利用C#语言结合海康ISAPI协议来实现车牌识别一体机的语音播报和LED显示功能。通过详细解析了ISAPI协议的工作原理及其核心功能模块,并提供了具体的核心代码示例,帮助大家理解和实践。无论是开发新的智能安防系统还是对现有系统进行优化升级,这些知识都具有重要的指导意义。

关键词

ISAPI协议、海康车牌识别一体机、C#、语音播报、LED显示、Digest认证、智能安防、HTTP/HTTPS、RESTful、XML/json、设备管理、视频流控制、智能分析、云台控制、事件管理、热成像处理

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:上位机李工

出处:mp.weixin.qq.com/s/GaU0dbSDxKeSVEUAquhZBQ

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!