1.目的
(1)学习如何使用openCV的filter2D函数实现滤波器
2.原理
[1]卷积
卷积是每一个图像快和某个算子之间进行运算的操作
[2]核
核说白了就是一个固定大小的数值数组。该数组带有一个 锚点 ,一般位于数组中央。
[3]卷积操作
<1>将核的锚点放在该特定位置的像素上,同时,核内的其他值与该像素邻域的各像素重合;
<2>将核内各值与相应像素值相乘,并将乘积相加;
<3>将所得结果放到与锚点对应的像素上;
<4>对图像所有像素重复上述过程。
3.部分代码解释
(1)filter2D
/*
filter2D参数解释
src:输入图像
dst:输出图像
depth:图像深度,若为负值,则深度和原始图像一样
anchor:锚点,一般设置为卷积核中心
delta:偏置,卷积操作后加在被处理像素上
BORDER_DEFAULT:保持默认值,更多细节会在后续给出
*/
filter2D(src, dst, src.depth(), kernel, anchor, delta, BORDER_DEFAULT);
4.完整代码
(1)CommonInclude.h
#ifndef COMMON_INCLUDE
#define COMMON_INCLUDE
#include<iostream>
using namespace std;
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
#endif
(2)LinearFilter.cpp
#include "CommonInclude.h"
int kernel_size = 1;
int max_kernel_size = 21;
char windowName[] = "Linear Filter";
Mat src, dst;
void LinearFilter(int, void*){
//归一化核
Mat kernel = Mat::ones(2*kernel_size+1, 2*kernel_size+1, CV_32F)*1.0/((2*kernel_size+1)*(2*kernel_size+1));
Point anchor = Point(-1,-1);
double delta = 0;
/*
filter2D参数解释
src:输入图像
dst:输出图像
depth:图像深度,若为负值,则深度和原始图像一样
anchor:锚点,一般设置为卷积核中心
delta:偏置,卷积操作后加在被处理像素上
BORDER_DEFAULT:保持默认值,更多细节会在后续给出
*/
filter2D(src, dst, src.depth(), kernel, anchor, delta, BORDER_DEFAULT);
imshow(windowName, dst);
}
int main(int argc, char** argv){
if(argc < 2){
cout << "more parameters are required!!!" << endl;
return(-1);
}
namedWindow(windowName, CV_WINDOW_AUTOSIZE);
src = imread(argv[1]);
if(!src.data){
cout << "error to read image!!!" << endl;
return(-1);
}
createTrackbar("Kernel Size:\n 2*n+1", windowName,
&kernel_size, max_kernel_size,
LinearFilter);
LinearFilter(0,0);
waitKey(0);
return(0);
}