在之前生成的24位真彩图的基础上,加入脉冲噪声与椒盐噪声,再利用均值滤波与中值滤波处理。
椒盐噪声
在给定的像素颜色分量上添加椒盐噪声的步骤包括:
生成一个随机值(0到1之间)。
如果这个随机值小于某个概率阈值,就将该颜色分量替换为最小值(椒噪声)。
如果随机值介于概率阈值和两倍概率阈值之间,就将该颜色分量替换为最大值(盐噪声)。
在你的代码中,我已经添加了 addSaltPepperNoise 函数,以下是具体实现:
cpp
void addSaltPepperNoise(uint8_t& colorComponent, double probability) {
double randomValue = static_cast<double>(rand()) / RAND_MAX;
if (randomValue < probability / 2) {
colorComponent = 0; // 椒噪声,将颜色分量设置为最小值
} else if (randomValue < probability) {
colorComponent = 255; // 盐噪声,将颜色分量设置为最大值
}
}
这个函数接受一个颜色分量和一个概率作为参数。在函数内部,它生成一个0到1之间的随机值,并根据概率阈值将颜色分量替换为最小值或最大值,实现了椒盐噪声的效果。在主循环中,我调用这个函数并传递了绿色分量和椒盐噪声的概率(这里是0.1,你可以根据需要调整)。
脉冲噪声
对于脉冲噪声,过程类似于椒盐噪声,但是当随机值小于概率阈值时,将颜色分量替换为最小值或最大值。以下是添加脉冲噪声的函数 addImpulseNoise 的实现:
cpp
void addImpulseNoise(uint8_t& colorComponent, double probability) {
double randomValue = static_cast<double>(rand()) / RAND_MAX;
if (randomValue < probability) {
// 将颜色分量替换为最小值或最大值,可以根据需要调整
colorComponent = (randomValue < probability / 2) ? 0 : 255;
}
}
这个函数也接受一个颜色分量和一个概率作为参数。它生成一个0到1之间的随机值,如果这个随机值小于概率阈值,就将颜色分量替换为最小值或最大值,实现了脉冲噪声的效果。在主循环中,你可以调用这个函数,并传递需要添加脉冲噪声的颜色分量以及脉冲噪声的概率(可以根据需要调整)。
中值滤波
中值滤波是一种常用的数字图像处理技术,用于去除图像中的噪声。它的基本思想是取一组像素值的中间值,然后用这个中间值来代替原始像素值。这个方法对于椒盐噪声和脉冲噪声等突发性的噪声效果较好。
下面是中值滤波的基本步骤:
- 选择滤波器大小
中值滤波器是一个类似于窗口的区域,它在图像上滑动。选择合适大小的滤波器取决于图像的噪声类型和强度。 - 将滤波器应用于图像:
对于每个像素,将滤波器的中心放在该像素上,然后将滤波器覆盖的区域内的像素值提取出来。 - 对提取的像素值进行排序
将提取的像素值进行排序,以找到中间值。通常,使用一维或二维滤波器,具体取决于图像的特性。 - 取中值替代原始像素值
用排序后的像素值中间的值来替代原始像素值。这样,原始像素值中的噪声将被平滑,而不会受到过多的影响。
中值滤波的优点包括对各种类型的噪声(包括椒盐噪声和脉冲噪声)的有效去除,而且相对于其他线性滤波方法,它能够更好地保留图像的边缘细节。然而,中值滤波的缺点是在某些情况下可能导致图像模糊,特别是对于一些细小的结构。选择合适的滤波器大小对于取得良好的效果非常重要。
cpp
// 中值滤波
uint8_t medianFilter(std::vector<uint8_t>& values) {
size_t size = values.size();
std::sort(values.begin(), values.end());
if (size % 2 == 0) {
// 如果数组大小为偶数,取中间两个值的平均值
return static_cast<uint8_t>((values[size / 2 - 1] + values[size / 2]) / 2);
} else {
// 如果数组大小为奇数,取中间值
return values[size / 2];
}
}
均值滤波
均值滤波是一种常见的图像处理滤波器,其基本思想是用一组像素的平均值来替代中心像素的值。均值滤波在一定程度上可以减少图像的噪声,但与中值滤波相比,它对椒盐噪声和脉冲噪声的效果通常较差。
以下是均值滤波的基本步骤:
-
选择滤波器大小: 均值滤波器是一个局部区域,它在图像上滑动。选择滤波器的大小决定了用于计算平均值的像素范围。
-
将滤波器应用于图像: 对于每个像素,将滤波器的中心放在该像素上,然后将滤波器覆盖的区域内的像素值提取出来。
-
计算提取的像素值的平均值: 对提取的像素值进行求和,然后除以像素值的数量,得到平均值。
用平均值替代原始像素值: 将计算得到的平均值替代原始像素值。这样可以减小噪声的影响。
cpp
// 均值滤波
void meanFilter(std::vector<uint8_t>& values) {
// 计算平均值
uint32_t sum = 0;
for (uint8_t value : values) {
sum += value;
}
uint8_t average = static_cast<uint8_t>(sum / values.size());
// 用平均值替代原始像素值
for (uint8_t& value : values) {
value = average;
}
}