在C#中实现图像的阈值分割是计算机视觉中的一个常见任务。阈值分割通过将图像的像素值与指定的阈值进行比较,来将图像分成前景和背景。下面是一个简单的示例,演示如何将阈值分割功能封装到一个函数中,并在函数开头进行定义。
思路:建立三个类分别为
一.测试类
二.类 封装阈值分割
三.类 封装图像
1)新建一个类ThresholdDef:这个类里面就是用来写阈值分割的类:分为普通阈值分割 自动阈值分割
成员变量:
1.普通阈值分割 里面有最小灰度值MinGray 最大灰度值MaxGray 参数
2.自动阈值分割 里面有max_separability/smooth_histo 亮light暗Dark参数
//判断阈值分割的方式 是自动还是普通
public 阈值分割方式 _Segment;
//普通阈值分割
//成员变量
public int _MaxGray;
public int _MinGray;
//自动阈值分割
//成员变量
public 自动阈值分割方法 _SegmentMothd;//判断自动阈值分割是用的max_separability 还是smooth_histo
public 亮或暗 _LightOrDark;//判断自动阈值分割中的亮暗
定义几个枚举类型:
public enum 阈值分割方式
{
Threshold = 0,//普通阈值分割
BinaryThreshold = 1,//自动阈值分割
}
public enum 自动阈值分割方法
{
max_separability = 0,
smooth_histo = 1,
}
public enum 亮或暗
{
dark = 0,
light = 1
}
然后构造函数:自动阈值分割,普通阈值分割
public ThresholdDef(int MaxGray,int MinGray)
{
_Segment= 阈值分割方式.Threshold;//阈值分割为普通型
_MaxGray =MaxGray;
_MinGray=MinGray;
}
public ThresholdDef(自动阈值分割方法 segmentMothd, 亮或暗 lightOrDark)
{
_Segment= 阈值分割方式.BinaryThreshold;
_SegmentMothd = segmentMothd;
_LightOrDark = lightOrDark;
}
以下是完整代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Algorithm //域名可以更改
{
public enum 阈值分割方式
{
Threshold = 0,//普通阈值分割
BinaryThreshold = 1,//自动阈值分割
}
public enum 自动阈值分割方法
{
max_separability = 0,
smooth_histo = 1,
}
public enum 亮或暗
{
dark = 0,
light = 1
}
public class ThresholdDef
{
//判断阈值分割的方式 是自动还是普通
public 阈值分割方式 _Segment;
//普通阈值分割
//成员变量
public int _MaxGray;
public int _MinGray;
public ThresholdDef(int MaxGray,int MinGray)
{
_Segment= 阈值分割方式.Threshold;//阈值分割为普通型
_MaxGray =MaxGray;
_MinGray=MinGray;
}
//自动阈值分割
//成员变量
public 自动阈值分割方法 _SegmentMothd;//判断自动阈值分割是用的max_separability 还是smooth_histo
public 亮或暗 _LightOrDark;//判断自动阈值分割中的亮暗
public ThresholdDef(自动阈值分割方法 segmentMothd, 亮或暗 lightOrDark)
{
_Segment= 阈值分割方式.BinaryThreshold;
_SegmentMothd = segmentMothd;
_LightOrDark = lightOrDark;
}
}
}
2)封装图像
新建一个处理图像的类ImageHelper:
1.读取图片
//读取图片
public static bool ReadImage(out HObject hImage, string filename, HWindow window)
2.构建一个静态的布尔型的ReadImage方法
-
bool
:这是方法的返回类型,表示该方法将返回一个布尔值 (true
或false
)。布尔值通常用于表示成功与否或是非状态。 -
string filename
:这是一个普通的参数,表示图像文件的路径和文件名。方法将读取这个文件。 -
HWindow window
:这是一个窗口对象,通常用于显示图像。在图像处理或计算机视觉库中,HWindow
用于显示或绘制图像。
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);
//设置显示范围
//HWindowControl.HalconWindow -->控件的句柄 设置显示范围
HOperatorSet.SetPart(window, 0, 0, (height - 1), (width - 1));
//显示
HOperatorSet.DispObj(hImage, window);
return true;
}
catch
{
hImage = null;
return false;
}
}
3.构建静态布尔型普通分割方法
//图片阈值分割
public static bool Threshold(HObject hImage, out HObject Region, int Min, int Max)
{
HOperatorSet.Threshold(hImage, out Region, Min, Max);
return true;
}
4.构建静态布尔型自动分割方法
HOperatorSet.BinaryThreshold
是 Halcon 库中的一个方法,用于进行图像的二值化处理。这个方法的参数包括:
hImage
:输入图像对象。out Region
:输出参数,表示二值化后的区域。segmentMethod.ToString()
:将分割方法枚举或类型转换为字符串,以便传递给BinaryThreshold
方法。lightOrDark.ToString()
:将亮或暗枚举或类型转换为字符串,指定二值化是为了提取亮部还是暗部。out shuchu
:接收方法输出的HTuple。
public static bool BinaryThreshold(HObject hImage, out HObject Region, 自动阈值分割方法 segmentMothd, 亮或暗 lightOrDark)
{
HTuple shuchu;
HOperatorSet.BinaryThreshold(hImage, out Region, segmentMothd.ToString(), lightOrDark.ToString(), out shuchu );
return true;
}
5.构建 ThresholdALL
方法处理图像的阈值分割。它根据 ThresholdDef
的 _Segment
属性选择不同的分割方法。
public static bool ThresholdALL(HObject hImage,out HObject Region,ThresholdDef thresholdDef)
{
Region = null;
switch (thresholdDef._Segment)
{
case 阈值分割方式.Threshold:
Console.WriteLine("我调用了普通阈值分割 Threshold");
return Threshold(hImage, out Region, thresholdDef._MinGray, thresholdDef._MinGray);
case 阈值分割方式.BinaryThreshold:
Console.WriteLine("我调用了自动阈值分割 BinaryThreshold");
return BinaryThreshold(hImage, out Region, thresholdDef._SegmentMothd, thresholdDef._LightOrDark);
default:
return false;
}
}
以下是完整代码:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using HalconDotNet;
namespace Algorithm //域名 算法
{
//这个类就是用来图像处理的算法类 图片读取 图片分割
public class ImageHelper
{
//读取图片
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);
//设置显示范围
//HWindowControl.HalconWindow -->控件的句柄 设置显示范围
HOperatorSet.SetPart(window, 0, 0, (height - 1), (width - 1));
//显示
HOperatorSet.DispObj(hImage, window);
return true;
}
catch
{
hImage = null;
return false;
}
}
//图片阈值分割
public static bool Threshold(HObject hImage, out HObject Region, int Min, int Max)
{
HOperatorSet.Threshold(hImage, out Region, Min, Max);
return true;
}
public static bool BinaryThreshold(HObject hImage, out HObject Region, 自动阈值分割方法 segmentMothd, 亮或暗 lightOrDark)
{
HTuple shuchu;
HOperatorSet.BinaryThreshold(hImage, out Region, segmentMothd.ToString(), lightOrDark.ToString(), out shuchu );
return true;
}
//写一个总的类来判断阈值分割是否封装成功
public static bool ThresholdALL(HObject hImage,out HObject Region,ThresholdDef thresholdDef)
{
Region = null;
switch (thresholdDef._Segment)
{
case 阈值分割方式.Threshold:
Console.WriteLine("我调用了普通阈值分割 Threshold");
return Threshold(hImage, out Region, thresholdDef._MinGray, thresholdDef._MinGray);
case 阈值分割方式.BinaryThreshold:
Console.WriteLine("我调用了自动阈值分割 BinaryThreshold");
return BinaryThreshold(hImage, out Region, thresholdDef._SegmentMothd, thresholdDef._LightOrDark);
default:
return false;
}
}
}
}
3)测试类
为了测试是否封装成功,需要分别创建两个按钮,一个是用来测试封装图片是否成功,另一个是测试阈值分割和自动阈值分割是否封装成功
窗体如图所示:
阈值分割的按钮的点击事件处理
private HObject ho_image;
private void button_threshod_Click(object sender, EventArgs e)
{
string filename = "E:\\zhizao\\照片\\die_03\\die_03.png";
bool result = Algorithm.ImageHelper.ReadImage(out ho_image, filename, hWindowControl1.HalconWindow);
HObject Region;
Algorithm.ThresholdDef thresholdDef=new Algorithm.ThresholdDef(自动阈值分割方法.max_separability,亮或暗.dark);
//Algorithm.ThresholdDef thresholdDef = new Algorithm.ThresholdDef(11, 25);//实例化普通阈值分割
Algorithm.ImageHelper.ThresholdALL(ho_image, out Region, thresholdDef);
//显示窗体
HOperatorSet.DispObj(Region, hWindowControl1.HalconWindow);
}
读取照片的点击事件
private void button_ReadImage_Click(object sender, EventArgs e)
{
string filename = "E:\\zhizao\\照片\\die_03\\die_03.png";
bool result = Algorithm.ImageHelper.ReadImage(out ho_image, filename, hWindowControl1.HalconWindow);
if (result != true)
{
MessageBox.Show(" Algorithm.ImageHelper.ReadImage 失败");
}
}
结果如果所示:
以上全部代码
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 Algorithm;
using HalconDotNet;
namespace 练习封装
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private HObject ho_image;
private void button_threshod_Click(object sender, EventArgs e)
{
string filename = "E:\\zhizao\\照片\\die_03\\die_03.png";
bool result = Algorithm.ImageHelper.ReadImage(out ho_image, filename, hWindowControl1.HalconWindow);
HObject Region;
Algorithm.ThresholdDef thresholdDef=new Algorithm.ThresholdDef(自动阈值分割方法.max_separability,亮或暗.dark);
//Algorithm.ThresholdDef thresholdDef = new Algorithm.ThresholdDef(11, 25);//实例化普通阈值分割
Algorithm.ImageHelper.ThresholdALL(ho_image, out Region, thresholdDef);
//显示窗体
HOperatorSet.DispObj(Region, hWindowControl1.HalconWindow);
}
private void button_ReadImage_Click(object sender, EventArgs e)
{
string filename = "E:\\zhizao\\照片\\die_03\\die_03.png";
bool result = Algorithm.ImageHelper.ReadImage(out ho_image, filename, hWindowControl1.HalconWindow);
if (result != true)
{
MessageBox.Show(" Algorithm.ImageHelper.ReadImage 失败");
}
}
}
}