使用访问图像三种办法,指针,迭代器,动态地址计算

news2024/11/16 13:54:31

使用访问图像三种办法,指针,迭代器,动态地址计算

指针访问

方法一

#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;
#include <iostream>
#include <fstream>
using namespace cv; //包含cv命名空间
#include <opencv2/core/core.hpp>



#include <opencv2/opencv.hpp>

//-------------------------【全局函数声明部分】------------------------
// 描述: 全局函数声明
//--
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
//---------------------------【main()函数】--------------------------
// 描述: 控制台应用程序的入口函数,我们的程序从这里开始执行
//----------------
int main()
{
	//【1】创建原始图并显示
	Mat srcImage = imread("1.jpg");
	imshow("原始图像", srcImage);
	//【2】按原始图的参数规格来创建创建效果图
	Mat dstImage;
	dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//效果图的大小、类型与原图片相同
	//【3】记录起始时间
	double time0 = static_cast<double>(getTickCount());
	//【4】调用颜色空间缩减函数
	colorReduce(srcImage, dstImage, 32);
	//【5】计算运行时间并输出
	time0 = ((double)getTickCount() - time0) / getTickFrequency(); cout << "此方法运行时间为: " << time0 << "秒" << endl; //输出运行时间
	//【6】显示效果图
	imshow("效果图", dstImage);
	waitKey(0);
}
void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
	//参数准备
	outputImage = inputImage.clone(); //复制实参到临时变量
	int rowNumber = outputImage.rows; //行数
	int colNumber = outputImage.cols * outputImage.channels(); //列数×通道数=每一行元素的个数
	//双重循环,遍历所有的像素值
	for (int i = 0; i < rowNumber; i++) //行循环
	{
		uchar* data = outputImage.ptr<uchar>(i); //获取第i行的首地址
		for (int j = 0; j < colNumber; j++) //列循环
		{
			// ---------【开始处理每个像素】-------------
			data[j] = data[j] / div * div + div / 2;
			// ----------【处理结束】---------------------
		} //行处理结束
	}
}

在这里插入图片描述

指针访问方法二

#include <opencv2/opencv.hpp>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("path/to/your/image.jpg");

    // 检查图像是否成功加载
    if (image.empty()) {
        std::cerr << "Error: Could not read the image." << std::endl;
        return -1;
    }

    // 获取图像的行数和列数
    int rows = image.rows;
    int cols = image.cols;

    // 访问图像像素(以BGR格式为例)
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            // 获取像素值
            cv::Vec3b& pixel = image.at<cv::Vec3b>(i, j);

            // 修改像素值,例如将蓝色通道置为0
            pixel[0] = 0;  // 蓝色通道
            pixel[1] = pixel[1];  // 绿色通道(保持不变)
            pixel[2] = pixel[2];  // 红色通道(保持不变)
        }
    }

    // 显示修改后的图像
    cv::imshow("Modified Image", image);

    // 等待按键
    cv::waitKey(0);

    return 0;
}

在这里插入图片描述

使用迭代器调用图片

#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;
#include <iostream>
#include <fstream>
using namespace cv; //包含cv命名空间
#include <opencv2/core/core.hpp>



#include <opencv2/opencv.hpp>

//-------------------------【全局函数声明部分】------------------------
// 描述: 全局函数声明
//--
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
//---------------------------【main()函数】--------------------------
// 描述: 控制台应用程序的入口函数,我们的程序从这里开始执行
//----------------
int main()
{
	//【1】创建原始图并显示
	Mat srcImage = imread("1.jpg");
	imshow("原始图像", srcImage);
	//【2】按原始图的参数规格来创建创建效果图
	Mat dstImage;
	dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//效果图的大小、类型与原图片相同
	//【3】记录起始时间
	double time0 = static_cast<double>(getTickCount());
	//【4】调用颜色空间缩减函数
	colorReduce(srcImage, dstImage, 32);
	//【5】计算运行时间并输出
	time0 = ((double)getTickCount() - time0) / getTickFrequency(); cout << "此方法运行时间为: " << time0 << "秒" << endl; //输出运行时间
	//【6】显示效果图
	imshow("效果图", dstImage);
	waitKey(0);
}

void colorReduce(Mat& inputImage, Mat & outputImage, int div)
{
//参数准备
outputImage = inputImage. clone(); //复制实参到临时变量
//获取迭代器
Mat_<Vec3b>::iterator it = outputImage. begin<Vec3b>(); //初始位置的迭代器
Mat_<Vec3b>::iterator itend = outputImage. 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;
// ------------------------ 【处理结束】-----------------------
}
}

在这里插入图片描述

方法二使用迭代器调用图片

#include <opencv2/opencv.hpp>

int main() {
	// 读取图像
	cv::Mat image = cv::imread("1.jpg");

	// 检查图像是否成功加载
	if (image.empty()) {
		std::cerr << "Error: Could not read the image." << std::endl;
		return -1;
	}

	// 使用迭代器访问图像像素(以BGR格式为例)
	for (cv::MatIterator_<cv::Vec3b> it = image.begin<cv::Vec3b>(); it != image.end<cv::Vec3b>(); ++it) {
		// 获取当前像素值
		cv::Vec3b& pixel = (*it);

		// 修改像素值,例如将蓝色通道置为0
		pixel[0] = 0;  // 蓝色通道
		pixel[1] = pixel[1];  // 绿色通道(保持不变)
		pixel[2] = pixel[2];  // 红色通道(保持不变)
	}

	// 显示修改后的图像
	cv::imshow("Modified Image", image);

	// 等待按键
	cv::waitKey(0);

	return 0;
}


使用动态地址调用图片

#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;
#include <iostream>
#include <fstream>
using namespace cv; //包含cv命名空间
#include <opencv2/core/core.hpp>



#include <opencv2/opencv.hpp>

//-------------------------【全局函数声明部分】------------------------
// 描述: 全局函数声明
//--
void colorReduce(Mat& inputImage, Mat& outputImage, int div);
//---------------------------【main()函数】--------------------------
// 描述: 控制台应用程序的入口函数,我们的程序从这里开始执行
//----------------
int main()
{
	//【1】创建原始图并显示
	Mat srcImage = imread("1.jpg");
	imshow("原始图像", srcImage);
	//【2】按原始图的参数规格来创建创建效果图
	Mat dstImage;
	dstImage.create(srcImage.rows, srcImage.cols, srcImage.type());//效果图的大小、类型与原图片相同
	//【3】记录起始时间
	double time0 = static_cast<double>(getTickCount());
	//【4】调用颜色空间缩减函数
	colorReduce(srcImage, dstImage, 32);
	//【5】计算运行时间并输出
	time0 = ((double)getTickCount() - time0) / getTickFrequency(); cout << "此方法运行时间为: " << time0 << "秒" << endl; //输出运行时间
	//【6】显示效果图
	imshow("效果图", dstImage);
	waitKey(0);
}
void colorReduce(Mat& inputImage, Mat& outputImage, int div) {
	//参数准备
	outputImage = inputImage.clone(); //复制实参到临时变量
	int rowNumber = outputImage.rows; //行数
	int colNumber = outputImage.cols; //列数
	//存取彩色图像像素
	for (int i = 0; i < rowNumber; i++)
	{
		for (int j = 0; j < colNumber; j++)
		{
			//------------------ 【开始处理每个像素】--------------------
			outputImage.at<Vec3b>(i, j)[0] =
				outputImage.at<Vec3b>(i, j)[0] / div * div + div / 2; //蓝色通道
			outputImage.at<Vec3b>(i, j)[1] = outputImage.at<Vec3b>(i, j)[1] / div * div + div / 2; //绿色通道
			outputImage.at<Vec3b>(i, j)[2] =
				outputImage.at<Vec3b>(i, j)[2] / div * div + div / 2; //红色通道
				//------ 【处理结束】-
		} //行处理结束
	}
}

在这里插入图片描述

方法二动态地址计算


#include <opencv2/opencv.hpp>

int main() {
	// 读取图像
	cv::Mat image = cv::imread("1.jpg");

	// 检查图像是否成功加载
	if (image.empty()) {
		std::cerr << "Error: Could not read the image." << std::endl;
		return -1;
	}

	// 获取图像的行数和列数
	int rows = image.rows;
	int cols = image.cols;

	// 访问图像像素(以BGR格式为例)通过动态地址方式
	for (int i = 0; i < rows; ++i) {
		// 获取当前行的指针
		uchar* rowPtr = image.ptr<uchar>(i);

		for (int j = 0; j < cols; ++j) {
			// 计算像素的偏移量
			int offset = j * image.channels();

			// 修改像素值,例如将蓝色通道置为0
			rowPtr[offset] = 0;          // 蓝色通道
			rowPtr[offset + 1] = rowPtr[offset + 1];  // 绿色通道(保持不变)
			rowPtr[offset + 2] = rowPtr[offset + 2];  // 红色通道(保持不变)
		}
	}

	// 显示修改后的图像
	cv::imshow("Modified Image", image);

	// 等待按键
	cv::waitKey(0);

	return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1067091.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TS中interface接口的使用

接口用来定义一个类的结构&#xff0c;用来定义一个接口中应该包含哪些属性和方法 语法结构如下&#xff1a; interface 接口名 { // 属性和方法 } 一、使用接口进行类型声明 我们声明一个对象类型可以使用如下方法&#xff1a; // 定义一个对象类型 type Mytype {name: st…

show index 中部分字段的含义

show index from 表名 查看某张表的索引情况 另: SELECT * FROM information_schema.STATISTICS WHERE TABLE_NAME "t1" 与 show index from t1 作用相似,且会返回更多的字段信息 创建一张测试表t1: CREATE TABLE t1 ( id INT ( 11 ) NOT NULL AUTO_INCREMENT, nam…

【C++】STL详解(十二)—— 用哈希表封装出unordered_map和unordered_set

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C学习 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【C】STL…

Zookeeper 集群搭建

Zookeeper Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目 Zookeeper 工作机制 Zookeeper从设计模式角度来理解&#xff1a;是一个基于观察者模式设计的分布式服务管理框架 一旦这些数据的状态发生变化&#xff0c;Zookeeper就将负责通知…

【EI复现】基于同步发电机转动惯量和阻尼系数协同自适应控制策略(Simulink仿真实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

华为OD机试 - 计算最大乘积(2022Q4 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

分贝定义简介

一、什么是分贝 辅助单元Bel表示任何给定部件、电路或系统的输入和输出之间的对数比L,并且可以用电压、电流或功率来表示: 如果使用场量(电压或电流)代替功率量,则: 我们可以将增益或损耗因子相加为正或负dB值,而不是将其乘以比率。 分贝与功率转化的速读表如下所示:…

流程图设计制作都有哪些好用的工具

流程图是一种直观的图形表示方式&#xff0c;通常用于显示事物的过程、步骤和关系。在现代工作中&#xff0c;设计师经常需要绘制各种流程图来解释工作过程、产品设计等。本文将为您推荐7个流程图软件&#xff0c;以帮助您快速绘制高效的流程图&#xff0c;并提高工作效率。 即…

IDEA 2021.2.2设置自动热部署

1.导入包坐标 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency> 2.pom.xml添加piugins插…

Redis-双写一致性

双写一致性 双写一致性解决方案延迟双删&#xff08;有脏数据的风险&#xff09;分布式锁&#xff08;强一致性&#xff0c;性能比较低&#xff09;异步通知&#xff08;保证数据的最终一致性&#xff0c;高并发情况下会出现短暂的不一致情况&#xff09; 双写一致性 当修改了数…

光伏并网逆变器低电压穿越技术研究(Simulink仿真)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

JavaScript系列从入门到精通系列第十八篇:JavaScript中的函数作用域

文章目录 前言 一&#xff1a;函数作用域 前言 我们刚才提到了&#xff0c;在<Script>标签当中进行定义的变量、对象、函数对象都属于全局作用域&#xff0c;全局作用域在页面打开的时候生效在页面关闭的时候失效。 一&#xff1a;函数作用域 调用函数时创建函数作用域…

New Journal of Physics:不同机器学习力场特征的准确性测试

文章信息 作者&#xff1a;Ting Han1, Jie Li1, Liping Liu2, Fengyu Li1, * and Lin-Wang Wang2, * 通信单位&#xff1a;内蒙古大学物理科学与技术学院、中国科学院半导体研究所 DOI&#xff1a;10.1088/1367-2630/acf2bb 研究背景 近年来&#xff0c;基于DFT数据的机器学…

Docker安装及基本使用

一、Docker安装 1.下载关于Docker的依赖环境 在Xterm中输入以下代码安装依赖环境 回车 yum -y install yum-utils device-mapper-persistent-datalvm2 2.设置一下下载Docker的镜像源 依赖环境下载完毕以后&#xff0c;设置下载的镜像源&#xff0c;如果不设置&#xff0c…

使用Docker部署Redis(单机部署)

目录 一、查看Redis镜像版本二、拉取自己需要的镜像版本三、创建挂载目录四、添加配置文件五、运行Redis容器六、连接测试 一、查看Redis镜像版本 先去Docker Hub查看Redis镜像有那些版本&#xff0c;我部署的时候Redis最新已经到7.x的版本了&#xff0c;我这里准备部署6.x的版…

17哈希表-简单遍历

目录 LeetCode之路——383. 赎金信 分析&#xff1a; 解法一&#xff1a;哈希表 解法二&#xff1a;数组 LeetCode之路——383. 赎金信 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&…

pinduoduo.item_get拼多多平台根据ID取商品详情 API 封装数据接口返回值说明

参数说明 通用参数说明 version:API版本key:调用key,测试key:test_api_keyapi_name:API类型[item_search,item_get]cache:[yes,no]默认yes&#xff0c;将调用缓存的数据&#xff0c;速度比较快result_type:[json,xml,serialize,var_export]返回数据格式&#xff0c;默认为jsonl…

【SQL】MySQL中的约束

1. 主键约束&#xff08;primary key&#xff09;&#xff1a; 相当于唯一约束非空约束分为单列主键&#xff0c;多列联合主键&#xff0c;一个表只有一个主键多列联合主键的每列都不能为空 2. 自增长约束&#xff08;auto_increment&#xff09;&#xff1a; 用在单列主键后…

Druid数据库连接池

spring:datasource:username: rootpassword: 19990802url: jdbc:mysql://localhost:3306/mybatis?useUnicodetrue&characterEncodingutf-8&serverTimezoneGMTdriver-class-name: com.mysql.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource # type可以指定…

【C++设计模式之迭代器模式】分析及示例

简介 迭代器模式是一种行为型设计模式&#xff0c;它提供了一种顺序访问聚合对象元素的方法&#xff0c;而又不需要暴露聚合对象的内部结构。迭代器模式通过将遍历算法封装在迭代器对象中&#xff0c;可以使得遍历过程更简洁、灵活&#xff0c;并且符合开闭原则。 描述 迭代…