一.这里我简单的搞一个winform交互界面
左边是一个listview控件用来将我们的检测的数据输出显示在该控件上
中间是一个pictureBox1将我们的图像数据显示在该控件上
二.配置我们的联合编程环境
(1)
注意:这里要看的halcon版本x64的就吧这个首选32为取消掉,x86的可以勾上,不然会报以下错误:
entrypointnotfoundexception: 无法在 dll“halcon”中找到名为“hlireleaseexternalownership”的入口点。
(2)
找到我们halcon的文档位置我的是"C:\Program Files\MVTec\HALCON-17.12-Progress\bin\dotnet35"给你们借鉴,找到下面的文件复制到我们winform的debug目录下
找不到debug文件的可以有右键我们winform项目有个在资源文件管理器中打开文件夹
在bin文件夹里复制到debug目录中
建议将我们的图像资源也放到debug目录下方便我们后面的路径书写
(3)
添加我们的引用
1.右键引用点击添加引用2.点击最近然后点击浏览找到我们的文档进行添加3.勾选上
三.打开我们在halcon中导出来的c#代码进行逻辑编程(不知道怎么导出的看halcon部分有详细教程)
//
// File generated by HDevelop for HALCON/.NET (C#) Version 17.12
//
using HalconDotNet;
public partial class HDevelopExport
{
#if !(NO_EXPORT_MAIN || NO_EXPORT_APP_MAIN)
public HDevelopExport()
{
// Default settings used in HDevelop
HOperatorSet.SetSystem("width", 512);
HOperatorSet.SetSystem("height", 512);
if (HalconAPI.isWindows)
HOperatorSet.SetSystem("use_window_thread","true");
action();
}
#endif
#if !NO_EXPORT_MAIN
// Main procedure
private void action()
{
// Local iconic variables
HObject ho_Image, ho_ResultImage=null, ho_ResultRegions=null;
HObject ho_ResultConnectedRegions=null, ho_ResultSelectedRegions1=null;
HObject ho_ResultCircle=null, ho_ResultContour=null;
// Local control variables
HTuple hv_ImageFiles = null, hv_Width = null;
HTuple hv_Height = null, hv_WindowHandle = null, hv_MetrologyHandle = null;
HTuple hv_Row = null, hv_Column = null, hv_Radius = null;
HTuple hv_CirCleRadiusTolerance = null, hv_Index = null;
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_Image);
HOperatorSet.GenEmptyObj(out ho_ResultImage);
HOperatorSet.GenEmptyObj(out ho_ResultRegions);
HOperatorSet.GenEmptyObj(out ho_ResultConnectedRegions);
HOperatorSet.GenEmptyObj(out ho_ResultSelectedRegions1);
HOperatorSet.GenEmptyObj(out ho_ResultCircle);
HOperatorSet.GenEmptyObj(out ho_ResultContour);
HOperatorSet.ListFiles("C:/Users/14350/Desktop/halcon1/联合编程/img/img", (new HTuple("files")).TupleConcat(
"follow_links"), out hv_ImageFiles);
ho_Image.Dispose();
HOperatorSet.ReadImage(out ho_Image, hv_ImageFiles.TupleSelect(0));
//获取图像大小
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
HOperatorSet.SetWindowAttr("background_color","black");
HOperatorSet.OpenWindow(0,0,hv_Width/4,hv_Height/4,0,"visible","",out hv_WindowHandle);
HDevWindowStack.Push(hv_WindowHandle);
if (HDevWindowStack.IsOpen())
{
HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());
}
//创建测量模型
HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
//设置测量模型的大小
HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);
HOperatorSet.DrawCircle(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Radius);
//也可以配置其他的参数,例如测量对象的宽度允许范围
hv_CirCleRadiusTolerance = 100;
//对多张图像进行测量
for (hv_Index=0; (int)hv_Index<=(int)((new HTuple(hv_ImageFiles.TupleLength()
))-1); hv_Index = (int)hv_Index + 1)
{
ho_ResultImage.Dispose();
HOperatorSet.ReadImage(out ho_ResultImage, hv_ImageFiles.TupleSelect(hv_Index));
//阈值分割,挑选出来配件部分
ho_ResultRegions.Dispose();
HOperatorSet.Threshold(ho_ResultImage, out ho_ResultRegions, 3, 60);
//连通性
ho_ResultConnectedRegions.Dispose();
HOperatorSet.Connection(ho_ResultRegions, out ho_ResultConnectedRegions);
//特征提取:用面积,和圆两个指标提取 area
ho_ResultSelectedRegions1.Dispose();
HOperatorSet.SelectShape(ho_ResultConnectedRegions, out ho_ResultSelectedRegions1,
(new HTuple("area")).TupleConcat("roundness"), "and", (new HTuple(250000)).TupleConcat(
0.9), (new HTuple(320000)).TupleConcat(1));
//获取
HOperatorSet.AreaCenter(ho_ResultSelectedRegions1, out hv_ResultArea, out hv_ResultRow,
out hv_ResultColumn);
//设置输出的颜色
if (HDevWindowStack.IsOpen())
{
HOperatorSet.SetColor(HDevWindowStack.GetActive(), "green");
}
if (HDevWindowStack.IsOpen())
{
HOperatorSet.SetDraw(HDevWindowStack.GetActive(), "margin");
}
if (HDevWindowStack.IsOpen())
{
HOperatorSet.DispObj(ho_ResultImage, HDevWindowStack.GetActive());
}
//生成圆:注意,这里借助了上方两个特征提取出来的坐标
ho_ResultCircle.Dispose();
HOperatorSet.GenCircle(out ho_ResultCircle, hv_ResultRow, hv_ResultColumn,
hv_Radius);
//把圆添加到模型中
HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_ResultRow,
hv_ResultColumn, hv_Radius, 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);
//在轮廓基础上获得此次测量的结果:第二个参数是每个图象的索引
HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
"all", "result_type", "radius", out hv_CircleRadiusResult);
//显示图像
if (HDevWindowStack.IsOpen())
{
HOperatorSet.DispObj(ho_ResultImage, HDevWindowStack.GetActive());
}
//显示测量轮廓
if (HDevWindowStack.IsOpen())
{
HOperatorSet.DispObj(ho_ResultContour, HDevWindowStack.GetActive());
}
//设置文字位置
HOperatorSet.SetTposition(hv_WindowHandle, 0, 0);
//在指定位置显示信息
HOperatorSet.WriteString(hv_WindowHandle, "圆的半径:"+hv_CircleRadiusResult);
// stop(...); only in hdevelop
}
//清除测量模型
HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);
ho_Image.Dispose();
ho_ResultImage.Dispose();
ho_ResultRegions.Dispose();
ho_ResultConnectedRegions.Dispose();
ho_ResultSelectedRegions1.Dispose();
ho_ResultCircle.Dispose();
ho_ResultContour.Dispose();
}
#endif
}
#if !(NO_EXPORT_MAIN || NO_EXPORT_APP_MAIN)
public class HDevelopExportApp
{
static void Main(string[] args)
{
new HDevelopExport();
}
}
#endif
看着挺长但是很多会用不到只需要粘我们需要的就行
四.c#代码编程
(1)完整代码
using HalconDotNet;
using System;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using System.Threading;
using System.Windows.Forms;
namespace halcon检测项目
{
public partial class Form1 : Form
{
HTuple hv_Row = null, hv_Column = null, hv_Radius = null;
HObject image;
HTuple windowID;
Thread t1;
HObject[] ImageArr = new HObject[8];
bool t1_Stop = false;
bool t1_Pause = false; // 添加暂停标志变量
public Form1()
{
InitializeComponent();
// 初始化ListView相关设置
InitializeListView();
}
private void InitializeListView()
{
listView1.View = View.Details;
listView1.GridLines = true;
listView1.FullRowSelect = true;
listView1.Columns.Add("编号", 80);
listView1.Columns.Add("半径", 100);
listView1.Columns.Add("结果", 100);
}
// 其他原有的代码区域(资源加载、窗口创建等代码保持不变)
#region 先把资源加载进来
private void LoadBateImage()
{
for (int i = 0; i < 8; i++)
{
HOperatorSet.ReadImage(out ImageArr[i], $"img/{i}.bmp");
}
}
#endregion
#region 加载窗体
private void CreateHalconWindow()
{
HTuple winforms = this.pictureBox1.Handle;
HOperatorSet.SetWindowAttr("background_color", "red");
HOperatorSet.OpenWindow(0, 0, this.pictureBox1.Width, this.pictureBox1.Height, winforms, "", "", out windowID);
}
#endregion
#region 加载默认图片
private void LoadImage()
{
HOperatorSet.ReadImage(out image, "img/0.bmp");
HTuple Width = null, Height = null;
HOperatorSet.GetImageSize(image, out Width, out Height);
HOperatorSet.SetColor(windowID, "red");
HOperatorSet.SetPart(windowID, 0, 0, Height, Width);
HOperatorSet.DispObj(image, windowID);
}
#endregion
#region 加载配置环境
private void Form1_Load(object sender, EventArgs e)
{
LoadBateImage();
CreateHalconWindow();
LoadImage();
t1 = new Thread(new ThreadStart(PlayThread));
}
#endregion
#region 开始测量
private void button1_Click(object sender, EventArgs e)
{
t1_Stop = false;
if (t1.ThreadState == ThreadState.Unstarted)
{
t1.Start();
}
if (t1.ThreadState == ThreadState.Stopped || t1.ThreadState == ThreadState.Aborted)
{
t1 = new Thread(new ThreadStart(PlayThread));
t1.Start();
}
}
private void PlayThread()
{
int i = 0;
t1_Stop = false;
t1_Pause = false; // 初始化暂停标志变量
while (!t1_Stop)
{
if (t1_Pause) // 检查暂停标志变量
{
// 等待直到暂停标志被清除或线程停止
while (t1_Pause && !t1_Stop)
{
Thread.Sleep(100); // 休眠一小段时间,避免过度占用CPU
}
}
HOperatorSet.DispObj(ImageArr[i], windowID);
HTuple Width = null, Height = null;
HOperatorSet.GetImageSize(ImageArr[i], out Width, out Height);
HOperatorSet.SetPart(windowID, 0, 0, Height, Width);
double CriRad = ImageMeasure(ImageArr[i]);
string result = CriRad > 311 && CriRad < 313 ? "OK" : "NG";
// 将测量数据添加到ListView
AddDataToListView(i, CriRad, result);
if (CriRad > 311 && CriRad < 313)
{
string filePath = @"OK\OK.txt"; // 指定完整路径,包括目录和文件名
// 确保目录存在
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
// 写入内容(如果文件不存在会自动创建)
string ok = $" OK, 序号{i}零件测得半径:{CriRad}\n";
File.AppendAllText(filePath, ok);
}
else
{
string filePath = @"NG\NG.txt"; // 指定完整路径,包括目录和文件名
// 确保目录存在
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
// 写入内容(如果文件不存在会自动创建)
string ng = $" NG, 序号{i}零件测得半径:{CriRad}\n";
File.AppendAllText(filePath, ng);
}
Thread.Sleep(1000);
i++;
if (i >= 8)
{
i = 0;
}
}
}
private void AddDataToListView(int index, double radius, string result)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
ListViewItem item = new ListViewItem(index.ToString());
item.SubItems.Add(radius.ToString());
item.SubItems.Add(result);
listView1.Items.Add(item);
});
}
else
{
ListViewItem item = new ListViewItem(index.ToString());
item.SubItems.Add(radius.ToString());
item.SubItems.Add(result);
listView1.Items.Add(item);
}
}
private double ImageMeasure(HObject ho_ResultImage)
{
// 原有的测量代码逻辑保持不变
HObject ho_ResultRegions = null;
HObject ho_ResultConnectedRegions = null;
HObject ho_ResultSelectedRegions1 = null;
HObject ho_ResultCircle = null;
HObject ho_ResultContour = null;
HTuple hv_Width = null, hv_Height = null;
HTuple hv_CirCleRadiusTolerance = new HTuple(100);
HTuple hv_ResultArea = null, hv_ResultRow = null;
HTuple hv_ResultColumn = null, hv_MetrologyCircleIndice = null;
HTuple hv_CircleRadiusResult = null;
HTuple hv_MetrologyHandle = new HTuple();
HOperatorSet.GetImageSize(ho_ResultImage, out hv_Width, out hv_Height);
// 开始测量
HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);
// 特征提取
HOperatorSet.Threshold(ho_ResultImage, out ho_ResultRegions, 3, 60);
HOperatorSet.Connection(ho_ResultRegions, out ho_ResultConnectedRegions);
HOperatorSet.SelectShape(ho_ResultConnectedRegions, out ho_ResultSelectedRegions1,
(new HTuple("area")).TupleConcat("roundness"), "and", (new HTuple(250000)).TupleConcat(
0.9), (new HTuple(320000)).TupleConcat(1));
HOperatorSet.AreaCenter(ho_ResultSelectedRegions1, out hv_ResultArea, out hv_ResultRow, out hv_ResultColumn);
HOperatorSet.SetColor(windowID, "green");
HOperatorSet.SetDraw(windowID, "margin");
HOperatorSet.DispObj(ho_ResultImage, windowID);
// 生成圆
HOperatorSet.GenCircle(out ho_ResultCircle, hv_ResultRow, hv_ResultColumn, hv_Radius.D);
// 把圆添加到模型中
HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_ResultRow,
hv_ResultColumn, hv_Radius.D, 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);
HOperatorSet.GetMetrologyObjectResultContour(out ho_ResultContour, hv_MetrologyHandle,
"all", "all", 1.5);
// 在轮廓基础上获得此次测量的结果
HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
"all", "result_type", "radius", out hv_CircleRadiusResult);
// 显示图像
HOperatorSet.DispObj(ho_ResultImage, windowID);
// 显示测量轮廓
HOperatorSet.DispObj(ho_ResultContour, windowID);
HOperatorSet.SetTposition(windowID, 0, 0);
HOperatorSet.WriteString(windowID, "圆的半径:" + hv_CircleRadiusResult);
HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);
// 释放资源
ho_ResultRegions.Dispose();
ho_ResultConnectedRegions.Dispose();
ho_ResultSelectedRegions1.Dispose();
ho_ResultCircle.Dispose();
ho_ResultContour.Dispose();
// 返回结果
return hv_CircleRadiusResult.D;
}
#endregion
private void button2_Click(object sender, EventArgs e)
{
// 停止检测
t1_Stop = true;
t1_Pause = false; // 清除暂停标志变量
}
private void button3_Click(object sender, EventArgs e)
{
//清空OK和NG文件夹
DirectoryInfo di = new DirectoryInfo("OK");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
di = new DirectoryInfo("NG");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
// 交互测量绘制模型圆
InteractiveMeasure(image);
}
private void InteractiveMeasure(HObject ho_Image)
{
// 原有的交互测量代码逻辑保持不变
HTuple hv_WindowHandle = windowID;
HOperatorSet.DrawCircle(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Radius);
// 显示交互绘制的圆
HObject ho_InteractiveCircle = null;
HOperatorSet.GenCircle(out ho_InteractiveCircle, hv_Row, hv_Column, hv_Radius);
HOperatorSet.SetColor(windowID, "blue");
HOperatorSet.DispObj(ho_InteractiveCircle, windowID);
// 使用交互绘制的圆进行测量
HTuple hv_MetrologyHandle = new HTuple();
HTuple hv_MetrologyCircleIndice = new HTuple();
HTuple hv_CirCleRadiusTolerance = new HTuple(100);
HTuple hv_CircleRadiusResult = new HTuple();
// 创建测量模型
HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
HTuple hv_Width = null, hv_Height = null;
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);
// 添加交互绘制的圆到测量模型中
HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_Row, hv_Column, hv_Radius, 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_Image, hv_MetrologyHandle);
// 获取测量结果
HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
"all", "result_type", "radius", out hv_CircleRadiusResult);
// 显示测量结果
HOperatorSet.SetTposition(windowID, 0, 0);
HOperatorSet.WriteString(windowID, "交互测量的圆的半径:" + hv_CircleRadiusResult);
// 释放资源
ho_InteractiveCircle.Dispose();
HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);
}
}
}
(2).在Form1_Load中加载配置环境
// 其他原有的代码区域(资源加载、窗口创建等代码保持不变)
#region 先把资源加载进来
private void LoadBateImage()
{
for (int i = 0; i < 8; i++)
{
HOperatorSet.ReadImage(out ImageArr[i], $"img/{i}.bmp");
}
}
#endregion
#region 加载窗体
private void CreateHalconWindow()
{
HTuple winforms = this.pictureBox1.Handle;
HOperatorSet.SetWindowAttr("background_color", "red");
HOperatorSet.OpenWindow(0, 0, this.pictureBox1.Width, this.pictureBox1.Height, winforms, "", "", out windowID);
}
#endregion
#region 加载默认图片
private void LoadImage()
{
HOperatorSet.ReadImage(out image, "img/0.bmp");
HTuple Width = null, Height = null;
HOperatorSet.GetImageSize(image, out Width, out Height);
HOperatorSet.SetColor(windowID, "red");
HOperatorSet.SetPart(windowID, 0, 0, Height, Width);
HOperatorSet.DispObj(image, windowID);
}
#endregion
#region 加载配置环境
private void Form1_Load(object sender, EventArgs e)
{
LoadBateImage();
CreateHalconWindow();
LoadImage();
t1 = new Thread(new ThreadStart(PlayThread));
}
#endregion
这一步为了1.加载窗体2.将初始的图像显示出来3.将图像资源加载出来(在我们生成的c#代码中都有选择粘贴出来)
(3)绘制模版
private void button3_Click(object sender, EventArgs e)
{
//清空OK和NG文件夹
DirectoryInfo di = new DirectoryInfo("OK");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
di = new DirectoryInfo("NG");
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
// 交互测量绘制模型圆
InteractiveMeasure(image);
}
private void InteractiveMeasure(HObject ho_Image)
{
// 原有的交互测量代码逻辑保持不变
HTuple hv_WindowHandle = windowID;
HOperatorSet.DrawCircle(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Radius);
// 显示交互绘制的圆
HObject ho_InteractiveCircle = null;
HOperatorSet.GenCircle(out ho_InteractiveCircle, hv_Row, hv_Column, hv_Radius);
HOperatorSet.SetColor(windowID, "blue");
HOperatorSet.DispObj(ho_InteractiveCircle, windowID);
// 使用交互绘制的圆进行测量
HTuple hv_MetrologyHandle = new HTuple();
HTuple hv_MetrologyCircleIndice = new HTuple();
HTuple hv_CirCleRadiusTolerance = new HTuple(100);
HTuple hv_CircleRadiusResult = new HTuple();
// 创建测量模型
HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
HTuple hv_Width = null, hv_Height = null;
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);
// 添加交互绘制的圆到测量模型中
HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_Row, hv_Column, hv_Radius, 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_Image, hv_MetrologyHandle);
// 获取测量结果
HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
"all", "result_type", "radius", out hv_CircleRadiusResult);
// 显示测量结果
HOperatorSet.SetTposition(windowID, 0, 0);
HOperatorSet.WriteString(windowID, "交互测量的圆的半径:" + hv_CircleRadiusResult);
// 释放资源
ho_InteractiveCircle.Dispose();
HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);
}
当我们点击button3的时候进行绘制我们的模版圆用于后续的检测
HOperatorSet.DrawCircle(hv_WindowHandle, out hv_Row, out hv_Column, out hv_Radius);
主要就是这句
后续是将我们绘制的圆和数据显示出来
(4)测量零件
#region 开始测量
private void button1_Click(object sender, EventArgs e)
{
t1_Stop = false;
if (t1.ThreadState == ThreadState.Unstarted)
{
t1.Start();
}
if (t1.ThreadState == ThreadState.Stopped || t1.ThreadState == ThreadState.Aborted)
{
t1 = new Thread(new ThreadStart(PlayThread));
t1.Start();
}
}
private void PlayThread()
{
int i = 0;
t1_Stop = false;
t1_Pause = false; // 初始化暂停标志变量
while (!t1_Stop)
{
if (t1_Pause) // 检查暂停标志变量
{
// 等待直到暂停标志被清除或线程停止
while (t1_Pause && !t1_Stop)
{
Thread.Sleep(100); // 休眠一小段时间,避免过度占用CPU
}
}
HOperatorSet.DispObj(ImageArr[i], windowID);
HTuple Width = null, Height = null;
HOperatorSet.GetImageSize(ImageArr[i], out Width, out Height);
HOperatorSet.SetPart(windowID, 0, 0, Height, Width);
double CriRad = ImageMeasure(ImageArr[i]);
string result = CriRad > 311 && CriRad < 313 ? "OK" : "NG";
// 将测量数据添加到ListView
AddDataToListView(i, CriRad, result);
if (CriRad > 311 && CriRad < 313)
{
string filePath = @"OK\OK.txt"; // 指定完整路径,包括目录和文件名
// 确保目录存在
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
// 写入内容(如果文件不存在会自动创建)
string ok = $" OK, 序号{i}零件测得半径:{CriRad}\n";
File.AppendAllText(filePath, ok);
}
else
{
string filePath = @"NG\NG.txt"; // 指定完整路径,包括目录和文件名
// 确保目录存在
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
// 写入内容(如果文件不存在会自动创建)
string ng = $" NG, 序号{i}零件测得半径:{CriRad}\n";
File.AppendAllText(filePath, ng);
}
Thread.Sleep(1000);
i++;
if (i >= 8)
{
i = 0;
}
}
}
private void AddDataToListView(int index, double radius, string result)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
ListViewItem item = new ListViewItem(index.ToString());
item.SubItems.Add(radius.ToString());
item.SubItems.Add(result);
listView1.Items.Add(item);
});
}
else
{
ListViewItem item = new ListViewItem(index.ToString());
item.SubItems.Add(radius.ToString());
item.SubItems.Add(result);
listView1.Items.Add(item);
}
}
private double ImageMeasure(HObject ho_ResultImage)
{
// 原有的测量代码逻辑保持不变
HObject ho_ResultRegions = null;
HObject ho_ResultConnectedRegions = null;
HObject ho_ResultSelectedRegions1 = null;
HObject ho_ResultCircle = null;
HObject ho_ResultContour = null;
HTuple hv_Width = null, hv_Height = null;
HTuple hv_CirCleRadiusTolerance = new HTuple(100);
HTuple hv_ResultArea = null, hv_ResultRow = null;
HTuple hv_ResultColumn = null, hv_MetrologyCircleIndice = null;
HTuple hv_CircleRadiusResult = null;
HTuple hv_MetrologyHandle = new HTuple();
HOperatorSet.GetImageSize(ho_ResultImage, out hv_Width, out hv_Height);
// 开始测量
HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);
HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);
// 特征提取
HOperatorSet.Threshold(ho_ResultImage, out ho_ResultRegions, 3, 60);
HOperatorSet.Connection(ho_ResultRegions, out ho_ResultConnectedRegions);
HOperatorSet.SelectShape(ho_ResultConnectedRegions, out ho_ResultSelectedRegions1,
(new HTuple("area")).TupleConcat("roundness"), "and", (new HTuple(250000)).TupleConcat(
0.9), (new HTuple(320000)).TupleConcat(1));
HOperatorSet.AreaCenter(ho_ResultSelectedRegions1, out hv_ResultArea, out hv_ResultRow, out hv_ResultColumn);
HOperatorSet.SetColor(windowID, "green");
HOperatorSet.SetDraw(windowID, "margin");
HOperatorSet.DispObj(ho_ResultImage, windowID);
// 生成圆
HOperatorSet.GenCircle(out ho_ResultCircle, hv_ResultRow, hv_ResultColumn, hv_Radius.D);
// 把圆添加到模型中
HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_ResultRow,
hv_ResultColumn, hv_Radius.D, 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);
HOperatorSet.GetMetrologyObjectResultContour(out ho_ResultContour, hv_MetrologyHandle,
"all", "all", 1.5);
// 在轮廓基础上获得此次测量的结果
HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice,
"all", "result_type", "radius", out hv_CircleRadiusResult);
// 显示图像
HOperatorSet.DispObj(ho_ResultImage, windowID);
// 显示测量轮廓
HOperatorSet.DispObj(ho_ResultContour, windowID);
HOperatorSet.SetTposition(windowID, 0, 0);
HOperatorSet.WriteString(windowID, "圆的半径:" + hv_CircleRadiusResult);
HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);
// 释放资源
ho_ResultRegions.Dispose();
ho_ResultConnectedRegions.Dispose();
ho_ResultSelectedRegions1.Dispose();
ho_ResultCircle.Dispose();
ho_ResultContour.Dispose();
// 返回结果
return hv_CircleRadiusResult.D;
}
#endregion
private void InitializeListView()
{
listView1.View = View.Details;
listView1.GridLines = true;
listView1.FullRowSelect = true;
listView1.Columns.Add("编号", 80);
listView1.Columns.Add("半径", 100);
listView1.Columns.Add("结果", 100);
}
这里hv_Radius.D来获取到我们模版圆的半径来绘制模版进行对比
其中我还加入了将测量结果分析后加载到listview控件中显示以及创建两个文件夹ok和ng分别存储不良和良品数据。
联合编程核心就是-------粘代码不要自己无脑写简化自己的操作
效果放在主页视频中了,退出按钮效果漏写了0.0