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

本篇使用的项目为:filter2D

#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);
	// 自定义滤波 - 均值卷积
	int k = 15;
	Mat mkernel = Mat::ones(k, k, CV_32F) / (float)(k*k);

	Mat dst;
	filter2D(src, dst, -1, mkernel, Point(-1, -1), 0, BORDER_DEFAULT);
	imshow("custom mean filter", dst);

	// 非均值滤波
	Mat roberts = (Mat_<int>(2, 2) << 1, 0, 0, -1);

	Mat result;
	filter2D(src, result, CV_32F, roberts, Point(-1, -1), 127, BORDER_DEFAULT);
	convertScaleAbs(result, result);
	imshow("robot filter", result);

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

自定义滤波的核心就是自定义卷积核

filter2D:使用自定义卷积核对图像做卷积操作

  • src:输入图像
  • dst:输出图像,具有和src相同的尺寸和通道数
  • ddepth:dst的深度
  • kernel:自定义卷积核,更准确地说法应该是相关核,因为实际上是做互相关。会引用到所有通道,如果想在不同通道应用不同的卷积核,则需要先将通道分离进行单独的处理
  • anchor:锚点
  • delta:在储存目标图像前可选的添加到像素的值,可用于提升亮度。 默认值为0
  • borderType:图像边缘处理方式

关于自定义卷积核,例如:

3*3均值滤波:

Mat kernel = Mat::ones(3, 3, CV_32F) / (float)(3*3);

2*2非均值滤波器

Mat roberts = (Mat_<int>(2, 2) << 1, 0, 0, -1); // roberts算子

convertScaleAbs:缩放、计算绝对值并将结果转换为8-bit

void convertScaleAbs(InputArray src, OutputArray dst, double alpha = 1, double beta = 0);

$$dst= \texttt{saturate_cast<uchar>} (|src* alpha+beta|)$$