C#_Halcon 实现对图像的处理

 通过C#与Halcon混编实现图像的显示、ROI区域画圆、通过线程采集本地图像、计算圆形区域的半径、UI显示计算结果、存储结果到本地csv文件。

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


namespace HalconDemo
{
    public partial class Form1 : Form
    {
        private HTuple WindowID;
        private HObject Image;
        //存放图像的数组
        private HObject[] ImageArrary = new HObject[8];
        //线程对象
        private Thread ThreadObject;

        //线程停止标记
        private bool Thread_Stop = false;
        public Form1()
        {
            InitializeComponent();
            Image = new HObject();

            CreateHalconWindow();
            // LoadImage();
            LoadBatchImage();
            ThreadObject = new Thread(new ThreadStart(PlayThread));
            //允许跨线程访问界面
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
        }

        public void PlayThread()
        {
            int i = 0;
            Thread_Stop = false;
            HTuple width = null, height = null;
            while (!Thread_Stop)
            {
                HOperatorSet.DispObj(ImageArrary[i], WindowID);
                //获取图像大小
                HOperatorSet.GetImageSize(ImageArrary[i], out width, out height);
                //缩放图像适应窗口
                HOperatorSet.SetPart(WindowID, 0, 0, height, width);

               double circleRadius =  CaculateCircleR(ImageArrary[i]);

                if (circleRadius >= 311&& circleRadius <= 313)//PASS
                {
                    //更新结果到UI上
                    UpdatetestResult(i.ToString() + '@' + circleRadius.ToString() +"@PASS");
                    //保存数据
                    SaveResult("编号,半径,测试结果", i.ToString() + ',' + circleRadius.ToString() + ",PASS");
                    //保存图像
                    string fileName = DateTime.Now.ToString("yyyy年MM月dd日mm分ss秒fff毫秒");
                    HOperatorSet.WriteImage(ImageArrary[i], "bmp", 0, "image/" + fileName + ".bmp");
                }
                else//NG
                {
                    //更新结果到UI上
                    UpdatetestResult(i.ToString() + '@' + circleRadius.ToString() + "@NG");
                    //保存数据
                    SaveResult("编号,半径,测试结果", i.ToString() + ',' + circleRadius.ToString() + ",NG");
                    //保存图像
                    string fileName = DateTime.Now.ToString("yyyy年MM月dd日mm分ss秒fff毫秒");
                    HOperatorSet.WriteImage(ImageArrary[i], "bmp", 0, "image/" + fileName + ".bmp");
                }

                Thread.Sleep(300);
                i++;
                if(i>=8)
                {
                    i = 0;
                }
            }
        }
        //更新结果到UI上
        private void UpdatetestResult(string result)
        {
            string[] subResult = result.Split('@');
            ListViewItem lt = new ListViewItem(subResult[0]);
            lt.SubItems.Add(subResult[1]);
            lt.SubItems.Add(subResult[2]);
            this.Result_listView.Items.Add(lt);
        }
        //保存数据到csv文件
        public void SaveResult(string ResultHeader,string ResultContent)
        {
            string fileName = DateTime.Now.ToString("yyyy年MM月dd日");
            bool flag = File.Exists(@"Result/" + fileName + ".csv");
            if (!flag)
            {
                WriteCsv(@"Result/" + fileName + ".csv", ResultHeader);
                WriteCsv(@"Result/" + fileName + ".csv", ResultContent);

            }
            else
            {
                WriteCsv(@"Result/" + fileName + ".csv", ResultContent);
            }

        }
        public void WriteCsv(string FilePath,string WriteContent)
        {
            //打开一个文件流
            FileStream fs = new FileStream(FilePath, FileMode.Append);
            //处理文本文件
            StreamWriter sw = new StreamWriter(fs, Encoding.Default);
            sw.Write(WriteContent+"\n");
            sw.Close();
            fs.Close();
        }
        //批量加载图像
        public void LoadBatchImage()
        {
            for(int i = 0; i < 8; i++)
            {
                HOperatorSet.ReadImage(out ImageArrary[i], i.ToString() + ".bmp");
            }
        }
        public void CreateHalconWindow()
        {
            HTuple FatherWindow = this.pictureBox1.Handle;

            HOperatorSet.SetWindowAttr("background_color", "green");

            HOperatorSet.OpenWindow(0, 0, pictureBox1.Width, pictureBox1.Height, FatherWindow, "visible", "",out WindowID);
            
        }

        public void LoadImage()
        {
            //读取一张图像
            HOperatorSet.ReadImage(out Image, "1.bmp");

            HTuple width = null, height = null;

            //获取图像大小
            HOperatorSet.GetImageSize(Image, out width, out height);

            //设置对象显示的颜色
            HOperatorSet.SetColor(WindowID, "yellow");

            //通过改变图像的缩放来适应图像在窗口的正常显示
            HOperatorSet.SetPart(WindowID, 0, 0, height, width);

            //在窗口上显示图像
            HOperatorSet.DispObj(Image, WindowID);
        }

        private void button_start_Click(object sender, EventArgs e)
        {
            //开启正常测试线程
            if(ThreadObject.ThreadState == System.Threading.ThreadState.Unstarted)
            {
                ThreadObject.Start();
            }

            if((ThreadObject.ThreadState == System.Threading.ThreadState.Stopped)||(ThreadObject.ThreadState == System.Threading.ThreadState.Aborted))
            {
                ThreadObject = new Thread(new ThreadStart(PlayThread));
                ThreadObject.Start();
            }
        }

        private void button_stop_Click(object sender, EventArgs e)
        {
            Thread_Stop = true;
        }

        private void buttonDraw_Click(object sender, EventArgs e)
        {
            // Local iconic variables 

            HObject ho_Image, ho_Circle;

            // Local control variables 
 
            HTuple hv_NewRow = new HTuple();
            HTuple hv_NewColumn = new HTuple(), hv_NewRadius = new HTuple();
            // Initialize local and output iconic variables 
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_Circle);

            //设置显示对象颜色
            HOperatorSet.SetColor(WindowID, "yellow");

            //设置区域填充模式为margin
            HOperatorSet.SetDraw(WindowID, "margin");

            //显示图像
            HOperatorSet.DispObj(ho_Image, WindowID);

            //创建一个圆形ROI
            hv_NewRow.Dispose(); hv_NewColumn.Dispose(); hv_NewRadius.Dispose();
            HOperatorSet.DrawCircle(WindowID, out hv_NewRow, out hv_NewColumn, out hv_NewRadius);

            //生成一个圆
            ho_Circle.Dispose();
            HOperatorSet.GenCircle(out ho_Circle, hv_NewRow, hv_NewColumn, hv_NewRadius);

            HOperatorSet.DispObj(ho_Circle, WindowID);

            ho_Image.Dispose();
            ho_Circle.Dispose();

            hv_NewRow.Dispose();
            hv_NewColumn.Dispose();
            hv_NewRadius.Dispose();
        }


        private double CaculateCircleR(HObject ho_ResultImage)
        {
            // Local iconic variables 

            HObject  ho_ResultRegion = null;
            HObject ho_ResultConnectedRegions = null, ho_ResultSelectedRegions = null;
            HObject ho_ResultCircle = null, ho_ResultContour = null;

            // Local control variables 

            HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
            HTuple hv_WindowHandle = new HTuple(), hv_MetrologyHandle = new HTuple();
            HTuple hv_CircleRadiusTolerance = new HTuple(), hv_NewRadius = new HTuple();
            HTuple hv_ImageFiles = new HTuple(), hv_Index = new HTuple();
            HTuple hv_ResultArea = new HTuple(), hv_ResultRow = new HTuple();
            HTuple hv_ResultColumn = new HTuple(), hv_MetrologyCircleIndice = new HTuple();
            HTuple hv_CircleRadiusResult = new HTuple();
            // Initialize local and output iconic variables 

            HOperatorSet.GenEmptyObj(out ho_ResultRegion);
            HOperatorSet.GenEmptyObj(out ho_ResultConnectedRegions);
            HOperatorSet.GenEmptyObj(out ho_ResultSelectedRegions);
            HOperatorSet.GenEmptyObj(out ho_ResultCircle);
            HOperatorSet.GenEmptyObj(out ho_ResultContour);

            //获取图像大小
            hv_Width.Dispose(); hv_Height.Dispose();
            HOperatorSet.GetImageSize(ho_ResultImage, out hv_Width, out hv_Height);


            //创建测量模型
            hv_MetrologyHandle.Dispose();
            HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);

            //设置测量对象图像大小
            HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);
            //
            hv_CircleRadiusTolerance.Dispose();
            hv_CircleRadiusTolerance = 100;

            //圆半径
            hv_NewRadius.Dispose();
            hv_NewRadius = 324;


            //阈值图像
            ho_ResultRegion.Dispose();
            HOperatorSet.Threshold(ho_ResultImage, out ho_ResultRegion, 0, 60);
            //区域连通处理
            ho_ResultConnectedRegions.Dispose();
            HOperatorSet.Connection(ho_ResultRegion, out ho_ResultConnectedRegions);
            //根据面积和圆度来过滤想要的圆区域
            ho_ResultSelectedRegions.Dispose();
            HOperatorSet.SelectShape(ho_ResultConnectedRegions, out ho_ResultSelectedRegions,
                (new HTuple("area")).TupleConcat("roundness"), "and", (new HTuple(250000)).TupleConcat(
                0.9), (new HTuple(320000)).TupleConcat(1));
            //获取圆的中心坐标和面积
            hv_ResultArea.Dispose(); hv_ResultRow.Dispose(); hv_ResultColumn.Dispose();
            HOperatorSet.AreaCenter(ho_ResultSelectedRegions, out hv_ResultArea, out hv_ResultRow,
                out hv_ResultColumn);
            //设置输出对象的颜色

            HOperatorSet.SetColor(WindowID, "green");
            //设置区域的填充模式

            HOperatorSet.SetDraw(WindowID, "margin");

            //显示图像

            HOperatorSet.DispObj(ho_ResultImage, WindowID);

            //生成圆
            ho_ResultCircle.Dispose();
            HOperatorSet.GenCircle(out ho_ResultCircle, hv_ResultRow, hv_ResultColumn,
                hv_NewRadius);
            //添加圆到测量模型里
            hv_MetrologyCircleIndice.Dispose();
            HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_ResultRow,
                hv_ResultColumn, hv_NewRadius, hv_CircleRadiusTolerance, 5, 1.5, 30, (new HTuple("measure_transition")).TupleConcat(
                "min_score"), (new HTuple("all")).TupleConcat(0.4), out hv_MetrologyCircleIndice);
            //测量并拟合几何形状
            HOperatorSet.ApplyMetrologyModel(ho_ResultImage, hv_MetrologyHandle);
            //获取测量模型里的测量轮廓
            ho_ResultContour.Dispose();
            HOperatorSet.GetMetrologyObjectResultContour(out ho_ResultContour, hv_MetrologyHandle,
                "all", "all", 1.5);
            //获取测量模型里的测量结果
            hv_CircleRadiusResult.Dispose();
            HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
                "all", "result_type", "radius", out hv_CircleRadiusResult);

            //显示测量轮廓

            HOperatorSet.DispObj(ho_ResultContour, WindowID);

            //设置文字显示位置
            HOperatorSet.SetTposition(WindowID, 0, 0);
            //          在窗口指定位置输出文字信息
            using (HDevDisposeHelper dh = new HDevDisposeHelper())
            {
                HOperatorSet.WriteString(WindowID, "圆外径:" + hv_CircleRadiusResult);
            }
            // stop(...); only in hdevelop

            //清除测量模型
            HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);

            ho_ResultRegion.Dispose();
            ho_ResultConnectedRegions.Dispose();
            ho_ResultSelectedRegions.Dispose();
            ho_ResultCircle.Dispose();
            ho_ResultContour.Dispose();

            hv_Width.Dispose();
            hv_Height.Dispose();
            hv_WindowHandle.Dispose();
            hv_MetrologyHandle.Dispose();
            hv_CircleRadiusTolerance.Dispose();
            hv_NewRadius.Dispose();
            hv_ImageFiles.Dispose();
            hv_Index.Dispose();
            hv_ResultArea.Dispose();
            hv_ResultRow.Dispose();
            hv_ResultColumn.Dispose();
            hv_MetrologyCircleIndice.Dispose();
            hv_CircleRadiusResult.Dispose();

            return hv_CircleRadiusResult.D;
        }

    }
}
 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值