【机器视觉C#联合Halcon】

前言:本人小白一个,自学初入C#(可能连初入也不算,哈哈哈),目前从事机器视觉方面的工作,写这篇文章主要是记录自己平时遇到的一些问题,不懂的地方大家多多支持啊!------------持续更新中。

文章目录

  • 一、准备工作
  • 二、操作步骤
    • 1.控件自适应窗口大小
    • 2.图片的平移缩放


学习C#之前,我从事了2年的视觉评估工作,平时主要就是打光测试啊,写写评估报告,拜访客户等简单的工作,用的视觉软件是海康的VM。没有什么技术含量,但是所谓万事开头难,既然入了这一行,那就得珍惜这个机会。后来利用工作之余,慢慢摸索C#,当然现在也在摸索中。
由于不是专业出生,专业知识非常薄弱,要是以后我问出一些弱智问题,望大家不要取笑。
最近我模仿MVS里的例子BasicDemo,准备自己写一个一样的程序,并添加一点其他功能,把目前遇到的一些问题记录下来。


一、准备工作

安装的软件有:VS2015,Halcon18,MVS。
这里我不准备用Halcon来调用相机,而是用MVS的DLL来调用相机,Halcon主要用于图像的处理。

二、操作步骤

找到MVS的例子文件夹,打开BasicDemo例子,具体位置如下,把自己想要的功能复制到自己的程序中(这里我选择直接全部复制,懒得重新写)。
C:\Program Files (x86)\MVS\Development\Samples\C#\BasicDemo

1.控件自适应窗口大小

我添加得第一个功能就是改变窗口大小,里面的控件自适应比例,具体代码如下(来源网络):

class ControlsAutosize
    {
        /*该类包含两个方法:setTag和setControl
         * setTag记录当前窗体控件大小
         * setControl当窗体大小发生改变时,控件随之等比例改变
         */
        public void setTag(Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                con.Tag = con.Width + ";" + con.Height + ";" + con.Left + ";" + con.Top + ";" + con.Font.Size;
                if (con.Controls.Count > 0)
                {
                    setTag(con);
                }
            }
        }
        public void setControls(float newx, float newy, Control cons)
        {
            //遍历窗体中的控件,重新设置控件的值
            foreach (Control con in cons.Controls)
            {
                //获取控件的Tag属性值,并分割后存储字符串数组
                if (con.Tag != null)
                {
                    string[] mytag = con.Tag.ToString().Split(new char[] { ';' });
                    //根据窗体缩放比例确定控件的值
                    con.Width = Convert.ToInt32(System.Convert.ToSingle(mytag[0]) * newx);//宽度
                    con.Height = Convert.ToInt32(System.Convert.ToSingle(mytag[1]) * newy);//高度
                    con.Left = Convert.ToInt32(System.Convert.ToSingle(mytag[2]) * newx);//左边距
                    con.Top = Convert.ToInt32(System.Convert.ToSingle(mytag[3]) * newy);//顶边距
                    Single currentSize = System.Convert.ToSingle(mytag[4]) * newy;//字体大小
                    con.Font = new System.Drawing.Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
                    if (con.Controls.Count > 0)
                    {
                        setControls(newx, newy, con);
                    }
                }
            }
        }
     }

然后再直接调用就行了

//变量定义
        private float x;
        private float y;
public BasicDemo()
        {
            InitializeComponent();
            x = this.Width;
            y = this.Height;
            ControlsAutosize controlsAutosize = new ControlsAutosize();
            controlsAutosize.setTag(this);
        }

在窗体的Resize事件下添加如下代码:

private void BasicDemo_Resize(object sender, EventArgs e)
        {
            float newx = (this.Width) / x;//宽放大倍数
            float newy = (this.Height) / y;//高放大倍数
            ControlsAutosize controlsAutosize = new ControlsAutosize();
            controlsAutosize.setControls(newx, newy, this);
        }

运行效果如下:
【机器视觉C#联合Halcon】_第1张图片

原文链接:https://blog.csdn.net/qq_42002500/article/details/107656851


2.图片的平移缩放

第二个功能为图像显示窗口显示自己想要的图像,并且能够实现平移缩放功能,效果如下:

要实现这个功能,我们要借助Halcon里面的一个控件HWindowControl,添加步骤为工具箱右键–选择项–浏览–找到halcondotnet–完成,最后就可以在工具箱里找到这个控件,可以看到这里其实还有另外一个控件HSmartWindowControl,这个控件也可以用,而且自带平移功能,网上说这个控件不太稳定,但试了一下没什么问题,为了避免以后出现异常,我还是使用的HWindowControl控件。
添加完后,我们再添加一个button,label和contextMenuStrip控件,分别为加载图片,记录鼠标位置,单击鼠标右键弹出菜单栏功能。
为contextMenuStrip1添加适应屏幕和缩放平移两个选项,当单击适应屏幕时,图片将会填充整个图像显示区域,当单击缩放平移时,图片此时才可以进行缩放平移操作,否则将不能进行此项功能,并且把contextMenuStrip1关联到hWindowControl1_ContextMenuStrip属性中。

在适应屏幕ToolStripMenuItem_Click事件添加如下代码:

private void 适应屏幕ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, height - 1, widht - 1);
            HOperatorSet.ClearWindow(hWindowControl1.HalconWindow);
            HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
        }

在缩放平移ToolStripMenuItem_Click事件添加如下代码:

private void 缩放平移ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IsMove = true;
        }

在bnLaodPicture_Click事件添加如下代码:

		//变量定义
		double RowDown;//记录鼠标左键点击图片时的坐标
        double ColDown;//记录鼠标左键点击图片时的坐标
        bool IsMove = false;//判断是否需要平移缩放
        bool MoveFlag;//是否在移动
        HObject ho_Image;//图片变量
        HTuple widht, height;//图片的长和宽
        string path;//文件路径
private void bnLaodPicture_Click(object sender, EventArgs e)
        {
            HOperatorSet.GenEmptyObj(out ho_Image);
            ho_Image.Dispose();
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Multiselect = false;   //是否允许多选
            dialog.Title = "请选择图片";  //窗口title
            dialog.Filter = "*.All|*.*|*.png|*.png*|*.jpg|*.jpg*";   //可选择的文件类型
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                path = dialog.FileName;  //获取文件路径
                HOperatorSet.ReadImage(out ho_Image, path);
                HOperatorSet.GetImageSize(ho_Image, out widht, out height);
                HOperatorSet.SetPart(hWindowControl1.HalconWindow, 0, 0, height - 1, widht - 1);
                hWindowControl1.HalconWindow.DispObj(ho_Image);
            }
        }

在hWindowControl1_HMouseDown事件添加如下代码,这里先判断是否点击菜单栏的缩放平移,再判断是否加载过图片:

private void hWindowControl1_HMouseDown(object sender, HMouseEventArgs e)
        {
            try
            {
                if (IsMove)
                {
                    if (ho_Image != null)
                    {
                        //记录按键按下的坐标点
                        RowDown = e.Y;
                        ColDown = e.X;
                        MoveFlag = true;
                    }
                    else
                    {
                        MessageBox.Show("请先加载图片!", "提示");
                    }
                }
            }
            catch (HalconException HDevExpDefaultException)
            {
                throw HDevExpDefaultException;
            }
        }

在hWindowControl1_HMouseMove事件添加如下代码,这里是当鼠标移动到图像显示区域,记录鼠标的当前位置并算出偏移量,实现图片的平移,平移之前判断鼠标左键是否按下以及MoveFlag是否为true,否则不进行平移;

private void hWindowControl1_HMouseMove(object sender, HMouseEventArgs e)
        {
            HTuple row1, col1, row2, col2;
            label4.Text = "R:" + e.Y.ToString("f1") + " C:" + e.X.ToString("f1");
            try
            {
                if (MoveFlag && e.Button == MouseButtons.Left)
                {
                    double RowOffSet = RowDown - e.Y;
                    double ColumnOffSet = ColDown - e.X;
                    HOperatorSet.ClearWindow(hWindowControl1.HalconWindow);
                    HOperatorSet.GetPart(hWindowControl1.HalconWindow, out row1, out col1, out row2, out col2);
                    HOperatorSet.SetPart(hWindowControl1.HalconWindow, RowOffSet + row1, ColumnOffSet + col1, RowOffSet + row2, ColumnOffSet + col2);
                    HOperatorSet.SetPart(hWindowControl1.HalconWindow, RowOffSet + row1, ColumnOffSet + col1, RowOffSet + row2, ColumnOffSet + col2);
                    HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
                }
            }
            catch (HalconException HDevExpDefaultException)
            {
                throw HDevExpDefaultException;
            }
        }

在hWindowControl1_HMouseUp事件添加如下代码,这里是当鼠标左键松开后,判定移动结束:

private void hWindowControl1_HMouseUp(object sender, HMouseEventArgs e)
        {
            MoveFlag = false;
        }

在hWindowControl1_HMouseWheel事件添加如下代码,这里是监听鼠标滚轮:

private void hWindowControl1_HMouseWheel(object sender, HMouseEventArgs e)
        {
            if (IsMove)
            {
                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(hWindowControl1.HalconWindow, out Row, out Col, out Button);
                HOperatorSet.GetPart(hWindowControl1.HalconWindow, 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(hWindowControl1.HalconWindow, r1, c1, r2, c2);
                    HOperatorSet.ClearWindow(hWindowControl1.HalconWindow);
                    HOperatorSet.DispObj(ho_Image, hWindowControl1.HalconWindow);
                }
            }
        }

至此,图片的平移缩放功能就大功告成了,以上有什么不足之处请谅解,毕竟是小白,如果您有更好的方法,欢迎评论。

最后附上源码:
https://download.csdn.net/download/qq_45072282/85069439


你可能感兴趣的:(c#)