【ITK库学习】使用itk库进行图像滤波ImageFilter:频域滤波

news/2024/7/21 7:52:07 标签: 学习, 计算机视觉, 算法, 图像处理, c++

目录

  • 1、itkFFTConvolutionImageFilter 快速傅里叶变换计算
  • 2、扩展:itkConvolutionImageFilter.h
  • 3、itkFFTShiftImageFilter 频率转移滤波器
  • 4、itkFFTNormalizedCorrelationImageFilter FFT实现的归一化相关滤波器

1、itkFFTConvolutionImageFilter 快速傅里叶变换计算

该类使用傅里叶域中的乘法将给定图像与任意图像内核进行卷积。

该过滤器产生的输出相当于 ConvolutionImageFilter 的输出,当核较大时,它利用卷积定理来加速卷积计算。由于FFT的特性,它可以大大加速卷积计算,尤其是对于卷积核较大的情况。但是对于某些特殊的卷积核,如具有特定形状或非对称性的核,可能会导致较大的计算误差。

警告
该过滤器忽略内核图像的间距、原点和方向,并将它们视为与输入图像中的相同。

常用的成员函数

  • SetKernelImage():设置卷积内核

示例代码

#include "itkImage.h"
#include "itkFFTConvolutionImageFilter.h"

typedef itk::Image<float, 3> FloatImageType;

bool FFTConvolutionImageFilter(FloatImageType* image, FloatImageType* outputImage)
{
    typename FloatImageType::Pointer kernelImage = FloatImageType::New();
    unsigned int width = 10;
	createKernel(kernelImage, width);
	
    typedef itk::FFTConvolutionImageFilter<FloatImageType, FloatImageType> FFTConvolutionFilterType;
	typename FFTConvolutionFilterType::Pointer fftFilter = FFTConvolutionFilterType::New();
	fftFilter->SetInput(image);
	fftFilter->SetKernelImage(kernelImage);
	try
	{
		fftFilter->Update();
	}
	catch (itk::ExceptionObject& ex)
	{
		//读取过程发生错误
		std::cerr << "Error: " << ex << std::endl;
		return false;
	}

	outputImage = fftFilter->GetOutput();
	return true;
}


void CreateKernel(FloatImageType::Pointer kernel, unsigned int width)
{
  FloatImageType::IndexType start;
  start.Fill(0);
 
  FloatImageType::SizeType size;
  size.Fill(width);
 
  FloatImageType::RegionType region;
  region.SetSize(size);
  region.SetIndex(start);
 
  kernel->SetRegions(region);
  kernel->Allocate();
 
  itk::ImageRegionIterator<FloatImageType> imageIterator(kernel, region);
 
  while (!imageIterator.IsAtEnd())
  {
    // imageIterator.Set(255);
    imageIterator.Set(1);
 
    ++imageIterator;
  }
}

2、扩展:itkConvolutionImageFilter.h

该类将给定图像与任意图像内核进行卷积。

该滤波器的工作原理是将翻转后的内核集中在图像中的每个像素处,并计算图像中的像素值与内核中的像素值之间的内积。

内核的中心定义为[(2*i+s−1)/2],其中 i 是索引,s 是内核图像的最大可能区域的大小。

对于所有维度上具有奇数大小的内核,这对应于中心像素,如果核图像的某个维度具有偶数大小,则该维度中核的中心索引将是小于图像中心的连续索引的最大积分索引。

可以选择使用 NormalizeOn() 将内核标准化为总和为 1,默认情况下标准化处于关闭状态。

警告
该过滤器忽略内核图像的间距、原点和方向,并将它们视为与输入图像中的相同。

其常用的成员函数与代码结构与FFTConvolutionImageFilter类似,参见1中内容

3、itkFFTShiftImageFilter 频率转移滤波器

将傅里叶变换的零频率分量移至图像的中心。

傅立叶变换生成的图像中,零频率分量位于图像的角落,使其难以理解,该滤波器将组件移动到图像的中心。

注意:对于奇数尺寸的图像,如果不对两个过滤器中的一个(且仅一个)使用 SetInverse(true),则应用此过滤器两次将不会生成与原始图像相同的图像。

常用的成员函数

  • Set/GetInverse():设置/获取过滤器是否必须反转变换,这个选项对于输入图像的尺寸都是偶数的情况没有影响,但是如果至少有一个维度的尺寸是奇数,则需要使用这个选项来恢复原始图像,简而言之,这个选项的作用是针对尺寸为奇数的输入图像进行处理,使其尺寸与原始图像保持一致
  • InverseOn/Off():同上

示例代码

#include "itkImage.h"
#include "itkFFTShiftImageFilter.h"

typedef itk::Image<float, 3> FloatImageType;

bool FFTShiftImageFilter(FloatImageType* image, FloatImageType* outputImage)
{
    typedef itk::FFTShiftImageFilter<FloatImageType, FloatImageType> FFTShiftFilterType;
	typename FFTShiftFilterType::Pointer fftFilter = FFTShiftFilterType::New();
	fftFilter->SetInput(image);
	try
	{
		fftFilter->Update();
	}
	catch (itk::ExceptionObject& ex)
	{
		//读取过程发生错误
		std::cerr << "Error: " << ex << std::endl;
		return false;
	}

	outputImage = fftFilter->GetOutput();
	return true;
}

4、itkFFTNormalizedCorrelationImageFilter FFT实现的归一化相关滤波器

使用 FFT 计算归一化互相关。

该滤波器使用 FFT 而不是空间相关来计算两个图像的归一化互相关 (NCC),对于相当大的结构元素,它比空间关联要快得多,该过滤器是更通用的 MaskedFFTNormalizedCorrelationImageFilter 的子类,其操作原理是将该算法中的掩码设置为图像,正如下面的参考文献中详细描述的,利用更通用的掩模算法没有计算消耗,因为计算仍然需要对图像进行 FFT。

输入:需要两个图像作为输入,fixedImage 和 movingImage,在相关性的背景下,输入通常被定义为:“图像”和“模板”,该过滤器能够关联任意两个图像,并且不限于小型移动图像(模板)。

可选参数:RequiredNumberOfOverlappingPixels 使用户能够指定两个图像的多少体素必须重叠; 相关图中由少于此数量的体素产生的任何位置将被设置为零,较大的值会将相关图像周围较大边界上的像素清零,因此,较大的值消除了不太稳定的计算,但也限制了捕获范围,如果“RequiredNumberOfOverlappingPixels”设置为 0(默认值),则不会进行归零。

图像大小:fixedImage 和 movingImage 不必具有相同的大小。 此外,虽然一些算法要求“模板”小于“图像”,因为两者不完全重叠的区域中存在误差,但该过滤器没有这样的限制。

图像间距:由于计算是在像素域中完成的,因此所有输入图像必须具有相同的间距。

输出: 输出是 RealPixelType 的图像,即两幅图像的 NCC,其值范围为 -1.0 到 1.0。 根据定义,该 NCC 图像的大小为 size(fixedImage) + size(movingImage) - 1。

常用的成员函数

  • Set/GetInverse():设置/获取过滤器是否必须反转变换,这个选项对于输入图像的尺寸都是偶数的情况没有影响,但是如果至少有一个维度的尺寸是奇数,则需要使用这个选项来恢复原始图像,简而言之,这个选项的作用是针对尺寸为奇数的输入图像进行处理,使其尺寸与原始图像保持一致
  • InverseOn/Off():同上

示例代码

#include "itkImage.h"
#include "itkFFTNormalizedCorrelationImageFilter.h"

typedef itk::Image<float, 3> FloatImageType;

bool FFTNormalizedCorrelationImageFilter(FloatImageType* image, FloatImageType* outputImage)
{
	itk::Index<3> offset;
	offset[0] = 5;
	offset[1] = 6;
	offset[2] = 6;

	typename FloatImageType::Pointer fixedImage = FloatImageType::New();
	itk::Index<3> cornerOfFixedSquare;
	cornerOfFixedSquare[0] = 3;
	cornerOfFixedSquare[1] = 8;
	cornerOfFixedSquare[2] = 6;
	createImage(fixedImage, cornerOfFixedSquare);

	typename FloatImageType::Pointer movingImage = FloatImageType::New();
	itk::Index<3> cornerOfMovingSquare;
	cornerOfMovingSquare[0] = cornerOfFixedSquare[0] + offset[0];
	cornerOfMovingSquare[1] = cornerOfFixedSquare[1] + offset[1];
	cornerOfMovingSquare[2] = cornerOfFixedSquare[2] + offset[2];
	createImage(movingImage, cornerOfMovingSquare);
	
    typedef itk::FFTNormalizedCorrelationImageFilter<FloatImageType, FloatImageType> FFTNormalizedCorrelationFilterType;
	typename FFTNormalizedCorrelationFilterType::Pointer fftFilter = FFTNormalizedCorrelationFilterType::New();
	fftFilter->SetFixedImage(fixedImage);
	fftFilter->SetMovingImage(movingImage);
	try
	{
		fftFilter->Update();
	}
	catch (itk::ExceptionObject& ex)
	{
		//读取过程发生错误
		std::cerr << "Error: " << ex << std::endl;
		return false;
	}

	outputImage = fftFilter->GetOutput();
	return true;
}

void createImage(FloatImageType::Pointer image, const itk::Index<3>& cornerOfSquare)
{
	FloatImageType::IndexType start;
	start.Fill(0);

	FloatImageType::SizeType size;
	size.Fill(51);

	FloatImageType::RegionType region(start, size);

	image->SetRegions(region);
	image->Allocate();
	image->FillBuffer(0);

	itk::ImageRegionIterator<FloatImageType> imageIterator(image, region);

	FloatImageType::IndexValueType squareSize = 8;

	while (!imageIterator.IsAtEnd())
	{
		if (imageIterator.GetIndex()[0] > cornerOfSquare[0] &&
			imageIterator.GetIndex()[0] < cornerOfSquare[0] + squareSize &&
			imageIterator.GetIndex()[1] > cornerOfSquare[1] && imageIterator.GetIndex()[1] < cornerOfSquare[1] + squareSize)
		{
			imageIterator.Set(255);
		}
		++imageIterator;
	}
}


http://www.niftyadmin.cn/n/5261836.html

相关文章

【wimdows电脑上管理员账户与管理员身份的区别】

管理员账户 在控制面板的用户账户中&#xff0c;点击更改账户类型&#xff0c;可以看到目前的账户是“管理员账户”还是“标准账户”。 管理员身份 在快捷方式上右击&#xff0c;可以看到&#xff0c;可以选择以管理员身份运行该软件。 如何查看某个应用是否以管理员身份…

Oracle数据库本地部署结合内网穿透实现公网环境PLSQL远程访问

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

debian12 最小化安装桌面 i3wm

怕记不住&#xff0c;先临时记录一下&#xff0c;还未整理&#xff0c;先凑合着看 debian12 最小安装 i3wm 一、先安装 debian12 最小安装 软件包只选择最后的两个 SSH服务&#xff0c;和管理工具 安装后查看IP&#xff0c;并用另一台电脑 ssh 连接操作&#xff0c;这样比较…

想要在电脑桌面上使用手机便签怎么操作?

作为一名上班族&#xff0c;我们时常需要在电脑和手机之间同步使用便签&#xff0c;以记录工作、生活中的重要事项。然而&#xff0c;有些时候我们可能更习惯在手机上使用便签&#xff0c;但又希望在电脑桌面上也能够方便地查看和编辑这些便签。那么&#xff0c;如何在电脑桌面…

实现树形结构的插件vue-tree-color及元素放大缩小拖动

实现流程图,借鉴vue-tree-color 引入依赖 npm install vue-tree-color 同时查看项目中是否已安装less和less-loader,因为该组件使用到less npm install --save-dev less less-loader 如果这里启动项目报错,有可能是less和less-loader的版本过高,可以降低版本,或者指定版本号…

vue实现自动打字效果(带光标效果)

代码介绍(其实就是通过字符串截取加定时拼接完成的,我相信有时间都能琢磨出来,来这里就是为了省事) 上vue页面代码: <template><div idApp><h2>{{text}}<span ref"fou" class"fousdis">{{_}}</span></h2></div>…

Python 使用 openpyxl 读取表格

当前环境&#xff1a;Win10 x64 MS office 2016 Python3.7 openpyxl3.0.9 1 表格内容(Sheet1 和 Sheet2) 2 读取表格数据示例 from openpyxl import load_workbookworkbook load_workbook(filename r图书.xlsx)# 获取工作簿的所有工作表 &#xff0c;返回列表类型 print…

如何性能测试中进行业务验证?

在性能测试过程中&#xff0c;验证HTTP code和响应业务code码是比较基础的&#xff0c;但是在一些业务中&#xff0c;这些参数并不能保证接口正常响应了&#xff0c;很可能返回了错误信息&#xff0c;所以这个时候对接口进行业务验证就尤其重要。下面分享一个对某个资源进行业务…