OpenCV入门学习-图像处理(二)
- OpenCV入门学习-图像处理(一)
- 绘图基础 | 随机数生成与文本绘制 | 图像平滑 | 形态学操作 | 图像金字塔 | 阈值操作
环境:
- win11 x64
- OpenCV 4.9.0
- VS 2022 (v143)
- C++ (ISO C++ 14 标准)
线性滤波器
涵盖以下内容:
- 使用OpenCV的
cv::filter2D()
函数创建自定义线性滤波器
- 理解图像处理中核(Kernel)的概念及相关运算(Correlation)
- 实现归一化盒式滤波器(Normalized Box Filter)并观察不同核尺寸的效果
理论基础
相关运算与核
在图像处理中,相关运算(Correlation)是核与图像局部区域进行加权求和的操作。核是一个固定大小的数值矩阵,其中心通常定义为锚点(Anchor Point)。
核的工作流程如下:
- 将核的锚点对准图像中的目标像素
- 核系数与对应像素值相乘后求和
- 将结果写入输出图像的锚点位置
- 遍历所有像素完成计算
数学表达式为:
\[
H(x, y) = \sum_{i=0}^{M_i-1} \sum_{j=0}^{M_j-1} I(x + i - a_i, y + j -
a_j) K(i, j) \nonumber
\]
归一化盒式滤波器
以尺寸为3×3的归一化盒式滤波器为例,核矩阵为:
\[
K = \frac{1}{9} \begin{bmatrix}
1 & 1 & 1 \\
1 & 1 & 1 \\
1 & 1 & 1
\end{bmatrix} \nonumber
\]
其作用是计算局部像素的平均值,实现图像模糊效果。
代码实现
以下代码展示了如何使用cv::filter2D()
实现不同尺寸的归一化盒式滤波器:
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
int main(int argc, char** argv) {
// 加载图像
::Mat src = cv::imread(cv::samples::findFile(argc >=2 ? argv[1] : "lena.jpg"));
cvif (src.empty()) {
("Error opening image\n");
printfreturn EXIT_FAILURE;
}
// 初始化参数
::Mat dst, kernel;
cv::Point anchor(-1, -1);
cvdouble delta = 0;
int ddepth = -1;
const char* window_name = "filter2D Demo";
// 循环应用不同尺寸的核
int ind = 0;
while (true) {
// 核尺寸在[3, 11]范围内按奇数递增
int kernel_size = 3 + 2 * (ind % 5);
= cv::Mat::ones(kernel_size, kernel_size, CV_32F) / (float)(kernel_size * kernel_size);
kernel
// 应用滤波器
::filter2D(src, dst, ddepth, kernel, anchor, delta, cv::BORDER_DEFAULT);
cv::imshow(window_name, dst);
cv
// 按ESC退出
char c = (char)cv::waitKey(500);
if (c == 27) break;
++;
ind}
return EXIT_SUCCESS;
}
滤波器应用
使用cv::filter2D
进行滤波操作:
src
:输入图像
dst
:输出图像
ddepth
:输出图像深度(-1表示与输入一致)
kernel
:自定义核
anchor
:核锚点位置(默认中心)
delta
:输出像素值的额外偏移量
参考资料
[1] OpenCV 官方文档
-------------本文结束 感谢您的阅读-------------