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

本篇使用的项目为:blur

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

using namespace cv;
using namespace std;

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

	// 均值模糊
	// 相当于和下面的卷积核做卷积操作:
	// 1 1 1
	// 1 1 1
	// 1 1 1
	Mat mean_dst;
	blur(src, mean_dst, Size(3, 3), Point(-1, -1));
	imshow("mean dst", mean_dst);

	// 高斯模糊
	Mat gauss_dst;
	GaussianBlur(src, gauss_dst, Size(5, 5), 15);
	imshow("gaussina dst", gauss_dst);

	// 盒子模糊 - 在这里等效于均值模糊
	Mat box_dst;
	boxFilter(src, box_dst, -1, Size(25, 25), Point(-1, -1), true, BORDER_DEFAULT);
	imshow("box dst", box_dst);
	
	waitKey(0);
	destroyAllWindows();
	return 0;
}

blur:均值模糊

void blur( InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT );
  • src:输入图像,可以为任意通道,当进行滤波时,各通道的处理是独立的。但是深度只能为CV_8U, CV_16U, CV_16S, CV_32F或CV_64F
  • dst:输出图像,与src具有相同的尺寸和类型
  • ksize:卷积核尺寸
  • anchor:锚点,将卷积结果赋值给哪个位置的像素。(-1, -1)代表卷积核中心位置
  • borderType:图像边缘处理方式。注意是在卷积之前进行填充
    • BORDER_CONSTANT:用指定像素值填充。iiiiii|abcdefgh|iiiiiii(用i填充)。在此不可用。
    • BORDER_REPLICATE:用边缘像素填充。aaaaaa|abcdefgh|hhhhhhh
    • BORDER_WRAP:包裹填充。cdefgh|abcdefgh|abcdefg。左填到右,右填到左,上填到下,下填到上
    • BORDER_REFLECT_101。以边界为对称轴反射复制像素。gfedcb|abcdefgh|gfedcba
    • BORDER_DEFAULT,即BORDER_REFLECT_101

关于锚点anchor:

opencv4入门笔记(16):图像模糊-萤火

关于边缘处理方式borderType,以BORDER_REFLECT_101为例:

opencv4入门笔记(16):图像模糊-萤火

GaussianBlur:高斯模糊。使用高斯滤波器进行滤波

一维高斯函数:

$$f(x)=e^{-\frac{x^2}{2\sigma^2}}$$

opencv4入门笔记(16):图像模糊-萤火

二维高斯函数:

$$f(x,y)=e^{-\frac{x^2 + y^2}{2\sigma^2}}$$

void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );
  • src:输入图像,可以为任意通道,当进行滤波时,各通道的处理是独立的。但是深度只能为CV_8U, CV_16U, CV_16S, CV_32F或CV_64F
  • dst:输出图像,与src具有相同的尺寸和类型
  • ksize:卷积核尺寸
    • 宽度和高度可以不一致,但必须为正的奇数或0
    • 当为0时,此时将通过sigma来自动计算
  • sigmaX:X方向的高斯核标准偏差
  • sigmaY:Y方向的高斯核标准偏差。如果sigmaY为0,那么它将会等于sigmaX;如果它们都等于0,将会通过ksize来自动计算
  • borderType:图像边缘处理方式

boxFilter:盒子模糊

opencv4入门笔记(16):图像模糊-萤火
void boxFilter( InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT );
  • src:输入图像
  • dst:输出图像,与输入具有相同的尺寸和类型
  • ddepth:输出图像的深度。当为-1时,与输入图像一致
  • ksize:卷积核尺寸
  • anchor:锚点
  • normalize:是否做归一化。当为true时,等效果于blur,事实上均值模糊blur就是归一化盒子模糊
  • borderType:图像边缘处理方式

高斯模糊与盒子模糊的差异

opencv4入门笔记(16):图像模糊-萤火

高斯模糊在中心位置(锚点)的卷积核权重会比周围的大,对细节保留得好一些。