zoukankan      html  css  js  c++  java
  • 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
        }
    }
  • 相关阅读:
    2、容器初探
    3、二叉树:先序,中序,后序循环遍历详解
    Hebbian Learning Rule
    论文笔记 Weakly-Supervised Spatial Context Networks
    在Caffe添加Python layer详细步骤
    论文笔记 Learning to Compare Image Patches via Convolutional Neural Networks
    Deconvolution 反卷积理解
    论文笔记 Feature Pyramid Networks for Object Detection
    Caffe2 初识
    论文笔记 Densely Connected Convolutional Networks
  • 原文地址:https://www.cnblogs.com/oucsheep/p/9626923.html
Copyright © 2011-2022 走看看