OpenCV中的像素数据类型与基本数据类型的对应关系

1 CV_8UCV_8UC3的含义

在定义Mat对象的时候,像素的数据类型经常使用CV_8UCV_8UC3来表示,例如:

	/** @overload
    @param rows Number of rows in a 2D array.
    @param cols Number of columns in a 2D array.
    @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or
    CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices.
    */
    //Mat(int rows, int cols, int type);
    Mat img(3, 3, CV_8U);

它们都是宏常量,OpenCV的源码中,将像素的数据类型进行了编号,而构造函数根据传入的type值(类型编号)确定像素的具体类型,例如0就代表unsigned char,这里用0、1、2 这些太过突兀,为了使其含义更清晰,所以使用了宏,例如:

	/*
	#define CV_8U   0
	#define CV_8S   1
	#define CV_16U  2
	#define CV_16S  3
	#define CV_32S  4
	#define CV_32F  5
	#define CV_64F  6
	#define CV_16F  7
	*/

像素的数据类型与C++中基本数据类型的对应的关系如下:
在这里插入图片描述

有些图像是多通道,那么一个像素实际上是包含了多个数,Mat类中把这多个数当成一个“像素”处理(只是这个像素比较“长”而已),并且为其声明了类型,即CV_8UC2、CV_8UC3、CV_8UC4、CV_8SC2、CV_8SC3等,它们的组成形式为:cv_<bit_depth>(S|U|F)C<number_of_channels>,即在单通道类型的基础上加上了一个C和数字,1表示1个通道,2表示2个通道,最多能表示4个通道。

多于4个通道时(例如5个通道),则使用宏函数,例如CV_8UC(5),宏函数最多只能表示512个通道

关于多个通道的宏与常数的对应关系如下表所示:(如果CV_8SC2,查表时则是查CV_8S所在行和C2所在列)
在这里插入图片描述
例如:

	printf("CV_8U: %d\n", CV_8U);
	printf("CV_8UC1: %d\n", CV_8UC1);
	printf("CV_8UC3: %d\n", CV_8UC3);

输出

CV_8U: 0
CV_8UC1: 0
CV_8UC3: 16

可以看到CV_8UC1CV_8U没差。

2 利用at访问矩阵中的元素时,必须指定数据类型

at虽然是Mat类的成员函数,但它确实模板函数,它使用时必须指定类型,而CV_8UCV_8UC3等,它们是宏,而不是类型,不能用到模板中。
若图像为单通道,模板中的类型列表应该用基本数据类型,对于多通道,则应该使用opencv源码中定义的向量类型(稍后会介绍)

	//单通道
	Mat img(3, 3, CV_8U);
	cout << (int)img.at<uchar>(0, 1) << endl;	//访问第0行第1列的元素

	//多通道
	Mat img2(3, 3, CV_8UC2);
	Vec2b v2b = img.at<Vec2b>(0, 1);
	cout << v2b << endl;			//访问第0行第1列的像素,这是一个二维向量
	cout << (int)v2b[0] << endl;	

输出

205
[205, 205]
205

这里出现了Vec2b,它其实是与CV_8UC2相匹配的向量类型,使用at访问像素时,向量的类型必须和像素类型严格匹配

opencv中的像素类型声明宏与向量类型的对应关系如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44457930/article/details/129865462