方法一:在.NET Framework4.0框架下 加装大华设想头并采用数据流方式实时读取摄像头数据;
关于摄像头数据读取方式主要有两种;1、采用数据流的方式;2、采用RTSP 流数据拉取; 两种方式各有千秋;主要看应用场景;本文采用了 sdk 中的数据流直接读取的方式;通过测试发现优点就是时效性更高一点。大约快500ms以上;
SDK 的下载请异步到 大华官网
设备网络SDK-浙江大华技术股份有限公司 (dahuatech.com)
关于摄像头的配置工作请自行越多使用说明本文不在阐述;
搭建第一个读数 摄像头数据并将数据转变成 opencv 需要的 mat 格式;
第一步:
新建一个 C# windows 窗体程序 名称定义为DaHuaDemo;
在窗体上放置如下控件 pictureBox 命名为realplay_pictureBox ;用于接收 摄像头流数据实时显示;pictureBox 命名为PBCaptureImage 用来处理识别后或者处理后的图片
放置:textbox 用于输入 摄像头的 IP 以及端口号和 登录用户名和密码;
放置button 用于登录:
代码如下:
private static fDisConnectCallBack m_DisConnectCallBack;
private static fHaveReConnectCallBack m_ReConnectCallBack;
private static fRealDataCallBackEx2 m_RealDataCallBackEx2;
private static fSnapRevCallBack m_SnapRevCallBack;
private IntPtr m_LoginID = IntPtr.Zero;
private NET_DEVICEINFO_Ex m_DeviceInfo;
private IntPtr m_RealPlayID = IntPtr.Zero;
private const int MaxSpeed = 8;
private const int MinSpeed = 1;
private static Mat rbgImg=new Mat();
private static Mat yuvImg;
private void RealPlayAndPTZDemo_Load(object sender, EventArgs e)
{
m_DisConnectCallBack = new fDisConnectCallBack(DisConnectCallBack);
m_ReConnectCallBack = new fHaveReConnectCallBack(ReConnectCallBack);
m_RealDataCallBackEx2 = new fRealDataCallBackEx2(RealDataCallBackEx);
m_SnapRevCallBack = new fSnapRevCallBack(SnapRevCallBack);
yuvImg = new Mat(2880, 2560, MatType.CV_8UC1);
// 这个地方 采用不同的 摄像头传递 图像大小确定
//yuvImg = new Mat(1440, 1280, MatType.CV_8UC1);
try
{
NETClient.Init(m_DisConnectCallBack, IntPtr.Zero, null);
NETClient.SetAutoReconnect(m_ReConnectCallBack, IntPtr.Zero);
NETClient.SetSnapRevCallBack(m_SnapRevCallBack, IntPtr.Zero);
InitOrLogoutUI();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
Process.GetCurrentProcess().Kill();
}
}
#region CallBack 回调
private void DisConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser)
{
this.BeginInvoke((Action)UpdateDisConnectUI);
}
private void UpdateDisConnectUI()
{
this.Text = "RealPlayAndPTZDemo(实时预览与云台Demo) --- Offline(离线)";
}
private void ReConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser)
{
this.BeginInvoke((Action)UpdateReConnectUI);
}
private void UpdateReConnectUI()
{
this.Text = "RealPlayAndPTZDemo(实时预览与云台Demo) --- Online(在线)";
}
private void RealDataCallBackEx(IntPtr lRealHandle, uint dwDataType, IntPtr pBuffer, uint dwBufSize, IntPtr param, IntPtr dwUser)
{
if (dwDataType == 2)
{
byte[] dd = new byte[dwBufSize];
Marshal.Copy(pBuffer, dd, 0, (int)dwBufSize);
Marshal.Copy(dd.ToArray(), 0, yuvImg.Data, dd.Length);
Cv2.CvtColor(yuvImg, rbgImg, ColorConversionCodes.YUV2BGR_I420);
PBCaptureImage.Image = BitmapConverter.ToBitmap(rbgImg);
}
}
private void SnapRevCallBack(IntPtr lLoginID, IntPtr pBuf, uint RevLen, uint EncodeType, uint CmdSerial, IntPtr dwUser)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "capture";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
if (EncodeType == 10) //.jpg
{
DateTime now = DateTime.Now;
string fileName = "async" + CmdSerial.ToString() + ".jpg";
string filePath = path + "\\" + fileName;
byte[] data = new byte[RevLen];
Marshal.Copy(pBuf, data, 0, (int)RevLen);
using (FileStream stream = new FileStream(filePath, FileMode.OpenOrCreate))
{
stream.Write(data, 0, (int)RevLen);
stream.Flush();
stream.Dispose();
}
}
}
#endregion
private void login_button_Click(object sender, EventArgs e)
{
if (IntPtr.Zero == m_LoginID)
{
if (tbIP.Text.Trim() != null)
{
IpAdd = tbIP.Text;
}
else
{
IpAdd = "192.168.1.108";
}
Port = 37777;
UserName = "admin";
UserPwd = "sail@2021";
m_DeviceInfo = new NET_DEVICEINFO_Ex();
m_LoginID = NETClient.LoginWithHighLevelSecurity(IpAdd, Port, UserName, UserPwd, EM_LOGIN_SPAC_CAP_TYPE.TCP, IntPtr.Zero, ref m_DeviceInfo);
if (IntPtr.Zero == m_LoginID)
{
MessageBox.Show(this, NETClient.GetLastError());
return;
}
LoginUI();
CameraPreview(true);
}
else
{
CameraPreview(false);
bool result = NETClient.Logout(m_LoginID);
if (!result)
{
MessageBox.Show(this, NETClient.GetLastError());
return;
}
m_LoginID = IntPtr.Zero;
InitOrLogoutUI();
}
}
/// <summary>
/// 预览
/// </summary>
/// <param name="vv"></param>
void CameraPreview(bool vv)
{
if (IntPtr.Zero == m_RealPlayID && vv)
{
// realplay 预览
EM_RealPlayType type;
if (streamtype_comboBox.SelectedIndex == 0)
{
type = EM_RealPlayType.Realplay;
}
else
{
type = EM_RealPlayType.Realplay_1;
}
m_RealPlayID = NETClient.RealPlay(m_LoginID, channel_comboBox.SelectedIndex, realplay_pictureBox.Handle, type);
if (IntPtr.Zero == m_RealPlayID)
{
MessageBox.Show(this, NETClient.GetLastError());
return;
}
NETClient.SetRealDataCallBack(m_RealPlayID, m_RealDataCallBackEx2, IntPtr.Zero, EM_REALDATA_FLAG.DATA_WITH_FRAME_INFO | EM_REALDATA_FLAG.PCM_AUDIO_DATA | EM_REALDATA_FLAG.RAW_DATA | EM_REALDATA_FLAG.YUV_DATA);
channel_comboBox.Enabled = false;
streamtype_comboBox.Enabled = false;
}
else
{
// stop realplay 关闭预览
bool ret = NETClient.StopRealPlay(m_RealPlayID);
if (!ret)
{
MessageBox.Show(this, NETClient.GetLastError());
return;
}
m_RealPlayID = IntPtr.Zero;
realplay_pictureBox.Refresh();
channel_comboBox.Enabled = true;
streamtype_comboBox.Enabled = true;
}
}
//RTSP 读取方式
void RtspT()
{
// 初始化摄像头
string rtspStr = "rtsp://admin:sail@2021@192.168.1.108:554/cam/realmonitor?channel=1&subtype=0";
var capture = new VideoCapture(rtspStr);
定义矩形结构元素
//Cv2.GetStructuringElement(MorphShapes.Rect, new Size(5, 5));
while (true)
{
if (!capture.IsOpened()) return;
// 读下一帧;
capture.Read(rbgImg);
if (rbgImg.Empty()) continue;
Reading_2(rbgImg, true);
//Task.Factory.StartNew(AutoIdentify);
Thread.Sleep(500);
// 显示结果
}
}