本系列代码托管于:https://github.com/chintsan-code/opencv4-tutorials

本篇使用的项目为:edge_preserving_filters

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, const char** argv) {
	Mat src = imread("../sample/example.png");
	if (src.empty()) {
		cout << "could not load image..." << endl;
		return -1;
	}
	namedWindow("input", WINDOW_AUTOSIZE);
	imshow("input", src);

	// 均值滤波
	Mat dst;
	blur(src, dst, Size(5, 5));
	imshow("mean denoise demo", dst);

	// 中值滤波
	medianBlur(src, dst, 5);
	imshow("median denoise demo", dst);

	// 高斯滤波
	GaussianBlur(src, dst, Size(5, 5), 0);
	imshow("gaussian denoise demo", dst);

	// 双边滤波
	bilateralFilter(src, dst, 0, 50, 10);
	imshow("bilateral denoise demo", dst);

	// 非局部均值滤波
	Mat gray, result2;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	fastNlMeansDenoisingColored(src, dst, 3., 3., 7, 21);
	imshow("NLM denoise demo", dst);
	fastNlMeansDenoising(gray, result2, 15, 10, 30);
	imshow("NLM denoise demo2", result2);

	waitKey(0);
	destroyAllWindows();
	return 0;
}

均值滤波和高斯滤波的缺点

  • 均值滤波:没有考虑到锚点出像素对整体比较大的贡献,而是将其与其他位置都乘以一样大的权重,事实上应该给锚点出最大的权重
  • 高斯滤波:虽然有将中心处(锚点)的权重设置为最大,但是没有考虑到与周围像素点差异比较大的情况,对边缘的保留不够

bilateralFilter:高斯双边滤波

常用于磨皮

void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT );
  • src:输入图像,8-bit或浮点数,单通道或3通道图像
  • dst:输出图像,与src具有相同的尺寸和类型
  • d:在过滤过程中每个像素邻域的直径。如果是非正数,则从 sigmaSpace 计算。一般设0,即使用自动计算
  • sigmaColor:构建高斯核函数,生成权重Wr
  • sigmaSpace:构建高斯核函数,生成权重Wd
  • borderType:图像边缘处理方式

fastNlMeansDenoising:针对灰度图像的非局部均值滤波

void fastNlMeansDenoising( InputArray src, OutputArray dst, float h = 3, int templateWindowSize = 7, int searchWindowSize = 21);
  • src:输入图像,8-bit的1、2、3、4通道图像
  • dst:输出图像,与src具有相同的尺寸和类型
  • h:调节滤波器强度的参数数组,一个参数应用于所有通道或每个通道一个参数在 dst。 大h值完美去除噪声但也去除图像细节,较小h值保留细节但也保留一些噪声
  • templateWindowSize:模板窗口大小,建议值7
  • searchWindowSize:搜索窗口大小,建议值21

fastNlMeansDenoisingColored:针对彩色图像的非局部均值滤波

void fastNlMeansDenoisingColored( InputArray src, OutputArray dst, float h = 3, float hColor = 3, int templateWindowSize = 7, int searchWindowSize = 21);
  • src:输入,8-bit三通道图像
  • dst:输出,与src具有相同的尺寸和类型
  • h:较大的 h 值可以完美去除噪声但也去除图像细节,较小的 h 值保留细节但也保留一些噪声
  • hColor:与 h 相同,但用于颜色分量。 对于大多数图像,值等于 10 就足以去除彩色噪声并且不会扭曲颜色
  • templateWindowSize:模板窗口大小,建议值7
  • searchWindowSize:搜索窗口大小,建议值21