6.7泊松噪声

embedded/2024/9/23 8:13:24/

基础概念

在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.ppmy.cn/embedded/115491.html

相关文章

「C++系列」动态内存

【人工智能教程】&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站&#xff1a;【人工智能教程】 文章目录 一、动态内存1. 使用new和delete①分配单个对象②分配对象数组 2. …

Android 车载应用开发指南 - CarService 详解(下)

车载应用正在改变人们的出行体验。从导航到娱乐、从安全到信息服务&#xff0c;车载应用的开发已成为汽车智能化发展的重要组成部分。而对于开发者来说&#xff0c;如何将自己的应用程序无缝集成到车载系统中&#xff0c;利用汽车的硬件和服务能力&#xff0c;是一个极具挑战性…

Rocky Linux 9 中添加或删除某个网卡的静态路由的方法

使用ip命令配置临时路由 添加静态路由 ip route add <目的网络> via <下一跳IP> dev <网卡接口名称>例: 给eth0网卡添加一个到达 192.168.2.0/24 网络&#xff0c;下一跳为 192.168.1.254 的路由 ip route add 192.168.2.0/24 via 192.168.1.254 dev eth0…

STM32 单片机最小系统全解析

STM32 单片机最小系统全解析 本文详细介绍了 STM32 单片机最小系统&#xff0c;包括其各个组成部分及设计要点与注意事项。STM32 最小系统在嵌入式开发中至关重要&#xff0c;由电源、时钟、复位、调试接口和启动电路等组成。 在电源电路方面&#xff0c;采用 3.3V 直流电源供…

医院信息化运维监控:确保医疗系统的稳定与安全

在当今数字化时代&#xff0c;医院的信息化水平直接关系到医疗服务的效率和质量。随着医疗信息化的不断推进&#xff0c;医院对信息化运维监控的需求也日益增强。特别是IT软硬件资源监控和机房动环监控&#xff0c;它们在保障医院信息系统稳定运行中发挥着至关重要的作用。 首先…

基于微信小程序的家教信息管理系统的设计与实现(论文+源码)_kaic

摘 要 随着互联网时代的来临&#xff0c;使得传统的家教模式已不复存在&#xff0c;亟需一种方便、快捷的在线教学平台。因此&#xff0c;利用Java语言作为支撑和MySQL数据库存储数据&#xff0c;结合微信小程序的便利性&#xff0c;为用户开发出了一个更加人性化、方便的家庭…

JavaDS —— 图

图的概念 图是由顶点集合以及顶点之间的关系组成的一种数据结构&#xff1a;G &#xff08;V&#xff0c;E&#xff09; 其中 V 表示的是顶点集合 &#xff1a; V { x | x 属于某个数据对象集} 是有穷非空集合 E 叫做边的集合 &#xff1a; E {(x, y) | x, y 属于 V} 或者 …

PyQt / PySide + Pywin32 + ctypes 自定义标题栏窗口 + 完全还原 Windows 原生窗口边框特效项目

项目地址&#xff1a; GitHub - github201014/PyQt-NativeWindow: A class of window include nativeEvent, use PySide or PyQt and Pywin32 and ctypesA class of window include nativeEvent, use PySide or PyQt and Pywin32 and ctypes - github201014/PyQt-NativeWindow…