6.7泊松噪声

基础概念

在OpenCV联合C++中给一张图片添加泊松噪声(Poisson Noise)可以通过生成随机数并在图像的每个像素上加上这些随机数来实现。泊松噪声是一种统计分布服从泊松分布的噪声,通常用于模拟光子计数等场景。

使用泊松噪声的场景

泊松噪声通常用于模拟光子计数过程中的噪声,例如在低光条件下拍摄的照片中,由于光子计数的统计特性,会产生这种类型的噪声。因此,在进行图像增强、图像去噪等处理时,添加泊松噪声可以帮助评估算法在实际应用中的鲁棒性。

示例代码1

以下是一个使用OpenCV和C++给一张图片添加泊松噪声的示例代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <random>// 添加泊松噪声的函数
void addPoissonNoise(cv::Mat &image, double scale = 1.0)
{// 创建随机数生成器std::random_device rd;std::default_random_engine gen(rd());std::poisson_distribution<int> dist(1.0); // 泊松分布// 获取图像的行数和列数int rows = image.rows;int cols = image.cols;// 遍历图像中的每一个像素for (int i = 0; i < rows; ++i){for (int j = 0; j < cols; ++j){// 生成一个泊松分布的随机数int noise = dist(gen);// 加上噪声//image.at<uchar>(i, j) = std::min(std::max(image.at<uchar>(i, j) + noise * scale, 0), 255);image.at<uchar>(i, j) = std::min(std::max((int)(image.at<uchar>(i, j) + noise * scale), 0), 255);}}
}int main()
{// 读取图像cv::Mat img = cv::imread("02.png", cv::IMREAD_GRAYSCALE);if (img.empty()){std::cerr << "Error loading image." << std::endl;return -1;}// 添加泊松噪声addPoissonNoise(img, 1.0); // scale 为 1.0// 显示原始图像cv::namedWindow("Original Image", cv::WINDOW_NORMAL);cv::imshow("Original Image", img);// 显示添加噪声后的图像cv::namedWindow("Noisy Image", cv::WINDOW_NORMAL);cv::imshow("Noisy Image", img);cv::waitKey(0);return 0;}代码解释
1. 读取图像:使用 cv::imread 函数读取原始图像,并将其转换为灰度图像。
2. 添加泊松噪声:定义一个 addPoissonNoise 函数,该函数接受一个图像矩阵 image 和一个缩放因子 scale。缩放因子 scale 控制噪声的强度。
3. 随机数生成器:使用 <random> 头文件中的 std::random_device 和 std::default_random_engine 生成随机数,std::poisson_distribution 生成符合泊松分布的随机数。
4. 遍历图像:遍历图像的每一个像素点,根据生成的泊松分布随机数给像素值加上噪声。
5. 限制像素值范围:确保像素值在0到255之间,避免超出8位灰度图像的范围。
6. 显示图像:使用 cv::imshow 函数显示原始图像和添加噪声后的图像。参数调整
•缩放因子 scale:控制噪声的强度,可以根据需要调整该参数。较大的 scale 值会导致更强的噪声。注意事项
•噪声强度:通过调整 scale 参数可以控制噪声的强度。
•数据类型:在加噪声时,需要注意像素值的数据类型。在上面的示例中,我们使用了 uchar 类型,因此需要确保像素值在0到255之间。
•性能优化:如果图像较大,遍历每一个像素可能会比较耗时,可以考虑使用OpenCV提供的并行处理方法,如 cv::parallel_for_ 等。通过上述方法,你可以很容易地在OpenCV和C++中给一张图片添加泊松噪声。这对于模拟真实世界中的噪声情况非常有用,尤其是在图像处理和计算机视觉的研究和应用中。

运行结果1

除噪方法

在OpenCV联合C++中去除一张图片上的泊松噪声(Poisson Noise),可以采用多种滤波方法。泊松噪声通常表现为与图像亮度相关的噪声,因此需要选择一种能够适应这种特性的滤波方法。以下是一些常用的滤波方法及其适用性:

1. 非局部均值去噪(Non-Local Means Denoising)

非局部均值去噪(NL-means)是一种高级去噪方法,它通过查找图像中的相似区域来进行去噪。这种方法可以在保持图像细节的同时去除噪声,尤其适用于泊松噪声。

示例代码

#include <opencv2/opencv.hpp>
#include <iostream>int main()
{// 读取图像cv::Mat img = cv::imread("path/to/noisy_image.jpg", cv::IMREAD_GRAYSCALE);if (img.empty()){std::cerr << "Error loading image." << std::endl;return -1;}// 显示原始噪声图像cv::namedWindow("Noisy Image", cv::WINDOW_NORMAL);cv::imshow("Noisy Image", img);// 应用非局部均值去噪cv::Mat denoisedImg;cv::fastNlMeansDenoising(img, denoisedImg, 10, 7, 21); // h=10, templateWindowSize=7, searchWindowSize=21// 显示去噪后的图像cv::namedWindow("Denoised Image", cv::WINDOW_NORMAL);cv::imshow("Denoised Image", denoisedImg);cv::waitKey(0);return 0;
}

运行结果

2. 双边滤波(Bilateral Filtering)

双边滤波是一种非局部均值滤波方法,它在平滑图像的同时能够较好地保留边缘。双边滤波不仅考虑空间邻域,还考虑像素值的相似性,因此在去除泊松噪声的同时,可以较好地保留图像细节。

示例代码

#include <opencv2/opencv.hpp>
#include <iostream>int main()
{// 读取图像cv::Mat img = cv::imread("path/to/noisy_image.jpg", cv::IMREAD_GRAYSCALE);if (img.empty()){std::cerr << "Error loading image." << std::endl;return -1;}// 显示原始噪声图像cv::namedWindow("Noisy Image", cv::WINDOW_NORMAL);cv::imshow("Noisy Image", img);// 应用双边滤波cv::Mat denoisedImg;cv::bilateralFilter(img, denoisedImg, 9, 75, 75); // d=9, sigmaColor=75, sigmaSpace=75// 显示去噪后的图像cv::namedWindow("Denoised Image", cv::WINDOW_NORMAL);cv::imshow("Denoised Image", denoisedImg);cv::waitKey(0);return 0;
}

运行结果

3. 高斯滤波(Gaussian Filtering)

高斯滤波是一种经典的平滑方法,可以用于去除高斯噪声。尽管泊松噪声与高斯噪声有所不同,但在某些情况下,高斯滤波仍然可以作为一种简单的去噪方法。

示例代码

#include <opencv2/opencv.hpp>
#include <iostream>int main()
{// 读取图像cv::Mat img = cv::imread("path/to/noisy_image.jpg", cv::IMREAD_GRAYSCALE);if (img.empty()){std::cerr << "Error loading image." << std::endl;return -1;}// 显示原始噪声图像cv::namedWindow("Noisy Image", cv::WINDOW_NORMAL);cv::imshow("Noisy Image", img);// 应用高斯滤波cv::Mat denoisedImg;cv::GaussianBlur(img, denoisedImg, cv::Size(3, 3), 0); // ksize 为 3x3 的高斯滤波// 显示去噪后的图像cv::namedWindow("Denoised Image", cv::WINDOW_NORMAL);cv::imshow("Denoised Image", denoisedImg);cv::waitKey(0);return 0;
}

运行结果

4. 维纳滤波(Wiener Filtering)

维纳滤波是一种基于最小均方误差估计的滤波方法,可以用于去除各种类型的噪声,包括泊松噪声。维纳滤波需要估计噪声的功率谱密度和信号的功率谱密度。示例代码维纳滤波在OpenCV中没有直接的支持,但可以通过自定义实现。

这里提供一个简化的伪代码示例:

示例代码

#include <opencv2/opencv.hpp>
#include <iostream>void applyWienerFilter(const cv::Mat &input, cv::Mat &output, double noiseVariance)
{// 假设输入图像为灰度图像cv::Mat fftInput, fftOutput, psf, noisePower, signalPower, wienerKernel;// 计算输入图像的傅里叶变换cv::dft(input, fftInput);// PSF(点扩散函数)可以是高斯核或其他核cv::GaussianBlur(cv::Mat::ones(input.size(), CV_32F), psf, cv::Size(3, 3),0);// 计算PSF的傅里叶变换cv::dft(psf, psf);// 计算噪声功率谱密度noisePower = cv::Mat::ones(fftInput.size(), CV_32F) * noiseVariance;// 估计信号功率谱密度signalPower = cv::abs(psf) * cv::abs(psf);// Wiener 滤波器wienerKernel = signalPower / (signalPower + noisePower);// 应用Wiener滤波器cv::mulSpectrums(fftInput, wienerKernel, fftOutput, 0);// 反傅里叶变换cv::dft(fftOutput, fftOutput, cv::DFT_INVERSE | cv::DFT_SCALE);// 逆变换回空间域cv::idft(fftOutput, output);
}int main()
{// 读取图像cv::Mat img = cv::imread("path/to/noisy_image.jpg", cv::IMREAD_GRAYSCALE);if (img.empty()){std::cerr << "Error loading image." << std::endl;return -1;}// 显示原始噪声图像cv::namedWindow("Noisy Image", cv::WINDOW_NORMAL);cv::imshow("Noisy Image", img);// 应用维纳滤波cv::Mat denoisedImg;applyWienerFilter(img, denoisedImg, 10.0); // 假设噪声方差为 10.0// 显示去噪后的图像cv::namedWindow("Denoised Image", cv::WINDOW_NORMAL);cv::imshow("Denoised Image", denoisedImg);cv::waitKey(0);return 0;
}

运行结果

总结

•非局部均值去噪(Non-Local Means Denoising):适用于需要保留图像细节的情况,能够较好地去除泊松噪声。
•双边滤波(Bilateral Filtering):在平滑图像的同时能够较好地保留边缘,适用于需要保持图像细节的情况。
•高斯滤波(Gaussian Filtering):简单易用,但在处理泊松噪声时效果可能不如非局部均值去噪和双边滤波。
•维纳滤波(Wiener Filtering):适用于需要精确去噪的情况,但实现较为复杂。

根据具体的应用需求和图像特点,可以选择最适合的方法。如果需要去除泊松噪声同时尽量保留图像细节,可以优先考虑非局部均值去噪和双边滤波。如果需要更高级的去噪效果,可以考虑维纳滤波。

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

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

相关文章

【解决】chrome 谷歌浏览器,鼠标点击任何区域都是 Input 输入框的状态,能看到输入的光标

chrome 谷歌浏览器&#xff0c;鼠标点击任何区域都是 Input 输入框的状态&#xff0c;能看到输入的光标 今天打开电脑的时候&#xff0c;网页中任何文本的地方&#xff0c;只要鼠标点击&#xff0c;就会出现一个输入的光标&#xff0c;无论在哪个站点哪个页面都是如此。 我知道…

Pandas 数据分析入门详解

今日内容大纲介绍 DataFrame读写文件 DataFrame加载部分数据 DataFrame分组聚合计算 DataFrame常用排序方式 1.DataFrame-保存数据到文件 格式 df对象.to_数据格式(路径) ​ # 例如: df.to_csv(data/abc.csv) 代码演示 如要保存的对象是计算的中间结果&#xff0c;或者以…

CQRS模型解析

简介 CQRS中文意思为命令于查询职责分离&#xff0c;我们可以将其了解成读写分离的思想。分为两个部分 业务侧和数据侧&#xff0c;业务侧主要执行的就是数据的写操作&#xff0c;而数据侧主要执行的就是数据的读操作。当然两侧的数据库可以是不同的。目前最为常用的CQRS思想方…

C++调用C# DLL之踩坑记录

C是非托管代码&#xff0c;C#则是托管代码&#xff0c;无法直接调用 CLR的介绍见CLR简介 MSDN提到了两种非托管-托管的交互技术&#xff1a;CLR Interop和COM Interop 后者要将C# 类库注册为COM组件&#xff0c;本文只探讨CLR&#xff0c;要通过C CLR写中间层代码 方式一&…

javascript 浏览器打印不同页面设置方向,横向纵向打印

// 在JavaScript中添加打印样式 const printStyle document.createElement(style); printStyle.innerHTML media print { page { size: landscape; }body { margin: 10mm; } }; document.head.appendChild(printStyle);// 触发打印 function printPage() {window.print(); }/…

获取参数

获取querystring参数 querystring 指的是URL中 ? 后面携带的参数&#xff0c;例如&#xff1a;http://127.0.0.1:9090/web?query杨超越。 获取请求的querystring参数的方法如下&#xff1a; 方法1&#xff1a; Query package main// querystringimport ("github.com/…

第6章 右值引用

6.1 左值和右值 区分左值与右值&#xff1a; 看能不能取地址 & 若能取地址则为左值 不能取地址为右值 int x 1; x;//这个是右值 x;//左值 x实现 int tmp x; x x1; return tmp; 返回临时的主要字符串也是左值 它可以取地址 6.2 左值引用 当我们需要将一个对象作为参数…

Vue工程师面试题

Vue工程师面试题通常涵盖Vue的基础知识、核心概念、性能优化、项目实践等多个方面。 一、Vue基础知识 Vue.js是什么? Vue.js(通常简称为Vue)是一个开源的JavaScript框架,用于构建用户界面和单页应用程序(SPA)。它由前谷歌工程师尤雨溪(Evan You)创建,以其轻量级、易用…

引领长期投资新篇章:价值增长与财务安全的双重保障

随着全球金融市场的不断演变&#xff0c;长期投资策略因其稳健性和对价值增长的显著推动作用而日益受到投资者的重视。在这一背景下&#xff0c;Zeal Digital Shares&#xff08;ZDS&#xff09;项目以其创新的数字股票产品&#xff0c;为全球投资者提供了一个全新的长期投资平…

最优化理论与自动驾驶(十一):基于iLQR的自动驾驶轨迹跟踪算法(c++和python版本)

最优化理论与自动驾驶&#xff08;四&#xff09;&#xff1a;iLQR原理、公式及代码演示 之前的章节我们介绍过&#xff0c;iLQR&#xff08;迭代线性二次调节器&#xff09;是一种用于求解非线性系统最优控制最优控制最优控制和规划问题的算法。本章节介绍采用iLQR算法对设定…

分析redis实现分布式锁的思路

文章目录 1、基于redis实现分布式锁&#xff1a;利用key的唯一性1.1、独占排他1.2、死锁问题1.2.1、redis客户端程序获取了锁之后&#xff0c;服务器立马宕机&#xff0c;就会导致死锁。1.2.2、不可重入&#xff1a;可重入 1.3、原子性&#xff1a;加锁和过期之间&#xff1a;s…

深入剖析Docker容器安全:挑战与应对策略

随着容器技术的广泛应用&#xff0c;Docker已成为现代应用开发和部署的核心工具。它通过轻量级虚拟化技术实现应用的隔离与封装&#xff0c;提高了资源利用率。然而&#xff0c;随着Docker的流行&#xff0c;其安全问题也成为关注焦点。容器化技术虽然提供了良好的资源隔离&…

Python青少年简明教程目录

Python青少年简明教程目录 学习编程语言时&#xff0c;会遇到“开头难”和“深入难”的问题&#xff0c;这是许多编程学习者都会经历的普遍现象。 学习Python对于青少年来说是一个很好的编程起点&#xff0c;相对容易上手入门&#xff0c;但语言特性复杂&#xff0c;应用较广&…

Android14 手机蓝牙配对后阻塞问题解决

Android14 手机蓝牙配对后阻塞问题解决 文章目录 Android14 手机蓝牙配对后阻塞问题解决一、前言二、手机蓝牙配对后阻塞问题解决1、部分日志&#xff1a;2、解决方法 三、其他1、Android14 蓝牙 BluetoothService 启动和相关代码介绍2、Android14 待机关机蓝牙自动关闭分析解决…

4.C_数据结构_队列

概述 什么是队列&#xff1a; 队列是限定在两端进行插入操作和删除操作的线性表。具有先入先出(FIFO)的特点 相关名词&#xff1a; 队尾&#xff1a;写入数据的一段队头&#xff1a;读取数据的一段空队&#xff1a;队列中没有数据&#xff0c;队头指针 队尾指针满队&#…

FPGA与Matlab图像处理之直方图均衡化

文章目录 一、什么是直方图?二、什么是直方图均衡化&#xff1f;三、Matlab实现直方图均衡化的步骤第一步&#xff1a; 彩色图像转成灰度图像第二步&#xff1a;提取亮度通道的直方图第三步&#xff1a;累计亮度通道的像素值频率第四步&#xff1a; 映射到新的灰度值 四、Veri…

docker挂载宿主机文件run命令启动报错

背景 使用docker安装mysql8,docker run 命令提示报错 命令: docker run -d \ -p 3306:3306 \ -v ~/docker/mysql8/log/mysqld.log:/var/log/mysqld.log \ -e MYSQL_ROOT_PASSWORD=123456 \ --name mysql8 mysql:8.0.36 报错信息 docker: Error response from daemon: fai…

嵌入式 开发技巧和经验分享

文章目录 前言嵌入式 开发技巧和经验分享目录1.1嵌入式 系统的 定义1.2 嵌入式 操作系统的介绍1.3 嵌入式 开发环境1.4 编译工具链和优化1.5 嵌入式系统软件开发1.6 嵌入式SDK开发2.1选择移植的系统-FreeRtos2.2FreeRtos 移植步骤2.3 系统移植之中断处理2.4系统移植之内存管理2…

【java面经】Redis速记

目录 基本概念 string hash list set zset 常见问题及解决 缓存穿透 缓存击穿 缓存雪崩 Redis内存管理策略 noeviction allkeys-lru allkeys-random volatile-random volatile-ttl Redis持久化机制 RDB快照 AOF追加文件 Redis多线程特性 Redis应用场景 缓…

《C++移动语义:解锁复杂数据结构的高效之道》

在 C的编程世界中&#xff0c;移动语义是一项强大的特性&#xff0c;它能够在处理复杂数据结构如链表、树等时&#xff0c;极大地提高程序的性能和效率。理解并正确实现移动语义在这些复杂数据结构中&#xff0c;对于开发者来说至关重要。 一、移动语义简介 C11 引入了移动语…