OpenCV(总结篇)图像逐像素访问(三种操作:指针、迭代器、at()函数)

目录

概述

1、指针访问

2、迭代器访问

3、at()函数访问

总代码

效果

参考资料


概述

访问图像像素值是图像处理的基本操作。OpenCV提供了很多访问方式,比较常用的三种方式: 
(1) 通过指针访问 (逐通道
(2) 通过迭代器访问 (逐像素
(3) 动态地址计算,通过at()函数实现(逐像素

方法比较: 
(1)用指针访问像素,速度最快;但在彩色图像处理中,如果要单独对某一个颜色分量处理,则需要通过数学公式计算,不是很直观; 
(2)推荐用通过迭代器访问像素,速度快,而且提取BGR某一颜色分量很方便。 
(3)at()函数适用于随机访问某个具体的像素点(已知该像素点行、列坐标),不建议用at()函数遍历整个图。

1、指针访问

指针通道访问 

//方式1:指针操作(逐通道访问)
void Handle_Ptr()
{
	uchar* p;
	//彩图
	for (int i = 0; i < src.rows; i++)
	{
		p = src.ptr<uchar>(i);				//指向每一行首地址
		for (int j = 0; j < src.cols * src.channels(); j++)
		{
			p[j] = 255 - p[j];				//反差处理
		}
	}

	//灰度图
	for (int i = 0; i < src_gray.rows; i++)
	{
		p = src_gray.ptr<uchar>(i);				//指向每一行首地址
		for (int j = 0; j < src_gray.cols; j++)
		{
			p[j] = 255 - p[j];					//反差处理
		}
	}
}

2、迭代器访问

迭代器像素访问

//方式2:迭代器操作(逐像素访问)
void Iterator()
{
	//彩色图
	//获取迭代器
	Mat_<Vec3b>::iterator it1 = src.begin<Vec3b>();			//初始位置的迭代器
	Mat_<Vec3b>::iterator itend1 = src.end<Vec3b>();		//终止位置的迭代器
	//彩色图逐像素操作
	for ( ; it1 != itend1; it1++)			//逐像素
	{
		(*it1)[0] = 255 - (*it1)[0];			//逐通道
		(*it1)[1] = 255 - (*it1)[1];			//逐通道
		(*it1)[2] = 255 - (*it1)[2];			//逐通道
	}

	//灰度图
	//获取迭代器
	Mat_<uchar>::iterator it2 = src_gray.begin<uchar>();		//初始位置的迭代器
	Mat_<uchar>::iterator itend2 = src_gray.end<uchar>();		//终止位置的迭代器
	//灰度图逐像素操作
	for (; it2 != itend2; it2++)
	{
		(*it2) = 255 - (*it2);
	}
}

3、at()函数访问

at()函数像素访问

//方式3:at()函数操作(逐像素访问)
void At()
{
	//彩色图
	for (int i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)				//逐像素
		{
			src.at<Vec3b>(i, j)[0] = 255 - (int)src.at<Vec3b>(i, j)[0];		//逐通道
			src.at<Vec3b>(i, j)[1] = 255 - (int)src.at<Vec3b>(i, j)[1];		//逐通道
			src.at<Vec3b>(i, j)[2] = 255 - (int)src.at<Vec3b>(i, j)[2];		//逐通道
		}
	}

	//灰度图
	for (int i = 0; i < src_gray.rows; i++)
	{
		for (int j = 0; j < src_gray.cols; j++)
		{
			src_gray.at<uchar>(i, j) = 255 - (int)src_gray.at<uchar>(i, j);
		}
	}
}

总代码

//图像像素的三种访问方式(指针、迭代器、at()函数)
//指针:逐通道访问		迭代器:逐像素访问		at()函数:逐通道访问
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

Mat src, src_gray;

//图像初始化
void Image_Init()
{
	src = imread("Resource/test.jpg");					//读取
	if (src.empty())
	{
		printf("could not load the picture...");
	}
	cvtColor(src, src_gray, COLOR_RGB2GRAY);
}

//方式1:指针操作(逐通道访问)
void Handle_Ptr()
{
	uchar* p;
	//彩图
	for (int i = 0; i < src.rows; i++)
	{
		p = src.ptr<uchar>(i);				//指向每一行首地址
		for (int j = 0; j < src.cols * src.channels(); j++)
		{
			p[j] = 255 - p[j];					//反差处理(逐通道)
		}
	}

	//灰度图
	for (int i = 0; i < src_gray.rows; i++)
	{
		p = src_gray.ptr<uchar>(i);				//指向每一行首地址
		for (int j = 0; j < src_gray.cols; j++)
		{
			p[j] = 255 - p[j];							//反差处理(逐通道)
		}
	}
}

//方式2:迭代器操作(逐像素访问)
void Iterator()
{
	//彩色图
	//获取迭代器
	Mat_<Vec3b>::iterator it1 = src.begin<Vec3b>();			//初始位置的迭代器
	Mat_<Vec3b>::iterator itend1 = src.end<Vec3b>();		//终止位置的迭代器
	//彩色图逐像素操作
	for ( ; it1 != itend1; it1++)			//逐像素
	{
		(*it1)[0] = 255 - (*it1)[0];			//逐通道
		(*it1)[1] = 255 - (*it1)[1];			//逐通道
		(*it1)[2] = 255 - (*it1)[2];			//逐通道
	}

	//灰度图
	//获取迭代器
	Mat_<uchar>::iterator it2 = src_gray.begin<uchar>();			//初始位置的迭代器
	Mat_<uchar>::iterator itend2 = src_gray.end<uchar>();		//终止位置的迭代器
	//灰度图逐像素操作
	for (; it2 != itend2; it2++)
	{
		(*it2) = 255 - (*it2);
	}
}

//方式3:at()函数操作(逐像素访问)
void At()
{
	//彩色图
	for (int i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)				//逐像素
		{
			src.at<Vec3b>(i, j)[0] = 255 - (int)src.at<Vec3b>(i, j)[0];		//逐通道
			src.at<Vec3b>(i, j)[1] = 255 - (int)src.at<Vec3b>(i, j)[1];		//逐通道
			src.at<Vec3b>(i, j)[2] = 255 - (int)src.at<Vec3b>(i, j)[2];		//逐通道
		}
	}

	//灰度图
	for (int i = 0; i < src_gray.rows; i++)
	{
		for (int j = 0; j < src_gray.cols; j++)
		{
			src_gray.at<uchar>(i, j) = 255 - (int)src_gray.at<uchar>(i, j);
		}
	}
}

//显示图像
void Image_Show()
{
	imshow("彩图", src);
	imshow("灰度图", src_gray);
}

int main()
{
	Image_Init();					//图像初始化

	//Handle_Ptr();					//1、指针操作

	//Iterator();					//2、迭代器操作

	At();							//3、at()函数操作

	Image_Show();					//显示图像

	waitKey(0);

	return 0;
}

效果

 

参考资料

https://blog.youkuaiyun.com/zhu_hongji/article/details/81333200

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_(*^▽^*)_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值