OpenCV的周期性噪声去除滤波器(70)

返回:OpenCV系列文章目录(持续更新中......)
上一篇:OpenCV如何通过梯度结构张量进行各向异性图像分割(69)
下一篇 :OpenCV如何为我们的应用程序添加跟踪栏(71)

目录

目标

理论

如何消除傅里叶域中的周期性噪声?

源代码

解释

结果

目标

在本教程中,您将学习:

  • 如何消除傅里叶域中的周期性噪声

理论

注意

解释基于该书[108]。此页面上的图像是真实世界的图像。

周期性噪声在傅里叶域中产生尖峰,通常可以通过视觉分析检测到。

如何消除傅里叶域中的周期性噪声?

通过频域滤波可以显著降低周期性噪声。在此页面上,我们使用具有适当半径的陷波抑制滤波器来完全封闭傅里叶域中的噪声尖峰。陷波滤波器抑制中心频率附近预定义邻域中的频率。陷波滤波器的数量是任意的。缺口区域的形状也可以是任意的(例如矩形或圆形)。在此页面上,我们使用三个圆形陷波抑制滤光片。图像的功率谱致密化用于噪声尖峰的视觉检测。

源代码

您可以在 OpenCV 源代码库中找到源代码。samples/cpp/tutorial_code/ImgProc/periodic_noise_removing_filter/periodic_noise_removing_filter.cpp

#include <iostream>
#include "opencv2/highgui.hpp"
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>using namespace cv;
using namespace std;void fftshift(const Mat& inputImg, Mat& outputImg);
void filter2DFreq(const Mat& inputImg, Mat& outputImg, const Mat& H);
void synthesizeFilterH(Mat& inputOutput_H, Point center, int radius);
void calcPSD(const Mat& inputImg, Mat& outputImg, int flag = 0);const String keys =
"{help h usage ? | | print this message }"
"{@image |period_input.jpg | input image name }"
;int main(int argc, char* argv[])
{CommandLineParser parser(argc, argv, keys);string strInFileName = parser.get<String>("@image");samples::addSamplesDataSearchSubDirectory("doc/tutorials/imgproc/periodic_noise_removing_filter/images");Mat imgIn = imread(samples::findFile(strInFileName), IMREAD_GRAYSCALE);if (imgIn.empty()) //check whether the image is loaded or not{cout << "ERROR : Image cannot be loaded..!!" << endl;return -1;}imshow("Image corrupted", imgIn);imgIn.convertTo(imgIn, CV_32F);// it needs to process even image onlyRect roi = Rect(0, 0, imgIn.cols & -2, imgIn.rows & -2);imgIn = imgIn(roi);// PSD calculation (start)Mat imgPSD;calcPSD(imgIn, imgPSD);fftshift(imgPSD, imgPSD);normalize(imgPSD, imgPSD, 0, 255, NORM_MINMAX);// PSD calculation (stop)//H calculation (start)Mat H = Mat(roi.size(), CV_32F, Scalar(1));const int r = 21;synthesizeFilterH(H, Point(705, 458), r);synthesizeFilterH(H, Point(850, 391), r);synthesizeFilterH(H, Point(993, 325), r);//H calculation (stop)// filtering (start)Mat imgOut;fftshift(H, H);filter2DFreq(imgIn, imgOut, H);// filtering (stop)imgOut.convertTo(imgOut, CV_8U);normalize(imgOut, imgOut, 0, 255, NORM_MINMAX);imwrite("result.jpg", imgOut);imwrite("PSD.jpg", imgPSD);fftshift(H, H);normalize(H, H, 0, 255, NORM_MINMAX);imshow("Debluring", imgOut);imwrite("filter.jpg", H);waitKey(0);return 0;
}void fftshift(const Mat& inputImg, Mat& outputImg)
{outputImg = inputImg.clone();int cx = outputImg.cols / 2;int cy = outputImg.rows / 2;Mat q0(outputImg, Rect(0, 0, cx, cy));Mat q1(outputImg, Rect(cx, 0, cx, cy));Mat q2(outputImg, Rect(0, cy, cx, cy));Mat q3(outputImg, Rect(cx, cy, cx, cy));Mat tmp;q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);
}void filter2DFreq(const Mat& inputImg, Mat& outputImg, const Mat& H)
{Mat planes[2] = { Mat_<float>(inputImg.clone()), Mat::zeros(inputImg.size(), CV_32F) };Mat complexI;merge(planes, 2, complexI);dft(complexI, complexI, DFT_SCALE);Mat planesH[2] = { Mat_<float>(H.clone()), Mat::zeros(H.size(), CV_32F) };Mat complexH;merge(planesH, 2, complexH);Mat complexIH;mulSpectrums(complexI, complexH, complexIH, 0);idft(complexIH, complexIH);split(complexIH, planes);outputImg = planes[0];
}void synthesizeFilterH(Mat& inputOutput_H, Point center, int radius)
{Point c2 = center, c3 = center, c4 = center;c2.y = inputOutput_H.rows - center.y;c3.x = inputOutput_H.cols - center.x;c4 = Point(c3.x,c2.y);circle(inputOutput_H, center, radius, 0, -1, 8);circle(inputOutput_H, c2, radius, 0, -1, 8);circle(inputOutput_H, c3, radius, 0, -1, 8);circle(inputOutput_H, c4, radius, 0, -1, 8);
}// Function calculates PSD(Power spectrum density) by fft with two flags
// flag = 0 means to return PSD
// flag = 1 means to return log(PSD)
void calcPSD(const Mat& inputImg, Mat& outputImg, int flag)
{Mat planes[2] = { Mat_<float>(inputImg.clone()), Mat::zeros(inputImg.size(), CV_32F) };Mat complexI;merge(planes, 2, complexI);dft(complexI, complexI);split(complexI, planes); // planes[0] = Re(DFT(I)), planes[1] = Im(DFT(I))planes[0].at<float>(0) = 0;planes[1].at<float>(0) = 0;// compute the PSD = sqrt(Re(DFT(I))^2 + Im(DFT(I))^2)^2Mat imgPSD;magnitude(planes[0], planes[1], imgPSD); //imgPSD = sqrt(Power spectrum density)pow(imgPSD, 2, imgPSD); //it needs ^2 in order to get PSDoutputImg = imgPSD;// logPSD = log(1 + PSD)if (flag){Mat imglogPSD;imglogPSD = imgPSD + Scalar::all(1);log(imglogPSD, imglogPSD);outputImg = imglogPSD;}
}

解释

通过频域滤波进行周期性降噪,包括功率谱密度计算(用于噪声尖峰视觉检测)、陷波抑制滤波器合成和频率滤波:

 // it needs to process even image onlyRect roi = Rect(0, 0, imgIn.cols & -2, imgIn.rows & -2);imgIn = imgIn(roi);// PSD calculation (start)Mat imgPSD;calcPSD(imgIn, imgPSD);fftshift(imgPSD, imgPSD);normalize(imgPSD, imgPSD, 0, 255, NORM_MINMAX);// PSD calculation (stop)//H calculation (start)Mat H = Mat(roi.size(), CV_32F, Scalar(1));const int r = 21;synthesizeFilterH(H, Point(705, 458), r);synthesizeFilterH(H, Point(850, 391), r);synthesizeFilterH(H, Point(993, 325), r);//H calculation (stop)// filtering (start)Mat imgOut;fftshift(H, H);filter2DFreq(imgIn, imgOut, H);// filtering (stop)

函数 calcPSD()计算图像的功率谱密度:

void calcPSD(const Mat& inputImg, Mat& outputImg, int flag)
{Mat planes[2] = { Mat_<float>(inputImg.clone()), Mat::zeros(inputImg.size(), CV_32F) };Mat complexI;merge(planes, 2, complexI);dft(complexI, complexI);split(complexI, planes); // planes[0] = Re(DFT(I)), planes[1] = Im(DFT(I))planes[0].at<float>(0) = 0;planes[1].at<float>(0) = 0;// compute the PSD = sqrt(Re(DFT(I))^2 + Im(DFT(I))^2)^2Mat imgPSD;magnitude(planes[0], planes[1], imgPSD); //imgPSD = sqrt(Power spectrum density)pow(imgPSD, 2, imgPSD); //it needs ^2 in order to get PSDoutputImg = imgPSD;// logPSD = log(1 + PSD)if (flag){Mat imglogPSD;imglogPSD = imgPSD + Scalar::all(1);log(imglogPSD, imglogPSD);outputImg = imglogPSD;}
}

函数 synthesizeFilterH()根据中心频率和半径形成理想圆形陷波抑制滤波器的传递函数:

void synthesizeFilterH(Mat& inputOutput_H, Point center, int radius)
{Point c2 = center, c3 = center, c4 = center;c2.y = inputOutput_H.rows - center.y;c3.x = inputOutput_H.cols - center.x;c4 = Point(c3.x,c2.y);circle(inputOutput_H, center, radius, 0, -1, 8);circle(inputOutput_H, c2, radius, 0, -1, 8);circle(inputOutput_H, c3, radius, 0, -1, 8);circle(inputOutput_H, c4, radius, 0, -1, 8);
}

函数 filter2DFreq()过滤频域中的图像。函数 fftshift()和 filter2DFreq()是从教程 Out-of-focus Deblur Filter 中复制的。

结果

下图显示了被各种频率的周期性噪声严重损坏的图像。

噪声分量很容易被看作是下图所示的功率谱密度中的亮点(尖峰)。

下图显示了具有适当半径的陷波抑制滤波器,以完全封闭噪声尖峰。

使用陷波抑制滤波器处理图像的结果如下所示。

这种改进是显而易见的。与原始图像相比,此图像包含的可见周期性噪声要少得多。

您还可以在 YouTube 上找到此过滤理念的快速视频演示。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/6627.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式之数据访问对象模式

在Java编程的浩瀚星海中&#xff0c;有一个模式低调却强大&#xff0c;它像是一位默默无闻的超级英雄&#xff0c;支撑起无数应用的数据脊梁——那就是数据访问对象&#xff08;DAO, Data Access Object&#xff09;模式&#xff01;想象一下&#xff0c;如果你能像操纵魔法一样…

Unity技术学习:RenderMesh、RenderMeshInstanced

叠甲&#xff1a;本人比较菜&#xff0c;如果哪里不对或者有认知不到的地方&#xff0c;欢迎锐评&#xff08;不玻璃心&#xff09;&#xff01; 导师留了个任务&#xff0c;渲染大量的、移动的物体。 当时找了几个解决方案&#xff1a; 静态批处理&#xff1a; 这东西只对静…

golang for经典练习 金字塔打印 示例 支持控制台输入要打印的层数

go语言中最经典的for练习程序 金字塔打印 &#xff0c;这也是其他语言中学习循环和条件算法最为经典的联系题。 其核心算法是如何控制内层循环变量j 每行打印的*号数量 j<i*2-1 和空格数量 j1 || j i*2-1 golang中实现实心金字塔 Solid Pyramid和空心金字塔 Hollow Pyram…

CSS浮动(如果想知道CSS有关浮动的知识点,那么只看这一篇就足够了!)

前言&#xff1a;在学习CSS排版的时候&#xff0c;浮动是我们必须要知道的知识点&#xff0c;浮动在设计之初是为了实现文字环绕效果的&#xff0c;但是后来被人们发现浮动在CSS排版中有着很好的实用价值&#xff0c;所以浮动便成为了CSS排版的利器之一。 ✨✨✨这里是秋刀鱼不…

pandas学习笔记12

缺失数据处理 其实在很多时候&#xff0c;人们往往不愿意过多透露自己的信息。假如您正在对用户的产品体验做调查&#xff0c;在这个过程中您会发现&#xff0c;一些用户很乐意分享自己使用产品的体验&#xff0c;但他是不愿意透露自己的姓名和联系方式&#xff1b; 还有一些用…

《尿不湿级》STM32 F103C8T6最小系统板搭建(五)BOOT

一、BOOT是什么&#xff1f; 大多数初学者第一次接触BOOT总是对这个词感到不解&#xff0c;从哪冒出一个奇奇怪怪的东西还要接跳线帽&#xff0c;为什么要配置它才能进行串口程序的下载&#xff1f;为什么不正确配置会导致单片机无法正常启动…… boot&#xff0c;及物动词&…

AI-数学-高中56-成对数据统计-线性回归方程

原作者视频&#xff1a;【成对数据统计】【一数辞典】1线性回归方程_哔哩哔哩_bilibili 注意&#xff1a;高中只学线性回归。 最小二乘法&#xff08;残差和平方最小的直线、方差最小>拟合程度最好&#xff09;&#xff1a;

2.spring security 简单入门

创建springboot 项目&#xff0c;引入spring security坐标 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--spring security坐标--><dependency&g…

17_Scala面向对象高阶功能

文章目录 1.继承1.1 构造对象时,父类对象优于子类对象1.2父类主构造有参数,子类必须要显示地调用父类主构造器并传值 2.封装3.抽象3.1抽象定义3.2子类继承抽象类3.3抽象属性 4.伴生对象4.1创建类和伴生对象4.2调用 1.继承 –和Java一样,权限protected , public.父类定义子类用…

分布式锁之-redis

什么是分布式锁&#xff1f; 即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题&#xff0c;而分布式锁&#xff0c;就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是&#xff0c;分布式系统中竞争共享资源的最小粒度从线程升级成了…

详细介绍ARM-ORACLE Database 19c数据库下载

目录 1. 前言 2. 获取方式 2.1 ORACLE专栏 2.2 ORACLE下载站点 1. 前言 现有网络上已有非常多关于ORACLE数据库机下载的介绍&#xff0c;但对于ARM平台的介绍不多&#xff0c;借此机会我将该版的下载步骤做如下说明&#xff0c;希望能够一些不明之人提供帮助和参考 2. 获…

Linux理解文件操作 文件描述符fd 理解重定向 dup2 缓冲区 C语言实现自己的shell

文章目录 前言一、文件相关概念与操作1.1 open()1.2 close()1.3 write()1.4 read()1.4 写入的时候先清空文件内容再写入1.5 追加&#xff08;a && a&#xff09; 二、文件描述符2.1 文件描述符 fd 0 1 2 的理解2.2 FILE结构体&#xff1a;的源代码 三、深入理解文件描述…

DETR类型检测网络---思考和Tricks测试

目录 batch_size的影响辅助损失的作用学习率的影响Decoder层数增多的影响3D检测中, feats位置编码和query位置编码是否共享mpl层背景-关于query的生成方式 利用widthformer类似的方式简化注意力机制 batch_size的影响 batch8: batch20: 由实验结果可知:这里实验有问题,横坐标…

JAVA语言开发的智慧城管系统源码:技术架构Vue+后端框架Spring boot+数据库MySQL

通过综合应用计算机技术、网络技术、现代通信技术等多种信息技术&#xff0c;充分融合RS遥感技术、GPS全球定位技术、GIS地理信息系统&#xff0c;开始建设一个动态可视的、实时更新的、精细量化的城市管理系统。智慧城管将采用云平台架构方式进行建设&#xff0c;基于现有数字…

人工智能大模型应用指南

大家好&#xff0c;我是爱编程的喵喵。双985硕士毕业&#xff0c;现担任全栈工程师一职&#xff0c;热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…

直流屏整流模块HG07A220R电源模块HG10A220R

直流屏整流模块HG07A220R电源模块HG10A220R 其他同类型监控模块PM09T电源模块HG22005/S&#xff0c;HG22010/S&#xff0c;HG11010/S&#xff0c;HG11020/S&#xff0c;HG10A220Z&#xff0c;HG10A220F&#xff0c;HG05A220Z&#xff0c;HG07A220Z&#xff0c;HG10A110Z&#x…

免费可商用字体素材大全,办公设计字体合集打包166款

一、素材描述 这是一套免费可商用字体素材&#xff0c;这些字体一般会在办公与设计的时候用到&#xff0c;比如&#xff0c;Photoshop、illustrator、Coreldraw、AfterEffects、Indesign、WPS、Office&#xff0c;等等&#xff0c;想要更好更快地办公与设计&#xff0c;字体还…

【Java】面向对象核心知识点(二),文章层次分明,内容精益求精,代码简单易懂

目录 一、构造方法 1.1 概念 1.2 作用 1.3 代码 二、抽象 2.1 概念 2.2 作用 2.3 注意 2.4 代码 三、接口 3.1 概念 3.2 作用 3.3 注意 3.4 语法 3.5 代码 四、内部类 4.1 成员内部类 4.2 局部内部类 4.3 静态内部类 4.4 匿名内部类 &#xff08;原创文章&…

WWW‘24 | 课程学习CL+模仿学习IL用于ETF及商品期货交易

WWW24 | 课程学习CL模仿学习IL用于ETF及商品期货交易 原创 QuantML QuantML 2024-05-04 13:47 论文地址&#xff1a;[2311.13326] Curriculum Learning and Imitation Learning for Model-free Control on Financial Time-series (arxiv.org) 本文探讨了在金融时间序列数据上…

W801学习笔记十七:古诗学习应用——上

硬件驱动以及软件架构大体上已经完成&#xff0c;尚存一些遗漏之处&#xff0c;后续会寻找合适的时机进行补充。自此章起&#xff0c;将正式迈入软件应用阶段&#xff0c;尤其是游戏开发领域。 关于第一个应用&#xff0c;此前已有一些构想&#xff1a; 其一&#xff0c;随机…