需求

需要在无人艇上添加海康威视的实时摄像头。

  1. 本地IP192.168.0.100 摄像头IP 192.168.0.64 用户名admin 密码nanfoon51077533 端口8000
  2. 海康配置可在文件中更改。
  3. 摄像头添加在BoatStatus页的右侧地图模块的右上角。
  4. 通过一个按钮来控制摄像头的开启和关闭。
  5. 图像双击后弹出独立窗口。

摄像头未开启时的效果图:

摄像头开启后的效果图:
弹出后的独立窗口示意图:

实现

1. 添加按钮

地图页在MissionPlanner项目下面的GCSViews文件夹里面的FlightData.cs里面。如下图:
toolbox里面找到Button,拖至地图位置,并将其text属性更改。如图所示:

2. 更改海康威视参数

因为公司海康威视通用同一个配置参数,先要更改设备参数。进入海康威视的配置软件:
点击添加至客户端后会弹出下面的窗口,输入原参数,起一个别名,点击添加。
选中刚才添加的设备,点击远程配置


生效后不要忘记更改本地计算机的IP地址。再次进入远程配置,更改密码


顺带把OSD显示改下:

3. 添加视频窗口

toolbox里面找到pictureBox拖入地图右上侧。并将其visible属性改为falsesize改为300,300.

4. 添加视频代码

双击Camera按键进入点击事件代码块。

设备网络SDK开发包(64bit)【库文件】里的HCNetSDK.dll、HCCore.dll、HCNetSDKCom文件夹、PlayCtrl.dll、SuperRender.dll、AudioRender.dll、ssleay32.dll、libeay32.dll等文件均拷贝放置在新建的bin文件夹里,将bin文件夹放置在Debug目录下。本例中 C:\Users\lenovo\Documents\Visual Studio 2017\Projects\FlotillaV4\FlotillaV4\bin\Debug

将海康实时预览示例代码一\PreviewDemo文件夹里的CHCNetSDK.cs复制到FlightData.cs相同文件夹下。右击将其添加如当前project。


双击打开,将第三行的namespace更改,如下:

namespace PreviewDemo

改为

namespace MissionPlanner.GCSViews

更改后导入进去的CHCNetSDK.cs文件可被FlightData.cs识别。
在新增的按键点击事件代码块添加以下代码:

        //HikVision Cameraprivate bool m_bInitSDK = false;private void ButtonCameraSwitch_Click(object sender, EventArgs e){m_bInitSDK = CHCNetSDK.NET_DVR_Init();if (m_bInitSDK == false){MessageBox.Show("NET_DVR_Init error!");return;}else{//保存SDK日志 To save the SDK logCHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);}}

添加完成后点击调试,启动调式运行,程序启动后点击按键,如无报错,说明添加进去的模块运行正常。继续编写。
在按键单击函数下方添加海康威视的资源释放函数,如下所示(添加后会提示重名或者变量未定义的错误,根据提示修改下就可以):

        //HikVision Cameraprivate bool m_bInitSDK = false;private Int32 m_lRealHandle = -1;private Int32 m_lUserID = -1;private void ButtonCameraSwitch_Click(object sender, EventArgs e){m_bInitSDK = CHCNetSDK.NET_DVR_Init();if (m_bInitSDK == false){MessageBox.Show("NET_DVR_Init error!");return;}else{//保存SDK日志 To save the SDK logCHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);}}/// <summary>/// 清理所有正在使用的资源。/// </summary>protected void HikDispose(bool disposing){if (m_lRealHandle >= 0){CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle);}if (m_lUserID >= 0){CHCNetSDK.NET_DVR_Logout(m_lUserID);}if (m_bInitSDK == true){CHCNetSDK.NET_DVR_Cleanup();}if (disposing){if (components != null){components.Dispose();}}base.Dispose(disposing);}

相同的方法添加更改所需代码,为了灵活变换显示区域,对preview代码块做了传递函数的更改,将picturebox作为传递变量改进去。代码块更改完后如下:

        //HikVision Cameraprivate bool m_bInitSDK = false;private Int32 m_lRealHandle = -1;private Int32 m_lUserID = -1;private uint iLastErr = 0;private string str;CHCNetSDK.REALDATACALLBACK RealData = null;private void ButtonCameraSwitch_Click(object sender, EventArgs e){m_bInitSDK = CHCNetSDK.NET_DVR_Init();if (m_bInitSDK == false){MessageBox.Show("NET_DVR_Init error!");return;}else{//保存SDK日志 To save the SDK logCHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);}if (m_lUserID < 0){//OpenHikLogin();HikPreview(PictureBoxHikVisionCameraOnMap);}else{//CloseHikPreview(PictureBoxHikVisionCameraOnMap);HikLogin();}}/// <summary>/// 清理所有正在使用的资源。/// </summary>protected void HikDispose(bool disposing){if (m_lRealHandle >= 0){CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle);}if (m_lUserID >= 0){CHCNetSDK.NET_DVR_Logout(m_lUserID);}if (m_bInitSDK == true){CHCNetSDK.NET_DVR_Cleanup();}if (disposing){if (components != null){components.Dispose();}}base.Dispose(disposing);}/// <summary>/// Login/// </summary>protected void HikLogin(){if (m_lUserID < 0){string DVRIPAddress = ConfigurationManager.AppSettings["HikIP"]; //设备IP地址或者域名Int16 DVRPortNumber = Convert.ToInt16(ConfigurationManager.AppSettings["HikPort"]);//设备服务端口号string DVRUserName = ConfigurationManager.AppSettings["UserName"];//设备登录用户名string DVRPassword = ConfigurationManager.AppSettings["PassWord"];//设备登录密码CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();//登录设备 Login the devicem_lUserID = CHCNetSDK.NET_DVR_Login_V30(DVRIPAddress, DVRPortNumber, DVRUserName, DVRPassword, ref DeviceInfo);if (m_lUserID < 0){iLastErr = CHCNetSDK.NET_DVR_GetLastError();str = "NET_DVR_Login_V30 failed, error code= " + iLastErr; //登录失败,输出错误号MessageBox.Show(str);return;}else{//登录成功
//                    MessageBox.Show("Login Success!");
//                    CustomMessageBox.Show("Login Success!");//                   btnLogin.Text = "Logout";}}else{//注销登录 Logout the deviceif (m_lRealHandle >= 0){MessageBox.Show("Please stop live view firstly");return;}if (!CHCNetSDK.NET_DVR_Logout(m_lUserID)){iLastErr = CHCNetSDK.NET_DVR_GetLastError();str = "NET_DVR_Logout failed, error code= " + iLastErr;MessageBox.Show(str);return;}m_lUserID = -1;
//                btnLogin.Text = "Login";}return;}/// <summary>/// HikPreview/// </summary>private void HikPreview( PictureBox pictrueBox ){if (m_lUserID < 0){MessageBox.Show("Please login the device firstly");return;}if (m_lRealHandle < 0){CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();lpPreviewInfo.hPlayWnd = pictrueBox.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 (textBoxID.Text != "")//{//    lpPreviewInfo.lChannel = -1;//    byte[] byStreamID = System.Text.Encoding.Default.GetBytes(textBoxID.Text);//    lpPreviewInfo.byStreamID = new byte[32];//    byStreamID.CopyTo(lpPreviewInfo.byStreamID, 0);//}if (RealData == null){RealData = new CHCNetSDK.REALDATACALLBACK(HikRealDataCallBack);//预览实时流回调函数}IntPtr pUser = new IntPtr();//用户数据//打开预览 Start live view m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser);if (m_lRealHandle < 0){iLastErr = CHCNetSDK.NET_DVR_GetLastError();str = "NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败,输出错误号MessageBox.Show(str);return;}else{//预览成功ButtonCameraSwitch.Text = "Stop";pictrueBox.Visible = true;}}else{//停止预览 Stop live view if (!CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle)){iLastErr = CHCNetSDK.NET_DVR_GetLastError();str = "NET_DVR_StopRealPlay failed, error code= " + iLastErr;MessageBox.Show(str);return;}m_lRealHandle = -1;ButtonCameraSwitch.Text = "Camera";pictrueBox.Visible = false;}return;}/// <summary>/// HikCallBack/// </summary>public void HikRealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser){if (dwBufSize > 0){byte[] sData = new byte[dwBufSize];System.Runtime.InteropServices.Marshal.Copy(pBuffer, sData, 0, (Int32)dwBufSize);string str = "实时流数据.ps";FileStream fs = new FileStream(str, FileMode.Create);int iLen = (int)dwBufSize;fs.Write(sData, 0, iLen);fs.Close();}}

5. 海康配置改为可在文件中更改

FlightData.cs添加 using System.Configuration; 引用。然后在启动文件夹下找到exe.config后缀的文件,打开,找到<appSettings>字段,如下所示:

  <appSettings><add key="UpdateLocationVersion" value="http://firmware.ardupilot.org/MissionPlanner/upgrade/version.txt" /><add key="UpdateLocation" value="http://firmware.ardupilot.org/MissionPlanner/upgrade/" /><add key="UpdateLocationMD5" value="http://firmware.ardupilot.org/MissionPlanner/checksums.txt" /><add key="UpdateLocationZip" value="http://firmware.ardupilot.org/MissionPlanner/MissionPlanner-latest.zip" /><add key="BetaUpdateLocationVersion" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/version.txt?tag=beta" /><add key="BetaUpdateLocationMD5" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/checksums.txt?tag=beta" /><add key="BetaUpdateLocationZip" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/MissionPlannerBeta.zip?tag=beta" /><add key="MasterUpdateLocationMD5" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/checksums.txt?branch=master" /><add key="MasterUpdateLocationZip" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/MissionPlannerBeta.zip?branch=master" /><add key="ParameterLocations" value="https://raw.githubusercontent.com/ardupilot/ardupilot/ArduCopter-stable/ArduCopter/Parameters.cpp;    https://raw.githubusercontent.com/ardupilot/ardupilot/ArduSub-stable/ArduSub/Parameters.cpp;      https://raw.githubusercontent.com/ardupilot/ardupilot/ArduPlane-stable/ArduPlane/Parameters.cpp;          https://raw.githubusercontent.com/ardupilot/ardupilot/APMrover2-stable/APMrover2/Parameters.cpp;          https://raw.githubusercontent.com/ardupilot/ardupilot/master/AntennaTracker/Parameters.cpp;" /><add key="ParameterLocationsBleeding" value="https://raw.githubusercontent.com/ardupilot/ardupilot/master/ArduCopter/Parameters.cpp;     https://raw.githubusercontent.com/ardupilot/ardupilot/master/ArduSub/Parameters.cpp;       https://raw.githubusercontent.com/ardupilot/ardupilot/master/ArduPlane/Parameters.cpp;          https://raw.githubusercontent.com/ardupilot/ardupilot/master/APMrover2/Parameters.cpp;          https://raw.githubusercontent.com/ardupilot/ardupilot/master/AntennaTracker/Parameters.cpp;" /><add key="ParameterMetaDataXMLFileName" value="ParameterMetaData.xml" /><add key="ParameterMetaDataXMLFileNameBackup" value="ParameterMetaDataBackup.xml" /><add key="ClientId" value="zHTnuEq0RAWoLy5thcvTtMdwX7r6et2L3MAhxv8a0" /><add key="ClientSecret" value="1ylYlXV4GuWJHIUywFg+XxE6hxsd3P/Dq5+J1PCUGxulC05/GC4Xpg==" /><add key="AuthURL" value="https://auth.altitudeangel.com" /><add key="APIURL" value="https://api.altitudeangel.com" /><add key="ClientSettingsProvider.ServiceUri" value="" /></appSettings>

在开始位置添加海康配置字段,如下:

  <appSettings><add key="LocalIP" value="192.168.0.100"/><add key="HikIP" value="192.168.0.64"/><add key="UserName" value="admin"/><add key="PassWord" value="nanfoon51077533"/><add key="HikPort" value="8000"/><add key="UpdateLocationVersion" value="http://firmware.ardupilot.org/MissionPlanner/upgrade/version.txt" /><add key="UpdateLocation" value="http://firmware.ardupilot.org/MissionPlanner/upgrade/" /><add key="UpdateLocationMD5" value="http://firmware.ardupilot.org/MissionPlanner/checksums.txt" /><add key="UpdateLocationZip" value="http://firmware.ardupilot.org/MissionPlanner/MissionPlanner-latest.zip" /><add key="BetaUpdateLocationVersion" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/version.txt?tag=beta" /><add key="BetaUpdateLocationMD5" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/checksums.txt?tag=beta" /><add key="BetaUpdateLocationZip" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/MissionPlannerBeta.zip?tag=beta" /><add key="MasterUpdateLocationMD5" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/checksums.txt?branch=master" /><add key="MasterUpdateLocationZip" value="https://ci.appveyor.com/api/projects/meee1/missionplanner/artifacts/MissionPlannerBeta.zip?branch=master" /><add key="ParameterLocations" value="https://raw.githubusercontent.com/ardupilot/ardupilot/ArduCopter-stable/ArduCopter/Parameters.cpp;    https://raw.githubusercontent.com/ardupilot/ardupilot/ArduSub-stable/ArduSub/Parameters.cpp;      https://raw.githubusercontent.com/ardupilot/ardupilot/ArduPlane-stable/ArduPlane/Parameters.cpp;          https://raw.githubusercontent.com/ardupilot/ardupilot/APMrover2-stable/APMrover2/Parameters.cpp;          https://raw.githubusercontent.com/ardupilot/ardupilot/master/AntennaTracker/Parameters.cpp;" /><add key="ParameterLocationsBleeding" value="https://raw.githubusercontent.com/ardupilot/ardupilot/master/ArduCopter/Parameters.cpp;     https://raw.githubusercontent.com/ardupilot/ardupilot/master/ArduSub/Parameters.cpp;       https://raw.githubusercontent.com/ardupilot/ardupilot/master/ArduPlane/Parameters.cpp;          https://raw.githubusercontent.com/ardupilot/ardupilot/master/APMrover2/Parameters.cpp;          https://raw.githubusercontent.com/ardupilot/ardupilot/master/AntennaTracker/Parameters.cpp;" /><add key="ParameterMetaDataXMLFileName" value="ParameterMetaData.xml" /><add key="ParameterMetaDataXMLFileNameBackup" value="ParameterMetaDataBackup.xml" /><add key="ClientId" value="zHTnuEq0RAWoLy5thcvTtMdwX7r6et2L3MAhxv8a0" /><add key="ClientSecret" value="1ylYlXV4GuWJHIUywFg+XxE6hxsd3P/Dq5+J1PCUGxulC05/GC4Xpg==" /><add key="AuthURL" value="https://auth.altitudeangel.com" /><add key="APIURL" value="https://api.altitudeangel.com" /><add key="ClientSettingsProvider.ServiceUri" value="" /></appSettings>

找到之前添加的HikLogin(),找到如下代码:

                string DVRIPAddress = "192.168.0.64"; //设备IP地址或者域名Int16 DVRPortNumber = 8000;//设备服务端口号string DVRUserName = "admin";//设备登录用户名string DVRPassword = "nanfoon51077533";//设备登录密码

更改为:

                string DVRIPAddress = ConfigurationManager.AppSettings["HikIP"]; //设备IP地址或者域名Int16 DVRPortNumber = Int16.Parse( ConfigurationManager.AppSettings["HiPort"]);//设备服务端口号string DVRUserName = ConfigurationManager.AppSettings["UserName"];//设备登录用户名string DVRPassword = ConfigurationManager.AppSettings["PassWord"];//设备登录密码

实际运行效果:

6. 双击窗体弹出新界面

通过新建窗体来承载弹出的新视频界面,弹出后阴藏地图上的相机按钮来防止用户干扰,关闭弹出的窗口后返回至地图页显示。
在FlightData.cs文件里面的海康威视代码区域增加图像picturebox的双击事件函数:

        private void PictureBoxHikVisionCameraOnMap_DoubleClick(object sender, System.EventArgs e){}

返回到设计窗体选中海康的picturebox空间,在右下角的属性中选中事件栏,找到doubleclick项,在下拉菜单里面选中刚才写的事件函数名,链接事件。

代码写完之后如下:

        /// <summary>/// Double click event , to Pop the free moved Hik camera windows./// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void PictureBoxHikVisionCameraOnMap_DoubleClick(object sender, System.EventArgs e){//            CustomMessageBox.Show("Double click trigered");  // test the trigger event.Form PupHikForm = new Form();  //creat the new from.PupHikForm.ShowIcon = false;PupHikForm.Text = "Flotilla-HikVision";PupHikForm.FormClosed += new FormClosedEventHandler(PuphikForm_FormClosed); //the close event.PictureBox PupHikFormPictureBox = new PictureBox(); PupHikFormPictureBox.BackColor = Color.DeepPink; // to test the Pic box.PupHikFormPictureBox.Size = PupHikForm.Size;//to auto size with the Form.PupHikFormPictureBox.Anchor = ( AnchorStyles.Top|AnchorStyles.Bottom|AnchorStyles.Left|AnchorStyles.Right);PupHikForm.Controls.Add(PupHikFormPictureBox); // Add the pic in formButtonCameraSwitch.PerformClick(); //close the on map picbox by trigger the button event mannuely.HikLogin(); // Login againHikPreview(PupHikFormPictureBox); //previewButtonCameraSwitch.Visible = false;PupHikForm.Show();}/// <summary>/// close event/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void PuphikForm_FormClosed(Object sender, FormClosedEventArgs e){PictureBoxHikVisionCameraOnMap.Visible = true;HikPreview(PictureBoxHikVisionCameraOnMap);//call it two times to avoid the logic conflict. HikPreview(PictureBoxHikVisionCameraOnMap);ButtonCameraSwitch.Visible = true;}

Mission Planner 二次开发之添加海康威视摄像机相关推荐

  1. 基于ZFAKA二次开发,添加PayJS支付渠道

    基于ZFAKA二次开发,添加PayJS支付渠道 项目地址:https://github.com/hiyouli/payjs-for-zfaka 关于ZFAKA,请移步:ZFAKA 免费.安全.稳定.高 ...

  2. QGIS二次开发地图添加标记添加注记Svg小图标SvgItem

    QGIS二次开发地图添加标记添加注记Svg小图标 即QgsAnnotationLayer.QgsMarkerSymbol和QgsAnnotationMarkerItem的用法,我把QGIS3.20软件 ...

  3. gige相机二次开发_GigE Vision接口摄像机及其应用

    摘  要: GigE Vision接口技术成为了机器视觉工业的一项非常具有吸引力的技术,Basler scout系列GigE Vision摄像机具有卓越的性能, Basler提供了Pylon驱动包开发 ...

  4. 基于EasyNVR二次开发实现自己的摄像机IPC/NVR无插件化直播解决方案

    基于EasyNVR二次开发实现自己的摄像机IPC/NVR无插件化直播解决方案 参考文章: (1)基于EasyNVR二次开发实现自己的摄像机IPC/NVR无插件化直播解决方案 (2)https://ww ...

  5. 基于EasyNVR摄像机无插件直播方案二次开发实现自己的摄像机IPC-NVR无插件化直播解决方案

    背景介绍 在之前的博客中<基于EasyNVR实现RTSP/Onvif监控摄像头Web无插件化直播监控>,对EasyNVR所实现的功能我们已经有较多描述,这些也在方案地址:http://ww ...

  6. UG二次开发GRIP添加属性

    组件 或 零件 添加属性 entity/COMP,ent string/std(2,132),str(4,132),mold(132) string/add(2,132) entity/obj STR ...

  7. 【CAD二次开发】添加cad支持文件夹

    我们有时候自己的模板需要用到指定的字体,我们可以把字体放到插件的安装目录里,通过添加支持路径的方式来实现添加CAD字体. //添加自定义字体搜索目录string filePath = Assembly ...

  8. 【Revit二次开发】添加菜单和按钮

    添加菜单和按钮 Ribbon菜单 Ribbon菜单的创建以及各种不同的button Ribbon菜单 这个类是PushButton和PulldownButton的基类. 按钮放在panel内,pane ...

  9. UG二次开发GRIP添加加工工序

    注 我不是原创,转载的 ENTITY/OBJ(25),SURF1(5000),cbnd(90),BEID ENTITY/surf2(5000)NUMBER/NUM L00: PARAM/'请您输入料厚 ...

最新文章

  1. C++ mutable
  2. iOS 字符属性NSAttributedString描述
  3. mysql query cache 命中率_MySQL缓存命中率概述及如何提高缓存命中率
  4. 协同过滤:基于用户的协同过滤itemCF
  5. java定义一个盒子类box_定义一个Box(盒子)类,在该类定义中包括数据成员: length(长),width(宽)和height(...
  6. 《笨办法学python》(《learn python the hard way 3thrd》)习题48(ex48)的代码实现
  7. 企业实战(Jenkins+GitLab+SonarQube)_02_Jenkins运行
  8. kali的burpsuite笔记
  9. 惠普Teradici PCoIP 受OpenSSL 漏洞影响,波及1500万个端点
  10. golang从简单的即时聊天来看架构演变
  11. 零基础CSS入门教程(24)–内联/内部/外部样式
  12. 读王阳明二知行合一2有感
  13. Alpha测试与Beta测试
  14. Azure PowerShell (14) 批量导出Azure ASM ACL和ARM NSG配置信息
  15. 计算机毕业设计=基于微信小程序的停车场管理系统
  16. 超简单:快速制作一款高逼格词云图
  17. unable to qualify my own domain name
  18. 【LeNet、AlexNet、VGG】
  19. osgi为什么不流行_传承千年的“按辈分取名”,现在为什么不流行了?有个原因很尴尬...
  20. 鸿蒙珠传承现代,鸿蒙珠-从灵珠开始万界修炼-话本小说网

热门文章

  1. 解决SpringBoot集成分页插件pagehelper出现的循环依赖问题
  2. Oracle19c PDB级别Failover 出错场景测试
  3. 全球与中国精密空调市场现状及未来发展趋势
  4. 公共基础知识:中国陶瓷发展史
  5. Maven安装卸载本地jar
  6. 解决Lasso回归ConvergenceWarning: Objective did not converge. You might want to increase the number of it
  7. 中国无线电频率频段划分及主要用途
  8. 如何测试tcp端口是否开放
  9. get和post方法使用建议
  10. Python爬取表情包