【学习opencv】opencv中遍历像素点以及Mat类解释

一、Mat的构造函数

Mat类中有很多构造函数:

1.Mat(Size size, int type, const Scalar& s);

@param size 2D array size: Size(cols, rows),在Size的构造函数里,列和行是相反的
@param type Array type. 用 CV_8UC1, …, CV_64FC4 来创建1到4通道的矩阵, 用 CV_8UC(n), …, CV_64FC(n) 来创建多通道的矩阵最高为 CV_CN_MAX(opencv定义的常量)
@param s 初始化矩阵的值,在构造函数之后可以用等号给矩阵所有元素赋值

2.Mat(const Mat& m, const Rect& roi);

example:

Mat roi(src,Rect(23,67,89,179));//截取src中感兴趣的区域到roi中

上面只介绍了两个构造函数,mat还有很多重载的构造函数,值得注意的是mat的构造函数中很多是仅仅创建头指针并指向某一内存,并不实际开辟内存空间(上述1构造函数就算开辟了内存,因为已经初始化了)。要真正完成复制的话,需要使用函数clone()或者copyTo()。Copy函数只是复制了mat的头指针,即指针指向同一片内存。

二、Mat的成员说明

Mat类中有很多成员变量,如elemsize,elemsize1,step,depth,type,channels等。

1.步长step以及elemsize

下图为二维矩阵,注意这里维数的概念,二维即矩阵是按行存储的,多维则是按面存储的,下图表示一个有两行,三列,二维的Mat对象(通道为3)

其中elemsize和step返回的均是字节数,这里值的注意是Mat类中的data头指针是unsigned char类型的,即一个字节,则指针的移动是按一个字节一个字节来的。
elemsize1是矩阵一个元素内一个通道所占的字节数
elemsize是矩阵一个元素所占的字节数
step[0]是一行所占的字节数
step[1]=elemsize

当为多维时:

2.depth以及type

初学opencv1时不太理解图像的深度具体指什么,opencv加入mat后,用矩阵的概念描述图像,使很多概念清晰很多。
首先了解什么是type,在Mat的构造函数里就出现过type

Mat(Size size, int type, const Scalar& s);

这里的type是个整数值,但平时我们用的是CV_8UC3等来写入type的值,如下,

Mat ds(src.size(),CV_16SC3);

CV_8UC3等均是是opencv内定义的宏,其与整数之间的映射如下图:

而depth是图像矩阵元素内每个通道所占的的位数,在opencv内提供了整型数与位数的映射关系

enum {
CV_8U=0,
CV_8S=1,
CV_16U=2,
CV_16S=3,
CV_32S=4,
CV_32F=5,
CV_64F=6 };

总的来说:

三、遍历元素

(以下遍历均为赋值到另一Mat中,在内存连续的情况下用指针遍历,isContinuous可判断是否连续)

1.at成员函数遍历

Mat src = imread("face4.jpg",0);
Mat dst(src.size(),src.type());
for (int i = 0; i < src.rows; i++)
	{
		for (int j = 0; j < src.cols; j++)
		{
			dst.at<uchar>(i, j) = src.at<uchar>(i, j);
		}
	}

用at成员函数遍历时,需要知道Mat中存储元素的类型(如上例中需要知道存储的类型为CV_8U,即uchar类型),来填入参数尖括号内的类型参数。
在已知通道数和每个通道数据类型的情况下,指定给 at 方法的数据类型如下表所示:

2.ptr函数访问

Mat src = imread("face4.jpg",0);
Mat dst(src.size(),src.type());
uchar* sr(NULL);
uchar* dr(NULL);
for (int i = 0; i < src.rows; i++)
{
	/*sr = src.ptr<uchar>(i);
	dr = dst.ptr<uchar>(i);*/
	for (int j = 0; j < src.cols; j++)
	//dr[j] = sr[j];
	*dst.ptr(i, j) = *src.ptr(i, j);
}

ptr函数返回指定的行首地址,也可返回某个元素的地址。(注意这里sr,dr指针定义为uchar类型,因为mat中数据块的头指针为uchar*类型)

3.不用函数利用指针访问

for (int i = 0; i <src. rows; i++)
	{
	for(int j=0;j<src.cols*src.channels();j++)
	//针对二维矩阵均可以如此访问内存
		{

			uchar *p = src.data + i*src.step[0] + j;
			*(dst.data + i*dst.step[0] + j)= *p;
			
		}
	
	}

以上三种访问方式原理均为通过步长step来定位元素位置,at和ptr函数内部也是如此。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值