【opencv入门教程】15. 访问像素的十四种方式
文章选自:
一、像素访问
一张图片由许多个点组成,每个点就是一个像素,每个像素包含不同的值,对图像像素操作是图像处理过程中常使用的
二、访问像素
void Samples::AccessPixels1(Mat &image, int div = 64) {int nl = image.rows; //行数int nc = image.cols * image.channels(); //每行元素的总元素数量for (int j = 0; j < nl; j++) {uchar *data = image.ptr<uchar>(j);for (int i = 0; i < nc; i++) {//-------------开始处理每个像素-------------------data[i] = data[i] / div * div + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}//-----------------------------------【方法二】-------------------------------------------------
// 说明:利用 .ptr 和 * ++
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels2(Mat &image, int div = 64) {int nl = image.rows; //行数int nc = image.cols * image.channels(); //每行元素的总元素数量for (int j = 0; j < nl; j++) {uchar *data = image.ptr<uchar>(j);for (int i = 0; i < nc; i++) {//-------------开始处理每个像素-------------------*data++ = *data / div * div + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}//-----------------------------------------【方法三】-------------------------------------------
// 说明:利用.ptr 和 * ++ 以及模操作
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels3(Mat &image, int div = 64) {int nl = image.rows; //行数int nc = image.cols * image.channels(); //每行元素的总元素数量for (int j = 0; j < nl; j++) {uchar *data = image.ptr<uchar>(j);for (int i = 0; i < nc; i++) {//-------------开始处理每个像素-------------------int v = *data;*data++ = v - v % div + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}//----------------------------------------【方法四】---------------------------------------------
// 说明:利用.ptr 和 * ++ 以及位操作
//----------------------------------------------------------------------------------------------------
void Samples::AccessPixels4(Mat &image, int div = 64) {int nl = image.rows; //行数int nc = image.cols * image.channels(); //每行元素的总元素数量int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));//掩码值uchar mask = 0xFF << n; // e.g. 对于 div=16, mask= 0xF0for (int j = 0; j < nl; j++) {uchar *data = image.ptr<uchar>(j);for (int i = 0; i < nc; i++) {//------------开始处理每个像素-------------------*data++ = *data & mask + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}//----------------------------------------【方法五】----------------------------------------------
// 说明:利用指针算术运算
//---------------------------------------------------------------------------------------------------
void Samples::AccessPixels5(Mat &image, int div = 64) {int nl = image.rows; //行数int nc = image.cols * image.channels(); //每行元素的总元素数量int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));int step = image.step; //有效宽度//掩码值uchar mask = 0xFF << n; // e.g. 对于 div=16, mask= 0xF0//获取指向图像缓冲区的指针uchar *data = image.data;for (int j = 0; j < nl; j++) {for (int i = 0; i < nc; i++) {//-------------开始处理每个像素-------------------*(data + i) = *data & mask + div / 2;//-------------结束像素处理------------------------} //单行处理结束data += step; // next line}
}//---------------------------------------【方法六】----------------------------------------------
// 说明:利用 .ptr 和 * ++以及位运算、image.cols * image.channels()
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels6(Mat &image, int div = 64) {int nl = image.rows; //行数int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));//掩码值uchar mask = 0xFF << n; // e.g. 例如div=16, mask= 0xF0for (int j = 0; j < nl; j++) {uchar *data = image.ptr<uchar>(j);for (int i = 0; i < image.cols * image.channels(); i++) {//-------------开始处理每个像素-------------------*data++ = *data & mask + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}// -------------------------------------【方法七】----------------------------------------------
// 说明:利用.ptr 和 * ++ 以及位运算(continuous)
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels7(Mat &image, int div = 64) {int nl = image.rows; //行数int nc = image.cols * image.channels(); //每行元素的总元素数量if (image.isContinuous()) {//无填充像素nc = nc * nl;nl = 1; // 为一维数列}int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));//掩码值uchar mask = 0xFF << n; // e.g. 比如div=16, mask= 0xF0for (int j = 0; j < nl; j++) {uchar *data = image.ptr<uchar>(j);for (int i = 0; i < nc; i++) {//-------------开始处理每个像素-------------------*data++ = *data & mask + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}//------------------------------------【方法八】------------------------------------------------
// 说明:利用 .ptr 和 * ++ 以及位运算 (continuous+channels)
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels8(Mat &image, int div = 64) {int nl = image.rows; //行数int nc = image.cols; //列数if (image.isContinuous()) {//无填充像素nc = nc * nl;nl = 1; // 为一维数组}int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));//掩码值uchar mask = 0xFF << n; // e.g. 比如div=16, mask= 0xF0for (int j = 0; j < nl; j++) {uchar *data = image.ptr<uchar>(j);for (int i = 0; i < nc; i++) {//-------------开始处理每个像素-------------------*data++ = *data & mask + div / 2;*data++ = *data & mask + div / 2;*data++ = *data & mask + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}// -----------------------------------【方法九】 ------------------------------------------------
// 说明:利用Mat_ iterator
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels9(Mat &image, int div = 64) {//获取迭代器Mat_<Vec3b>::iterator it = image.begin<Vec3b>();Mat_<Vec3b>::iterator itend = image.end<Vec3b>();for (; it != itend; ++it) {//-------------开始处理每个像素-------------------(*it)[0] = (*it)[0] / div * div + div / 2;(*it)[1] = (*it)[1] / div * div + div / 2;(*it)[2] = (*it)[2] / div * div + div / 2;//-------------结束像素处理------------------------} //单行处理结束
}//-------------------------------------【方法十】-----------------------------------------------
// 说明:利用Mat_ iterator以及位运算
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels10(Mat &image, int div = 64) {// div必须是2的幂int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));//掩码值uchar mask = 0xFF << n; // e.g. 比如 div=16, mask= 0xF0// 获取迭代器Mat_<Vec3b>::iterator it = image.begin<Vec3b>();Mat_<Vec3b>::iterator itend = image.end<Vec3b>();//扫描所有元素for (; it != itend; ++it) {//-------------开始处理每个像素-------------------(*it)[0] = (*it)[0] & mask + div / 2;(*it)[1] = (*it)[1] & mask + div / 2;(*it)[2] = (*it)[2] & mask + div / 2;//-------------结束像素处理------------------------} //单行处理结束
}//------------------------------------【方法十一】---------------------------------------------
// 说明:利用Mat Iterator_
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels11(Mat &image, int div = 64) {//获取迭代器Mat_<Vec3b> cimage = image;Mat_<Vec3b>::iterator it = cimage.begin();Mat_<Vec3b>::iterator itend = cimage.end();for (; it != itend; it++) {//-------------开始处理每个像素-------------------(*it)[0] = (*it)[0] / div * div + div / 2;(*it)[1] = (*it)[1] / div * div + div / 2;(*it)[2] = (*it)[2] / div * div + div / 2;//-------------结束像素处理------------------------}
}void Samples::AccessPixels12(Mat &image, int div = 64) {int nl = image.rows; //行数int nc = image.cols; //列数for (int j = 0; j < nl; j++) {for (int i = 0; i < nc; i++) {//-------------开始处理每个像素-------------------image.at<Vec3b>(j, i)[0] = image.at<Vec3b>(j, i)[0] / div * div + div / 2;image.at<Vec3b>(j, i)[1] = image.at<Vec3b>(j, i)[1] / div * div + div / 2;image.at<Vec3b>(j, i)[2] = image.at<Vec3b>(j, i)[2] / div * div + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}//----------------------------------【方法十三】-----------------------------------------------
// 说明:利用图像的输入与输出
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels13(const Mat &image, //输入图像Mat & result, // 输出图像int div = 64) {int nl = image.rows; //行数int nc = image.cols; //列数//准备好初始化后的Mat给输出图像result.create(image.rows, image.cols, image.type());//创建无像素填充的图像nc = nc * nl;nl = 1; //单维数组int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));//掩码值uchar mask = 0xFF << n; // e.g.比如div=16, mask= 0xF0for (int j = 0; j < nl; j++) {uchar * data = result.ptr<uchar>(j);const uchar *idata = image.ptr<uchar>(j);for (int i = 0; i < nc; i++) {//-------------开始处理每个像素-------------------*data++ = (*idata++) & mask + div / 2;*data++ = (*idata++) & mask + div / 2;*data++ = (*idata++) & mask + div / 2;//-------------结束像素处理------------------------} //单行处理结束}
}//--------------------------------------【方法十四】-------------------------------------------
// 说明:利用操作符重载
//-------------------------------------------------------------------------------------------------
void Samples::AccessPixels14(Mat &image, int div = 64) {int n = static_cast<int>(log(static_cast<double>(div)) / log(2.0));//掩码值uchar mask = 0xFF << n; // e.g. 比如div=16, mask= 0xF0//进行色彩还原image = (image & Scalar(mask, mask, mask)) + Scalar(div / 2, div / 2, div / 2);
}
相关文章:

【opencv入门教程】15. 访问像素的十四种方式
文章选自: 一、像素访问 一张图片由许多个点组成,每个点就是一个像素,每个像素包含不同的值,对图像像素操作是图像处理过程中常使用的 二、访问像素 void Samples::AccessPixels1(Mat &image, int div 64) {int nl imag…...

【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
导航: 本文一些内容需要聚簇索引、非聚簇索引、B树、覆盖索引、索引下推等前置概念,虽然本文有简单回顾,但详细可以参考下文的【MySQL高级篇】 【Java笔记踩坑汇总】Java基础JavaWebSSMSpringBootSpringCloud瑞吉外卖/谷粒商城/学成在线设计模…...
根据html的段落长度设置QtextBrowser的显示内容,最少显示一个段落
要根据 HTML 段落的长度设置 QTextBrowser 的显示内容,并确保至少显示一个段落,可以通过以下步骤来实现: 加载 HTML 内容:首先,你需要加载 HTML 内容到 QTextBrowser 中。可以通过 setHtml() 方法来设置 HTML。 计算段…...

基于Huffman编码的GPS定位数据无损压缩算法
目录 一、引言 二、霍夫曼编码 三、经典Huffman编码 四、适应性Huffman编码 五、GPS定位数据压缩 提示:文末附定位数据压缩工具和源码 一、引言 车载监控系统中,车载终端需要获取GPS信号(经度、纬 度、速度、方向等)实时上传…...

php:完整部署Grid++Report到php项目,并实现模板打印
一、下载Grid++Report软件 路径:开发者安装包下载 - 锐浪报表工具 二、 安装软件 1、对下载的压缩包运行内部的exe文件 2、选择语言 3、 完成安装引导 下一步即可 4、接收许可协议 点击“我接受” 5、选择安装路径 “浏览”选择安装路径,点击"安装" 6、完成…...
C标签和 EL表达式的在前端界面的应用
目录 前言 常用的c标签有: for循环 1 表示 普通的for循环的 2 常在集合中使用 表示 选择关系 1 简单的表示如果 2 表示如果。。否则。。 EL表达式 格式 : ${属性名/对象/ 集合} 前言 本篇博客介绍 c标签和el表达式的使用 使用C标签 要引入 …...
Linux絮絮叨(四) 系统目录结构
Linux 系统的目录结构(Filesystem Hierarchy Standard, FHS)定义了 Linux 系统中文件系统的标准布局,以下是一些常见目录的功能: 根目录 / 描述:所有文件和目录的起始点,Linux 文件系统的根。内容…...

Java基于SpringBoot的网上订餐系统,附源码
博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…...
《Java核心技术I》死锁
死锁 账户1:200元账户2: 300元线程1:从账号1转300到账户2线程2:从账户2转400到账户1 如上,线程1和线程2显然都被阻塞,两个账户的余额都不足以转账,两个线程都无法执行下去。 有可能会因为每一个线程要等…...

【Windows11系统局域网共享文件数据】
【Windows11系统局域网共享文件数据】 1. 引言1. 规划网络2. 获取必要的硬件3. 设置网络4. 配置网络设备5. 测试网络连接6. 安全性和维护7. 扩展和优化 2. 准备工作2.1: 启用网络发现和文件共享2.2: 设置共享文件夹 3. 访问共享文件夹4. 小贴士5. 总结 1. 引言 随着家庭和小型办…...

MCU、ARM体系结构,单片机基础,单片机操作
计算机基础 计算机的组成 输入设备、输出设备、存储器、运算器、控制器 输入设备:将其他信号转换为计算机可以识别的信号(电信号)。输出设备:将电信号(0、1)转为人或其他设备能理解的…...

在办公室环境中用HMD替代传统显示器的优势
VR头戴式显示器(HMD)是进入虚拟现实环境的一把钥匙,拥有HMD的您将能够在虚拟现实世界中尽情探索未知领域,正如如今的互联网一样,虚拟现实环境能够为您提供现实中无法实现的或不可能实现的事。随着技术的不断进步&#…...
ssm 多数据源 注解版本
application.xml 配置如下 <!-- 使用 DruidDataSource 数据源 --><bean id"primaryDataSource" class"com.alibaba.druid.pool.DruidDataSource" init-method"init" destroy-method"close"></bean> <!-- 使用 数…...

selenium常见接口函数使用
博客主页:花果山~程序猿-CSDN博客 文章分栏:测试_花果山~程序猿的博客-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 1. 查找 查找方式 css_s…...

STM32F103单片机使用STM32CubeMX新建IAR工程步骤
打开STM32CubeMX软件,选择File 选择新建工程 在打开的窗口输入单片机型号 在右下角选择单片机型号,然后点右上角 start project,开始新建工程。 接下来设置调试接口,在左边System Core中选择 SYS,然后在右右边debu…...
刷题重开:找出字符串中第一个匹配项的下标——解题思路记录
问题描述: 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。 示例 1: 输入&…...

product/admin/list?page=0size=10field=jancodevalue=4562249292272
文章目录 1、ProductController2、AdminCommonService3、ProductApiService4、ProductCommonService5、ProductSqlService https://api.crossbiog.com/product/admin/list?page0&size10&fieldjancode&value45622492922721、ProductController GetMapping("ad…...
人工智能机器学习无监督学习概念及应用详解
无监督学习:深入解析 引言 在人工智能和机器学习的领域中,无监督学习(Unsupervised Learning)是一种重要的学习范式。与监督学习不同,无监督学习不依赖于标签数据,而是通过模型从无标签的数据中学习数据的…...

APM装机教程(五):测绘无人船
文章目录 前言一、元生惯导RTK使用二、元厚HXF260测深仪使用三、云卓H2pro遥控器四、海康威视摄像头 前言 船体:超维USV-M1000 飞控:pix6c mini 测深仪:元厚HXF160 RTK:元生惯导RTK 遥控器:云卓H12pro 摄像头…...

微信小程序 运行出错 弹出提示框(获取token失败,请重试 或者 请求失败)
原因是:需要登陆微信公众平台在开发管理 中设置 相应的 服务器域名 中的 request合法域名 // index.jsPage({data: {products:[],cardLayout: grid, // 默认卡片布局为网格模式isGrid: true, // 默认为网格布局page: 0, // 当前页码size: 10, // 每页大小hasMore…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...