探索C#与Halcon DLL的交互之旅(三)—— 将 阈值分割(Threshold)与自动阈值分割(BinaryThreshold)封装到一个函数中

在上一篇文章里,我们通过阈值分割技术展示了如何高效调用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);

}

本篇代码内容较多,步骤详细,需要读者耐心阅读,以更好地了解和掌握相关概念与技能。对于小白这些内容可能会有些挑战性,但别担心,这是学习过程的一部分。不要害怕犯错,实践是学习的最佳途径,所以勇敢尝试,亲自动手操作吧,通过仔细研究本文和逐步跟随教程,你会发现实践中有无穷的乐趣和满足感等待着你!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值