目录
Cv2.GetStructuringElement()创建形态学操作的结构元素
Cv2.MorphologyEx() 形态学运算(腐蚀膨胀、开闭运算)
核心知识:
-
均值滤波:一种常用的图像平滑处理方法,通过将像素的领域内像素值取平均来减少图像中的噪声,从而达到图像平滑的效果,图像会更模糊。
-
膨胀(Dilation):形态学操作,用于扩展图像中的亮区域(像素值较大的区域)。它的原理是在图像上滑动结构元素,将结构元素覆盖区域内的像素设置为最大像素值。膨胀操作可以增加亮区域的大小,填充小的空洞,以及连接相邻的区域。
-
腐蚀(Erosion):形态学操作,用于缩小图像中的亮区域,同时扩展暗区域(像素值较小的区域)。原理是在图像上滑动结构元素,将结构元素覆盖区域内的像素设置为最小像素值。腐蚀操作可以消除小的噪声、分割相连的区域,并改变区域的形状。
-
开运算(Opening):先进行腐蚀操作,然后进行膨胀操作。通常用于去除小的噪声点。
-
闭运算(Closing): 先进行膨胀操作,然后进行腐蚀操作。通常用于填充小的空洞。
核心函数:
CV2.Blur() 均值滤波
Cv2.Blur(Mat src, Mat dst, Size ksize, Point anchor = null, BorderTypes borderType = BorderTypes.Default);
src
:输入图像。dst
:输出图像,滤波操作的结果将存储在这里。ksize
:内核大小,应为正奇数。anchor
:内核锚点,默认为中心点。borderType
:边界扩展方式,默认为BorderTypes.Default
。
Cv2.GaussianBlue() 高斯滤波
void Cv2.GaussianBlur( src, dst, Size ksize, double sigmaX, double sigmaY = 0, BorderTypes borderType = BorderTypes.Default);
ksize
:高斯内核的大小,必须是正奇数。这个参数决定了模糊的程度。sigmaX
:X 方向上的高斯核标准差。如果设置为 0,则由ksize.width
计算得出。sigmaY
:Y 方向上的高斯核标准差。如果设置为 0,则与sigmaX
相同。borderType
:边界填充方式,默认为BorderTypes.Default
。
Cv2.GetStructuringElement()创建形态学操作的结构元素
用于创建膨胀和腐蚀操作所需的结构元素
Mat Cv2.GetStructuringElement(MorphShapes shape, Size ksize, Point anchor = null);
shape
: 结构元素的形状,可以是MorphShapes.Rect
(矩形)、MorphShapes.Ellipse
(椭圆)或MorphShapes.Cross
(十字形)之一。ksize
: 结构元素的大小,即矩阵的尺寸。anchor
: 结构元素的锚点,默认为null
。在大多数情况下,不需要设置这个参数。
Cv2.Erode()腐蚀
Cv2.Erode(Mat src, Mat dst, Mat kernel, Point anchor, int iterations, BorderTypes borderType, Scalar borderValue);
src
:输入图像。dst
:输出图像,腐蚀操作的结果将存储在这里。kernel
:结构元素,定义腐蚀的形状和大小。anchor
:结构元素的锚点,默认为中心点。iterations
:腐蚀的迭代次数,默认为1。borderType
:边界扩展方式,默认为BorderTypes.Default
。borderValue
:边界扩展时填充的值,默认为默认的边界值。
Cv2.Dilate() 膨胀
Cv2.Dilate(Mat src, Mat dst, Mat kernel, Point anchor = null, int iterations = 1, BorderTypes borderType = BorderTypes.Default, Scalar borderValue = default)
参数同腐蚀
Cv2.MorphologyEx() 形态学运算(腐蚀膨胀、开闭运算)
Cv2.MorphologyEx(Mat src, Mat dst, MorphTypes op, Mat kernel, OpenCvSharp.Point anchor = null, int iterations = 1, BorderTypes borderType = BorderTypes.Constant, Scalar borderValue = default);
src
: 输入图像,进行形态学操作的源图像。dst
: 输出图像,形态学操作的结果将会保存在这里。op
: 形态学操作的类型,可选项为MorphTypes
枚举,包括MorphTypes.Erode
、MorphTypes.Dilate
、MorphTypes.Open(开运算)
、MorphTypes.Close(闭运算)
等。kernel
: 结构元素,定义了形态学操作的形状和大小。anchor
: 结构元素的锚点位置,默认为null
,表示结构元素的锚点位于中心。iterations
: 形态学操作的迭代次数,表示应用操作的次数,默认为 1。
示例:
Mat srcImage = Cv2.ImRead("input.jpg", ImreadModes.Grayscale);
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));
// 腐蚀
Mat erodedImage = new Mat();
Cv2.Erode(srcImage, erodedImage, element);
// 膨胀
Mat dilatedImage = new Mat();
Cv2.Dilate(srcImage, dilatedImage, element);
// 开运算
Cv2.MorphologyEx(srcImage, dstImageOpen, MorphTypes.Open,element);
// 闭运算
Cv2.MorphologyEx(srcImage, dstImageClose, MorphTypes.Close, element);
源代码:
1、创建窗体程序,相关控件
2、源码:
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 OpenCvSharp;
using OpenCvSharp.Extensions;
namespace 图像模糊_均值滤波
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Mat srcImage; // 成员变量用于在不同方法中共享图像
private void button1_Click(object sender, EventArgs e)
{
try
{
//选择图像文件
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Image Files(*.jpg;*.png;*.bmp;*)|*.jpg;*.png;*.bmp;";
if (openFileDialog.ShowDialog() != DialogResult.OK)
return;
string imagePath = openFileDialog.FileName;
// 读取图像
srcImage = Cv2.ImRead(imagePath);
// 显示原图
//Cv2.NamedWindow("原图", WindowFlags.Normal);
//Cv2.ResizeWindow("原图", 800, 640);
Cv2.ImShow("原图", srcImage);
}
catch (OpenCvSharp.OpenCVException ex)
{
//处理异常
MessageBox.Show("图像处理发生错误" + ex.Message);
}
}
private void button2_Click(object sender, EventArgs e)
{
if (srcImage == null)
{
MessageBox.Show("请先加载图像!");
return;
}
// 均值滤波
Mat dstImage = new Mat();
Cv2.Blur(srcImage, dstImage, new OpenCvSharp.Size() { Width = 7, Height = 7 });
Cv2.ImShow("均值滤波效果", dstImage);
Cv2.WaitKey();
}
// 腐蚀
private void button3_Click(object sender, EventArgs e)
{
if (srcImage == null)
{
MessageBox.Show("请先加载图像!");
return;
}
// 进行腐蚀操作
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size() { Width = 15, Height = 15 });
Mat dstImage2 = new Mat();
Cv2.Erode(srcImage, dstImage2, element);
Cv2.ImShow("腐蚀效果", dstImage2);
Cv2.WaitKey();
}
// 膨胀
private void button4_Click(object sender, EventArgs e)
{
if (srcImage == null)
{
MessageBox.Show("请先加载图像!");
return;
}
// 进行膨胀操作
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size() { Width = 15, Height = 15 });
Mat dstImage3 = new Mat();
Cv2.Dilate(srcImage, dstImage3, element);
Cv2.ImShow("膨胀效果", dstImage3);
Cv2.WaitKey();
}
private void button5_Click(object sender, EventArgs e)
{
if (srcImage == null)
{
MessageBox.Show("请先加载图像!");
return;
}
Mat dstImage4 = new Mat();
Cv2.GaussianBlur(srcImage, dstImage4, new OpenCvSharp.Size(3, 3), 0);
Cv2.ImShow("高斯滤波", dstImage4);
Cv2.WaitKey();
}
// 开运算
private void button6_Click(object sender, EventArgs e)
{
if (srcImage == null)
{
MessageBox.Show("请先加载图片");
return;
}
Mat dstImage5 = new Mat();
// 先腐蚀后膨胀
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(-1, -1));
Cv2.MorphologyEx(srcImage, dstImage5, MorphTypes.Open,element);
Cv2.ImShow("开运算", dstImage5);
}
// 闭运算
private void button7_Click(object sender, EventArgs e)
{
if (srcImage == null)
{
MessageBox.Show("请先加载图片");
return;
}
Mat dstImage6 = new Mat();
// 先膨胀后腐蚀
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(-1, -1));
Cv2.MorphologyEx(srcImage, dstImage6, MorphTypes.Close, element);
Cv2.ImShow("闭运算", dstImage6);
}
// Canny算法边缘检测
private void button8_Click(object sender, EventArgs e)
{
Mat dstImage7 = new Mat();
Mat dstImage8 = new Mat();
Cv2.Blur(srcImage, dstImage7,new OpenCvSharp.Size(5,5));
Cv2.Canny(dstImage7, dstImage8, 30, 60);
Cv2.ImShow("Canny", dstImage8);
Cv2.WaitKey();
}
}
}
结果图: