初探core组件:OpenCV数据结构与基本绘图

news2024/11/29 8:44:44

OpenCV数据结构与基本绘图

1. 基础图像容器 Mat

1.1 数字图像存储概述

我们有多种方法从现实世界获取数字图像:数码相机、扫描仪、计算机断层扫描和磁共振成像等等。在每一种情况下,我们(人类)看到的都是图像。然而,当把它转化为我们的数字设备时,我们记录的是图像中每个点的数值。
在这里插入图片描述
例如,在上面的图像中,你可以看到汽车的镜子只不过是一个包含所有像素点强度值的矩阵。我们如何获得和存储像素值可能根据我们的需要而有所不同,但最终计算机世界里面的所有图像都可能被简化为数字矩阵和描述矩阵本身的其他信息。

1.2 Mat的使用

关于Mat类我们首先要知道:

  1. 不必在手动为其开辟空间
  2. 不必在不需要时立即将空间释放

大多数OpenCV函数会自动分配其输出数据所需的空间。如果你传递一个已经存在的Mat对象,它已经为矩阵分配了所需的空间,这将被重复使用。换句话说,我们在任何时候都只使用执行任务所需的内存。
Mat基本上是一个有两个数据部分的类:矩阵头(包含信息,如矩阵的大小,用于存储的方法,矩阵存储在哪个地址,等等)和一个指向包含像素值的矩阵的指针(根据选择的存储方法,采取任何尺寸)。矩阵头的大小是恒定的,但是矩阵本身的大小可能因图像的不同而不同,而且通常要大几个数量级。
为了解决这个问题,OpenCV使用了一个参考计数系统。这个想法是,每个Mat对象都有自己的头,然而一个矩阵可以在两个Mat对象之间共享,只要它们的矩阵指针指向同一个地址。此外,复制操作者将只复制头和指向大矩阵的指针,而不是数据本身。

问题:如果矩阵属于多个Mat对象,那么不再需要它时,谁来负责清理呢?
最后一个使用过它的对象。通过引用计数器机制来实现。我们无论什么时候复制一个Mat对象的信息头,都会增加矩阵的引用次数。反之,当一个头被释放之后,这个计数被减一;当计数值为0,矩阵就会被清理。
但某些时候你想复制矩阵本身,这个时候可以用clone()或者copyTo()函数

1.3 像素值的存储方法

  • RGB颜色空是最常用的 颜色空间这归功于它也是人眼内部构成颜色的方式它的基色是红色、
    绿色和蓝色有时为了表示透明颜色也会加入第四个元素 alpha(A)。
  • HSV和HLS把颜色分解成色调、饱和度和亮度。这是描述颜色更自然的方式,比如可以通过抛弃最后一个元素,使算法对输入图像的光照条件不敏感。
  • YCrCb在JPEG图像格式中广泛使用
  • COE Lab*是一种在感知上均匀的颜色空间,它适用来度量两个颜色之间的距离。

1.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型,每个像素由三个像素组成三通道。而预先定义的通道数可以多达四个。另外,Scalar是个short型的向量,能使用指定的定制化值来初始化矩阵,它还可以用于表示颜色。

  1. 使用C/C++数组并通过构造函数进行初始化
    int sz[3] = {2,2,2};
    Mat L(3,sz, CV_8UC(1), Scalar::all(0));

上面的例子演示了如何创建一个超过两维的矩阵: 指定维度,然后传递一个指向一个数组的指针,一个数组包含每个维度的尺寸。

  1. 利用create()函数
	Mat M;
	M.create(4, 4, CV_8UC(2));
	cout << "M=" << endl<< M << endl;

在这里插入图片描述
该创建方法不能为矩阵设初值,只是在改变尺寸时重新为矩阵数据开辟内存而已。

  1. 采用Matlab式的初始化方法
	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;

在这里插入图片描述

2.常用的数据结构和函数

2.1 点的表示:Point类

Point类数据结构表示了二维坐标系下的点,即由其图像坐标x和y指定的2D点。

	Point point;
	point.x=10;
	point.y=8
	//或者
	Point point=Point(10,8);

OpenCV中有如下定义:

typedef Point_<int> Point2i;
typedef Point2i Point;
typedef Point_<float> Point2f;

所以,Point<int>、 Point2i、Point 互相等价 Point_<float>、Point2f 互相等价。

2.3 颜色的表示:Scalar类

Scalar()表示具有四个元素的数组,在OpenCV中被大量用于传递像素值,如RGB颜色值。而RGB颜色值为三个参数,其实对于Scalar函数来说,如果用不到第四个参数,则可以不用写出来;若只写三个参数,OpenCV会认为我们就像表示三个参数。

如果给出Scalar(a,b,c)
那么定义的RGB颜色值:红色分量为c,绿色分量为b,蓝色分量为a。

2.4 尺寸的表示:Size类

Size(width,heigth)
Size(5,5)
构造出Size宽度和高度都为5
即XXX.width=5,XXX.height=5

2.5 矩形的表示:Rect类

Rect类的成员变量有x、y、width、height,分别为左上角的坐标和矩形的宽和高。

常用的成员函数有:
Size()返回值为Size;
area(),返回矩形的面积;
contains(Point)判断点是否在矩形;
inside(Rect)函数判断矩形是否在矩形内
tl()返回左上角的点坐标
br()返回右下角的点坐标
求两个矩形的交集:Rect rect = rect1 & rect2;
求两个矩形的并集:Rect rect = rect1 | rect2;
平移操作:Rect rectShift = rect + point;
缩放操作:Rect rectSccale = rect + size;

2.5 颜色空间转换:cvtColor()函数

cvtColor()函数是OpenCV里的颜色空间转换函数,可以实现RGB颜色向HSV、HSI等颜色空间的转换,也可以转换为灰度图。
void cvtColor(InputArray src, OutputArray dst,int code, int dstCn=0)

  • 第一个参数:输入图像
  • 第二个参数:输出图像
  • 第三个参数:颜色空间转换的标识符
  • 第四个参数:目标图像的通道数,若该参数为0,表示目标图像取源图像的通道数。
    例如:cvtColor(srcImage,dstImage,COLOR_GRAY2BGR)
    在这里插入图片描述

3.基础图形的绘制

  • 用于绘制直线的line函数
  • 用于绘制椭圆的ellipse函数
  • 用于绘制矩形的rectangle函数
  • 用于绘制圆的circle函数
  • 用于绘制填充的多边形的fillPoly函数
    定义几个自定义的绘制函数,然后调用这些自定义函数绘制yi一幅图:化学原子图。

程序的宏定义
#define WINDOW_WIDTH 600 //定义窗口大小

3.1 DrawEllipse()函数的写法

//自定义绘制函数:实现了绘制不同角度、相同尺寸的椭圆
void DrawEllipse(Mat img, double angle) {
	int thickness = 2;
	int lineType = 8;
	ellipse(img,
		Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2),
		Size(WINDOW_WIDTH/4,WINDOW_WIDTH/16),
		angle,
		0,
		360,
		Scalar(255,129,0),
		thickness,
		lineType
		);
}

ellipse函数的参数及其含义:
在这里插入图片描述

3.2 DrawFilledCircle()函数的写法

//自定义的绘制函数,实现了实心圆的绘制
void DrawFilledCircle(Mat img, Point center) {
	int thickness = -1;
	int lineType = 8;

	circle(img,
		center,
		WINDOW_WIDTH / 32,
		Scalar(0, 0, 255),
		thickness,
		lineType
	);
}

在这里插入图片描述

3.3 main()函数

#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define WINDOW_WIDTH 600
#define WINDOW_NAME "绘制图"
int main() {
	Mat atomImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);

	//1.1:绘制椭圆
	DrawEllipse(atomImage, 90);
	DrawEllipse(atomImage, 0);
	DrawEllipse(atomImage, 45);
	DrawEllipse(atomImage, -45);

	//1.2:绘制圆心
	DrawFilledCircle(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2));

	imshow(WINDOW_NAME, atomImage);
	
	waitKey(0);
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/646336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不可错过的Markdown编辑利器:跟随Typora,书写卓越

在现代社会中&#xff0c;快速而优雅地处理文本已经成为许多人的必备技能。尤其是对于程序员、研究者和专业撰稿人来说&#xff0c;拥有一款功能强大且易上手的文本编辑器显得尤为重要。Typora正是这样一款受到广泛好评的Markdown编辑器&#xff0c;它以简洁的界面、丰富的功能…

《实战AI低代码》AI大模型在低代码开发项目管理中的实战经验总结

目录 一、WBS任务分解 二、知识库自动生成 三、实施风险预估 随着ChatGPT大火之后,新的AI技术和模型被证明已经具备的很高的使用价值。 诸如Copilot、Midjourney、notion等产品通过AI的加持,已经让用户能够充分地在应用层面感受到了便利性。 原本几天的工作通过AI模型,可…

Web实验三 CSS基本网页布局实验

实验原理 通过定义css样式&#xff0c;理解css属性以及页面真整体结构布局的方法及设计思想。 实验目的 理解并掌握多种css选择器的使用方法 理解并掌握后代选择器的作用及使用设计方法 理解并掌握伪类的作用、意义及使用方法 理解并掌握基于div容器页面布局的方法 理解并掌握…

TANL:STRUCTURED PREDICTION AS TRANSLATION BETWEEN AUGMENTED NATURAL LANGUAGES

原文链接&#xff1a;https://openreview.net/pdf?idUS-TP-xnXI ICLR 2021 介绍 问题 大多数解决结构性预测的方法都是在预训练模型上对特定的任务进行训练&#xff0c;存在两个局限性&#xff1a; 1&#xff09;判别分类器不能很好地利用预训练模型中对于该任务标签的已知知…

这个事实已冲击并颠覆我的认知:时间不多了

我们都知道人生短暂&#xff0c;可到底是怎么个短法&#xff1f; 十年是个模糊的表述&#xff0c;我们很难在脑海里想象十年是什么概念&#xff0c;但如果换成十个冬天&#xff0c;跟父母在一起十天&#xff0c;这样描述就会更直观些。 WaitButWhy对人生的时间进行了拆解&#…

Cesium教程(十九):Cesium粒子系统

Cesium教程(十九):Cesium粒子系统 1、粒子系统 1.1 什么是粒子系统 Cesium粒子系统是一种模拟复杂物理效应的图形技术,是由小图像组成的集合,当他们在一起形成更复杂的“模糊”对象时,会形成火、烟、云或烟火等。 1.2 初始粒子系统 效果预览 完整代码 <!DOCTYPE htm…

day05--java高级编程:Junit单元测试框架、泛型,集合:集合数组互转,迭代器,增强for循环,集合工具类,数据结构简介

补充&#xff1a;Junit单元测试框架 1. 简介 概述&#xff1a; JUnit是使用Java语言实现的单元测试框架&#xff0c;它是开源的&#xff0c;Java开发者都应当学习并使用JUnit编写单元测试。此外&#xff0c;几乎所有的IDE工具都集成了JUnit&#xff0c;这样我们就可以直接在…

CoreDX DDS应用开发指南(9)服务质量QoS

12 服务质量QoS DDS的强大功能之一是支持各种服务质量(QoS)设置。QoS设置允许应用程序开发人员定制发布者、订阅者的行为以及它们之间的通信。 从DomainParticipantFactory到DataReader和DataWriter,大多数DDS实体都有一组适用的QoS设置。QoS设置包含在一个结构中。 例如,D…

【Flutter】Flutter 如何获取当前路由

文章目录 一、前言二、Flutter 路由基础知识1. 什么是路由2. Flutter 中的路由管理 三、如何在 Flutter 中获取当前路由1. 使用 NavigatorState 类2. 使用 ModalRoute 类 四、代码示例1. 一个简单的获取当前路由的例子2. 实际业务场景中获取当前路由的例子 五、完整可运行的代码…

什么才是好的测试用例?

对于测试用例来讲&#xff0c;“好的”测试用例一定是一个完备的集合&#xff0c;能够覆盖所有的等价类以及各种边界值&#xff0c;而跟能否发现缺陷无关。 如果把测试软件看做一个池塘&#xff0c;软件缺陷是池塘中的鱼&#xff0c;建立测试用例集的过程就像是在编织一张捕鱼…

新能源驱动电机NVH开发研究

摘要&#xff1a; 本文介绍了新能源驱动电机行业发展现状&#xff0c;详细论述了目前行业内主流电机&#xff1a; 1、驱动电机现状 驱动电机是新能源车辆和混合动力车辆的核心动力源&#xff0c;基于电磁感应效应&#xff0c;驱动电机将整车提供的电能转化为机械能&#xff0c…

一文3000字从0到1用【 pytest+excel】实现自动化接口测试

项目结构 1.common 存放公用方法 login.py 前置条件类public.py 获取文件指定目录类 复制代码 2. base 存放底层方法类 method.py复制代码 3. data 存放数据 data.xls 复制代码 4. tests 存放用例类 pytest test_excel.py5. utils存放工具类operationExcel.py 复制代码 代…

谷歌高级语法有哪些,以及如何开发国外客户

谷歌高级语法指令常用的有下面几个&#xff1a; site、inurl、intitle、intext、filetype、link、index of、related 谷歌高级语法用法&#xff1a; 1.Site的三种常用用法 示例&#xff1a;site域名&#xff08;site:org&#xff09; site域名contact(site:org contact) 产…

HarmonyOS元服务端云一体化开发快速入门(上)

一、前提条件 您已使用已实名认证的华为开发者帐号登录DevEco Studio。 请确保您的华为开发者帐号余额充足&#xff0c;账户欠费将导致云存储服务开通失败。 二、选择云开发模板 1.选择以下任一种方式&#xff0c;打开工程创建向导界面。 如果当前未打开任何工程&#xff0c…

【宿舍管理系统】注册登录页面的实现(前端)

目录 一.创建一个jsp文件&#xff0c;命名为login.jsp 代码&#xff1a; 1. 2. 3. 4. 5. 6. ​编辑 二. 创建一个css文件&#xff0c;并命名为style.css 1. ​编辑效果如下&#xff1a; ​编辑 代码解析&#xff1a; 2. 效果如下&#xff1a; 代码解析&#xff1…

如何做好《关键信息基础设施安全保护要求》提到的收敛暴露面?

5月1日&#xff0c;《信息安全技术 关键信息基础设施安全保护要求》&#xff08;GB/T 39204-2022&#xff09;国家标准正式实施。该标准作为关键信息基础设施安全保护标准体系的构建基础&#xff0c;提出了关键信息基础设施安全保护的三项基本原则&#xff0c;为运营者开展关键…

华为OD机试真题 JavaScript 实现【最左侧冗余覆盖子串】【2023Q2 100分】

一、题目描述 给定两个字符串 s1 和 s2 和正整数k&#xff0c;其中 s1 长度为 n1&#xff0c;s2 长度为 n2&#xff0c; 在s2中选一个子串&#xff0c;满足: 该子串长度为n1k&#xff1b;该子串中包含s1中全部字母&#xff1b;该子串每个字母出现次数不小于s1中对应的字母&am…

2023年,现在学Python还吃香吗?计算机专业怎么样?

自从ChatGPT诞生以来&#xff0c;各大科技公司纷纷推出了自己的AI产品&#xff0c;在这个赛道上卷生卷死&#xff0c;纷纷布局。 从Google的Bard AI、OpenAI出走团队的Claude&#xff0c;到中国的众多公司&#xff0c;如百度的文心一言。 总的来说&#xff0c;AI的应用领域日…

Java培训周期一般多长?Java培训班过来人告诉你!

市场上比较靠谱的java培训机构的培训时间一般都是5-6个月&#xff0c;好程序员是4个月&#xff0c;个别培训机构可能因为班型不同而有所区别。学的时间太短学到的知识可能会有遗漏&#xff0c;造成基础不扎实;学习时间太长也会过于拖沓&#xff0c;还降低了整个培训的性价比。 …

qt creator使用问题

qt creator 多版本安装需要卸载之前的版本&#xff0c;安装目录默认在Qt目录下&#xff08;qt的sdk也在qt目录下&#xff09; 编译过程中遇到一些很奇怪问题&#xff0c;建议优先重新编译。 issue qtcreator inappropriate for the inferior 构建套件&#xff0c;前面的感…