使用filter2D()函数实现自定义线性滤波器。本节自定义一个均值滤波器,并更改核的大小,显示不同核的滤波效果。在前面的图像平滑部分,已经接触过相关的内容。CVer:【3】OpenCV图像处理模块(3)图像平滑
理论
相关
一般意义上,相关是用核遍历图像的运算。
什么是核
本质上说是一个固定大小的系数矩阵,且有一个锚点(anchor),通常位于核的中心。
核与相关运算
将锚点(anchor)放在图像一个像素的位置,核的系数分别于图像中对应位置的像素相乘,求和。求和结果作为图像中anchor点位置的运算结果。移动锚点,重复上述运算,最终得到整幅图像的相关运算结果。这个过程可以用下面公式表示。
OpenCV提供了filter2D()函数实现上述功能。
接下来的示例代码实现均值滤波。如果核大小为3,那么核为
分别执行核大小为3、5、7、9的均值滤波。
代码
// @tutorials imgproc module 11
// @文件 filter2D_demo.cpp
// @主题 自定义线性滤波器
// @修改 CVer
// @日期 2020年1月3日
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main ( int argc, char** argv )
{
Mat src, dst;
Mat kernel; //核
Point anchor;
double delta;
int ddepth; //输出图像深度
int kernel_size;//核大小
const char* window_name = "filter2D Demo";
const char* imageName = "lena.jpg";
src = imread( samples::findFile( imageName ), IMREAD_COLOR );
if( src.empty() )
{
printf(" Error opening imagen");
return EXIT_FAILURE;
}
//初始化参数
anchor = Point( -1, -1 );//表示中心
delta = 0;//增量为0
ddepth = -1;//表示输入输出类型一致
//循环,每隔0.5s更改滤波器的核大小,处理显示图像
int ind = 0;
for(;;)
{
//更新滤波的核大小,生成均值滤波的核
kernel_size = 3 + 2*( ind%5 );
kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);
//滤波,显示
//参数——输入图像、输出图像、输出图像类型、核、中心点、滤波后像素值增量、输出图像边界类型
filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
imshow( window_name, dst );
//按ESC退出
char c = (char)waitKey(500);
if( c == 27 )
{ break; }
ind++;
}
return EXIT_SUCCESS;
}
结果
均值滤波效果,核大小分别为3、5、7、9。