目标:
使用OpenCV中的函数cv::filter2D 自定义线性滤波器。
理论:
卷积
在一个非常普遍的意义上,卷积是一个图像的每一个部分和一个核之间的操作。
什么是核?
一个核实质上是一个固定大小矩阵,中心点被称为锚点,如下图所示。
如何利用卷积核进行卷积 ?
假设您想知道图像中某个特定位置的结果值。卷积的值以下列方式计算:
1) 将核的锚点(中心点)放在要计算像素上,卷积核剩余的部分对应在图像相应的像素上。
2) 用卷积核中的系数和图像中相应的像素值相乘,并求和。
3) 将最终结果赋值给锚点对应的像素。
4) 通过将核在整个图像滑动,重复以上计算过程直到处理完所有的像素。
用一个表达式表示以上过程如下:
代码
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
/* @function main */
int main ( int argc, char** argv )
{
Mat src, dst;
Mat kernel;
Point anchor;
double delta;
int ddepth;
int kernel_size;
char* window_name = "filter2D Demo";
int c;
src = imread( argv[1] );
if( !src.data )
{ return -1; }
namedWindow( window_name, WINDOW_AUTOSIZE );
anchor = Point( -1, -1 );
delta = 0;
ddepth = -1;
int ind = 0;
while( true )
{
c = waitKey(500);
if( (char)c == 27 )
{ break; }
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 );
ind++;
}
return 0;
}
结果
执行一个normalized box filter。例如核的大小为3.如下图:
代码执行时和的大小为3,5,7,9和11的结果如下: