您现在的位置是:首页 >技术教程 >opencv_c++学习(十六)网站首页技术教程
opencv_c++学习(十六)
一、线性滤波
均值滤波:
blur(InputArray src, utputArray dst,Size ksize, Point anchor = Point(-i,-1), int borderType = BoRDER_DEFAULT)
src:待均值滤波的图像,图像的数据类型必须是CV_8U、CV_16U、CV_16S、CV_32F和CV_64F这五种数据类型之一。
dst:均值滤波后的图像,与输入图像具有相同的尺寸和数据类型。
ksize:卷积核尺寸。
anchor:内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。
borderType:像素外推法选择标志。
方框滤波:
boxFilter(InputArray src, outputArray dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER__DEFAULT)
src:输入图像。
dst:输出图像,与输入图像具有相同的尺寸和通道数。
ddepth:输出图像的数据类型(深度),根据输入图像的数据类型不同拥有不同的取值范围。
ksize:卷积核尺寸。
anchor:内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。
normalize:是否将卷积核进行归一化的标志,默认参数为true,表示进行归一化。
borderType:像素外推法选择标志。
高斯滤波:
GaussianBlur(InputArray src, outputArray dst, Size ksize, double sligmax, double sigmaY = 0, int borderType = eORDER_DEFAULT
src:待高斯滤波图像,数据类型必须为CV_8U,CV_16U,CV_16S,cV_32F或CV_64F。
dst:输出图像,与输入图像src具有相同的尺步、通道数和数据类型。
ksize:高斯滤波器的尺寸,滤波器可以不为正方形,但是必须是正奇数。如果尺寸为0,则由标准偏差计算尺寸。
sigmaX:X方向的高斯滤波器标准偏差。
sigmaY:Y方向的高斯滤波器标准偏差;如果输入量为0,则将其设置为等于sigmaX,如果两个轴的标准差均为0,则根据输入的高斯滤波器尺寸计算标准偏差。
borderType:像素外推法选择标志。
使用案例如下:
int main() {
//读取图片
Mat src = imread("1.png");
if (src.empty())
{
printf("不能打开空图片");
return -1;
}
//设定一个滤波后结果的Mat类
Mat result;
//调用均值滤波函数进行滤波,滤波器核大小为3*3
blur(src, result, Size(3, 3));
//展示图片
imshow("jun", result);
//方框滤波
Mat result_box;
//开始方框滤波,核大小为3*3,不进行归一化
boxFilter(src, result_box, -1, Size(3, 3), Point(-1, -1), false);
//展示图片
imshow("fang", result_box);
//高斯滤波
Mat result_gaussian;
//开始高斯滤波,核大小为3*3
GaussianBlur(src, result_gaussian, Size(3, 3), 10, 20);
//展示图片
imshow("gaosi", result_gaussian);
waitKey(0);
return 0;
}
二、非线性滤波——中值滤波
medianBlur(lnputArraysrc, OutputArray dst, int ksize
src:待中值滤波的图像,可以是单通道,三通道和四通道,数据类型与滤波器的尺寸相关,当滤波器尺寸为3或5时,图像可以是CV_8U,CV_16U或CV_32F类型,对于较大尺寸的滤波器,数据类型只能是CV_8U。
dst:输出图像,与输入图像src具有相同的尺寸和数据类型。
ksize:滤波器尺寸,必须是大于1的奇数,例如: 3、5、7…
使用案例如下:
int main() {
//读取图片
Mat src = imread("1.png", IMREAD_ANYCOLOR);
if (src.empty())
{
printf("不能打开空图片");
return -1;
}
//设定一个滤波后结果的Mat类
Mat result;
//进行尺寸为3的中值滤波
medianBlur(src, result, 3);
//展示图片
imshow("中值", result);
waitKey(0);
return 0;
}
三、可分离滤波
sepFilter2D(lnputArray src, outputArray dst,int ddepth, lnputArray kernelX, lnputArray kernelY, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT
src:待滤波图像。
dst:输出图像,与输入图像src具有相同的尺寸、通道数和数据类型。ddepth:输出图像的数据类型(深度)。
kernelX:X方向的滤波器。
kernelY: Y方向的滤波器。
anchor:内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。
delta:偏值,在计算结果中加上偏值。
border’Tvpe:像素外推法选择标志。
对以上的操作进行理论验证,代码如下:
int main() {
//设定一个Mat矩阵
float points[25] = { 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);
//x方向、y方向和联合滤波器的构建
Mat a = (Mat_<float>(3, 1) << -1, 2, -1);
Mat b = a.reshape(1, 1);
//联合滤波器
Mat ab = a * b;
//验证高斯滤波的可分离性
//生成高斯核
Mat gaussX = getGaussianKernel(3, 1);
//定义两种滤波器输出的结果
Mat gaussData, gaussDataXY;
//单纯高斯滤波
GaussianBlur(data, gaussData, Size(3, 3), 1, 1, BORDER_CONSTANT);
//分离滤波
sepFilter2D(data, gaussDataXY, -1, gaussX, gaussX, Point(-1, -1), 0, BORDER_CONSTANT);
Mat dataYX, dataY, dataXY, dataXY_sep;
//分别进行行列滤波
filter2D(data, dataY, -1, a, Point(-1, -1), 0, BORDER_CONSTANT);
filter2D(dataY, dataYX, -1, b, Point(-1, -1), 0, BORDER_CONSTANT);
//进行合并行列滤波
filter2D(data, dataXY, -1, ab, Point(-1, -1), 0, BORDER_CONSTANT);
//进行分离滤波
sepFilter2D(data, dataXY_sep, -1, b, b, Point(-1, -1), 0, BORDER_CONSTANT);
waitKey(0);
return 0;
}
对图像进行可分离滤波:
//读取图片
Mat src = imread("1.png", IMREAD_ANYCOLOR);
if (src.empty())
{
printf("不能打开空图片");
return -1;
}
Mat imgXY;
filter2D(src, imgXY, -1, ab, Point(-1, -1), 0, BORDER_CONSTANT);
imshow("分离", imgXY);