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
        }
    }
  • 相关阅读:
    快速幂 --- CSU 1556: Jerry's trouble
    iOS masonry 不规则tagView布局 并自适应高度
    iOS 渐变色实现,渐变色圆环,圆环进度条
    iOS scrollView中嵌套多个tableView处理方案
    iOS 多网络请求同步并发
    iOS UIView添加阴影
    什么是比特币,什么是区块链,什么是挖矿,为什么要挖?关于比特币,关于区块链,你想要知道的
    Xcode wifi连接真机调试
    iOS 添加WKWebView导致控制器无法释放的问题
    解决百度网盘非会员下载速度限制的完整方案
  • 原文地址:https://www.cnblogs.com/oucsheep/p/9626923.html
Copyright © 2011-2022 走看看