首页 > 其他分享 >Halcon使用入门

Halcon使用入门

时间:2023-11-30 17:37:43浏览次数:39  
标签:HOperatorSet 入门 Image Halcon WindowID ho 使用 public out

  使用WPF并采取MVVM模式

MVVM相关  

  

  添加引用Halcon:

  XAML设计:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="0.8*" />
        <RowDefinition Height="0.2*" />
    </Grid.RowDefinitions>
    <HalconDotNet:HWindowControlWPF x:Name="HWindow" Grid.Row="0" Grid.ColumnSpan="2"
                                    HMouseDown="HWindow_HMouseDown" HMouseMove="HWindow_HMouseMove"
                                    HMouseUp="HWindow_HMouseUp" HMouseWheel="HWindow_HMouseWheel" />
    <Button x:Name="StartBtn" Grid.Row="1" Content="导入" Width="100" Height="50" Command="{Binding Import}"
            CommandParameter="{Binding ElementName=HWindow,Path=HalconWindow}" />
    <Label x:Name="WindowIDLabel" HorizontalAlignment="Left"
           Margin="50,0,0,0"
           Grid.Row="1"
           VerticalAlignment="Center" Width="205" />
</Grid>

  “导入”按钮绑定“Import”命令,传递参数 “CommandParameter="{Binding ElementName=HWindow,Path=HalconWindow}"“暂未用到,因为绑定不成功。

  Command类:

using System;
using System.Windows.Input;

namespace HalconWPFDemo.Common
{
    /// <summary>
    /// 命令类
    /// </summary>
    public class Command : ICommand
    {
        private readonly Action<object> execAction;
        private readonly Func<object, bool> changeFunc;

        public Command(Action<object> execAction, Func<object, bool> changeFunc)
        {
            this.execAction = execAction;
            this.changeFunc = changeFunc;
        }

        #region 实现接口

        /// <summary>
        /// 事件处理器,从名字可以看出来该事件处理器关注于第二个成员,也就是当命令能否执行的状态出现改变时可以使用此事件通知到关注此命令执行状态的成员;
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// 通过这个方法,可以设置命令能不能继续执行,即返回值为TRUE,命令继续执行,返回值为FALSE命令不会执行;
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool CanExecute(object parameter)
        {
            var a = this.changeFunc.Invoke(parameter);
            return this.changeFunc.Invoke(parameter);
        }

        /// <summary>
        /// 命令的执行逻辑放在这个方法里边,当CanExecute返回值为TRUE时,该方法才会被执行。
        /// </summary>
        /// <param name="parameter"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void Execute(object parameter)
        {
            this.execAction.Invoke(parameter);
        }

        #endregion
    }
}

  HalconViewModel类:

using System.ComponentModel;
using System.Windows.Input;
using HalconWPFDemo.Common;
using Microsoft.Win32;

namespace HalconWPFDemo.ViewModel
{
    public class HalconViewModel : INotifyPropertyChanged
    {
        private readonly bool isCanExec = true;

        // private HTuple _windowID;
        //
        // public HTuple WindowID
        // {
        //     get
        //     {
        //         return _windowID;
        //     }
        //     set
        //     {
        //         _windowID = value;
        //         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(WindowID));
        //     }
        // }

        public ICommand Import => new Command(ImportAction, MyCanExec);

        #region 实现接口

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        private void ImportAction(object pramparameter)
        {
            var FilePath = string.Empty;
            var open     = new OpenFileDialog();
            open.Filter      = "图片|*.gif;*.jpg;*.jpeg;*.bmp;*.png;";
            open.Title       = "请选择图片";
            open.Multiselect = false;
            if (open.ShowDialog() == true)
            {
                FilePath = open.FileName;
            }

            var method = new HalconMethod();
            if (!string.IsNullOrEmpty(FilePath))
            {
                method.action(Singleton.Instance().WindowID, FilePath);
            }
        }

        private bool MyCanExec(object pramparameter)
        {
            return isCanExec;
        }
    }
}

Halcon相关:

  MainWindow.xaml.cs:

  在HWindowControlWPF控件的事件中,分别实现HMouseDown(按下鼠标)、HMouseUp(松开鼠标)、HMouseWheel(滑动滚轮)。

using System.Threading.Tasks;
using System.Windows;
using HalconDotNet;
using HalconWPFDemo.Common;
using HalconWPFDemo.ViewModel;

namespace HalconWPFDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private double       ColDown; //鼠标按下时的列坐标
        public  HalconMethod halconMethod = new HalconMethod();
        private double       RowDown; //鼠标按下时的行坐标

        public MainWindow()
        {
            InitializeComponent();
            DataContext = new HalconViewModel();

            //初始化Halcon控件
            Task.Delay(500).ContinueWith(t => // 等待500毫秒
            {
                while (Singleton.Instance().WindowID == null)
                {
                    Singleton.Instance().WindowID = HWindow.HalconWindow;
                    Dispatcher?.Invoke(() =>
                    {
                        WindowIDLabel.Content = "WindowID: " + Singleton.Instance().WindowID;
                    });
                }
            }, TaskContinuationOptions.OnlyOnRanToCompletion);
        }

        private void HWindow_HMouseMove(object sender, HMouseEventArgsWPF e)
        {
        }

        /// <summary>
        /// 松开鼠标按键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HWindow_HMouseUp(object sender, HMouseEventArgsWPF e)
        {
            if (HalconMethod.ho_Image != null)
            {
                halconMethod.HmouseUp(Singleton.Instance().WindowID, RowDown, ColDown);
            }
        }

        /// <summary>
        /// 滚轮滑动,缩放图像
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HWindow_HMouseWheel(object sender, HMouseEventArgsWPF e)
        {
            if (HalconMethod.ho_Image != null)
            {
                halconMethod.Zoom(Singleton.Instance().WindowID, e);
            }
        }

        /// <summary>
        /// 鼠标按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HWindow_HMouseDown(object sender, HMouseEventArgsWPF e)
        {
            if (HalconMethod.ho_Image != null)
            {
                HTuple Row, Column, Button;
                HOperatorSet.GetMposition(Singleton.Instance().WindowID, out Row, out Column, out Button);
                RowDown = Row;    //鼠标按下时的行坐标
                ColDown = Column; //鼠标按下时的列坐标
            }
        }
    }
}

  单例类:

  主要用于记录并传递HWindowControlWPF控件的HalconWindow值,即作为控件的标识符。

using HalconDotNet;

namespace HalconWPFDemo.Common
{
    public class Singleton
    {
        /// <summary>
        /// Halcon控件的HalconWindow值
        /// </summary>
        public HTuple WindowID { get; set; }

        #region 单例方法

        private static Singleton instance;

        private Singleton()
        {
        }

        public static Singleton Instance()
        {
            if (instance == null)
            {
                lock (typeof(Singleton))
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }

            return instance;
        }

        #endregion
    }
}

  HalconMethod类:

using System.Windows;
using HalconDotNet;

namespace HalconWPFDemo.Common
{
    public class HalconMethod
    {
        public static HObject ho_Image, ho_ImageEmphasize, ho_GrayImage, ho_Regions;

        public static HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
        //private  HObject ho_Image, ho_ImageEmphasize;
        //private  HTuple hv_Width = new HTuple(), hv_Height = new HTuple();

        /// <summary>
        /// Halcon导入并显示图片
        /// </summary>
        public void action(HTuple WindowID, string FilePath)
        {
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_ImageEmphasize);
            HOperatorSet.GenEmptyObj(out ho_GrayImage);
            HOperatorSet.GenEmptyObj(out ho_Regions);

            ho_Image.Dispose();
            HOperatorSet.ReadImage(out ho_Image, FilePath);
            hv_Width.Dispose();
            hv_Height.Dispose();
            HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);

            //转换灰度图
            ho_GrayImage.Dispose();
            HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage); //RGB转为灰度图
            ho_Image = ho_GrayImage;

            // 增强图像的对比度,基于拉普拉斯算子来进行边缘增强
            ho_ImageEmphasize.Dispose();
            HOperatorSet.Emphasize(ho_Image, out ho_ImageEmphasize, 7, 7, 2);
            ho_Image = ho_ImageEmphasize;

            //二值化
            ho_Regions.Dispose();
            HOperatorSet.Threshold(ho_Image, out ho_Regions, 77, 250);
            ho_Image = ho_Regions;

            //显示全部图像
            HOperatorSet.SetPart(WindowID, 0, 0, hv_Height - 1, hv_Width - 1);
            HOperatorSet.ClearWindow(WindowID);
            HOperatorSet.DispObj(ho_Image, WindowID); //显示图像

            //ho_Image.Dispose();
            //ho_ImageEmphasize.Dispose();
            hv_Width.Dispose();
            hv_Height.Dispose();
        }
        
         /// <summary>
         /// 移动图像
         /// </summary>
         /// <param name="WindowID"></param>
         /// <param name="RowDown"></param>
         /// <param name="ColDown"></param>
        public void HmouseUp(HTuple WindowID, double RowDown, double ColDown)
        {
            HTuple row1, col1, row2, col2, Row, Column, Button;

            HOperatorSet.GetMposition(WindowID, out Row, out Column, out Button);

            double RowMove = Row    - RowDown;                                                              //鼠标弹起时的行坐标减去按下时的行坐标,得到行坐标的移动值
            double ColMove = Column - ColDown;                                                              //鼠标弹起时的列坐标减去按下时的列坐标,得到列坐标的移动值
            HOperatorSet.GetPart(WindowID, out row1, out col1, out row2, out col2);                         //得到当前的窗口坐标
            HOperatorSet.SetPart(WindowID, row1 - RowMove, col1 - ColMove, row2 - RowMove, col2 - ColMove); //这里可能有些不好理解。以左上角原点为参考点
            HOperatorSet.ClearWindow(WindowID);
            if (hv_Height != null && ho_Image != null)
            {
                HOperatorSet.DispObj(ho_Image, WindowID);
            }
            else
            {
                MessageBox.Show("请加载一张图片");
            }
        }

        /// <summary>
        /// 缩放图像
        /// </summary>
        /// <param name="WindowID"></param>
        /// <param name="e"></param>
        public void Zoom(HTuple WindowID, HMouseEventArgsWPF e)
        {
            HTuple Zoom, Row,     Col,   Button;
            HTuple Row0, Column0, Row00, Column00, Ht, Wt, r1, c1, r2, c2;
            if (e.Delta > 0)
            {
                Zoom = 1.5;
            }
            else
            {
                Zoom = 0.5;
            }

            HOperatorSet.GetMposition(WindowID, out Row, out Col, out Button);
            HOperatorSet.GetPart(WindowID, out Row0, out Column0, out Row00, out Column00);
            Ht = Row00    - Row0;
            Wt = Column00 - Column0;
            if (Ht * Wt < 32000 * 32000 || Zoom == 1.5) //普通版halcon能处理的图像最大尺寸是32K*32K。如果无限缩小原图像,导致显示的图像超出限制,则会造成程序崩溃
            {
                r1 = Row0    + (1 - 1.0 / Zoom) * (Row - Row0);
                c1 = Column0 + (1 - 1.0 / Zoom) * (Col - Column0);
                r2 = r1      + Ht               / Zoom;
                c2 = c1      + Wt               / Zoom;
                HOperatorSet.SetPart(WindowID, r1, c1, r2, c2);
                HOperatorSet.ClearWindow(WindowID);
                if (ho_Image != null && WindowID != null)
                {
                    HOperatorSet.DispObj(ho_Image, WindowID);
                }
            }
        }
    }
}

  算子解释:

  HOperatorSet.GenEmptyObj(out ho_Image):类似于实例化对象;

  HOperatorSet.ReadImage(out ho_Image, FilePath):读取FilePath路径的图片,并传入到ho_Image中;

  HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height):获取图像尺寸,并将长和宽分别传入到hv_Width和hv_Height中;

  HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage):将RGB图像转换为灰度图像,ho_GrayImage即获得的灰度图;

  HOperatorSet.Emphasize(ho_Image, out ho_ImageEmphasize, 7, 7, 2):增强图像的对比度,基于拉普拉斯算子来进行边缘增强。Image:输入的要增强的图像;ImageEmphasize:输出的对比度增强的图像; MaskWidth, MaskHeight:输入的掩膜宽度、高度;

  HOperatorSet.Threshold(ho_GrayImage, out ho_Regions, 77, 250):二值化,通过确定 MinGray(最小灰度)和 MaxGray(最大灰度)值对一幅灰度图像进行分割,满足区域灰度值介于最小最大之间的图像区域保存至 Region 变量中。满足条件的区域在图像上显示的灰度值为白色,不满足的则为黑色。这个例子表示灰度值在77到250的为白色,其他为黑色;

  HOperatorSet.SetPart(WindowID, 0, 0, hv_Height - 1, hv_Width - 1):将全部图像显示到控件中。从(0,0)坐标处到(hv_Height - 1, hv_Width - 1)坐标处的图像区域显示到图像控件中;

   测试结果:

标签:HOperatorSet,入门,Image,Halcon,WindowID,ho,使用,public,out
From: https://www.cnblogs.com/shieryoufeng/p/17867614.html

相关文章

  • 面向对象---入门级(最基础的部分)python
    #面向对象---入门#思想或者宗旨:抽象、封装、继承、多态#完成对一个类的创建,(先抽象)(类名一般大写)classStudent:name=""age=""sex=""score=""#访问类里的元素name="李四"Student.name="张三"print(Student.name)print(name)#name=“......
  • 当多个使用弹窗类组件,可使用这种方式封装组件。(以下使用antd-vue、vue3)
    1.代码点击查看代码<template><slot:openDialog="openDialog":closDialog="modalCancel"></slot><a-modalv-model:open="open"title="BasicModal"@cancel="modalCancel"><templat......
  • XmlRPC入门_组合类型操作
    1、数组操作#include<iostream>#include<winsock2.h>#include<windows.h>#include<xmlrpc-c/base.hpp>#include<xmlrpc-c/registry.hpp>#include<xmlrpc-c/server_abyss.hpp>#include<direct.h>#include<stdio.h&......
  • 【DFS深度优先遍历】给定一个数组,从第一个开始,正好走到数组最后,所使用的最少步骤数
    题目描述给定一个数组,从第一个开始,正好走到数组最后,所使用的最少步骤数。要求:第一步从第一元素开始,第一步小于<len/2(len为数组的长度)。从第二步开始,只能以所在成员的数字走相应的步数,不能多也不能少,如果目标不可达返回-1,输出最少的步骤数,不能往回走。输入759426835......
  • MAUI中使用ECharts数据可视化显示
    一、ECharts简介ECharts是一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。ECharts最初由百度团队开源,ECharts遵循Apache-2.0开源协议,免费商用。官网:https://echarts.apache.org/zh/index.html示例论坛:https://www.makeapie.cn/echar......
  • Jmeter接口自动化测试 —— Jmeter变量的使用
    ​在使用jmeter进行接口测试时,我们难免会遇到需要从上下文中获取测试数据的情况,这个时候就需要引入变量了。定义变量添加->配置元件->用户自定义的变量添加->配置元件->CSV数据文件设置变量的调用方式:${变量名}变量的作用范围:变量可以写入任何测试组件的任何字段中(除了T......
  • Unity 文字转语音 Microsoft Interop.SpeechLib使用
    需要提前做以下设置:Unity中需要设置:Editor->ProjectSettings->Player->OtherSettings->ApiCompatibilityLevel->选择.Net4.x系统需要提前下载中文语音包Win11可以在设置->时间和语言->语音中查看已下载的语音其中HuihuiYaoyaoKangkang为中文语音......
  • 使用keepalive针对页面缓存的一些问题的解决方法
    场景介绍在项目前端设计中有一个需求,需要跳转到其他页面先拿到数据,再返回到原界面,但是原界面填写的数据会被刷新,因此在这个地方需要对页面的数据进行缓存需求分析项目使用的是Vue3,对于页面缓存,在网上搜索后锁定了keepAlive做缓存简介keep-alive是Vue的内置组件,当它包裹动态组......
  • 如何在vscode环境下使用arduino?
    如何在vscode环境下使用arduino?下载Arduino软件在Arduino官网下载最新的Arduino软件(2.0版本以上)。在下载Arduino之后,电脑中会出现两个非常重要的文件夹:C:\Users\用户名\Documents\Arduino这个文件夹中会存放你安装的一些第三方库的文件等。C:\Users\用户名\AppData\Loca......
  • XmlRPC入门_基本类型操作
    #include<iostream>#include<winsock2.h>#include<windows.h>#include<xmlrpc-c/base.hpp>#include<xmlrpc-c/registry.hpp>#include<xmlrpc-c/server_abyss.hpp>#include<direct.h>#include<stdio.h>#inc......