本人研发一款基于传统图像处理算法的软件imgPro,核心功能是超多种算法组合调参和代码自动生成,定位是通用型软件,可以满足图像处理专业的学生或者图像处理初级工程师的一般需求。比如:
- 初步接触图像处理领域的张三,学习无从下手,我推荐阅读数字图像处理方面的书籍,并结合imgPro图像分析软件,可以快速入门此领域。
- 有一些图像处理基础的李四,想使用传统图像处理算法开发一个工程应用项目,但是对于算法的掌握不够全面。我相信,使用imgPro图像分析软件后,可以帮助你快速解决问题,或者提供一些开发思路。值的注意的是,imgPro中有一些经典工程应用组合算法的推荐,都可以在软件中实现,并支持生成代码。
- 脑海中有一些算法,但是代码能力稍微弱一些的王五,通常情况下,会从网络、ChatGPT、Deepseek中查找算法的代码,一顿操作后,可能还运行不起来,也有可能代码本身就不正确,很是浪费时间。但是,王五直接操作imgPro图像分析软件,快速调参,满意可视化结果之后,一键生成代码,岂不美哉。
试用版软件无需激活,获取方式如下:
链接:https://pan.baidu.com/s/1ExksEfGtD8ovPw9VJ0fPWA?pwd=i267
提取码:i267
目录
1 基本定义
中值滤波是一种常用的非线性滤波技术,在图像处理领域广泛应用,尤其在去除脉冲噪声(如椒盐噪声)方面效果显著,同时能较好地保留图像的边缘信息,避免像线性滤波那样容易使图像模糊。
中值滤波是将图像中每个像素点的值替换为该点邻域内所有像素值的中值的滤波方法。其中,“邻域” 通常是一个正方形、圆形或十字形的窗口(也称为模板),窗口大小可根据实际需求选择(如 3×3、5×5 等)。
例如,对于一个 3×3 的窗口,取窗口内 9 个像素值按大小排序后,位于中间位置的第 5 个值即为中值,该中值将作为窗口中心像素的新值。
2 核心原理
中值滤波的核心原理基于统计排序:通过对像素邻域内的数值进行排序,用中值替代原中心像素值。由于中值不受极端值(噪声点通常表现为极大或极小的极端值)的影响,因此能有效剔除噪声,同时因为保留了邻域内的中间值,边缘等重要信息不易被模糊。
与均值滤波(线性滤波)相比,均值滤波会将噪声和邻域内的像素值平均,容易导致图像模糊;而中值滤波通过排序选择中间值,能在去噪的同时更好地保持图像细节。
3 算法步骤
- 选择窗口:确定一个合适的滤波窗口(如 3×3、5×5),窗口大小需根据噪声强度和图像细节需求调整(噪声越强,窗口可适当增大,但过大会导致图像模糊)。
- 滑动窗口:将窗口在图像上从左到右、从上到下依次滑动,每次滑动一个像素。
- 提取像素值:对于每个窗口位置,提取窗口内所有像素的灰度值(或 RGB 通道值)。
- 排序与取中值:将提取的像素值按从小到大(或从大到小)的顺序排序,取排序后位于中间位置的数值作为中值。
- 替换像素值:用计算得到的中值替换窗口中心像素的原数值。
- 重复操作:直到窗口遍历完图像的所有像素,得到滤波后的图像。
4 数学公式
假设有一个图像,其中每个像素的值为,窗口大小为 w×w(通常是奇数,例如 3x3、5x5 等),中值滤波的过程如下:
对于每个像素点 ,选择一个邻域窗口(例如 3×3 窗口):
其中, 为邻域内的像素点。
对邻域 中的像素值进行排序,并取其中的中值作为新像素值:
其中,是邻域像素值中的中位数。
4.1 举例说明
假设我们有一个 3×3 的图像块,像素值如下:
12 80 45
23 60 90
25 50 70
进行中值滤波时,窗口大小为 3×3,所以我们将这个窗口内的9个值进行排序并取中位数。首先对窗口中的值进行排序:
[12,23,25,45,50,60,70,80,90]
排序后的中值为 50,因此该位置的像素值将被替换为 50。
5 代码实现
打开图像 >>> 选择中值滤波 >>> 点击“C++”按钮 >>> 生成代码。
/****************************************************************************
**
** Source Code From Imgpro.
** Contact: https://space.bilibili.com/3546828442176056?spm_id_from=333.1007.0.0
**
** This file depends on the openc environment.
**
****************************************************************************/
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void zhongZhiLvBo(Mat& targetImage, Mat& resImage, int kSize)
{
if (kSize % 2 == 0) {
kSize++;
}
medianBlur(targetImage, resImage, kSize);
}
int main()
{
string imagePath = "";
Mat srcImage = imread(imagePath);
imshow("srcImage", srcImage);
Mat prevImage = srcImage;
Mat resImage;
zhongZhiLvBo(prevImage, resImage, 5);
imshow("result", resImage);
waitKey(0);
}
6 结果展示
配置Opencv环境 >>> 复制代码到VS >>> 编译运行。