我是靠谱客的博主 称心大侠,最近开发中收集的这篇文章主要介绍OpenCV数据结构与基本绘图(Mat 类、Point类、Scalar类等)1.基础图像容器 Mat2 常用的数据结构和函数3.基本图形的绘制,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 1.基础图像容器 Mat
    • 1.1Mat 结构的使用
    • 1.2像素值的存储方法
    • 1.3 显示创建 Mat 对象的七种方法
      • 1.3.1 Mat 的常用构造函数
    • 1.4 OpenCV 中的格式化输出方法
    • 1.5 输出其他常用数据结构
    • 1.6 取对角线元素
    • 1.7 Mat 表达式
    • 1.8 Mat 与 IplImage 和 CvMat 的转换
      • 1.8.1 Mat 转换为 IplImage 和 CvMat
      • 1.8.2 IplImage 和 CvMat 格式转为 Mat
  • 2 常用的数据结构和函数
    • 2.1 点的表示:Point 类
    • 2.2 颜色的表示:Scalar 类
    • 2.3 尺寸的表示:Size 类
    • 2.4 矩形的表示:Rect 类
    • 2.5 颜色空间转换:cvtColo()函数
    • 2.6 其他常用知识
  • 3.基本图形的绘制
    • 3.1 DrawEclipse() 函数的写法
    • 3.2 DrawFilledCircle() 函数的写法
    • 3.3 DrawPolygon() 函数的写法
    • 3.4 DrawLine() 函数的写法
    • 3.5 main 函数的写法

1.基础图像容器 Mat

1.1Mat 结构的使用

  Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸、存储方法,存储地址等信息)和一个指向所有像素值的矩阵(根据所选存储方法的不同,矩阵可以是不同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。因此在程序中传递图像并创建副本时,大的开销是由矩阵造成的,而不是信息头。
  为了解决开销问题,OpenCV 使用了引用计数机制。其思路是让每个 Mat 对象都拥有自己的信息头,但共享同一个矩阵。这通过让矩阵指针指向同一个地址实现。而拷贝构造函数则只复制信息头和矩阵指针,而不复制矩阵。

	Mat A,C;		//仅创建信息头部分
	A = imread("1.jpg, CV_LOAD_IMAGE_COLOR);	//为矩阵开辟内存
	Mat B(A);		//使用拷贝构造函数
	C = A;		//赋值运算

  我们可以创建只引用部分数据的信息头。比如想要创建一个感兴趣区域(ROI,region of interest),只需要创建包含边界信息的信息头:

	Mat D (A ,Rect(10, 10, 100));	//使用矩形界定
	Mat E = A(Range:all(), Range(1,3));	//用行和列界定

  对于矩阵的清理:通过引用计数机制来实现,我们无论什么时候复制一个 Mat 对象的信息头,都会增加矩阵的引用次数,反之,当一个头被释放后,这个计数被减一,当计数为零时,矩阵就会被清理。但某些时候想复制矩阵本身时(不是信息头和矩阵指针)。这时可以使用函数 clone() 或者 copyTo()。

	Mat F = A.clone();
	Mat G;
	A.copyTo(G);

  现在改变 F 或者 G就不会影响 Mat 信息头所指向的矩阵。
  可总结为以下四个要点:
  ● OpenCV 函数中输出图像的内存分配是自动完成的(如果不特别指定的话)。
  ● 使用 OpenCV 的 C++ 接口时不需要考虑内存释放的问题。
  ● 赋值运算符和拷贝构造函数(构造函数)只复制信息头。
  ● 使用函数 clone() 或者 copyTo() 来复制一幅图像的矩阵。

1.2像素值的存储方法

  存储像素值需要指定颜色空间和数据类型。颜色空间是指对于一个给定的颜色,如何组合颜色元素以对其编码。
  GRB 颜色空间是最常用的颜色空间,它的基色是红色、绿色和蓝色,有时为了表示透明颜色也会加入第四个元素 alpha(A)。
  颜色系统有很多,它们各有优势:
  ● GRB 是最常见的,这是因为人眼采用相似的工作机制,它也被显示设备所采用。
  ● HSV 和 HLS 把颜色分解成色调、饱和度和亮度/明度。这是描述颜色更自然的方式,比如可以通过抛弃最后一个元素,使算法对输入图像的光照条件不敏感。
  ● YCrCb 在 JPEG 图像格式中广泛使用。
  ● CIE Lab* 是一种在感知上均匀的颜色空间,它适合用来度量两个颜色之间的距离。
  每个组成元素都有自己的定义域,而定义域取决去其数据类型,如何存储一个元素决定了我们在其定义域上能控制的精度。最小的数据类型是 char ,占一个字节或者 8 位,可以是有符号型(0 ~ 255 之间)或是无符号型(-127 ~ +127)之间。尽管使用三个 char 类型元素已经可以表示 1600 万种颜色可能(使用 GBR 颜色空间),但若使用 float (4 字节,32 位)或 double 型(8 字节,64 位)则能给出更加精细的颜色分辨能力。

1.3 显示创建 Mat 对象的七种方法

  Mat 的 " << " 运算符也能将图片写入文件中,但该运算符只对二维矩阵有效。

方法一:使用 Mat 的构造函数:

	Mat M(2, 2, CV_8UC3, Scalar(0, 0, 255));
	cout << "M = " << endl << " " << M << endl << endl;

运行结果:

  对于二维多通道图像,需要定义其尺寸,即行数和列数。然后,需要指定存储元素的数据类型以及每个矩阵的点通道数。为此,依以下规则有多种定义:
  CV_[位数][带符号与否][类型前缀]C[通道数]
  比如 CV_8UC3 表示使用 8 位的 unsigned char 型,每个像素由三个元素组成三通道。而预先定义的 通道数可以多达四个。另外,Scalar 是个 short 型的向量,能使用指定的定制化值来初始化矩阵,它还可以用于表示颜色。当然,若需要更多通道,可以使用大写的宏并把通道数放在小括号中,如方法二。

1.3.1 Mat 的常用构造函数

//1.无参构造函数
Mat::Mat()

//2.创建行为 rows,列为 cols,类型为 type 的图像
Mat::Mat(int rows,int cols,int type)

//3.创建大小为 size,类型为 type 的图像
Mat::Mat(Size size,int type)

//4.创建行数为 rows,列数为 cols,类型为 type 的图像,并将所有元素初始化值为 s
Mat::Mat(int rows,int cols,int type,const Scalar& s)

//5.创建大小为 size,类型为 type 的图像,并将所有元素初始化为值 s
Mat::Mat(Size size,int type,const Scalar& s)

//6.将 m 赋值给新创建的对象,此处不会对图像数据进行复制,m 和新的图像共用图像数据
Mat::Mat(const Mat& m)

/*7.创建行数为 rows,列数为 cols,类型为 type 的图像,此构造函数不创建图像数据所需内存,而是直接使
用 data 所指内存,图像的步长由 step 指定8*/
Mat::Mat(int rows,int cols,int type,void* data,size_t step = AUTO_STEP)

//8.创建大小为 size,类型为 type 的图像,此构造函数不创建图像数据所需内存,而是直接使
//用 data 所指内存,图像的步长由 step 指定
Mat::Mat(int rows,int cols,int type,void* data,size_t step = AUTO_STEP)

/*9.创建的新图像为 m 的一部分,具体范围由 rowRange 和 colRange 指定,此构造函数也不进行图像数据
的复制操作,新图像与 m 共用图像数据。*/
Mat::Mat(const Mat& m,const Range& rowRange,const Range& colRange)

/*10.创建的图像为 m 的一部分,具体的范围 roi 指定,此函数也不进行图像的复制,新图像与原图像共享
图像数据 */
Mat::Mat(const Mat& m,const Rect& roi)

方法二:在 CC++ 中通过构造函数进行初始化

	Mat sz[3] = {
   2,2,2};
	Mat L(3, sz, CV_8UC, Scalar::all(0));

  上面的例子演示了如何创建一个超过两维的矩阵:指定维数,然后传递一个指向一个数组的指针,这个数组包含两个维度的尺寸,后续两个参数与方法一中的相同。

方法三:为已存在的 IplIamge 指针创建信息头
IplImage 的头文件为: #include<highgui/highgui_c.h>

	IplImage* img = cvLoadImage("1,jpg",1);
	Mat mtx(img);	//转换 IplImage* -> Mat;

方法四:利用 Create() 函数

	M.create(4, 4, CV_8UC(2));
	cout << "M = " << endl << " " << M << endl << endl;

运行结果:

  需要注意的是,此创建方法不能为矩阵设初值,只是在改变尺寸重新为矩阵开辟内存而已。

方法五:采用 Matlab 式的初始化方法
  Matlab 形式的初始化方法有:zeros() , ones() , eyes() 。使用以下方式指定尺寸和数据类型:

	Mat E = Mat::eye(4, 4, CV_64F);
	cout << "E = " << endl << " " << E << endl << endl;
	
	Mat O = Mat::ones(2, 2, CV_32F);
	cout << "O = " << endl << " "<

最后

以上就是称心大侠为你收集整理的OpenCV数据结构与基本绘图(Mat 类、Point类、Scalar类等)1.基础图像容器 Mat2 常用的数据结构和函数3.基本图形的绘制的全部内容,希望文章能够帮你解决OpenCV数据结构与基本绘图(Mat 类、Point类、Scalar类等)1.基础图像容器 Mat2 常用的数据结构和函数3.基本图形的绘制所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部