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.rhkb.cn/news/320220.html

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

相关文章

详解基于 RAG 的 txt2sql 全过程

前文 本文使用通义千问大模型和 ChromaDB 向量数据库来实现一个完整的 text2sql 的项目&#xff0c;并基于实际的业务进行效果的展示。 准备 在进行项目之前需要准备下面主要的内容&#xff1a; python 环境通义千问 qwen-max 模型的 api-keyChromaDB 向量数据库acge_text_…

Sharding Capital: 为什么投资全链流动性基础设施 Entangle ?

写在前面&#xff1a;Entangle 项目的名称取自于量子纠缠(Quantum entanglement)&#xff0c;体现了项目对于构建连接、关联和互通的愿景。就像量子纠缠将不同的粒子联系在一起&#xff0c;Entangle 旨在通过其跨链流动性和合成衍生品的解决方案将不同的区块链网络连接在一起&a…

django设计模式理解FBV和CBV

在 Web 开发中&#xff0c;FBV&#xff08;Function-Based Views&#xff09;和 CBV&#xff08;Class-Based Views&#xff09;是两种常见的视图设计模式&#xff0c;用于处理 HTTP 请求并生成相应的响应。下面是它们的简要解释&#xff1a; Function-Based Views (FBV) 在 …

激发创新活力,泸州老窖锻造人才“铁军”(内附长江酒道短评)

执笔 | 姜 姜 编辑 | 古利特 刚刚站上300亿元新台阶&#xff0c;泸州老窖再次传来喜讯。 <<<左右滑动查看更多>>> 4月28日&#xff0c;四川省庆祝“五一”国际劳动节大会在成都召开。泸州老窖股份有限公司工业4.0项目秘书长赵丙坤、泸州老窖酿酒有限责任公…

VS Code 远程连接 SSH 服务器

文章目录 一、安装 Remote - SSH 扩展并连接远程主机二、免密连接远程主机1. 生成 SSH 密钥对2. 将公钥复制到远程服务器3. 配置 SSH 客服端4. 连接测试 随着技术的不断迭代更新&#xff0c;在 Linux 系统中使用 Vim、nano 等基于 Shell 终端的编辑器&#xff08;我曾经也是个 …

利用AI大模型和Echarts 绘制知识图谱,实现文本信息提取和图数据库操作

引言 随着信息时代的到来&#xff0c;海量的文本数据成为了我们获取知识的重要来源。然而&#xff0c;如何从这些文本数据中提取出有用的信息&#xff0c;并将其以可视化的方式展示出来&#xff0c;一直是一个具有挑战性的问题。近年来&#xff0c;随着人工智能技术的发展&…

热敏电阻符号与常见术语详细解析

热敏电阻是一种电阻器&#xff0c;其特点是电阻值随温度的变化而显著变化&#xff0c;这使得它们成为非常有用的温度传感器。它们可以由单晶、多晶或玻璃、塑料等半导体材料制成&#xff0c;并分为两大类&#xff1a;正温度系数热敏电阻&#xff08;#PTC热敏电阻#&#xff09;和…

纯血鸿蒙APP实战开发——短视频切换实现案例

短视频切换实现案例 介绍 短视频切换在应用开发中是一种常见场景&#xff0c;上下滑动可以切换视频&#xff0c;十分方便。本模块基于Swiper组件和Video组件实现短视频切换功能。 效果图预览 使用说明 上下滑动可以切换视频。点击屏幕暂停视频&#xff0c;再次点击继续播放…

场外个股期权和场内个股期权的优缺点是什么?

场外个股期权和场内个股期权的优缺点 场外个股期权是指在沪深交易所之外交易的个股期权&#xff0c;其本质是一种金融衍生品&#xff0c;允许投资者在股票交易场所外以特定价格买进或卖出证券。场内个股期权是以单只股票作为标的资产的期权合约&#xff0c;其内在价值是基于标…

深度学习-线性回归+基础优化算法

目录 线性模型衡量预估质量训练数据参数学习训练损失最小化损失来学习参数显式解 总结基础优化梯度下降选择学习率 小批量随机梯度下降选择批量大小 总结线性回归的从零开始实现实现一个函数读取小批量效果展示这里可视化看一下 线性回归从零开始实现线性回归的简洁实现效果展示…

HCIP第二节

OSPF&#xff1a;开放式最短路径协议&#xff08;属于IGP-内部网关路由协议&#xff09; 优点&#xff1a;相比与静态可以实时收敛 更新方式&#xff1a;触发更新&#xff1a;224.0.0.5/6 周期更新&#xff1a;30min 在华为设备欸中&#xff0c;默认ospf优先级是10&#…

vue3+vite+js 实现移动端,PC端响应式布局

目前使用的是vue3vite&#xff0c;没有使用ts 纯移动端|PC端 这种适用于只适用一个端的情况 方法&#xff1a;amfe-flexible postcss-pxtorem相结合 ① 执行以下两个命令 npm i -S amfe-flexible npm install postcss-pxtorem --save-dev② main.js文件引用 import amfe-f…

使用固定公网地址远程访问开源服务器运维管理面板1Panel管理界面

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

【前端】输入时字符跳动动画实现

输入时字符跳动动画实现 在前端开发中&#xff0c;为了提升用户体验&#xff0c;我们经常需要为用户的交互行为提供即时的反馈。这不仅让用户知道他们的操作有了响应&#xff0c;还可以让整个界面看起来更加生动、有趣。本文将通过一个简单的例子讲解如何实现在用户输入字符时…

更适合宝妈和上班族的兼职,每天2小时收入250+的微头条项目

许多人通过撰写微头条赚取收入&#xff0c;但这通常需要自己寻找素材&#xff0c;然后逐字逐句地进行改编创作&#xff0c;整个过程既繁琐又低效。 然而&#xff0c;如今全球范围内的AI工具正如雨后春笋般涌现。百度推出了文心一言&#xff0c;阿里巴巴推出了AI工具通义千问&a…

Stateflow基础知识笔记

01--Simulink/Stateflow概述 Stateflow是集成于Simulink中的图形化设计与开发工具&#xff0c;主要 用于针对控制系统中的复杂控制逻辑进行建模与仿真&#xff0c;或者说&#xff0c; Stateflow适用于针对事件响应系统进行建模与仿真。 Stateflow必须与Simulink联合使用&#…

20240503解决Ubuntu20.04和WIN10双系统下WIN10的时间异常的问题

20240503解决Ubuntu20.04和WIN10双系统下WIN10的时间异常的问题 2024/5/3 9:33 缘起&#xff1a;因为工作需要&#xff0c;编译服务器上都会安装Ubuntu20.04。 但是因为WINDOWS强悍的生态系统&#xff0c;偶尔还是有必须要用WINDOWS的时候&#xff0c;于是也安装了WIN10。 双系…

LNMP部署wordpress

1.环境准备 总体架构介绍 序号类型名称外网地址内网地址软件02负载均衡服务器lb0110.0.0.5192.168.88.5nginx keepalived03负载均衡服务器lb0210.0.0.6192.168.88.6nginx keepalived04web服务器web0110.0.0.7192.168.88.7nginx05web服务器web0210.0.0.8192.168.88.8nginx06we…

Flask应用的部署和使用,以照片分割为例。

任务是本地上传一张照片&#xff0c;在服务器端处理后&#xff0c;下载到本地。 服务器端已经封装好了相关的程序通过以下语句调用 from amg_test import main from test import test main() test() 首先要在虚拟环境中安装flask pip install Flask 文件组织架构 your_pro…

BERT模型的网络结构解析 运行案例分析

整体结构 第一部分&#xff1a;嵌入层第二部分&#xff1a;编码层第三部分&#xff1a;输出层 对于一个m分类任务&#xff0c;输入n个词作为一次数据&#xff0c;单个批次输入t个数据&#xff0c;在BERT模型的不同部分&#xff0c;数据的形状信息如下&#xff1a; 注1&#x…