【图像处理】OpenCV系列十三 --- filter2D()、
一、filter2D()函数详解
1、函数原型
void filter2D(InputArray src,
OutputArray dst,
int ddepth,
InputArray kernel,
Point anchor = Point(-1,-1),
double delta = 0,
int borderType = BORDER_DEFAULT
)
2、函数功能
用kernel卷积核对src图像进行卷积,生成卷积之后的图像dst,该函数使用于任意线性滤波器的图像,支持就地操作。当其中心移动到图像外,函数可以根据指定的边界模式进行插值运算。
函数实质上是计算kernel与图像的相关性而不是卷积。
filter2D函数计算公式也就是说kernel并不是中心点的镜像,如果需要一个正真的卷积,使用函数flip()并将中心点设置为(kernel.cols - anchor.x - 1, kernel.rows - anchor.y -1)。
该函数在足够大的核(~11×11或更大)情况下使用基于DFT的算法,对于小核则使用直接算法。(使用createLinearFilter()检索得到).
3、参数详解
-
第一个参数,InputArray src,输入图像;
-
第二个参数,OutputArray dst, 输出图像,和输入图像具有相同的尺寸和通道数量;
-
第三个参数,int ddepth,目标图像深度,原图像和目标图像支持的图像深度如下:
-
src.depth() = CV_8U,
ddepth = -1/CV_16S/CV_32F/CV_64F -
src.depth() = CV_16U/CV_16S,
ddepth = -1/CV_32F/CV_64F -
src.depth() = CV_32F,
ddepth = -1/CV_32F/CV_64F -
src.depth() = CV_64F,
ddepth = -1/CV_64F
当ddepth输入值为-1时,目标图像和原图像深度保持一致;
-
-
第四个参数,InputArray kernel,卷积核(或者是相关核),一个单通道浮点型矩阵。如果想在图像不同的通道使用不同的kernel,可以先使用split()函数将图像通道事先分开,然后对每个通道单独进行卷积处理;
-
第五个参数,Point anchor,内核的基准点(anchor),其默认值为(-1,-1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点;
-
第六个参数,double delta,在储存目标图像前可选的添加到像素的值,默认值为0;
-
第七个参数,int borderType, 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。
4、实例
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("lena.png");
//判断图像是否加载成功
if (srcImage.data)
cout << "图像加载成功!" << endl << endl;
else
{
cout << "图像加载失败!" << endl << endl;
return -1;
}
namedWindow("srcImage", WINDOW_AUTOSIZE);
imshow("srcImage", srcImage);
// 卷积核
Mat kern = (Mat_<char>(3, 3)
<< 0, -1, 0,
-1, 5, -1,
0, -1, 0);
Mat dstImage;
// 对图像进行卷积
filter2D(srcImage, dstImage,
srcImage.depth(), kern);
namedWindow("dstImage", WINDOW_AUTOSIZE);
imshow("dstImage", dstImage);
waitKey(0);
return 0;
}
实验结果:
原图(左)与效果图(右)二、sepFilter2D()函数详解
1、函数原型
void sepFilter2D(InputArray src,
OutputArray dst,
int ddepth,
InputArray kernelX,
InputArray kernelY,
Point anchor = Point(-1, -1),
double delta = 0,
int borderType = BORDER_DEFAULT);
2、函数功能
sepFilter2D()用分解的核函数对图像做卷积。首先,图像的每一行与一维的核kernelX做卷积;然后,运算结果的每一列与一维的核kernelY做卷积。
3、参数详解
-
第一个参数,InputArray src,输入图像;
-
第二个参数,OutputArray dst, 输出图像,和输入图像具有相同的尺寸和通道数量;
-
第三个参数, int ddepth,输出图像的深度,原图像和目标图像支持的图像深度如下:
-
src.depth() = CV_8U,
ddepth = -1/CV_16S/CV_32F/CV_64F -
src.depth() = CV_16U/CV_16S,
ddepth = -1/CV_32F/CV_64F -
src.depth() = CV_32F,
ddepth = -1/CV_32F/CV_64F -
src.depth() = CV_64F,
ddepth = -1/CV_64F
-
-
第四个参数,InputArray kernelX,x方向的卷积核;
-
第五个参数,InputArray kernelY,y方向的卷积核;
-
第六个参数,Pointanchor=Point(-1,-1),处理的像素是核中心的像素;
-
第七个参数,double delta=0,在储存目标图像前可选的添加到像素的值,默认值为0;
-
第七个参数,int borderType, 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。
4、实例
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include<stdlib.h>
using namespace cv;
using namespace std;
int main()
{
Mat src, dst;
src = imread("lena.png");
// 显示原图
imshow("原图", src);
// x方向卷积核
Mat kx = (Mat_<float>(1, 3)
<< 0, -1, 0);
// y方向卷积核
Mat ky = (Mat_<float>(1, 3)
<< -1, 0, -1);
//进行卷积处理
sepFilter2D(src, dst,
src.depth(),
kx, ky,
Point(-1, -1),
0, BORDER_DEFAULT);
imshow("效果", dst);
waitKey(0);
return 0;
}
实验结果
原图(左)与效果图(右)三、sqrBoxFilter()函数详解
1、函数原型
void sqrBoxFilter(InputArray src,
OutputArray dst,
int ddepth,
Size ksize,
Point anchor = Point(-1, -1),
bool normalize = true,
int borderType = BORDER_DEFAULT);
2、函数功能
计算与滤波器重叠的像素值的归一化平方和。
3、参数详解
-
第一个参数,InputArray src,输入图像;
-
第二个参数,OutputArray dst, 输出图像,和输入图像具有相同的尺寸和通道数量;
-
第三个参数,int ddepth,目标图像深度;
-
第四个参数 Size ksize, 卷积核的大小;
-
第五个参数,Point anchor,内核的基准点(anchor),其默认值为(-1, -1)说明位于kernel的中心位置。基准点即kernel中与进行处理的像素点重合的点;
-
第六个参数,bool normalize,判断是否进行归一化处理;
-
第七个参数int borderType, 像素向外逼近的方法,默认值是BORDER_DEFAULT, 即对全部边界进行计算。
好了,今天的OpenCV关于图像卷积运算函数filter2D()学到这里就结束了,喜欢的朋友可以给我点个赞哦!!!