手写中值滤波与OpenCV的中值滤波对比效果

本文通过对比手写中值滤波和OpenCV库实现的中值滤波,展示了两者在图像去噪方面的相似效果。尽管手写实现与OpenCV在视觉效果上接近,但在效率上存在显著差距。文章提供了代码示例,解释了中值滤波的工作原理,并强调其在消除椒盐噪声上的优势。

《OpenCV系列教程》
《深度学习-如何提高数据集质量》

项目位置:OpenCV-Sample
代码位置:37-MedianBlur.py

先看一下效果吧,如图显示:
第一列:原图 第二列:自己手写的中值滤波 第三列 OpenCV的中值滤波.

原图 手写 openCV

在这里插入图片描述
在这里插入图片描述
肉眼参看非常的接近.但效率上仍然无法与OpenCV匹敌.一个天上一个地下.以学习的目的进行手写.
原理比较简单,对消除椒盐噪点效果是非常的好.上面的图就是一个充满了椒盐噪点的图片.

传入原始图像

如果图片是一个4x4的矩阵,kernel是一个3x3的矩阵,kernel会在图片上进行滑动.

假设这个就是原始图形
### C++ OpenCV 中值滤波 使用方法 在 C++ 编程环境中,OpenCV 提供了一个简单易用的函数 `cv::medianBlur` 来实现中值滤波功能。该函数可以有效地去除图像中的椒盐噪声并保留边缘细节。 #### 函数原型 以下是 `cv::medianBlur` 的函数声明: ```cpp void medianBlur(InputArray src, OutputArray dst, int ksize); ``` - **参数说明**: - `src`: 输入图像矩阵。 - `dst`: 输出图像矩阵,输入图像具有相同的尺寸和类型。 - `ksize`: 滤波窗口大小,必须为正奇数(如3、5、7等),表示模板边长。 #### 示例代码 下面是一个完整的示例程序,演示如何使用 OpenCV 对图像应用中值滤波: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 载入原始图像 Mat image = imread("input_image.jpg"); if (image.empty()) { cout << "无法读取图像,请检查路径是否正确!" << endl; return -1; } // 创建窗口用于显示图像 namedWindow("原图", WINDOW_AUTOSIZE); namedWindow("中值滤波效果", WINDOW_AUTOSIZE); // 显示原始图像 imshow("原图", image); // 定义输出图像变量 Mat outputImage; // 应用中值滤波,设置窗口大小为7x7 medianBlur(image, outputImage, 7); // 显示滤波后的图像 imshow("中值滤波效果", outputImage); // 等待按键事件 waitKey(0); return 0; } ``` #### 结果分析 通过调整 `ksize` 参数,可以控制滤波的效果强度。较大的窗口会更有效地减少噪声,但可能导致图像变得模糊[^3]。因此,在实际应用中需根据具体需求选择合适的窗口大小。 --- ### 自定义中值滤波实现 除了直接调用 OpenCV 提供的 `cv::medianBlur` 外,还可以手动编写中值滤波算法。以下是一段基于边界扩展和排序操作的手动实现代码: ```cpp #include <opencv2/opencv.hpp> #include <vector> #include <algorithm> #include <iostream> using namespace cv; using namespace std; // 手动实现中值滤波 void customMedianFilter(Mat& src, Mat& dst, Size kernelSize) { if (kernelSize.width % 2 == 0 || kernelSize.height % 2 == 0) { cerr << "错误:核大小必须为奇数!" << endl; return; } int halfWidth = kernelSize.width / 2; int halfHeight = kernelSize.height / 2; // 边界填充 Mat paddedSrc; copyMakeBorder(src, paddedSrc, halfHeight, halfHeight, halfWidth, halfWidth, BORDER_REPLICATE); dst.create(src.size(), src.type()); for (int y = halfHeight; y < paddedSrc.rows - halfHeight; ++y) { for (int x = halfWidth; x < paddedSrc.cols - halfWidth; ++x) { vector<int> windowValues; // 收集当前窗口内的像素值 for (int ky = -halfHeight; ky <= halfHeight; ++ky) { for (int kx = -halfWidth; kx <= halfWidth; ++kx) { windowValues.push_back(paddedSrc.at<uchar>(y + ky, x + kx)); } } // 排序并获取中位数 sort(windowValues.begin(), windowValues.end()); dst.at<uchar>(y - halfHeight, x - halfWidth) = windowValues[windowValues.size() / 2]; } } } int main() { Mat input = imread("noisy_image.png", IMREAD_GRAYSCALE); if (input.empty()) { cout << "无法加载图像!" << endl; return -1; } Mat result; customMedianFilter(input, result, Size(5, 5)); imshow("Original Image", input); imshow("Custom Median Filtered", result); waitKey(0); return 0; } ``` 此代码展示了如何不依赖内置函数而自行完成中值滤波过程,适合学习理解其实现机制[^4]。 --- ### 性能比较 对于大多数应用场景而言,推荐优先使用 OpenCV 内置的 `cv::medianBlur` 方法,因为它经过高度优化,性能远优于手写版本。然而,了解底层逻辑有助于深入掌握图像处理技术[^5]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值