C#多个海康相机的使用

目录

项目要求

项目环境

项目实现

TreeView

cameratree

opentree

鼠标拖拽事件 

检索相机

打开相机

相机功能

保存图像

关闭相机

显示图像


项目要求

        枚举相机生成相机树,拖动节点打开对应的相机。

        

项目环境

        C#、WinForm

项目实现

TreeView

cameratree

        1. 窗口添加存放检索相机treeview,并设置相关参数。

        2. 添加索引图标

//读取图像,创建ImageList
private void creat_imagelist()
{
    string path = "..\\Images\\";
    string[] files = Directory.GetFiles(path);
    foreach (string file in files)
    {
        System.Drawing.Image image = System.Drawing.Image.FromFile(file);
        ImageList.Images.Add(image);
    }
}

//在treeview初始化位置添加ImageList,节点图标默认是第一张图片
private void treeviewinit()
{
    creat_imagelist();
    cameratree.ImageList = ImageList;
}

opentree

        1.窗口添加打开相机treeview,并设置相关参数。

        2.添加索引图标(这里两个treeview用同一个ImageList)

private void treeviewinit()
{
    creat_imagelist();
    cameratree.ImageList = ImageList;
    opentree.ImageList = ImageList;
}

鼠标拖拽事件 

        右击devicetree节点,拖动到opentree。

#region 鼠标拖拽事件
private void cameratree_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        TreeNode selectedNode = cameratree.GetNodeAt(e.X, e.Y);

        if (selectedNode != null && !opennodes.Contains(selectedNode))
        {
            cameratree.SelectedNode = selectedNode;
            cameratree.DoDragDrop(selectedNode, DragDropEffects.Move);
        }
    }
}

private void opentree_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(TreeNode)))
    {
        e.Effect = DragDropEffects.Move;
    }
}

private void opentree_DragDrop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(TreeNode)))
    {
        TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
        string cameratype = draggedNode.Parent.Name;
        TreeNode[] targetNode = opentree.Nodes.Find(cameratype, false);
        if (targetNode.Length < 1)
        {
            TreeNode cameraname = new TreeNode(draggedNode.Parent.Text, draggedNode.ImageIndex, draggedNode.SelectedImageIndex);
            cameraname.Name = cameratype;
            opentree.Nodes.Add(cameraname);
        }
        targetNode = opentree.Nodes.Find(cameratype, false);
        TreeNode cameranode = (TreeNode)draggedNode.Clone();
        targetNode[0].Nodes.Add(cameranode);

        opentree.SelectedNode = cameranode;
        //记录打开的相机节点
        opennodes.Add(draggedNode);
    }
}
#endregion

检索相机

        枚举相机,函数返回相机数量,根据检索到的数量更新devicetree

public void camerascan()
{
    uint h_count;

    my_hik.CameraScan(out h_count);

    if (h_count > 0)
    {
        add_cameranode("hikvision", h_count);
    }
    else
    {
        MessageBox.Show("nofind hikvision camera");
    }    
}
public void add_cameranode(string cameratype, uint count)
{
    TreeNode[] targetnode = cameratree.Nodes.Find(cameratype, false);
    if (targetnode.Length > 0)
    {
        for (int i = 0; i < count; i++)
        {
            TreeNode cameranode = new TreeNode((cameratype + " " + i.ToString()), i + 1, i + 1);
            cameranode.Name = i.ToString();
            targetnode[0].Nodes.Add(cameranode);
        }
    }
    else
    {
        MessageBox.Show("nofind cameratree");
    }

}

打开相机

        根据给定索引打开对应相机,采图为回调函数

public void cameraopen()
{
    TreeNode opennode = cameratree.SelectedNode;
    bool openflag = true;
    string cameratype = cameratree.SelectedNode.Parent.Name;
    int selectdevice = int.Parse(cameratree.SelectedNode.Name);
    camerapicture.Add(new PictureBox());
    camerapicture[camerapicture.Count - 1].Name = cameratree.SelectedNode.Text;

    switch (cameratype)
    {
        case "do3think":
            {
                openflag = my_do3.CameraOpen((uint)selectdevice, camerapicture[camerapicture.Count - 1].Handle);
            }
            break;
        case "hikvision":
            {
                openflag = my_hik.CameraOpen(selectdevice, camerapicture[camerapicture.Count - 1].Handle);
            }
            break;
        case "mindvision":
            {
                openflag = my_mind.CameraOpen(selectdevice, camerapicture[camerapicture.Count - 1].Handle);
            }
            break;
        default: break;
    }

    if (openflag == false)
    {
        opennodes.Remove(opennode);
        cameratree.SelectedNode.Text += " (disconnect)";
        opentree.SelectedNode.Remove();
        camerapicture.RemoveAt(camerapicture.Count - 1);
        MessageBox.Show("fail open!");
    }
    imageshow();
}

相机功能

        窗口添加ContextMenuStrip组件,当opentree打开时,菜单显示在点击位置。

        private System.Windows.Forms.ContextMenuStrip camerafunc;
        private System.Windows.Forms.ToolStripMenuItem 保存图像ToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem 关闭相机ToolStripMenuItem;

private void opentree_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        TreeNode selectedNode = opentree.GetNodeAt(e.X, e.Y);
        if (selectedNode != null)
        {
            opentree.SelectedNode = selectedNode;
            camerafunc.Show(opentree, e.Location);
        }
    }
}

保存图像

        根据选择的节点,将保存对应相机图像。保存路径为打开文件夹的路径。

private void 保存图像ToolStripMenuItem_Click(object sender, EventArgs e)
{
    SaveFileDialog sfd = new SaveFileDialog();
    sfd.Filter = "bmp file(*.bmp)|*.bmp|jpeg file(*.jpeg)|*.jpeg|png file(*.png)|*.png|tif file(*.tif)|*.tif|gif file(*.gif)|*.gif|raw Files(*.dat)|*.dat";

    if (sfd.ShowDialog() == DialogResult.OK)
    {
        TreeNode selectnode = opentree.SelectedNode;
        TreeNodeCollection childNodes = selectnode.Parent.Nodes;
        int nodeindex = childNodes.IndexOf(selectnode);

        string filepath = sfd.FileName;

        switch (selectnode.Parent.Name)
        {
            case "do3think": my_do3.savefunc(filepath, nodeindex); break;
            case "hikvision": my_hik.savefunc(filepath, nodeindex); break;
            case "mindvision": my_mind.savefunc(filepath, nodeindex); break;
            default: break;
        }
    }
}

关闭相机

        根据选择的节点,关闭对应的相机

private void 关闭相机ToolStripMenuItem_Click(object sender, EventArgs e)
{
    TreeNode selectnode = opentree.SelectedNode;
    TreeNodeCollection childNodes = selectnode.Parent.Nodes;
    int nodeindex = childNodes.IndexOf(selectnode);

    switch (selectnode.Parent.Name)
    {
        case "do3think": my_do3.CameraClose(nodeindex); break;
        case "hikvision": my_hik.CameraClose(nodeindex); break;
        case "mindvision": my_mind.CameraClose(nodeindex); break;
        default: break;
    }

    foreach (PictureBox picture in camerapicture)
    {
        if (picture.Name == selectnode.Text)
        {
            camerapicture.Remove(picture);
            picture.Dispose();
            break;
        }
    }

    opennodes.RemoveAll(node => node.Text == selectnode.Text);
    selectnode.Remove();

    imageshow();
}

显示图像

        窗口添加pannel组件,调整到合适的大小位置。注:该模块引用他人代码,侵权删。

#region 显示模块        
public void onecamera()
{
    //布局对象
    TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();

    //设置布局的列数与行数(1列1行)
    tableLayoutPanel.ColumnCount = 1;
    tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));  //设置百分比

    tableLayoutPanel.RowCount = 1;
    tableLayoutPanel.RowStyles.Add(new ColumnStyle(SizeType.Percent, 100F));  //设置百分比

    //添加控件
    tableLayoutPanel.Controls.Add(camerapicture[0]);
    tableLayoutPanel.Dock = DockStyle.Fill;
    tableLayoutPanel.AutoSize = true;
    //this.Invoke(new AddControlDelegate(AddControl), new object[] { this.panel3, tableLayoutPanel });
    panel3.Controls.Add(tableLayoutPanel);
}

public void twocamera()
{
    //布局对象
    TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();

    //设置布局的行数
    tableLayoutPanel.RowCount = 3;  //分成上下两部分
    tableLayoutPanel.RowStyles.Add(new ColumnStyle(SizeType.Percent, 20F));  //设置百分比
    tableLayoutPanel.RowStyles.Add(new ColumnStyle(SizeType.Percent, 60F));
    tableLayoutPanel.RowStyles.Add(new ColumnStyle(SizeType.Percent, 20F));

    //创建布局器对象
    TableLayoutPanel tableLayUP = new TableLayoutPanel() { Dock = DockStyle.Fill };
    //左右等分(1行2列)
    tableLayUP.ColumnCount = 2;
    tableLayUP.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));  //设置百分比
    tableLayUP.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));

    //添加相机
    tableLayUP.Controls.Add(camerapicture[0], 0, 0);  //行列坐标
    tableLayUP.Controls.Add(camerapicture[1], 1, 0);

    //将上半部分添加到布局器中
    tableLayUP.AutoSize = true;
    tableLayoutPanel.Controls.Add(tableLayUP, 0, 1);

    //添加控件
    tableLayoutPanel.AutoSize = true;
    tableLayoutPanel.Dock = DockStyle.Fill;
    panel3.Controls.Add(tableLayoutPanel);
}

public void threecamera()
{
    //布局对象
    TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();

    //设置布局的行数
    tableLayoutPanel.RowCount = 2;  //分成上下两部分
    tableLayoutPanel.RowStyles.Add(new ColumnStyle(SizeType.Percent, 50F));  //设置百分比
    tableLayoutPanel.RowStyles.Add(new ColumnStyle(SizeType.Percent, 50F));

    //创建布局器对象
    TableLayoutPanel tableLayUP = new TableLayoutPanel() { Dock = DockStyle.Fill };
    //左右等分(1行2列)
    tableLayUP.ColumnCount = 2;
    tableLayUP.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));  //设置百分比
    tableLayUP.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
    //添加相机
    tableLayUP.Controls.Add(camerapicture[0], 0, 0);  //行列坐标
    tableLayUP.Controls.Add(camerapicture[1], 1, 0);

    //将上半部分添加到布局器中
    tableLayoutPanel.Controls.Add(tableLayUP, 0, 0);

    //创建布局器对象
    TableLayoutPanel tableLayDown = new TableLayoutPanel() { Dock = DockStyle.Fill };
    //左中右等分(1行3列)只用中间一列
    tableLayDown.ColumnCount = 3;
    tableLayDown.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 20F));  //设置百分比
    tableLayDown.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 60F));
    tableLayDown.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 20F));
    //添加相机
    tableLayDown.Controls.Add(camerapicture[2], 1, 0);  //行列坐标

    //将下半部分添加到布局器中
    tableLayoutPanel.Controls.Add(tableLayDown, 0, 1);

    //添加控件
    tableLayoutPanel.Dock = DockStyle.Fill;
    panel3.Controls.Add(tableLayoutPanel);
}

public void fourcamera()
{
    //布局对象
    TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();

    //设置布局的行数与列数
    tableLayoutPanel.ColumnCount = 2;
    tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));  //设置百分比
    tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));

    tableLayoutPanel.RowCount = 2;
    tableLayoutPanel.RowStyles.Add(new ColumnStyle(SizeType.Percent, 50F));  //设置百分比
    tableLayoutPanel.RowStyles.Add(new ColumnStyle(SizeType.Percent, 50F));

    //添加lab标签
    tableLayoutPanel.Controls.Add(camerapicture[0], 0, 0);  //行列坐标
    tableLayoutPanel.Controls.Add(camerapicture[1], 1, 0);
    tableLayoutPanel.Controls.Add(camerapicture[2], 0, 1);
    tableLayoutPanel.Controls.Add(camerapicture[3], 1, 1);

    //添加控件
    tableLayoutPanel.Dock = DockStyle.Fill;
    panel3.Controls.Add(tableLayoutPanel);
}

public void imageshow()
{
    panel3.Controls.Clear();

    foreach (PictureBox i in camerapicture)
    {
        i.Dock = DockStyle.Fill;
        i.SizeMode = PictureBoxSizeMode.StretchImage;
    }

    switch (camerapicture.Count)
    {
        case 1: onecamera(); break;
        case 2: twocamera(); break;
        case 3: threecamera(); break;
        case 4: fourcamera(); break;
        default: break;
    }
}
#endregion

  • 12
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在使用Qt加C++显示多个海康相机时,可以通过以下步骤实现: 1. 引入海康相机SDK:首先,在Qt工程中引入海康相机SDK,这可以通过将SDK的头文件和库文件添加到工程中来完成。 2. 创建相机实例:使用SDK提供的接口,创建一个或多个相机实例对象,每个实例都代表一个连接的相机。 3. 设置相机参数:可以通过相机实例对象设置相机的参数,如分辨率、曝光时间、白平衡等。 4. 打开相机连接:使用相机实例对象调用连接相机的函数,打开相机与电脑之间的连接通道。 5. 获取图像数据:通过相机实例对象调用获取图像数据的函数,获取相机实时采集的图像数据。 6. 图像处理与显示:对于每个相机获得的图像数据,可以进行图像处理操作,如图像增强、滤波等。然后,将处理后的图像数据显示在Qt的窗口中。 7. 实时更新显示:通过一个Qt的定时器,不断更新图像显示窗口的内容,以实现相机的实时视频显示效果。 8. 释放资源:在程序退出或相机不再使用时,需要释放相机实例对象和关闭相机连接,以释放资源。 通过以上步骤,我们可以通过Qt加C++实现多个海康相机的显示,每个相机都可以实时显示采集到的图像。当然,具体实现的细节还需根据SDK和Qt库的具体使用方法进行调试和优化。 ### 回答2: Qt是一种跨平台的C++开发框架,而海康相机是指海康威视公司生产的监控相机设备。要使用Qt来显示多个海康相机视频画面,首先需要使用海康SDK提供的API来获取相机的视频数据,然后使用Qt的图像显示组件来展示视频画面。 在Qt中,可以使用QThread类创建一个后台线程来与海康相机进行通信,并获取相机的视频数据。通过在后台线程中运行相机视频数据获取的逻辑,可以实现在主线程中不阻塞的情况下获取视频数据。 在获取到相机的视频数据后,可以将其转换为Qt支持的图像格式,例如QImage,然后使用Qt提供的图像显示组件,如QLabel或QGraphicsView,在界面上显示这些视频画面。 为了显示多个海康相机的视频画面,可以创建多个图像显示组件,然后分别将不同相机的视频数据分配给对应的图像显示组件。可以使用布局管理器来管理这些图像显示组件的位置和大小,以确保它们在界面上合理地排列。 此外,还可以使用一些Qt的UI控件来实现一些功能,例如选择不同相机进行预览、切换不同的预览布局、调整视频画面的参数等。 综上所述,通过使用Qt以及海康SDK提供的API,我们可以在界面上显示多个海康相机的视频画面。这样做可以有效地提高监控系统的可视化能力,并提供更好的用户体验。 ### 回答3: 要在Qt中显示多个海康相机,可以使用Qt的多线程编程以及海康相机SDK来实现。 首先,需要在Qt中创建一个多线程的类来处理海康相机的显示。在这个类中,可以使用海康相机SDK提供的接口来初始化相机,并设置采集参数、图像帧率等。接着,可以通过调用相机的采集函数来获取图像数据。获取到图像数据后,可以通过Qt的图像显示控件来显示图像,例如QLabel或QGraphicsView。 在主线程中,可以创建多个海康相机的实例,并分别将它们传递给多线程类的对象。这样每个相机都在独立的线程中运行,可以同时显示多个相机的图像。 另外,为了避免多个相机的图像显示混乱,可以为每个相机设置一个独立的图像显示控件,在多线程类中将图像数据显示到对应的控件中。 需要注意的是,海康相机SDK一般提供了基于C的编程接口,可以通过在Qt中使用外部C函数来调用这些接口。此外,为了确保相机的正常运行,可能需要在不同相机之间进行同步操作,例如设置采集帧率一致或者设置触发模式。 综上所述,要在Qt中显示多个海康相机,需要使用多线程编程和海康相机SDK来实现相机图像的采集和显示。通过将相机实例传递给多线程类对象,可以在独立的线程中显示每个相机的图像。同时,为了避免图像混乱,可以为每个相机设置独立的图像显示控件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值