结合opencv中的mat,用c++手撕图像高通滤波,不用opencv里面的函数
时间: 2024-12-17 14:12:14 浏览: 7
在OpenCV中,Mat是一个用于表示图像数据的数据结构,但在纯C++的情况下,我们可以手动实现高斯滤波。高斯滤波是一种平滑图像噪声、模糊边缘的技术,核心思想是根据高斯函数加权平均像素值。
以下是一个简单的步骤来实现二维高斯滤波:
1. **定义高斯核**:
创建一个大小为`(kernel_size, kernel_size)`的矩阵,填充上对应的高斯权重值。高斯核通常是由一个标准差(sigma)决定的,标准差越大,滤波效果越明显,但计算成本也越高。例如,对于3x3的核,可以这样生成:
```cpp
float sigma = 1.5f;
int kernel_size = std::ceil(6 * sigma);
Mat kernel(kernel_size, kernel_size, CV_32F);
for (int i = -kernel_size / 2; i <= kernel_size / 2; ++i) {
float x = static_cast<float>(i);
kernel.at<float>(i + kernel_size / 2, i + kernel_size / 2) = exp(-0.5f * x * x / (sigma * sigma));
}
```
2. **卷积操作**:
对输入图像应用滤波,这需要遍历图像的每个像素,将每个像素及其周围像素值按照高斯核进行加权求和:
```cpp
Mat src, dst;
src.copyTo(dst); // 先复制一份原始图像到dst,防止修改源图像
for (int y = kernel_size / 2; y < src.rows - kernel_size / 2; ++y) {
for (int x = kernel_size / 2; x < src.cols - kernel_size / 2; ++x) {
float sum = 0;
for (int ky = -kernel_size / 2; ky <= kernel_size / 2; ++ky) {
for (int kx = -kernel_size / 2; kx <= kernel_size / 2; ++kx) {
sum += src.at<float>(y + ky, x + kx) * kernel.at<float>(ky, kx);
}
}
dst.at<float>(y, x) = sum;
}
}
```
注意:这个过程比较繁琐,实际项目中一般会依赖OpenCV提供的`filter2D()`或更底层的`getOptimalDFTSize()`等函数来进行优化。
阅读全文