6.1均值滤波

目录

实验原理

示例代码

运行结果

注意事项

总结

实验代码

运行结果


实验原理

https://zhuanlan.zhihu.com/p/76188487

在OpenCV中,cv::blur函数用于对图像进行均值滤波(Mean Filter),这是一种线性滤波技术,主要用于平滑图像和去除噪声。均值滤波是一种线性滤波技术,它通过替换每个像素值为其邻域内的平均值来平滑图像,从而减少图像中的噪声。均值滤波器对于减少高斯噪声特别有效,但它可能会模糊边缘和其他细节。

函数原型

void blur(InputArray src, OutputArray dst, Size ksize, 
        Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT );

参数说明
src: 输入图像,它可以是多通道图像。
dst: 处理后的图像,与输入图像具有相同的尺寸和类型。
ksize: 内核大小,指定卷积核的大小,通常是一个正方形核,指定为一个 Size 对象。例如,Size(5, 5) 表示使用一个5x5的内核进行卷积操作。
anchor: 锚点位置,即内核相对于像素的位置。默认情况下(Point(-1, -1)),锚点位于内核中心。
borderType: 边界处理方式。当内核的一部分超出图像边界时,需要对这部分进行某种处理。默认为 BORDER_DEFAULT,通常意味着使用 BORDER_REFLECT_101。

常见的边界处理方式包括:
•BORDER_CONSTANT:用指定的常数值填充边界。
•BORDER_REPLICATE:边界像素值向外扩展。
•BORDER_REFLECT:反射边界,如12345反射为45454。
•BORDER_WRAP:循环边界,如12345循环为34512。


工作原理
均值滤波器的工作原理是对图像中的每个像素应用一个卷积核(Kernel),该核中的每个元素都是相等的权重(通常是1除以核的大小)。卷积核中的所有元素值相加求平均值,然后将这个平均值赋给当前像素点。

示例代码

下面是一个使用C++和OpenCV进行均值滤波的简单示例:

#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>

int main(int argc, char** argv)
{
	// 加载图像
	cv::Mat img = cv::imread("2B.png", cv::IMREAD_COLOR); // 读取彩色图像

	if (img.empty())
	{
		std::cout << "Could not open or find the image" << std::endl;
		return -1;
	}

	// 定义内核大小
	int kernel_size = 5; // 5x5 的内核
	cv::Size ksize(kernel_size, kernel_size);

	// 创建一个空的输出图像
	cv::Mat dst;

	// 应用均值滤波
	cv::blur(img, dst, ksize);

	// 显示结果
	cv::namedWindow("Original Image", cv::WINDOW_NORMAL);
	cv::imshow("Original Image", img);

	cv::namedWindow("Blurred Image", cv::WINDOW_NORMAL);
	cv::imshow("Blurred Image", dst);

	cv::waitKey(0);

	return 0;
}

运行结果

去除脸上毛孔

注意事项

  • 内核大小: 内核大小的选择会影响滤波的效果。较大的核可以产生更强烈的平滑效果,但可能会丢失更多的细节;较小的核则可以保留更多细节,但平滑效果较弱。
  • 性能: 在处理大图像或者使用大内核时,均值滤波可能比较耗时。
  • 边界效应: 在图像边界处,由于部分内核超出图像范围,因此边界上的像素可能会受到不同类型的处理,这取决于所选的边界类型。边界处理borderType参数决定了如何处理图像边缘的像素。

总结

均值滤波是一种简单有效的图像平滑方法,适用于去除图像中的噪声和平滑图像。通过调整卷积核的大小,可以控制平滑的程度。但是,它也会使图像中的边缘变得模糊,因此在某些应用中可能不是最佳选择。如果需要保留边缘细节,可以考虑使用其他类型的滤波器,如高斯滤波或者双边滤波。

实验代码

#include "pch.h"
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>

using namespace std;
using namespace cv;

//#pragma comment(lib, "opencv_world450d.lib")  //引用引入库 
//定义全局变量
Mat g_srcImage;         //定义输入图像
Mat g_dstImage;         //定义目标图像

const int g_nTrackbarMaxValue = 9;      //定义轨迹条最大值
int g_nTrackbarValue;                   //定义轨迹条初始值
int g_nKernelValue;                     //定义kernel尺寸

void on_kernelTrackbar(int, void*);     //定义回调函数

int main()
{
	g_srcImage = imread("A3.jpeg");

	//判断图像是否加载成功
	if (g_srcImage.empty())
	{
		cout << "图像加载失败!" << endl;
		return -1;
	}
	else
		cout << "图像加载成功!" << endl << endl;

	namedWindow("原图像", WINDOW_NORMAL);     //定义窗口显示属性
	imshow("原图像", g_srcImage);

	g_nTrackbarValue = 1;
	namedWindow("均值滤波", WINDOW_NORMAL);   //定义滤波后图像显示窗口属性

	//定义轨迹条名称和最大值
	char kernelName[20];
	sprintf(kernelName, "kernel尺寸 %d", g_nTrackbarMaxValue);

	//创建轨迹条
	createTrackbar(kernelName, "均值滤波", &g_nTrackbarValue, g_nTrackbarMaxValue, on_kernelTrackbar);
	on_kernelTrackbar(g_nTrackbarValue, 0);

	waitKey(0);

	return 0;
}

void on_kernelTrackbar(int, void*)
{
	//根据输入值重新计算kernel尺寸
	g_nKernelValue = g_nTrackbarValue * 2 + 1;

	//均值滤波函数
	blur(g_srcImage, g_dstImage, Size(g_nKernelValue, g_nKernelValue));

	imshow("均值滤波", g_dstImage);
}
 

运行结果

  • 16
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值