嵌入式人工智能应用-第三章 opencv操作3 图像平滑操作 下

发布于:2025-04-13 ⋅ 阅读:(21) ⋅ 点赞:(0)

5 高斯噪声(Gaussian Noise)

高斯噪声(Gaussian Noise)是一种符合正态(高斯)分布的随机噪声,广泛存在于传感器采集、信号传输等场景中。以下是关于高斯噪声的详细说明、添加方法及滤波方案。

特点:符合正态分布,模拟传感器噪声。
噪声值服从正态分布 在这里插入图片描述
其中:
μ(均值):通常为 0(对称分布);σ
σ(标准差):控制噪声强度(值越大,噪声越明显)

视觉表现:图像上出现细密的颗粒状噪声,类似“电视雪花”效果。

5.1 加入噪声

void addGaussianNoise(cv::Mat &image, double mean=0, double stddev=15) {
    cv::Mat noise = cv::Mat::zeros(image.size(), image.type());
    cv::randn(noise, mean, stddev); // 生成高斯噪声
    image += noise;
    cv::normalize(image, image, 0, 255, cv::NORM_MINMAX, image.type()); // 防止溢出
}

在这里插入图片描述

5.2 高斯滤波

原理:使用高斯核加权平均,与噪声分布特性匹配。

优点:计算高效,适合实时处理。

OpenCV 函数:cv::GaussianBlur()

函数原型:

void cv::GaussianBlur(
    InputArray src, 
    OutputArray dst,
    Size ksize, 
    double sigmaX,
    double sigmaY = 0,
    int borderType = BORDER_DEFAULT
);

参数:

ksize Size 高斯核大小(宽度和高度,必须为正奇数如3x3、5x5)。
sigmaX double X方向标准差。若为0,则自动从ksize计算:sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8
sigmaY double Y方向标准差(默认=0,表示与sigmaX相同)。
borderType int 边界填充方式(默认BORDER_DEFAULT)。

参考应用:

cv::Mat denoised;
cv::GaussianBlur(noisy_img, denoised, cv::Size(5, 5), 1.5); // 内核大小5x5,标准差1.5

在这里插入图片描述

5.4 双边滤波(Bilateral Filter)

原理:同时考虑空间距离和像素值差异,保留边缘。
bilateralFilter 为双边滤波,d 为计算的半径,在 d 以内的像素点会被纳入计算,如果 d=-1,则根据 sigmas 参数取值进行处理。Sigmac 决定多少差值之内的像素点会被计算。Sigmas 和 d 的值有关,如果 d 大于0,该值无效,如果小于 0,则根据 sigmas 来计算 d 的值。

优点:边缘保持效果好。

OpenCV 函数:cv::bilateralFilter()

cv::Mat denoised;
cv::bilateralFilter(noisy_img, denoised, 9, 75, 75); // 直径9,颜色/空间标准差75

在这里插入图片描述

5.5 总结

在这里插入图片描述

6 椒盐噪声(Salt-and-Pepper Noise)

椒盐噪声是一种常见的图像噪声,表现为随机出现的 纯白(盐噪声) 和 纯黑(椒噪声) 像素点,通常由传感器故障、信号传输错误或存储介质损坏引起。以下是其特性、添加方法及去噪方案。

6.1 定义

噪声像素值为 0(黑) 或 255(白),随机分布在图像中
在这里插入图片描述
视觉表现:图像上散落黑白点,类似胡椒和盐粒。

6.2 添加椒盐噪声

  #include "random"
void addSaltPepperNoise(cv::Mat &image, double prob = 0.05) {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(0.0, 1.0);

    for (int i = 0; i < image.rows; i++) {
        for (int j = 0; j < image.cols; j++) {
            double r = dis(gen);
            if (r < prob / 2) {
                image.at<cv::Vec3b>(i, j) = cv::Vec3b(0, 0, 0);    // 椒噪声(黑)
            } else if (r < prob) {
                image.at<cv::Vec3b>(i, j) = cv::Vec3b(255, 255, 255); // 盐噪声(白)
            }
        }
    }
}

在这里插入图片描述

6.3 中值滤波(Median Filter)

原理:用邻域像素的中值替代中心像素,有效消除孤立噪点。

优点:计算快,适合实时处理。

OpenCV 函数:cv::medianBlur()

cv::Mat denoised;
cv::medianBlur(noisy_img, denoised, 5); // 内核大小5x5(必须为奇数)

medianBlur 为中值滤波,ksize 为中值滤波的窗口大小。
在这里插入图片描述

6.5 总结

在这里插入图片描述

7 参考案例

7.1 模糊案例

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main (int argc,char **argv)
{
	Mat src = imread("cyq.jpg",1);
	if(src.empty())
	{
	cout << "Could not load image.."<<endl;
	return -1;
	}
	Mat image1,image2,image3;
	blur(src,image1,Size(3,3),Point(-1,-1));
	blur(src,image2,Size(29,1),Point(-1,-1));
	blur(src,image3,Size(1,20),Point(-1,-1));
	imshow("input",src);
	imshow("output1",image1);
	imshow("output2",image2);
	imshow("output3",image3);
	waitKey(0);
	return 0;
}

这部分代码很简单,使用 mat 将图像信息装起来,然后调用 OpenCV 提供的 blur 接口进行模糊,通过调整 Size 参数来看看均值滤波的效果。第一次调用 Size(3,3),表示卷积算子的大小为 3*3,这个值是可以随意改变的,但必须是正数,后面的 Point 表示采用卷积算子的中心点为计算结果。后面将 size 中的参数改变,例如 Size(29,1)是 x 方向的模糊,因为我们平时看到的移动都是相对于地面的,所以转换出来的图像像是瞬间移动了;Size(1,20)是在 y 方向的模糊,看起来像是向上跳跃的感觉。

7.1 中值滤波

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main (int argc,char **argv)
{
	 Mat src = imread("nn.png",1);
	 if(src.empty())
	 {
		 cout << "Could not load image.."<<endl;
		 return -1;
	 }
		 Mat dst;
		 medianBlur(src,dst,3);
		 imshow("input",src);
		 imshow("output",dst);
		 waitKey(0);
		 return 0;
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到