HSmartWindowControl 之 摄像头实时显示( 使用 WPF )

简介: 原文:HSmartWindowControl 之 摄像头实时显示( 使用 WPF )1、添加Halcon控件,创建WPF项目在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见:HSmartWindowControl之安装篇 (Visual Studio 2013 & Halcon 18)在WPF工程中添加好HSmartWindowControlWPF控件后,将其拖入主窗体即可。
原文: HSmartWindowControl 之 摄像头实时显示( 使用 WPF )

1、添加Halcon控件,创建WPF项目

在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见:

HSmartWindowControl之安装篇 (Visual Studio 2013 & Halcon 18)

在WPF工程中添加好HSmartWindowControlWPF控件后,将其拖入主窗体即可。

2、生成摄像头实时显示的halcon代码

使用Image Acquisition 连接笔记本自带的摄像头,然后生成实时显示的代码即可:

* Image Acquisition 01: Code generated by Image Acquisition 01
open_framegrabber ('DirectShow', 1, 1, 0, 0, 0, 0, 'default', 8, 'rgb', -1, 'false', 'default', '[0] Integrated Camera', 0, -1, AcqHandle)
grab_image_start (AcqHandle, -1)
while (true)
    grab_image_async (Image, AcqHandle, -1)
    * Image Acquisition 01: Do something
endwhile

3、导出C#代码

这里主要关注action函数:

// Main procedure 
  private void action()
  {
    // Local iconic variables 
    HObject ho_Image=null;
    // Local control variables 
    HTuple hv_AcqHandle = new HTuple();
    // Initialize local and output iconic variables 
    HOperatorSet.GenEmptyObj(out ho_Image);
    //Image Acquisition 01: Code generated by Image Acquisition 01
    //Image Acquisition 01: Attention: The initialization may fail in case parameters need to
    //Image Acquisition 01: be set in a specific order (e.g., image resolution vs. offset).
    hv_AcqHandle.Dispose();
    HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", 
        -1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_AcqHandle);

    HOperatorSet.GrabImageStart(hv_AcqHandle, -1);
    while ((int)(1) != 0)
    {
      ho_Image.Dispose();
      HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
      //Image Acquisition 01: Do something
    }
    ho_Image.Dispose();

    hv_AcqHandle.Dispose();

  }

这段代码只是实现了采集图像,没有在界面上显示。

4、向VS项目添加halcon导出的c#代码

向action()的代码中添加在窗口上显示图像的代码,即使用DispObj函数。然后把action添加到按钮响应中执行。

这样点击按钮之后就会进入死循环不停的GrabImage和DispObj,但是实际操作时界面会停止响应,而且图像并不会在窗口内刷新。

5、添加实时显示子线程

主线程中运行循环无法实时显示,必须创建子线程。

这里使用了工作者线程,点击按钮后,启动线程并执行一个循环显示采集的图像;再次点击按钮时,跳出循环结束worker线程。然后继续点击按钮又可以进入子线程开启实时显示,实现随意启停。

private void Button1_Click(object sender, RoutedEventArgs e)
        {
            if (isCameraOpened == false)
            {
                Button1.Content = "关闭实时显示";
                isCameraOpened = true;
                play_Thread = new Thread(action);
                play_Thread.Start();
            }
            else
            {
                Button1.Content = "开启实时显示";
                isCameraOpened = false;
            }            
        }

注意调用线程需添加引用:

using System.Threading;//多线程

需要注意的是,为了防止在实时显示过程中突然关闭窗体导致程序崩溃,在窗体的Un_load事件中加入强行停止子线程的代码。

private void Window_Unloaded(object sender, RoutedEventArgs e)
        {
            if(play_Thread.IsAlive)
            {
                play_Thread.Abort();
            }
        }

6、调整图像尺寸以适应halconwindow窗口

(1)使用HSmartWindowControlWPF控件时,无需再添加鼠标滚轮的响应函数便可使用鼠标滚轮控制图像缩放。

(2)显示单张图像时,可以直接向HSmartWindowControlWPF控件的HDisplayCurrentObject属性赋HObject类型的图像即可自动调整图像尺寸来适应窗口大小。

hSmartWindowControl1.HDisplayCurrentObject = new HImage("girl.png");

但是这个方式不能适用于动态捕获的图像,所以动态捕获的图像还需要手动判断来进行缩放。调整的方式比较简单,就是获取窗口尺寸和图像尺寸进行对比,根据图像过宽还是过高来缩放。

7、源代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HalconDotNet;
using System.Threading;//多线程

namespace HalconWindowWPFDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region 全局变量
        private static MainWindow mainWindow = new MainWindow();
        private static HWindow hwindow; //全局窗口变量
        Thread play_Thread; //实时显示线程
        private static bool isCameraOpened; //是否正在实时显示
        private static double halconWindowHeight; //halcon窗口高度
        private static double halconWindowWidth; ////halcon窗口宽度
        #endregion

        #region 初始化
        public MainWindow()
        {
            InitializeComponent();           
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            hwindow = hSmartWindowControl1.HalconWindow;//初始化窗口变量          
            isCameraOpened = false;
            //获取halcon窗口大小
            halconWindowHeight = mainWindow.hSmartWindowControl1.WindowSize.Width;
            halconWindowWidth = mainWindow.hSmartWindowControl1.WindowSize.Height;      
        }
        #endregion

        #region 界面响应
        /// <summary>
        /// 开启和关闭实时显示按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button1_Click(object sender, RoutedEventArgs e)
        {
            if (isCameraOpened == false)
            {
                Button1.Content = "关闭实时显示";
                isCameraOpened = true;
                play_Thread = new Thread(action);
                play_Thread.Start();
            }
            else
            {
                Button1.Content = "开启实时显示";
                isCameraOpened = false;
            }
            
        }
        /// <summary>
        /// 显示一张图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button2_Click(object sender, RoutedEventArgs e)
        {
            hSmartWindowControl1.HDisplayCurrentObject = new HImage("girl.png");
        }
        #endregion

        #region 实时显示用函数
        /// <summary>
        /// 摄像头实时显示
        /// </summary>
        private static void action()
        {
            // Local iconic variables 
            HObject ho_Image = null;
            // Local control variables 
            HTuple hv_AcqHandle = new HTuple();
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_Image);
            ho_Image.Dispose();
            hv_AcqHandle.Dispose();
            //Image Acquisition 01: Code generated by Image Acquisition 01          
            HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
                -1, "false", "default", "[0] Integrated Camera", 0, -1, out hv_AcqHandle);
            HOperatorSet.GrabImageStart(hv_AcqHandle, -1);                 

            while (isCameraOpened)
            {            
                HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1);
                if (!mainWindow.ShowHalconImage(ho_Image)) break;
            }
            ho_Image.Dispose();
            hv_AcqHandle.Dispose();
        }
        /// <summary>
        /// 显示图像
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        private bool ShowHalconImage(HObject ho_Image)
        {           
            #region 缩放图像,适应窗口           
            //获取图像大小及纵横比
            HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
            HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
            int im_width = int.Parse(hv_Width.ToString());
            int im_height = int.Parse(hv_Height.ToString());
            double im_AspectRatio = (double)(im_width) / (double)(im_height);
            //获取窗口大小及纵横比        
            double w_AspectRatio = halconWindowWidth / halconWindowHeight;

            HOperatorSet.SetSystem("int_zooming", "false");//图像缩放之前最好将此参数设置为false.
            HTuple para = new HTuple("constant");
            HObject ho_zoomImage;
            HOperatorSet.GenEmptyObj(out ho_zoomImage);

            ho_zoomImage.Dispose();
            if (halconWindowWidth < im_width && im_AspectRatio > w_AspectRatio)
            {
                //超宽图像               
                HOperatorSet.ZoomImageSize(ho_Image, out ho_zoomImage, halconWindowWidth, halconWindowWidth / im_AspectRatio, "constant");             
            }
            else if (halconWindowHeight < im_height && im_AspectRatio < w_AspectRatio)
            {
                //超高图像                
                HOperatorSet.ZoomImageSize(ho_Image, out ho_zoomImage, halconWindowHeight * im_AspectRatio, halconWindowHeight, para);
            }
            #endregion

            #region 显示图像                   
            try
            {
                hwindow.SetPart(0, 0, -2, -2); 
                hwindow.DispObj(ho_zoomImage);
            }
            catch (Exception exp)
            {
                //MessageBox.Show(exp.ToString());
                return false;
            }
            #endregion
            return true;            
        }
        #endregion

        #region 析构函数
        /// <summary>
        /// 关闭窗体时推出子线程,防止崩溃
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Unloaded(object sender, RoutedEventArgs e)
        {
            if(play_Thread.IsAlive)
            {
                play_Thread.Abort();
            }
        }
        #endregion
    }
}
目录
相关文章
|
编解码 开发工具 C语言
Qt编写自定义控件10-云台仪表盘
一、前言 做过安防视频监控的同学都清楚,在视频监控系统软件上都可以看到一个云台控制区域,可以对球机进行下下左右等八个方位的运动控制,还可以进行复位,一般都是美工作图好,然后贴图的形式加入到软件中,好处是程序简单,界面美工,主要取决于美工的美图能力,缺点是对于各种分辨率的适应性稍微差点,需要不同的图片切图贴图,除非默认做好的是大图自适应看不出差别,可能大部分人所在的公司都是小公司,一般美工人员比较少甚至没有,都需要程序员一人负责,甚至一开始就要考虑到各种分辨率的应用场景以及后期可能的换肤换色等。
1342 0
|
C# 编解码
WPF C# 多屏情况下,实现窗体显示到指定的屏幕内
原文:WPF C# 多屏情况下,实现窗体显示到指定的屏幕内 针对于一个程序,需要在两个显示屏上显示不同的窗体,(亦或N个显示屏N个窗体),可以使用如下的方式实现。
4674 0
|
7月前
|
监控 C# C++
VS+C#+WPF多线程视频摄像头播放器监控
VS+C#+WPF多线程视频摄像头播放器监控
164 0
VS+C#+WPF多线程视频摄像头播放器监控
|
7月前
|
数据采集 开发工具 图形学
Windows平台实现Unity下窗体|摄像头|屏幕采集推送
随着Unity3D的应用范围越来越广,越来越多的行业开始基于Unity3D开发产品,如传统行业中虚拟仿真教育、航空工业、室内设计、城市规划、工业仿真等领域。
|
3月前
|
C#
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
69 1
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
|
存储 JSON 移动开发
基于Qt的网络音乐播放器(五)实现歌词滚动显示
基于Qt的网络音乐播放器(五)实现歌词滚动显示
基于Qt的网络音乐播放器(五)实现歌词滚动显示
|
C# 数据格式 算法
C# WPF 歌词控件(支持逐字定位描色效果)
原文:C# WPF 歌词控件(支持逐字定位描色效果) 之前做了一个模仿网易云歌词的控件,实现了加载网易云歌词并能随音乐播放进度定位歌词。今天呢将在这个控件的基础上增加逐字定位描色功能,如下图效果(QQ音乐PC)所示:   我所使用的实现方法很简单粗暴,把每句歌词每个字切开,单独显示在一个描色的控件中,然后拼成一行完整的歌词,随音乐播放进度去找相应的字进行描色。
1332 0
|
C#
WPF中利用RadialGradient模拟放大镜效果
原文:WPF中利用RadialGradient模拟放大镜效果 --------------------------------------------------------------------------------引用时请保留以下信息:大可山 [MSN:a3news(AT)hotmail.
989 0
|
C# 开发工具 编解码
WPF中在摄像头视频上叠加控件的解决方案
原文:WPF中在摄像头视频上叠加控件的解决方案 一、视频呈现   前段时间,在一个wpf的项目中需要实时显示ip摄像头,对此的解决方案想必大家都应该知道很多。在winform中,我们可以将一个控件(一般用panel或者pictruebox)的句柄丢给摄像头的sdk以实现该功能,而在wpf中我们同样可以使用该方案快速实现。
1338 0
|
C# C++ 计算机视觉
WPF特效-绘制实时2D激光雷达图
原文:WPF特效-绘制实时2D激光雷达图 接前两篇: https://blog.csdn.net/u013224722/article/details/80738619 https://blog.csdn.net/u013224722/article/details/80738995 除了c# GDI 、Opencv(c++)、 c# Emgu绘图外,其实c#  WPF绘图功能也很强大。
1816 0