在学习图像滤波中了解到图像滤波具有可分离性,首先理解可分离滤波的概念:可分离性指的是先对X(Y)方向滤波,再对Y(X)方向滤波的结果与将两个方向联合滤波器的整体滤波结果相同。
两个滤波器的联合就是将两个方向的滤波器相乘,一个是一维行向量,一个是一维列向量,相乘得到的是一个矩阵滤波器即联合滤波器。
如果在使用filter2D()函数进行滤波前计算联合滤波器,需要调用两次的filter2D函数,实现起来比较冗杂。故在OpenCV4中提供了sepFilter2D()滤波函数,此函数可以输入两个方向的滤波器。
官方给出的函数原型为:
void cv::sepFilter2D(InputArray src,
OutputArray dst,
int ddepth,
InputArray kernelX,
InputArray kernelY,
Point anchor = Point(-1,-1),
double delta = 0,
int borderType = BORDER_DEFAULT
)
参数详解如下:
对比一下filter2D()函数的原型:
void cv::filter2D(InputArray src,
OutputArray dst,
int ddepth,
InputArray kernel,
Point anchor=Point(-1, -1),
double delta=0,
int borderType=BORDER_DEFAULT
)
参数详解可以见:cv.filter2D() 函数详解https://blog.csdn.net/hysterisis/article/details/113097507
可以发现sepFilter2D()可以输入两个方向的卷积核。而filter2D()函数需要通过滤波器尺寸区分滤波操作是作用在X还是Y方向上。
在此比较了filter2D()函数依次进行两个方向的滤波的结果与sepFilter2D()函数实现联合滤波的结果。同时将两个方向的滤波器核输入到sepFilter2D()中,验证两种结果是否相同。最后利用自定义的滤波器,对图像依次进行X方向滤波和Y方向滤波,查看滤波结果是否与使用联合滤波器的滤波结果一致。
实现代码如下:
//============================代码清单 *可分离图像滤波*==========================
#include
#include
using namespace cv;
using namespace std;
int main()
{
system("color F0"); //更改输出界面颜色
float points[25] = { 1,2,3,4,5,
6,7,8,9,10,
11,12,13,14,15,
16,17,18,19,20,
21,22,23,24,25 };
Mat data(5, 5, CV_32FC1, points);
//X方向、Y方向和联合滤波器的构建
Mat a = (Mat_(3, 1) << -1, 3, -1);
Mat b = a.reshape(1, 1);
Mat ab = a * b;
//验证高斯滤波的可分离性
Mat gaussX = getGaussianKernel(3, 1);
Mat gaussData, gaussDataXY;
GaussianBlur(data, gaussData, Size(3, 3), 1, 1, BORDER_CONSTANT);
sepFilter2D(data, gaussDataXY, -1, gaussX, gaussX, Point(-1, -1), 0, BORDER_CONSTANT);
//输入两种高斯滤波的计算结果
cout << "gaussData=" << endl
<< gaussData << endl << endl;
cout << "gaussDataXY=" << endl
<< gaussDataXY << endl << endl;
//线性滤波的可分离性
Mat dataYX, dataY, dataXY, dataXY_sep;
filter2D(data, dataY, -1, a, Point(-1, -1), 0, BORDER_CONSTANT);
filter2D(dataY, dataYX, -1, b, Point(-1, -1), 0, BORDER_CONSTANT);
filter2D(data, dataXY, -1, ab, Point(-1, -1), 0, BORDER_CONSTANT);
sepFilter2D(data, dataXY_sep, -1, b, b, Point(-1, -1), 0, BORDER_CONSTANT);
//输出分离滤波和联合滤波的计算结果
cout << "dataY=" << endl
<< dataY << endl << endl;
cout << "dataYX=" << endl
<< dataYX << endl << endl;
cout << "dataXY=" << endl
<< dataXY << endl << endl;
cout << "dataXY_sep=" << endl
<< dataXY_sep << endl << endl;
//对图像的分离操作
Mat img = imread("D:\\folder\\图片素材\\1.tif");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat imgYX, imgY, imgXY;
filter2D(img, imgY, -1, a, Point(-1, -1), 0, BORDER_CONSTANT);
filter2D(imgY, imgYX, -1, b, Point(-1, -1), 0, BORDER_CONSTANT);
filter2D(img, imgXY, -1, ab, Point(-1, -1), 0, BORDER_CONSTANT);
imshow("img", img);
imshow("imgY", imgY);
imshow("imgYX", imgYX);
imshow("imgXY", imgXY);
waitKey(0);
return 0;
}
得出的数据矩阵滤波结果:
图像滤波结果: