Lua做为内嵌脚本调用halcon算子

勇哥注:

把C#做为Lua的宿主,然后把把halcon算子封装成Lua的功能函数,就可以创建内嵌脚本。

你可以随时修改脚本,然后继续运行程序,实时生效。

或者你也可以指一个命令行窗口,以指令方式去执行封装好的Lua的功能函数,起到调试的效果。

内嵌脚本的好处是可以运行时暂停设备后,修改脚本后可以继续运行,这样不用为了修改功能而关闭软件,再修改软件后重新编译。这样可以非常灵活的在线修改逻辑。

以上的效果类似于Epson机器人的内嵌VB脚本语言,此模式在业内被大量应用。


(一)先写一段C#调用halcon功能的代码


如下,非常简单,只有打开相机、抓照、连续抓拍、停止抓拍   四个动作。

我们计划封装出来的Lua函数也做这个4个动作。

image.png

下面是C# 代码:

using HalconDotNet;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private HTuple ccdHandle = new HTuple();
        public Form1()
        {
            InitializeComponent();
            ccdHandle.Dispose();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
            -1, "false", "default", "[0] USB Camera", 0, -1, out ccdHandle);
            HOperatorSet.GrabImage(out HObject img, ccdHandle);
            HOperatorSet.GetImageSize(img, out HTuple width, out HTuple height);
            hWin.HalconWindow.SetPart(new HTuple(0), new HTuple(0), height, width);
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            HObject img;
            HOperatorSet.GenEmptyObj(out img);
            img.Dispose();
            HOperatorSet.GrabImage(out img, ccdHandle);
            hWin.HalconWindow.DispObj(img);
            img.Dispose();
        }

        private bool QuitGrab = false;
        private void button3_Click(object sender, EventArgs e)
        {
           
            QuitGrab = false;
            HObject img;
            HOperatorSet.GenEmptyObj(out img);
            img.Dispose();
            HOperatorSet.GrabImageStart(ccdHandle, -1);
            Task.Factory.StartNew(() =>
            {
                while (!QuitGrab)
                {
                    HOperatorSet.GrabImageAsync(out img, ccdHandle, -1);
                    hWin.HalconWindow.DispObj(img);
                    img.Dispose();   //(1)
                    Thread.Sleep(5);
                }
                img.Dispose();
            });
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            HOperatorSet.CloseFramegrabber(ccdHandle);
            ccdHandle.Dispose();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            QuitGrab = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;
        }
    }
}

注:

(1)注意 这句img.Dispose();  非常重要,在异常连续拍图时,如果没有这句,你的内存会像坐火箭一样向上升。

(2)演示时勇哥用的是VS2017+halcon19.11


(二)改造成Lua内嵌脚本


改造效果如下:

image.png


脚本编辑框中,可以以Lua的语法调用下面几个函数:

init()    //初始化相机

grab()   //拍照

cgrab()   //连续拍图

stop()    //停止连续拍图

close()   //关闭设备


有关Lua语言的介绍及简易语法说明见下面贴子:

Lua语法的代码演示

http://www.skcircle.com/?id=2259


实时指令那个文本框内,你可以直接敲入上面的函数名(不带括号),回车即可以执行。


源代码:

using HalconDotNet;
using NLua;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private Lua Luas = new Lua();
        // lua脚本的地址
        private string LuaPath;

        HalconFun halcon = HalconFun.Instance;

        public Form1()
        {
            InitializeComponent();
            halcon.SetHwin(this.hWin);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            halcon.init();
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            halcon.grab();
        }

      
        private void button3_Click(object sender, EventArgs e)
        {
            halcon.cgrab();
           
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            halcon.close();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            halcon.stop();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Luas.State.Encoding = Encoding.UTF8;
            LoadLua();

            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;
        }

        private void LoadLua()
        {
            try
            {
                Luas.LoadCLRPackage();
                Luas.DoString(richTextBox1.Text);

                // 注册C#函数供Lua调用
                //Luas.RegisterFunction("CSharpFunction", this, typeof(Form1).GetMethod("CSharpFunction"));
                //lua.RegisterFunction 注册静态方法(注册到Lua中以后方法的名称,空,程序的类型 typeof(Program).(传入C#中的方法名:需要是公有方法))
                Luas.RegisterFunction("msgshow", null, typeof(MessageBox).GetMethod("Show", new[] { typeof(string) }));

                Luas.RegisterFunction("init", halcon, typeof(HalconFun).GetMethod("init"));
                Luas.RegisterFunction("grab", halcon, typeof(HalconFun).GetMethod("grab"));
                Luas.RegisterFunction("cgrab", halcon, typeof(HalconFun).GetMethod("cgrab"));
                Luas.RegisterFunction("stop", halcon, typeof(HalconFun).GetMethod("stop"));
                Luas.RegisterFunction("close", halcon, typeof(HalconFun).GetMethod("close"));

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            try
            {
                Luas.LoadCLRPackage();
                Luas.DoString(richTextBox1.Text);
                MessageBox.Show("重载成功!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                Luas.GetFunction("LuaFunction").Call();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            this.textBox1.Text = "";
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == (char)Keys.Enter)//设置监听键为回车
            {
               switch(this.textBox1.Text)
                {
                    case "init":
                        halcon.init();
                        break;
                    case "grab":
                        halcon.grab();
                        break;
                    case "cgrab":
                        halcon.cgrab();
                        break;
                    case "stop":
                        halcon.stop();
                        break;
                    case "close":
                        halcon.close();
                        break;
                }
            }

        }
    }

    public class HalconFun
    {
        private static readonly Lazy<HalconFun> lazyInstance = new Lazy<HalconFun>(() => new HalconFun());

        public static HalconFun Instance => lazyInstance.Value;

        private HTuple ccdHandle = new HTuple();

        private HWindowControl myHwin;

        private bool QuitGrab = false;

        HalconFun()
        {

        }

        public void SetHwin(HWindowControl _win)
        {
            this.myHwin = _win;
        }

        public void init()
        {
            HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
          -1, "false", "default", "[0] USB Camera", 0, -1, out ccdHandle);
            HOperatorSet.GrabImage(out HObject img, ccdHandle);
            HOperatorSet.GetImageSize(img, out HTuple width, out HTuple height);
            myHwin.HalconWindow.SetPart(new HTuple(0), new HTuple(0), height, width);
        }

        public void grab()
        {
            HObject img;
            HOperatorSet.GenEmptyObj(out img);
            img.Dispose();
            HOperatorSet.GrabImage(out img, ccdHandle);
            myHwin.HalconWindow.DispObj(img);
            img.Dispose();
        }

        public void cgrab()
        {
            QuitGrab = false;
            HObject img;
            HOperatorSet.GenEmptyObj(out img);
            img.Dispose();
            HOperatorSet.GrabImageStart(ccdHandle, -1);
            Task.Factory.StartNew(() =>
            {
                while (!QuitGrab)
                {
                    HOperatorSet.GrabImageAsync(out img, ccdHandle, -1);
                    myHwin.HalconWindow.DispObj(img);
                    img.Dispose();
                    Thread.Sleep(5);
                }
                img.Dispose();
            });
        }

        public void stop()
        {
            QuitGrab = true;
        }

        public void close()
        {
            HOperatorSet.CloseFramegrabber(ccdHandle);
            ccdHandle.Dispose();
        }


    }
}


勇哥注:

init函数里勇哥是halcon方式初始化了手里的一个usb相机。

你可以把它换成你自己的相机,或者改成文件。



可执行的源码下载:

支付10元或购买VIP会员后,才能查看本内容!立即支付升级会员查询订单





本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2024-05-04 18:56:33 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年5月    »
12345
6789101112
13141516171819
20212223242526
2728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864