OpenCV—数据结构与基本绘图(一)

简介: OpenCV—数据结构与基本绘图(一)

第4章:OpenCV数据结构与基本绘图

一、基础图像容器Mat

1、数字图像存储概述

我们通过显示屏看到的图像是由数字设备记录的图像中的每个点的数值。

2、Mat结构的使用

(1)优点:

  • 不必要再动手为其开辟空间
  • 不必再不需要时立马将空间释放

(2)Mat简介:

Mat是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸、存储方法、存储地址等信息)和一个指向存储所有像素值的矩阵的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。所以,创建图像副本时,大的开销时由矩阵造成的,而不是信息头。


为了解决以上开销大的问题,OpenCV使用了引用计数机制:让每个Mat对象有自己的信息头,通过矩阵指针指向同一地址,让它们共享一个矩阵。

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

以上代码中的所有Mat对象最终都指向同一个也是唯一一个数据矩阵。

附加:

  • 可以创建只引用部分数据的信息头
Mat D (A,Rect(10,10,100,100));//使用矩形界定
Mat E=A(Range:all(),Range(1,3));//用行和列界定
  • 若是矩阵属于多个Mat对象,通过引用计数机制来实现,复制一次Mat对象的信息头,增加一次引用次数。当一个头释放后,计数减一;计数为0时,矩阵就会被清理。
  • 此时若想复制矩阵本身(不只是信息头和矩阵指针)
Mat A;
//Mat F = A.clone();
Mat F;
A.copyTo(F);

(3)补充:上面(1)和(2)的内容是书上讲的,新手小白看的不是很懂,可以去b站了解一下。

3、像素值的存储方法

说明:存储像素值需要指定颜色空间和数据类型。颜色系统如下:

  • RGB颜色空间是最常用的一种颜色空间,他的基色是红色、绿色和蓝色,表示透明的颜色也会加入第四个颜色alpha
  • HSV和HLS把颜色分解成色调、饱和度和亮度。

每个组成元素都有自己的定义域,而定义域取决于其数据类型。符号型(0-255)和无符号型(-127-127)

4、显示创建Mat对象的七种方法(初始化)

(1)使用Mat()构造函数

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

CV_[位数] [带符合与否] [类型前缀] C[通道数] :

如:CV_8UC3:表示8位的unsigned char型,每个像素由三个元素组成的三通道。

(2)在C/C++中通过构造函数进行初始化

下面代码讲述如何创建一个超过两维的矩阵:指定维数,然后传递一个指向一个数组的指针,这个数组包含每个维度的尺寸,后面两个参数与(1)方法一致。

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

说明:Scalar是一个short型的向量,能使用指定的定制化值来初始化矩阵,还可以用于表示颜色。

(3)为已经存在的IplImage指针创建信息头

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

(4)利用Create()函数

说明:利用Mat类中的Create()成员函数进行Mat类的初始化操作

M.create(4,4,CV_8UC(2));
printf("M= \n");
cout << m << endl<<endl;

(5)采用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<<" "<<O<<endl<<endl;

Mat Z=Mat::zeros(3,3,CV_8UC1);
cout<<"Z = "<<endl<<" "<<Z<<endl<<endl;

(6)对小矩阵使用逗号分隔符初始化函数

Mat C=(Mat_<double>(3,3)<<0,-1,0,-1,5,-1,0,-1,0);
cout<<"C= "<<endl<<" "<<C<<endl<<endl;

(7)为已存在的对象创建新信息头

说明:使用成员函数clone()或者copyTo()为一个已经存在的Mat对象创建一个新的信息头

Mat RowClone=C.row(1).clone();
cout<<"RowClone= "<<endl<<" "<<RowClone<<endl<<endl;

5、OpenCV中的格式化输出方式

首先对于r矩阵的定义,通过randu()函数产生的随机值来填充矩阵,定一个上下限来确保随机值在期望范围内:

Mat r = Mat(10,3,CV_8UC3);//10代表10行,3表示几个通道;后面3表示每个通道数量
randu(r,Scalar::all(0),Scalar::all(255));

(1)OpenCV默认

cout<<"r(opencv默认) = "<<r<<";"<<endl<<endl;

(2)python风格

cout<<"r(python)风格= "<<format(r,Formatter::FMT_PYTHON)<<";"<<endl<<endl;

(3)逗号分隔风格(CSV)

cout<<"r(逗号分隔风格)= "<<format(r,Formatter::FMT_CSV )<<";"<<endl<<endl;
//format格式化

(4)Numpy风格

cout<<"r(Numpy风格)= "<<format(r,Formatter::FMT_NUMPY )<<";"<<endl<<endl;
//format格式化

(5)C语言风格

cout<<"r(C风格)= "<<format(r,Formatter::FMT_C )<<";"<<endl<<endl;

6、输出其他常用的数据结构

(1)定义和输出二维点

Point2f p(6,2);
cout<<"【二维点】p= "<<p<<";"<<endl;

(2)定义和输出三维点

Point3f p(6,2,0);
cout<<"【三维点】p3f= "<<p3f<<";\n"<<endl;

(3)定义和输出基于Mat的std::vector(vector是一个能够存放任意类型的动态数组,能够增加和压缩数据.)

vector<float> v;
v.push_back(3);
v.push_back(5);
v.push_back(7);
cout<<"【基于Mat的vector】shortvec= "<<Mat(v)<<";\n"<<endl;

(4)定义和输出std::vector点(以存放Point2f为例)

vector<Point2f>point(20);
for(size_t i=0;i<points.size();i++){
    points[i]=Point2f((float)(i*5),(float)(i%7));
    cout<<"【二维点向量】points = "<<points<<";"<<endl;
}

相关文章
|
机器学习/深度学习 人工智能 自然语言处理
【深度学习】深度学习的概述及应用,附带代码示例
深度学习(Deep Learning,简称DL)是机器学习领域中的一个重要分支,其目标是通过模拟人脑神经网络的工作机制,构建多层次的抽象特征表示,使机器能够自动从原始数据中提取关键信息,从而实现高精度的任务执行。深度学习通过多层神经网络结构及其训练方式,实现了从低级像素级别到高级概念级别的递进式知识层次。 深度学习的主要组件包括输入层、隐藏层和输出层。隐藏层的数量和层数决定了模型的复杂度和表达能力。在训练过程中,权重更新和梯度下降法是关键步骤,目的是最小化损失函数,提高预测精度。深度学习主要基于反向传播算法(BP Algorithm)来优化模型参数,通过正向传播、损失计算、反向传播和梯度下降等
559 8
|
传感器 人工智能 自动驾驶
驱动未来:自动驾驶技术与智能交通系统的奇妙融合
在科技飞速发展的时代背景下,自动驾驶技术和智能交通系统正成为改变我们出行方式的重要推动力。本文将探讨自动驾驶技术的原理、应用以及其与智能交通系统的紧密关系,展示它们带给我们的便利性、安全性和环境友好性。
|
机器学习/深度学习 数据挖掘 大数据
层次分析法(AHP)原理以及应用
层次分析法(AHP)原理以及应用
3388 0
层次分析法(AHP)原理以及应用
|
供应链 安全 数据可视化
数智洞察丨我国推进交通基础设施数字化的机遇和挑战
笔者围绕公路交通“路、场、桥隧构造物、附属设施”4类全要素和“规划设计、建造、运行管理、养护、安全”等5个核心环节全周期的基础设施数字化内涵解读和场景设想。
数智洞察丨我国推进交通基础设施数字化的机遇和挑战
|
存储 JavaScript 小程序
为了实践微前端,重构了自己的导航网站
为了实践微前端,重构了自己的导航网站
259 0
为了实践微前端,重构了自己的导航网站
|
Web App开发 Dart 安全
flutter项目迁移空安全
迁移 你的代码里大部分需要更改的代码,都是可以轻易推导的。例如,如果一个变量可以为空,它的类型需要 ? 后缀。一个不可以为空的命名参数,需要使用 required 标记。
357 0
flutter项目迁移空安全
|
1天前
|
人工智能 运维 安全
|
3天前
|
SpringCloudAlibaba 负载均衡 Dubbo
微服务架构下Feign和Dubbo的性能大比拼,到底鹿死谁手?
本文对比分析了SpringCloudAlibaba框架下Feign与Dubbo的服务调用性能及差异。Feign基于HTTP协议,使用简单,适合轻量级微服务架构;Dubbo采用RPC通信,性能更优,支持丰富的服务治理功能。通过实际测试,Dubbo在调用性能、负载均衡和服务发现方面表现更出色。两者各有适用场景,可根据项目需求灵活选择。
363 123
微服务架构下Feign和Dubbo的性能大比拼,到底鹿死谁手?
|
6天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
540 107

热门文章

最新文章