在上一篇文章里,我们通过阈值分割技术展示了如何高效调用Halcon的DLL,实现了图像处理的一个关键步骤。今天,我们将深入探讨如何将这一技术与自动阈值分割结合,并封装成一个独立函数。这不仅能简化操作流程,还能拓展功能,提升我们在实际应用中的工作效率。准备好了吗?让我们继续在Halcon的世界中探索更多可能性!
Step1:右键项目新建一个类,这里命名为ImageHalpers
Step2:添加using HalconDotNet;
Step3:将命名空间重命名为Algorithm
Step4:接下来定义三个枚举类型,分别是MethodOfThreshold、MethodOfBinarythreshold和DarkOrLight。这些枚举类型用于表示不同的阈值分割方式、自动阈值分割方法和暗色或亮色的选项。
public enum MethodOfThreshold //阈值分割方式
{
Threshold = 0,//普通阈值分割
BinaryThreshold = 1,//自动阈值分割
}
public enum MethodOfBinarythreshold //自动阈值分割方法
{
max_separability = 0,
smooth_histo = 1,
}
public enum DarkOrLight
{
dark = 0,
light = 1,
}
Step5:接着来写我们的ImageHelper类,其中包含了一些用于处理图像的方法:ReadImage,Threshold,BinaryThreshold,ThresholdAll。
(1)ReadImage方法
/读取图片 并在指定窗体显示
///<param name = "hImage"></param>
///<param name = "filename"></param>
///<returns></returns>
public static bool ReadImage(out HObject hImage, string filename, HWindow window)
{
try
{
HOperatorSet.ReadImage(out hImage, filename);
HTuple width, height;
HOperatorSet.GetImageSize(hImage, out width, out height);
HOperatorSet.SetPart(window,0,0,(height-1),(width-1));
HOperatorSet.DispObj(hImage,window);
return true;
}
catch (Exception)
{
hImage = null;
return false;
}
}
(2)Threshold方法
public static bool Threshold(HObject hImage, out HObject Region, int Min, int Max)
{
HOperatorSet.Threshold(hImage, out Region, Min, Max);
return true;
}
(3)BinaryThreshold方法
public static bool BinaryThreshold(HObject hImage, out HObject Region, MethodOfBinarythreshold method, DarkOrLight darkAndLight)
{
HTuple use;
HOperatorSet.BinaryThreshold(hImage, out Region, method.ToString(), darkAndLight.ToString(), out use);
return true;
}
(4)ThresholdAll方法
public static bool ThresholdAll(HObject hImage, out HObject Region, int MinGray, int MaxGray, MethodOfThreshold method, MethodOfBinarythreshold method2 = MethodOfBinarythreshold.max_separability, DarkOrLight method3 = DarkOrLight.dark)
{
Region = null;
switch (method)
{
case MethodOfThreshold.Threshold:
return Threshold(hImage, out Region, MinGray, MaxGray);
case MethodOfThreshold.BinaryThreshold:
return BinaryThreshold(hImage, out Region,method2,method3);
default:
return false;
}
}
Step6:新建一个窗体命名为FormOfTest,用于检测我们的封装
Step7:在窗体设计中,如图添加
Step8:双击测试封装读取图片按钮,进入按钮点击事件代码
private HObject ho_image;
private void button1_Click(object sender, EventArgs e)
{
string filename = "D:\\桌面\\imgFiles\\image_01.jpg";
bool result = Algorithm.ImageHelper.ReadImage(out ho_image, filename, hWindowControl1.HalconWindow);
if (result != true)
{
MessageBox.Show(" Algorithm.ImageHelper.ReadImage 失败");
}
}
Step9:双击测试封装阈值分割按钮,进入按钮点击事件代码
private void button2_Click(object sender, EventArgs e)
{
// 定义图片文件路径
string filename = "D:\\桌面\\imgFiles\\image_01.jpg";
// 读取图片文件,并将结果存储在ho_image变量中
bool result = Algorithm.ImageHelper.ReadImage(out ho_image, filename, hWindowControl1.HalconWindow);
// 定义一个区域对象
HObject Region;
// 对图片进行阈值分割处理,将结果存储在Region变量中
Algorithm.ImageHelper.ThresholdAll(ho_image, out Region, 0, 100, Algorithm.MethodOfThreshold.BinaryThreshold, Algorithm.MethodOfBinarythreshold.max_separability, Algorithm.DarkOrLight.dark);
// 在窗口中显示分割后的区域
HOperatorSet.DispObj(Region,hWindowControl1.HalconWindow);
}
Step10:F5启动代码查看当前效果(记得设置当前窗体为主窗体运行)
运行结果如下:
点击读取图片:
点击阈值分割(这里的灰度值需要自己根据图片调整):
到这里整体没有问题,接下来我们新建一个类,命名为ThresholdDef,命名空间Algorithm,将上面ImageHelper中的三个枚举剪切到这里
namespace Algorithm
{
public enum MethodOfThreshold //阈值分割方式
{
Threshold = 0,//普通阈值分割
BinaryThreshold = 1,//自动阈值分割
}
public enum MethodOfBinarythreshold//自动阈值分割方法
{
max_separability = 0,
smooth_histo = 1,
}
public enum DarkOrLight
{
dark = 0,
light = 1,
}
public class ThresholdDef
{
// 构造函数,接受两个整数参数minGray和maxGray
public ThresholdDef(int minGray, int maxGray)
{
// 将_Segment设置为MethodOfThreshold枚举中的Threshold值
_Segment = MethodOfThreshold.Threshold;
// 将传入的maxGray赋值给_MaxGray
_MaxGray = maxGray;
// 将传入的minGray赋值给_MinGray
_MinGray = minGray;
}
// 构造函数,接受两个参数:segmentMethod(MethodOfBinarythreshold类型)和darkOrLight(DarkOrLight类型)
public ThresholdDef(MethodOfBinarythreshold segmentMethod, DarkOrLight darkOrLight)
{
// 将_Segment设置为MethodOfThreshold枚举中的BinaryThreshold值
_Segment = MethodOfThreshold.BinaryThreshold;
// 将传入的segmentMethod赋值给_SegmentMethod
_SegmentMethod = segmentMethod;
// 将传入的darkOrLight赋值给_DarkOrLight
_DarkOrLight = darkOrLight;
}
// 定义一个公共的MethodOfThreshold类型的变量_Segment
public MethodOfThreshold _Segment;
// 定义一个公共的整数类型的变量_MaxGray,表示最大灰度值
public int _MaxGray;
// 定义一个公共的整数类型的变量_MinGray,表示最小灰度值
public int _MinGray;
// 定义一个公共的MethodOfBinarythreshold类型的变量_SegmentMethod,表示二值化阈值方法
public MethodOfBinarythreshold _SegmentMethod;
// 定义一个公共的DarkOrLight类型的变量_DarkOrLight,表示暗或亮模式
public DarkOrLight _DarkOrLight;
}
并修改ImageHelper中的ThresholdAll方法:
public static bool ThresholdALL(HObject hImage, out HObject Region, ThresholdDef threSholdDef)
{
Region = null;
switch (threSholdDef._Segment)
{
case MethodOfThreshold.Threshold:
Console.WriteLine("我调用了普通阈值分割 Threshold");
return Threshold(hImage, out Region, threSholdDef._MinGray, threSholdDef._MinGray);
case MethodOfThreshold.BinaryThreshold:
Console.WriteLine("我调用了自动阈值分割 BinaryThreshold(");
return BinaryThreshold(hImage, out Region, threSholdDef._SegmentMethod, threSholdDef._DarkOrLight);
default:
return false;
}
}
然后回到我们的FormOfTest.cs中,就可以在测试阈值分割的点击事件中调用封装的方法了!
private void button2_Click(object sender, EventArgs e)
{
string filename = "D:\\桌面\\imgFiles\\Image_03.jpg";
bool result = Algorithm.ImageHelper.ReadImage(out ho_image, filename, hWindowControl1.HalconWindow);
HObject Region;
//Algorithm.ImageHelper.ThresholdAll(ho_image, out Region, 0, 100, Algorithm.MethodOfThreshold.BinaryThreshold, Algorithm.MethodOfBinarythreshold.max_separability, Algorithm.DarkOrLight.dark);
//HOperatorSet.DispObj(Region,hWindowControl1.HalconWindow);
Algorithm.ThresholdDef thresholdDef = new Algorithm.ThresholdDef(MethodOfBinarythreshold.max_separability,DarkOrLight.dark);
Algorithm.ImageHelper.ThresholdAll(ho_image,out Region, thresholdDef);
HOperatorSet.DispObj(Region,hWindowControl1.HalconWindow);
}
本篇代码内容较多,步骤详细,需要读者耐心阅读,以更好地了解和掌握相关概念与技能。对于小白这些内容可能会有些挑战性,但别担心,这是学习过程的一部分。不要害怕犯错,实践是学习的最佳途径,所以勇敢尝试,亲自动手操作吧,通过仔细研究本文和逐步跟随教程,你会发现实践中有无穷的乐趣和满足感等待着你!