OpenCV实现可分离滤波
短信预约 -IT技能 免费直播动态提醒
自定义滤波
无论是图像卷积还是滤波,在原图像上移动滤波器的过程中每一次的计算结果都不会影响到后面过程的计算结果,因此图像滤波是一个并行的算法,在可以提供并行计算的处理器中可以极大的加快图像滤波的处理速度。
图像滤波还具有可分离性
先对X(Y)方向滤波,再对Y(X)方向滤波的结果与将两个方向的滤波器联合后整体滤波的结果相同。两个方向的滤波器的联合就是将两个方向的滤波器相乘,得到一个矩形的滤波器
void filter2D( InputArray class="lazy" data-src, OutputArray dst, int ddepth,
InputArray kernel, Point anchor = Point(-1,-1),
double delta = 0, int borderType = BORDER_DEFAULT );
- class="lazy" data-src:待滤波图像
- dst:输出图像,与输入图像class="lazy" data-src具有相同的尺寸、通道数和数据类型。
- ddepth:输出图像的数据类型(深度),根据输入图像的数据类型不同拥有不同的取值范围,具体的取值范围在表5-1给出,当赋值为-1时,输出图像的数据类型自动选择。
- kernel:滤波器。
- anchor:内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。基准点即卷积核中与进行处理的像素点重合的点,其位置必须在卷积核的内部。
- delta:偏值,在计算结果中加上偏值。
- borderType:像素外推法选择标志,取值范围在表3-5中给出。默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。
void sepFilter2D( InputArray class="lazy" data-src, OutputArray dst, int ddepth,
InputArray kernelX, InputArray kernelY,
Point anchor = Point(-1,-1),
double delta = 0, int borderType = BORDER_DEFAULT );
- class="lazy" data-src:待滤波图像
- dst:输出图像,与输入图像class="lazy" data-src具有相同的尺寸、通道数和数据类型。
- ddepth:输出图像的数据类型(深度),根据输入图像的数据类型不同拥有不同的取值范围,具体的取值范围在表5-1给出,当赋值为-1时,输出图像的数据类型自动选择。
- kernelX:X方向的滤波器,
- kernelY:Y方向的滤波器。
- anchor:内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。基准点即卷积核中与进行处理的像素点重合的点,其位置必须在卷积核的内部。
- delta:偏值,在计算结果中加上偏值。
- borderType:像素外推法选择标志,取值范围在表3-5中给出。默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。
简单示例
//
// Created by smallflyfly on 2021/6/15.
//
#include "opencv2/highgui.hpp"
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main() {
float points[] = {
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);
// 验证高斯滤波器可分离
Mat gaussX = getGaussianKernel(3, 1);
cout << gaussX << endl;
Mat gaussDstData, gaussDataXY;
GaussianBlur(data, gaussDstData, Size(3, 3), 1, 1, BORDER_CONSTANT);
sepFilter2D(data, gaussDataXY, -1, gaussX, gaussX, Point(-1, -1), 0, BORDER_CONSTANT);
cout << gaussDstData << endl;
cout << gaussDataXY << endl;
cout << "######################################" << endl;
// Y方向上滤波
Mat a = (Mat_<float>(3, 1) << -1, 3, -1);
// X方向上滤波
Mat b = a.reshape(1, 1);
// XY联合滤波
Mat ab = a * b;
Mat dataX, dataY, dataXY1, dataXY2, dataSepXY;
filter2D(data, dataX, -1, b);
filter2D(dataX, dataXY1, -1, a);
filter2D(data, dataXY2, -1, ab);
sepFilter2D(data, dataSepXY, -1, a, b);
// 验证结果
cout << dataXY1 << endl;
cout << dataXY2 << endl;
cout << dataSepXY << endl;
Mat im = imread("test.jpg");
resize(im, im, Size(0, 0), 0.5, 0.5);
Mat imX, imY, imXY, imSepXY;
filter2D(im, imX, -1, b);
filter2D(imX, imXY, -1, a);
sepFilter2D(im, imSepXY, -1, a, b);
imshow("imXY", imXY);
imshow("imSepXY", imSepXY);
waitKey(0);
destroyAllWindows();
return 0;
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341