ITK-中值滤波

作者:翟天保Steven

版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

中值滤波原理

中值滤波是一种常用的非线性滤波技术,用于去除图像中的噪声,特别是椒盐噪声和脉冲噪声。它通过在图像中移动一个窗口,并用窗口内像素的中值替换中心像素的值,从而达到去噪的效果。

可以概括为以下几个步骤:

  1. 选择滤波窗口:定义一个窗口(通常是矩形或方形),该窗口覆盖目标像素及其邻域像素。窗口的大小由用户指定,例如3×3、5×5等。

  2. 移动窗口:将窗口依次移动到图像中的每一个像素位置,逐个处理每个像素。

  3. 计算中值:对于窗口覆盖的每一个位置,按像素值大小排序,然后选择中间的值作为中值。如果窗口包含奇数个像素,中值就是排序后中间位置的像素值;如果窗口包含偶数个像素,中值是排序后中间两个像素值的平均值或其中之一。

  4. 替换像素值:用计算得到的中值替换当前窗口中心像素的值。

中值滤波具有以下效果和优点:

  1. 去除噪声:中值滤波特别适用于去除椒盐噪声和脉冲噪声,因为它能够有效地过滤掉极值点(即噪声),而不会过多影响其他像素。

  2. 保留边缘:与均值滤波不同,中值滤波能够更好地保留图像中的边缘和细节。因为中值滤波是基于像素排序的非线性操作,边缘不会像均值滤波那样被模糊掉。

  3. 鲁棒性:中值滤波对图像中的孤立噪声点有很强的鲁棒性,能够保持图像的结构和细节。

中值滤波在图像处理和计算机视觉中有广泛的应用,尤其是在图像预处理阶段,用于去除噪声、平滑图像等。它在医学图像处理、卫星图像分析和工业检测等领域中得到了广泛应用。

环境准备

参见:Windows下用CMake编译ITK及配置测试_itk配置-CSDN博客

功能解析

1.引入必要的头文件:

复制代码
#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkMedianImageFilter.h>
#include <itkRescaleIntensityImageFilter.h>
#include <itkJPEGImageIOFactory.h>
#include <itkCastImageFilter.h>

2.初始化图像类型和读写器:

复制代码
typedef itk::Image<unsigned char, 2> CharImageType;
typedef itk::Image<float, 2> FloatImageType;
typedef itk::ImageFileReader<CharImageType> ReaderType;
typedef itk::ImageFileWriter<CharImageType> WriterType;
itk::JPEGImageIOFactory::RegisterOneFactory();
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();

3.设置文件名:

复制代码
// 设置
reader->SetFileName("test.jpg");            // 要读取的文件名
writer->SetFileName("median_output3.jpg");    // 写入的文件名

4.类型转换:

复制代码
// 类型转换
typedef itk::CastImageFilter<CharImageType, FloatImageType> CastFilterType;
CastFilterType::Pointer castfilter = CastFilterType::New();
castfilter->SetInput(reader->GetOutput());

5.创建中值滤波器,并配置参数:

复制代码
// 创建中值滤波器
typedef itk::MedianImageFilter<FloatImageType, FloatImageType> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetInput(castfilter->GetOutput());
// 设置参数
FilterType::InputSizeType radius;
radius.Fill(3); // 设置中值滤波器的半径
filter->SetRadius(radius);

6.类型转换:

复制代码
// 将浮点图像转换为unsigned char类型
typedef itk::RescaleIntensityImageFilter<FloatImageType, CharImageType> RescaleFilterType;
RescaleFilterType::Pointer castfilter2 = RescaleFilterType::New();
castfilter2->SetInput(filter->GetOutput());

7.连接过滤器输出到写入器并执行写入操作:

复制代码
writer->SetInput(castfilter2->GetOutput());
try
{
    writer->Update();
}
catch (itk::ExceptionObject &error)
{
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
}

完整代码

复制代码
#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkMedianImageFilter.h>
#include <itkRescaleIntensityImageFilter.h>
#include <itkJPEGImageIOFactory.h>
#include <itkCastImageFilter.h>

int main()
{
	// 初始化
	typedef itk::Image<unsigned char, 2> CharImageType;
	typedef itk::Image<float, 2> FloatImageType;
	typedef itk::ImageFileReader<CharImageType> ReaderType;
	typedef itk::ImageFileWriter<CharImageType> WriterType;
	itk::JPEGImageIOFactory::RegisterOneFactory();
	ReaderType::Pointer reader = ReaderType::New();
	WriterType::Pointer writer = WriterType::New();

	// 设置
	reader->SetFileName("test.jpg");            // 要读取的文件名
	writer->SetFileName("median_output3.jpg");    // 写入的文件名

	// 类型转换
	typedef itk::CastImageFilter<CharImageType, FloatImageType> CastFilterType;
	CastFilterType::Pointer castfilter = CastFilterType::New();
	castfilter->SetInput(reader->GetOutput());

	// 创建中值滤波器
	typedef itk::MedianImageFilter<FloatImageType, FloatImageType> FilterType;
	FilterType::Pointer filter = FilterType::New();
	filter->SetInput(castfilter->GetOutput());

	// 设置参数
	FilterType::InputSizeType radius;
	radius.Fill(3); // 设置中值滤波器的半径
	filter->SetRadius(radius);

	// 将浮点图像转换为unsigned char类型
	typedef itk::RescaleIntensityImageFilter<FloatImageType, CharImageType> RescaleFilterType;
	RescaleFilterType::Pointer castfilter2 = RescaleFilterType::New();
	castfilter2->SetInput(filter->GetOutput());

	// 输出
	writer->SetInput(castfilter2->GetOutput());
	try
	{
		writer->Update();
	}
	catch (itk::ExceptionObject &error)
	{
		std::cerr << "Error: " << error << std::endl;
		return EXIT_FAILURE;
	}

	std::cout << "Median filtering completed successfully." << std::endl;
	return EXIT_SUCCESS;
}

测试效果

通过调整参数,可以实现不同的滤波效果。

如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关推荐
胖墩会武术6 小时前
【OpenCV图像处理】深度学习:cv2.dnn() —— 图像分类、人脸检测、目标检测
图像处理·pytorch·python·opencv
深圳市快瞳科技有限公司8 小时前
宠物识别丨基于弱监督学习的宠物视频内容自动标注技术实践
人工智能·计算机视觉·目标跟踪
AI即插即用10 小时前
即插即用系列 | 2025 SOTA Strip R-CNN 实战解析:用于遥感目标检测的大条带卷积
人工智能·pytorch·深度学习·目标检测·计算机视觉·cnn·智慧城市
B站_计算机毕业设计之家11 小时前
python手写数字识别系统 CNN算法 卷积神经网络 OpenCV和Keras模型 计算机视觉 (建议收藏)✅
python·深度学习·opencv·机器学习·计算机视觉·cnn
这张生成的图像能检测吗12 小时前
(论文速读)SpiralMLP:一个轻量级的视觉MLP架构
图像处理·人工智能·深度学习·计算机视觉·mlp框架·分类、检测、分割
CoovallyAIHub12 小时前
分割万事万物的AI,再进化!Meta SAM 3 来了,支持中文提示词!
深度学习·算法·计算机视觉
赋创小助手12 小时前
英特尔确认取消 8 通道 Diamond Rapids:服务器 CPU 战局再度升级
服务器·图像处理·人工智能·深度学习·计算机视觉·自然语言处理·自动驾驶
zl_vslam13 小时前
SLAM中的非线性优-3D图优化之四元数在Opencv-PNP中的应用(五)
人工智能·算法·计算机视觉
1***Q78413 小时前
Docker计算机视觉应用
计算机视觉·docker·容器
王林(瑞昱Realtek,龙迅)1 天前
视频拼接,分割,矩阵技术方案介绍
图像处理·嵌入式硬件·显示器·8k显示·画面拼接