VTK修炼之道42:频域处理_高通滤波(理想+巴特沃兹)

2023-12-02 12:08

本文主要是介绍VTK修炼之道42:频域处理_高通滤波(理想+巴特沃兹),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.理想高通滤波器

高通滤波与低通滤波正好相反,是频域图像的高频部分通过而抑制低频部分。在图像中图像的边缘对应高频分量,因此高通滤波的效果是图像锐化。同样最简单的高通滤波器是理想高通滤波器。通过设置一个频率阈值,将高于该阈值的频率部分通过,而低于阈值的低频部分设置为0。

VTK中理想高通滤波的实例如下:

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageFFT.h>
#include <vtkImageIdealHighPass.h>
#include <vtkImageRFFT.h>
#include <vtkImageCast.h>
#include <vtkImageExtractComponents.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>int main(int argc, char* argv[])
{vtkSmartPointer<vtkJPEGReader> reader =vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName("lena.jpg");reader->Update();vtkSmartPointer<vtkImageFFT> fftFilter =vtkSmartPointer<vtkImageFFT>::New();fftFilter->SetInputConnection(reader->GetOutputPort());fftFilter->Update();vtkSmartPointer<vtkImageIdealHighPass> highPassFilter =vtkSmartPointer<vtkImageIdealHighPass>::New();highPassFilter->SetInputConnection(fftFilter->GetOutputPort());highPassFilter->SetXCutOff(0.1);highPassFilter->SetYCutOff(0.1);highPassFilter->Update();vtkSmartPointer<vtkImageRFFT> rfftFilter =vtkSmartPointer<vtkImageRFFT>::New();rfftFilter->SetInputConnection(highPassFilter->GetOutputPort());rfftFilter->Update();vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal =vtkSmartPointer<vtkImageExtractComponents>::New();ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());ifftExtractReal->SetComponents(0);vtkSmartPointer<vtkImageCast> castFilter =vtkSmartPointer<vtkImageCast>::New();castFilter->SetInputConnection(ifftExtractReal->GetOutputPort());castFilter->SetOutputScalarTypeToUnsignedChar();castFilter->Update();/vtkSmartPointer<vtkImageActor> originalActor =vtkSmartPointer<vtkImageActor>::New();originalActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> erodedActor =vtkSmartPointer<vtkImageActor>::New();erodedActor->SetInputData(castFilter->GetOutput());/double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 };double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 };vtkSmartPointer<vtkRenderer> leftRenderer =vtkSmartPointer<vtkRenderer>::New();leftRenderer->AddActor(originalActor);leftRenderer->SetViewport(leftViewport);leftRenderer->SetBackground(1.0, 1.0, 1.0);leftRenderer->ResetCamera();vtkSmartPointer<vtkRenderer> rightRenderer =vtkSmartPointer<vtkRenderer>::New();rightRenderer->AddActor(erodedActor);rightRenderer->SetViewport(rightViewport);rightRenderer->SetBackground(1.0, 1.0, 1.0);rightRenderer->ResetCamera();/vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->SetSize(640, 320);rw->AddRenderer(leftRenderer);rw->AddRenderer(rightRenderer);rw->SetWindowName("IdealHighPassExample");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();rwi->SetInteractorStyle(style);rwi->SetRenderWindow(rw);rwi->Start();return 0;
}


同低通滤波一样,首先将读入图像通过vtkImageFFT转换到频域空间,定义vtkImageIdealHighPass对象,并通过SetXCutOff ()和SetYCutOff() 设置X和Y方向的截止频率。然后通过vtkImageRFFT将处理后的图像转换到空域中,得到高通滤波图像。为了显示的需要,还需要提取图像分量和数据类型的转换。

下面是理想高通滤波的执行结果:


从结果看出高通滤波后图像得到锐化处理,图像中仅剩下边缘。

2.巴特沃兹高通滤波

理想高通滤波器不能通过电子元器件来实现,而且存在振铃现象。在实际中最常使用的高通滤波器是巴特沃斯高通滤波器。该滤波器的转移函数是:


D(u,v)表示频域中点到频域平面的距离,是截止频率。当D(u,v)大于时,对应的H(u,v)逐渐接近1,从而使得高频部分得以通过;而当D(u,v)小于时,H(u,v)逐渐接近0,实现低频部分过滤。巴特沃斯高通滤波器在VTK中对应vtkImageButterworthHighPass类。

下面代码说明了vtkImageButterworthHighPass对图像进行高通滤波:

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageFFT.h>
#include <vtkImageButterworthHighPass.h>
#include <vtkImageRFFT.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageCast.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>int main(int argc, char* argv[])
{vtkSmartPointer<vtkJPEGReader> reader =vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName("lena.jpg");reader->Update();vtkSmartPointer<vtkImageFFT> fftFilter =vtkSmartPointer<vtkImageFFT>::New();fftFilter->SetInputConnection(reader->GetOutputPort());fftFilter->Update();vtkSmartPointer<vtkImageButterworthHighPass> highPassFilter =vtkSmartPointer<vtkImageButterworthHighPass>::New();highPassFilter->SetInputConnection(fftFilter->GetOutputPort());highPassFilter->SetXCutOff(0.1);highPassFilter->SetYCutOff(0.1);highPassFilter->Update();vtkSmartPointer<vtkImageRFFT> rfftFilter =vtkSmartPointer<vtkImageRFFT>::New();rfftFilter->SetInputConnection(highPassFilter->GetOutputPort());rfftFilter->Update();vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal =vtkSmartPointer<vtkImageExtractComponents>::New();ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());ifftExtractReal->SetComponents(0);vtkSmartPointer<vtkImageCast> castFilter =vtkSmartPointer<vtkImageCast>::New();castFilter->SetInputConnection(ifftExtractReal->GetOutputPort());castFilter->SetOutputScalarTypeToUnsignedChar();castFilter->Update();vtkSmartPointer<vtkImageActor> originalActor =vtkSmartPointer<vtkImageActor>::New();originalActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> erodedActor =vtkSmartPointer<vtkImageActor>::New();erodedActor->SetInputData(castFilter->GetOutput());//double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 };double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 };vtkSmartPointer<vtkRenderer> leftRenderer =vtkSmartPointer<vtkRenderer>::New();leftRenderer->AddActor(originalActor);leftRenderer->ResetCamera();leftRenderer->SetViewport(leftViewport);leftRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderer> rightRenderer =vtkSmartPointer<vtkRenderer>::New();rightRenderer->AddActor(erodedActor);rightRenderer->SetViewport(rightViewport);rightRenderer->SetBackground(1.0, 1.0, 1.0);rightRenderer->ResetCamera();vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(leftRenderer);rw->AddRenderer(rightRenderer);rw->SetSize(640, 320);rw->Render();rw->SetWindowName("Frequency_ButterworthHighPass");/vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();rwi->SetInteractorStyle(style);rwi->SetRenderWindow(rw);rwi->Start();return 0;
}


vtkImageButterworthHighPass与理想高通滤波使用方法一致。需要设置X和Y轴的截止频率,为了便于比较,其截止频域与理想高通滤波设置一致。

下图是执行结果:

3.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.


这篇关于VTK修炼之道42:频域处理_高通滤波(理想+巴特沃兹)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/445276

相关文章

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用

Java实现优雅日期处理的方案详解

《Java实现优雅日期处理的方案详解》在我们的日常工作中,需要经常处理各种格式,各种类似的的日期或者时间,下面我们就来看看如何使用java处理这样的日期问题吧,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言一、日期的坑1.1 日期格式化陷阱1.2 时区转换二、优雅方案的进阶之路2.1 线程安全重构2

Python处理函数调用超时的四种方法

《Python处理函数调用超时的四种方法》在实际开发过程中,我们可能会遇到一些场景,需要对函数的执行时间进行限制,例如,当一个函数执行时间过长时,可能会导致程序卡顿、资源占用过高,因此,在某些情况下,... 目录前言func-timeout1. 安装 func-timeout2. 基本用法自定义进程subp

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

浅析Java中如何优雅地处理null值

《浅析Java中如何优雅地处理null值》这篇文章主要为大家详细介绍了如何结合Lambda表达式和Optional,让Java更优雅地处理null值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录场景 1:不为 null 则执行场景 2:不为 null 则返回,为 null 则返回特定值或抛出异常场景

深入理解Apache Kafka(分布式流处理平台)

《深入理解ApacheKafka(分布式流处理平台)》ApacheKafka作为现代分布式系统中的核心中间件,为构建高吞吐量、低延迟的数据管道提供了强大支持,本文将深入探讨Kafka的核心概念、架构... 目录引言一、Apache Kafka概述1.1 什么是Kafka?1.2 Kafka的核心概念二、Ka

resultMap如何处理复杂映射问题

《resultMap如何处理复杂映射问题》:本文主要介绍resultMap如何处理复杂映射问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录resultMap复杂映射问题Ⅰ 多对一查询:学生——老师Ⅱ 一对多查询:老师——学生总结resultMap复杂映射问题

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整