一、编程环境:
OpenCV | 4.1.0 |
IDE | Visual Studio 2017 Enterprise (15.9.14) |
操作系统 | Windows 10 x64 中文专业版 (1903) |
二、OpenCV 自定义滤波:
图像卷积最主要功能有图像模糊、锐化、梯度边缘等,OpenCV 除了支持上述的卷积模糊(均值与边缘保留)还支持自定义卷积核,实现自定义的滤波操作。利用内核实现对图像的卷积运算。
自定义卷积核常见的主要是均值、锐化、梯度等算子。
三、程序说明:
- OpenCV 中的 filter2D()函数:利用内核实现对图像的卷积运算。
void filter2D( InputArray src, OutputArray dst, int ddepth,
InputArray kernel, Point anchor = Point(-1,-1),
double delta = 0, int borderType = BORDER_DEFAULT );
- 参数说明:
src:输入图像。
dst: 输出图像,和输入图像具有相同的尺寸和通道数量。
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 时,目标图像和原图像深度保持一致。
kernel:卷积核(或者是相关核),一个单通道浮点型矩阵。如果想在图像不同的通道使用不同的 kernel,可以先使用 split() 函数将图像通道事先分开。
anchor:内核的基准点(anchor),其默认值为 (-1,-1) 说明位于 kernel 的中心位置。基准点即 kernel 中与进行处理的像素点重合的点。
delta:在储存目标图像前可选的添加到像素的值,默认值为 0。
borderType:像素向外逼近的方法,默认值是 BORDER_DEFAULT,即对全部边界进行计算。
注意:滤波完成之后需要使用convertScaleAbs函数将结果转换为字节类型。
四、示例程序:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[]) {
Mat src = imread("../images/test.jpg");
if (src.empty()) {
printf("不能打开图像!\n");
return -1;
}
namedWindow("1-原图", WINDOW_AUTOSIZE);
imshow("1-原图", src);
Mat kernel1 = Mat::ones(5, 5, CV_32F) / (float)(25);
Mat kernel2 = (Mat_<char>(3, 3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
Mat kernel3 = (Mat_<int>(2, 2) << 1, 0, 0, -1);
Mat dst1, dst2, dst3;
filter2D(src, dst1, -1, kernel1);
filter2D(src, dst2, -1, kernel2);
filter2D(src, dst3, CV_32F, kernel3);
convertScaleAbs(dst3, dst3);
imshow("2-blur(5x5)", dst1);
imshow("3-shape(3x3)", dst2);
imshow("4-gradient(2x2)", dst3);
waitKey(0);
return 0;
}
五、运行效果: