介绍
Non-Local Means 非局部均值降噪算法,简称NLM,该算法来自 2005年论文“A non-local algorithm for image denoising”;该算法是经典的图像降噪算法,是很多降噪算法的参考对比算法。
2014 年,有 NLM衍生算法NLMP,该算法来自论文“Parameter-Free Fast Pixelwise Non-Local Means Denoising”;NLMP 算法快速且开源。
-
FFmpeg 项目已经集成NLM算法,集成到 filter 中。
-
OpenCV 项目已经集成NLM算法,有现成方法可调用,
fastNlMeansDenoising
、fastnlmeansdenisingcolored
、fastnlmeansdenisingmulti
、fastnlmeansdenisingcoloredmulti
。 -
项目地址:https://www.ipol.im/pub/art/2014/120/
-
原论文下载地址:https://download.csdn.net/download/yanceyxin/89281660
-
衍生论文下载地址:https://download.csdn.net/download/yanceyxin/89281644
-
NLMP 源码下载:https://download.csdn.net/download/yanceyxin/89281686
原理
- 来源
(1)图像中的像素点之间不是孤立存在的,某一点的像素与别处的像素点一定存在某种关联,可以概括为灰度相关性和几何结构相似性,这就是均值滤波的思想。但相似像素并不局限于某个局部区域,如图像中的长边缘、结构纹理等。
(2)NLM一般有两种应用方案,基于像素点方案、基于块方案。 - 算法流程
(1)在需要滤波像素点 u 周围设置半径 f 的邻块记作当前块,size为(2f+1)^2,同时设置一个与其等同大小的参考块,逐像素遍历整个图像,计算参考块于当前块的欧氏距离;
(2)计算出来的块与块之间的距离还不是参考块相对于当前块的权重,我们需要一个单调递减的函数来对欧式距离加以约束,距离越小权重越大,距离越远,权重越小且下降的速度越快。最后可以用这个函数来产生权重:为图像噪声方差;
(3)计算出参考块与当前块之间的权重,用参考块中心和对应的权重对当前块中心像素进行滤波;
- 核心思想:该算法利用图像中所有像素的信息,通过比较像素邻域的相似性来计算权重,然后进行加权平均。
- 算法特性:NL-means算法与局部滤波器或频域滤波器的主要区别在于,它系统地使用图像能提供的所有可能的自预测。
- NL-means算法的核心公式是:
- 相关原理图:
- 实验结果
源码示例
- 利用 OpenCV 集成的
fastNlMeansDenoisingColored
方法实验 NLM 算法
#include <opencv2/opencv.hpp>
#include <opencv2/photo.hpp>
int main() {
// 加载彩色噪声图像
cv::Mat noisy_image = cv::imread("noisy_image.jpg", cv::IMREAD_COLOR);
// 确保图像已加载
if(noisy_image.empty()) {
std::cout << "Failed to load the image" << std::endl;
return 1;
}
// 输出原始图像的尺寸
std::cout << "Noisy Image Size: " << noisy_image.size() << std::endl;
// 对图像进行去噪
cv::Mat output_image;
cv::fastNlMeansDenoisingColored(noisy_image, output_image, 10, 10, 7, 21);
// 输出去噪后图像的尺寸
std::cout << "Denoised Image Size: " << output_image.size() << std::endl;
// 保存去噪后的图像
cv::imwrite("denoised_image.jpg", output_image);
// 显示去噪前后的图像
cv::imshow("Noisy Image", noisy_image);
cv::imshow("Denoised Image", output_image);
cv::waitKey(0);
return 0;
}