当前位置: 首页 > article >正文

c/c++的opencv椒盐噪声

在 C/C++ 中实现椒盐噪声

椒盐噪声(Salt-and-Pepper Noise),也称为脉冲噪声(Impulse Noise),是数字图像中常见的一种噪声类型。它的特点是在图像中随机出现纯白色(盐)或纯黑色(椒)的像素点,看起来就像在图像上撒了盐和胡椒一样。这种噪声通常由图像传感器、传输错误或存储介质损坏等原因引起。

本文将介绍椒盐噪声的基本原理,并提供一个使用 C/C++ 实现向图像添加椒盐噪声的示例。

什么是椒盐噪声?

椒盐噪声会随机地将图像中的一些像素替换为最大值(通常是255,代表“盐”像素,即白色)或最小值(通常是0,代表“椒”像素,即黑色)。其他未受影响的像素则保持其原始值。

主要特点:

  • 外观: 图像中散布着孤立的亮点和暗点。
  • 影响: 噪声像素的值与周围像素的值有显著差异。
  • 密度: 椒盐噪声的强度通常用噪声密度来描述,即图像中受噪声污染的像素所占的百分比。

添加椒盐噪声的算法

向图像添加椒盐噪声的基本算法步骤如下:

  1. 遍历图像像素: 依次处理图像中的每一个像素,或者随机选择一定比例的像素进行处理。
  2. 生成随机数: 对每个待处理的像素,生成一个随机数(通常在 [0, 1] 区间内)。
  3. 判断是否添加噪声:
    • 将此随机数与预设的噪声密度阈值 d 进行比较。如果随机数小于 d,则该像素将被噪声污染。
  4. 确定噪声类型(盐或椒):
    • 如果像素被确定为噪声点,则再生成一个随机数(例如,也在 [0, 1] 区间内)。
    • 根据这个新的随机数决定是添加“盐”噪声还是“椒”噪声。例如,可以设定一个概率 p_salt(通常为0.5),如果随机数小于 p_salt,则将像素值设为最大值(如255);否则,设为最小值(如0)。
  5. 保持原样: 如果步骤3中判断像素不被噪声污染,则其像素值保持不变。

C/C++ 实现示例

下面是一个简单的 C/C++ 函数,用于向灰度图像(以二维数组表示)添加椒盐噪声。为了简化,我们假设像素值范围是 0 到 255。

#include <iostream>
#include <vector>
#include <cstdlib> // 用于 rand() 和 srand()
#include <ctime>   // 用于 time()// 假设图像数据结构
// 这里使用 std::vector<std::vector<int>> 来表示灰度图像
// 实际应用中可能是自定义的图像类或指向像素数据的指针/*** @brief 向灰度图像添加椒盐噪声* @param image 图像数据 (引用传递,会被直接修改)* @param noiseDensity 噪声密度 (0.0 到 1.0),表示受影响像素的比例* @param saltPepperRatio “盐”噪声相对于总噪声的比例 (0.0 到 1.0)* 例如,0.5 表示盐和椒的概率各占一半*/
void addSaltAndPepperNoise(std::vector<std::vector<int>>& image, double noiseDensity, double saltPepperRatio = 0.5) {if (image.empty() || image[0].empty()) {std::cerr << "错误:图像数据为空!" << std::endl;return;}if (noiseDensity < 0.0 || noiseDensity > 1.0) {std::cerr << "错误:噪声密度必须在 [0.0, 1.0] 之间!" << std::endl;return;}if (saltPepperRatio < 0.0 || saltPepperRatio > 1.0) {std::cerr << "错误:盐/椒比例必须在 [0.0, 1.0] 之间!" << std::endl;return;}int rows = image.size();int cols = image[0].size();// 初始化随机数生成器// 注意:srand() 最好在程序开始时调用一次,而不是每次调用函数时都调用// 这里为了示例的独立性,放在函数内部,但实际项目中应避免重复调用// static bool srand_called = false;// if (!srand_called) {//     srand(static_cast<unsigned int>(time(0)));//     srand_called = true;// }for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j) {// 生成一个0到1之间的随机数double randVal = static_cast<double>(rand()) / RAND_MAX;if (randVal < noiseDensity) {// 该像素被噪声污染double saltOrPepper = static_cast<double>(rand()) / RAND_MAX;if (saltOrPepper < saltPepperRatio) {image[i][j] = 255; // 盐噪声 (白色)} else {image[i][j] = 0;   // 椒噪声 (黑色)}}// else: 像素保持不变}}
}// 辅助函数:打印图像 (用于测试)
void printImage(const std::vector<std::vector<int>>& image) {if (image.empty()) return;for (const auto& row : image) {for (int pixel : row) {std::cout.width(4); // 设置输出宽度,方便对齐std::cout << pixel << " ";}std::cout << std::endl;}
}int main() {// 初始化随机数种子 (在main函数开始时调用一次)srand(static_cast<unsigned int>(time(0)));// 创建一个示例图像 (例如 5x5)int rows = 5, cols = 5;std::vector<std::vector<int>> myImage(rows, std::vector<int>(cols));// 填充一些初始像素值 (例如,都设为128)for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j) {myImage[i][j] = 128;}}std::cout << "原始图像:" << std::endl;printImage(myImage);// 添加椒盐噪声double density = 0.2; // 20% 的像素会被噪声污染double saltRatio = 0.5; // 盐和椒的比例为 1:1addSaltAndPepperNoise(myImage, density, saltRatio);std::cout << "\n添加椒盐噪声后的图像 (密度: " << density * 100 << "%):" << std::endl;printImage(myImage);return 0;
}

代码说明

  1. addSaltAndPepperNoise 函数:

    • 接收一个二维 std::vector<std::vector<int>> 作为图像数据。实际项目中,你可能会使用更专业的图像库(如 OpenCV)或自定义的图像数据结构。
    • noiseDensity 参数控制噪声的多少。例如,0.1 表示大约10%的像素会被修改。
    • saltPepperRatio 参数控制噪声点中“盐”像素(白色)所占的比例。0.5 表示盐和椒出现的概率均等。
    • 函数遍历图像中的每个像素。
    • 对于每个像素,生成一个随机数 randVal。如果 randVal 小于 noiseDensity,则该像素被选为噪声点。
    • 如果像素是噪声点,再生成一个随机数 saltOrPepper 来决定它是盐(255)还是椒(0)。
  2. 随机数生成:

    • srand(static_cast<unsigned int>(time(0))) 用于播种随机数生成器。这一步通常在程序开始时执行一次,以确保每次运行程序时都能得到不同的随机序列。在示例中,为了独立性,它被注释在了函数内部,并在 main 函数中调用。
    • rand() 生成一个伪随机整数,static_cast<double>(rand()) / RAND_MAX 将其归一化到 [0.0, 1.0] 范围内。
  3. main 函数示例:

    • 创建了一个简单的 5x5 图像,并用中间灰度值 (128) 初始化。
    • 调用 addSaltAndPepperNoise 函数添加噪声。
    • 打印原始图像和处理后的图像以供比较。

注意事项与改进

  • 彩色图像: 对于彩色图像(如RGB),可以独立地对每个颜色通道应用椒盐噪声,或者只对亮度/强度通道应用噪声。
  • 随机数生成器: C++11 及更高版本提供了更高级的随机数生成工具(在 <random> 头文件中),如 std::mt19937std::uniform_real_distribution,它们通常能提供比 rand() 更好的随机性。
  • 性能: 对于非常大的图像,直接遍历所有像素并为每个像素生成随机数可能不是最高效的方法。但对于大多数情况,这种方法的简单性和清晰度是足够的。
  • 图像库: 如果你正在进行更复杂的图像处理任务,建议使用像 OpenCV 这样的成熟图像处理库。这些库通常内置了添加各种类型噪声的函数,并且处理图像的加载、保存和操作更为便捷。

总结

椒盐噪声是一种简单的图像噪声模型,通过在C/C++中利用随机数生成器,我们可以有效地模拟这种噪声。理解其原理并能够手动实现它,对于学习图像处理和计算机视觉的基础非常有帮助。

相关文章:

c/c++的opencv椒盐噪声

在 C/C 中实现椒盐噪声 椒盐噪声&#xff08;Salt-and-Pepper Noise&#xff09;&#xff0c;也称为脉冲噪声&#xff08;Impulse Noise&#xff09;&#xff0c;是数字图像中常见的一种噪声类型。它的特点是在图像中随机出现纯白色&#xff08;盐&#xff09;或纯黑色&#x…...

C++ TCP程序增加TLS加密认证

TCP为什么要增加TLS TCP程序添加TLS主要是为了解决TCP协议本身的安全缺陷。TCP作为传输层协议,虽然提供了可靠的数据传输,但它是明文传输,存在几个关键的安全问题: 数据泄露风险:TCP传输的数据完全暴露在网络中,任何能够监听网络流量的人都可以直接读取传输内容。这对于…...

构建一个“论文检索 + 推理”知识库服务,支持用户上传 PDF/LATEX 源码后,秒级检索并获得基于内容的问答、摘要、引用等功能

文章目录 1 总体目标 / Overall Goal2 数据管线 / Data Pipeline3 检索策略 / Retrieval Strategy4 服务切分 / Service Decomposition5 Agent & Prompt 设计 / Agent & Prompt6 核心功能 / Core Features7 评测与监控 / Evaluation & Monitoring8 面试亮点 / Inte…...

VLC-QT 网页播放RTSP

先看效果图,代码在文章末尾,包含源码,vlc-qt完整的库 环境说明:VS 2017 QTQt5.13.0 MSVC2017 32位 将vlc_install 目录下的bin,include,lib里所有的东西分别放在qt目录下 bin -> C:\Qt\Qt5.13.0\5.13.0\msvc2017\bin include->C:\Qt\Qt5.13.0\5.13.0\msvc201…...

for(auto a:b)和for(auto a:b)的区别

#include<iostream> using namespace std; int main() {string s( "hello world" );for (auto c:s)c t ;cout<<s<<endl; //结果为hello worldfor (auto &c:s)c t ;cout<<s<<endl; //结果为ttttttttttt }for(auto a:b)中b为一…...

第2章-12 输出三角形面积和周长(走弯路解法)

本题要求编写程序&#xff0c;根据输入的三角形的三条边a、b、c&#xff0c;计算并输出面积和周长。注意&#xff1a;在一个三角形中&#xff0c; 任意两边之和大于第三边。三角形面积计算公式&#xff1a;areas(s−a)(s−b)(s−c)​&#xff0c;其中s(abc)/2。 import math de…...

Caddy如何在测试环境中使用IP地址配置HTTPS服务

前言 在开发和测试环境中&#xff0c;我们经常需要搭建HTTPS服务进行测试。但通常Let’s Encrypt等证书颁发机构要求使用有效域名&#xff0c;不直接支持IP地址。本文将详细介绍如何使用Caddy在测试环境中通过IP地址配置HTTPS服务&#xff0c;使用自签名证书解决这一问题。 环…...

shell中与>和<相关的数据流重定向操作符整理

shell中与>和<相关的数据流重定向操作符整理 输出重定向操作符>>>2>2>>&> 或 >&&>> 输入重定向操作符<<<<<< 组合重定向2>&1 文件描述符相关重定向[n]< file 和 [n]> file>&- 和 <&…...

【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix

【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix 文章目录 【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix一、资料准备1.去畸变影像2.相机文件3.外方位元素二、创建工程1.新建工程2.导入照片3.编辑相机文件4.编辑外方位元素文件,导入外方位元…...

创建型设计模式之Prototype(原型)

创建型设计模式之Prototype&#xff08;原型&#xff09; 摘要&#xff1a; Prototype&#xff08;原型&#xff09;设计模式通过复制现有对象来创建新对象&#xff0c;避免重复初始化操作。该模式包含Prototype接口声明克隆方法、ConcretePrototype实现具体克隆逻辑&#xff…...

JNI开发流程

一. 引言 最近在做一个自己的项目&#xff0c;就是基于FastDDS封装一套JAVA库&#xff0c;让android和java应用可以使用dds的功能。 由于FastDDS是使用C编写的开源库&#xff0c;因此java的类库想要调用FastDDS的接口&#xff0c;需要额外编写一个JNI层的动态库对FastDDS的接口…...

STM32G4 电机外设篇(二) VOFA + ADC + OPAMP

目录 一、STM32G4 电机外设篇&#xff08;二&#xff09; VOFA ADC OPAMP1 VOFA1.1 VOFA上位机显示波形 2 ADC2.1 用ADC规则组对板载电压和电位器进行采样 3 OPAMP&#xff08;运放&#xff09;3.1 结合STM32内部运放和ADC来完成对三相电流的采样3.2 运放电路分析 附学习参考…...

RAG应用:交叉编码器(cross-encoder)和重排序(rerank)

文章目录 Sentence Transformers交叉编码器交叉编码器使用示例检索和重排序Sentence Transformers Sentence Transformers 支持两种类型的模型: Bi-encoders 和 Cross-encoders。Bi-encoders 更快更可扩展,但 Cross-encoders 更准确。虽然两者都处理类似的高水平任务,但何时…...

微服务难题?Nacos服务发现来救场

文章目录 前言1.什么是服务发现2.Nacos 闪亮登场2.1 服务注册2.2 服务发现 3.Nacos 的优势3.1 简单易用3.2 高可用3.3 动态配置 4.实战演练4.1安装 Nacos4.2 服务注册与发现示例代码&#xff08;以 Spring Boot 为例&#xff09; 总结 前言 大家好&#xff0c;我是沛哥儿。今天…...

C# 结合PaddleOCRSharp搭建Http网络服务

Windows打开端口&#xff1a; 控制面板 > 系统和安全 > 防火墙> 高级设置 → 入站规则 → 右侧选择 → 新建规则 → 端口 → 协议类型 TCP→ 端口 using System; using System.Drawing; using System.IO; using System.Net; using System.Text; using System.Threadi…...

【连接器专题】SD卡座规格书审查需要审哪些方面?

在审查SD卡座规格书时,我们需要考虑哪些方面? 首先在拿到一份SD卡座的详细规格书时,一般供应商给到的规格书中包括了一些基础信息、产品图纸信息、技术参数信息,同时有些供应商会给出产品可靠性测试报告。因此我们会从这几个要素去看规格书。 基础信息 基础信息一般会给变更…...

JS手写代码篇---手写节流函数

8、节流函数 什么是节流函数&#xff1f; 指规定一个单位时间&#xff0c;在这个单位时间内&#xff0c;只能有一次触发事件的回调函数执行&#xff0c;如果在同一个单位时间内某事件被触发多次&#xff0c;只有一次能生效。 与防抖函数有什么区别&#xff1f; 防抖函数是延…...

UE5 C++动态调用函数方法、按键输入绑定 ,地址前加修饰符

UE5 C动态调用函数方法、按键输入绑定 &#xff0c;地址前加修饰符&&#xff0c;这个符号忘记输入的话&#xff0c;编译一直报错不通过 void ASnakeHead::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerIn…...

eBest智能价格引擎系统 助力屈臣氏饮料落地「价格大脑」+「智慧通路」数字基建​

从价格策略到终端执行&#xff0c;数字化正在重构饮料行业竞争壁垒&#xff01; 近日&#xff0c;eBest为屈臣氏饮料提供的智能价格引擎系统已正式上线并投入运营。同时&#xff0c;基于eBest SFA方案且与屈臣氏饮料业务场景深度耦合的Smart Field Operation智慧通路项目正式启…...

ubuntu mysql 8.0.42 基于二进制日志文件位置和GTID主从复制配置

目录 1 操作系统信息 2 MySql数据库版本 3 主机列表 4 MySQL服务器都安装依赖 5 主库服务器安装mysql软件步骤&#xff1a; 6 从服务器安装mysql软件步骤 7 基于二进制日志文件位置的主从复制配置 8 使用全局事务标识符进行主从复制(GTID) 9 部署过程遇到问题 1 操作系…...

Kettle 远程mysql 表导入到 hadoop hive

kettle 远程mysql 表导入到 hadoop hive &#xff08;教学用 &#xff09; 文章目录 kettle 远程mysql 表导入到 hadoop hive创建 对象 执行 SQL 语句 -mysql 导出 CSV格式CSV 文件远程上传到 HDFS运行 SSH 命令远程登录 run SSH 并执行 hadoop fs -put 建表和加载数据总结 创…...

完整解析 Linux Kdump Crash Kernel 工作原理和实操步骤

完整解析 Linux Kdump Crash Kernel 工作原理和实操步骤 一、前言 在使用 Linux 操作系统进行内核开发或者系统维护时&#xff0c;内核 panic 是最常见的系统崩溃环节。如果想要在内核崩溃后立即分析环境和输出内核内存 dump&#xff0c;Kdump crashkernel 是最接近完美的解…...

菜鸟之路Day36一一Web开发综合案例(部门管理)

菜鸟之路Day36一一Web开发综合案例&#xff08;部门管理&#xff09; 作者&#xff1a;blue 时间&#xff1a;2025.5.28 文章目录 菜鸟之路Day36一一Web开发综合案例&#xff08;部门管理&#xff09;一.环境搭建二.开发规范三.部门管理3.1查询3.2删除3.3新增3.3修改根据id来…...

LangChain实战:MMR和相似性搜索技术应用

导读&#xff1a;在当今大数据和人工智能快速发展的背景下&#xff0c;向量数据库的搜索技术正成为技术人员必须掌握的核心技能。本文将深入探讨LangChain框架与Milvus向量数据库的整合实践&#xff0c;重点对比分析相似度搜索与最大边际相关性&#xff08;MMR&#xff09;搜索…...

第 1 章:学习起步

1. React Native前置知识要求 在开始学习React Native之前&#xff0c;有一些前置知识你需要了解。不过别担心&#xff0c;我会带你逐步掌握这些内容&#xff0c;让你顺利入门。 1.1. JavaScript是必须掌握的 学习React Native&#xff0c;JavaScript是基础。你需要了解Java…...

SQL查询——大厂面试真题

前言 本文总结了SQLite数据库的核心操作要点&#xff1a;1. 基础语法&#xff1a;SQL语句不区分大小写&#xff0c;多语句需用分号分隔&#xff0c;支持多种注释方式2. 表操作&#xff1a;包括创建表&#xff08;定义主键、非空约束等&#xff09;、插入/更新/删除数据、添加/…...

Linux-pcie ranges介绍

参考链接&#xff1a;https://elinux.org/Device_Tree_Usage#PCI_Host_Bridge pcie bar高低端BAR起始地址介绍 pcie设备树节点 / {compatible "rockchip,rk3588";interrupt-parent <&gic>;#address-cells <2>;#size-cells <2>;pcie3x4: p…...

⭐ Unity AVProVideo插件自带播放器 脚本重构 实现视频激活重置功能

一、功能概述 本笔记记录直接修改插件自带的场景播放其中 原始的 MediaPlayerUI 脚本,实现激活时自动重置播放器的功能。 我用的插件版本是 AVPro Video - Ultra Edition 2.7.3 修改后的脚本将具备以下特性: 激活 GameObject 时自动重置播放位置到开头 可配置是否在重置后自…...

互联网大厂Java求职面试:云原生微服务架构设计与AI大模型集成实战

互联网大厂Java求职面试&#xff1a;云原生微服务架构设计与AI大模型集成实战 面试场景设定 人物设定&#xff1a; 李明&#xff08;技术总监&#xff09;&#xff1a;拥有15年分布式系统架构经验&#xff0c;主导过多个亿级用户系统的重构&#xff0c;对云原生和AI融合有深…...

详解K8s API Server 如何处理请求的?

详解K8s API Server 如何处理请求的? Kubernetes(K8s)是一个强大的容器编排系统,而API Server(kube-apiserver) 是它的核心组件之一。 如果把 K8s 比作一个国家,API Server 就是政府机构,所有资源的创建、修改、删除都要经过它审批! 🎯 API Server 的作用 📌 A…...