Blur均值模糊
//均值模糊,卷积核权重系数一样
void Blur(InputArray src,
OutputArray dst,
Size ksize,
Point? anchor = null,
BorderTypes borderType = BorderTypes.Reflect101)
参数 | 说明 |
InputArray src | 输入图像:可以任意通道,但深度必须为CV_8U, CV_16U, CV_16S, CV_32F or CV_64F |
OutputArray dst | 输出图像:与源图像有同样的大小和类型 |
Size ksize | 平滑核的大小:核越大越模糊 |
Point? anchor | 锚点:默认为(-1,-1),表示核中心 |
BorderTypes borderType | 边缘填充方式 |
卷积核:
GaussianBlur高斯模糊
//高斯模糊,卷积核系数中间高,周围低(按高斯函数计算得到)
void GaussianBlur(InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY = 0.0,
BorderTypes borderType = BorderTypes.Reflect101)
参数 | 说明 |
InputArray src | 输入图像:可以任意通道,但深度必须为CV_8U, CV_16U, CV_16S, CV_32F or CV_64F |
OutputArray dst | 输出图像:与源图像有同样的大小和类型 |
Size ksize | 高斯核:width与heigt可不一致,但必须为正奇数; 都为0的话,按sigma计算; 值越大越模糊 |
double sigmaX | 高斯核在x轴的标准差:值越大越模糊 |
double sigmaY | 高斯核在y轴的标准差:如果为0,则等于sigmaX; 如果sigmaX与sigmaY都为0,按Size计算,具体参考GetGaussianKernel |
BorderTypes borderType | 边缘填充方式 |
高斯核函数:
GetGaussianKernel获取高斯核滤波系数
Mat? GetGaussianKernel(int ksize,
double sigma,
MatType? ktype = null)
参数 | 说明 |
int ksize | 核大小:正奇数 |
double sigma | 高斯标准差:小于等于0时,按 sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8 计算 |
MatType? ktype | 滤波系数类型:CV_32F 或 CV_64F,默认为CV_64F |
MedianBlur中值模糊
//中值模糊,用核大小图像的中间值(排序后取中间值)填充(Blur是平均值,注意之间的不同)
//边缘填充方式为: BORDER_REPLICATE
void MedianBlur(InputArray src,
OutputArray dst,
int ksize)
参数 | 说明 |
InputArray src | 输入图像:1、3或4通道图像; 当ksize为3或5时,可以CV_8U, CV_16U, or CV_32F 其它时,只能为CV_8U |
OutputArray dst | 输出图像:与源图像有同样的大小和类型 |
int ksize | 核大小:必须为大于1的奇数(即:3、5、7等等) |
BilateralFilter双边模糊
//双边模糊,降低噪声的同时,保持边缘的锐化;缺点是速度比其他的慢
void BilateralFilter(InputArray src,
OutputArray dst,
int d,
double sigmaColor,
double sigmaSpace,
BorderTypes borderType = BorderTypes.Reflect101)
参数 | 说明 |
InputArray src | 输入图像:8位或浮点型,1或3通道图像 |
OutputArray dst | 输出图像:与源图像有同样的大小和类型 |
int d | 滤波过程中使用的每个像素邻域的直径。如果它是非正数,则从sigmaSpace计算。 |
double sigmaColor | 颜色空间滤波器的sigma值:这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。 |
double sigmaSpace | 坐标空间滤波器的sigma值:数值越大,意味着只要颜色足够接近,更远的像素就会相互影响。当d>0,d指定了邻域大小与sigmaSpace无关。否则,d于sigmaSpace成正比。 |
BorderTypes borderType | 边缘填充方式 |
源码示例
Mat src;
public void Run(ParamBase paramBase)
{
src = Cv2.ImRead(ImagePath.LenaColor);
if (src.Empty()) throw new Exception("图像读取有误");
Cv2.ImShow("Src", src);
using var blurDst = new Mat();
//均值模糊
Cv2.Blur(src, blurDst, new Size(7, 7));
Cv2.ImShow("Blur", blurDst);
//获取高斯核
//sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8
var gKernel = Cv2.GetGaussianKernel(7, 1);
using var gaussianDst = new Mat();
//高斯模糊
Cv2.GaussianBlur(src, gaussianDst, new Size(7, 7), 1.5d);
Cv2.ImShow("GaussianBlur", gaussianDst);
using var meanDst = new Mat();
//中值模糊
Cv2.MedianBlur(src, meanDst, 7);
Cv2.ImShow("MedianBlur", meanDst);
//双边模糊
TestBilateralFilter();
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
int bi_d = 15;//核直径
int bi_sigmaColor = 20;//颜色空间方差
int bi_sigmaSpace = 50;//坐标空间方差
string winName = "双边模糊";
string trackBarName_d = "d";
string trackBarName_sigmaColor = "sigmaColor";
string trackBarName_sigmaSpace = "sigmaSpace";
//是否正在创建滚动条
bool creatingTrackBar = true;
/// <summary>
/// 测试双边模糊
/// </summary>
private void TestBilateralFilter()
{
Cv2.NamedWindow(winName, WindowFlags.AutoSize);
//创建时,若对应的value不为0,会触发trackbarCallback函数
Cv2.CreateTrackbar(trackBarName_d, winName, ref bi_d, 50, trackbarCallback);
Cv2.CreateTrackbar(trackBarName_sigmaColor, winName, ref bi_sigmaColor, 100, trackbarCallback);
Cv2.CreateTrackbar(trackBarName_sigmaSpace, winName, ref bi_sigmaSpace, 100, trackbarCallback);
creatingTrackBar = false;
UpdateBiFilterImg();
while (true)
{
var key = Cv2.WaitKey(50);
if (key == (int)Keys.Escape) return;
//超过500毫秒才刷新,防止滚动太快,卡顿
if (lastTrackBarValueChangedTime < DateTime.Now.AddMilliseconds(-500) && needToUpdateBiFilterImg)
{
UpdateBiFilterImg();
}
}
}
//最后滚动条值修改时间
private DateTime lastTrackBarValueChangedTime = DateTime.MinValue;
//是否需要更新双边模糊输出图像
private bool needToUpdateBiFilterImg = false;
/// <summary>
/// 滚动条回调函数
/// </summary>
/// <param name="pos"></param>
/// <param name="userData"></param>
private void trackbarCallback(int pos, IntPtr userData)
{
if (creatingTrackBar) return;
lastTrackBarValueChangedTime = DateTime.Now;
needToUpdateBiFilterImg = true;
}
/// <summary>
/// 刷新双边模糊输出图像
/// </summary>
private void UpdateBiFilterImg()
{
using var biDst = new Mat();
Cv2.BilateralFilter(src, biDst, bi_d, bi_sigmaColor, bi_sigmaSpace);
Cv2.ImShow(winName, biDst);
needToUpdateBiFilterImg = false;
}