热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

独家|OpenCV1.1Mat基本图像容器(附链接)

翻译:陈之炎校对:吴振东、林夕本文约3600字,建议阅读10分钟本文为大家系统地介绍了OpenCV官方教程。写在前边让读者朋友们较为系统

翻译:陈之炎
校对:吴振东、林夕本文约3600字,建议阅读10分钟本文为大家系统地介绍了OpenCV官方教程。

写在前边

让读者朋友们较为系统地了解和学习OpenCV官方教程,数据派THU翻译组联合研究部共同推出OpenCV官方教程翻译系列。由于所列章节较多,教程将被分为多篇文章持续更新发布。

原文链接:https://docs.opencv.org/4.5.2/de/d7a/tutorial_table_of_content_core.html

目标

我们可以通过多种方式从现实世界中获取数字图像,比如:数码相机、扫描仪、计算机扫描和磁共振成像等等。在这些情况中,虽然我们肉眼看到的是图像,但是当需要将图像在数字设备中变换传输时,图像的每个像素则对应一个数值。

例如,上述图像你可以看到一个汽车的后视镜,它可以用包含像素点强度值的矩阵来表示。虽然获取并存储像素点强度值的方法各不相同,但是图像在计算机中最终是以数值矩阵的形式来存储和处理的。OpenCV是一个计算机视觉库,主要用于处理和操作图像像素矩阵信息。因此,你首先需要熟悉OpenCV是如何存储和处理图像的。

Mat

OpenCV诞生于2001年。当时的库均是C语言接口创建,图像以C 语言的数据结构IplImage形式存储。在以往的教程和培训材料中均可以看到这一点,而这同时也反映出了C语言的优缺点。最大的挑战来自于手动的内存管理,它假设由用户来负责内存的分配和释放。对于代码量比较小的程序,手动分配内存没有问题。但是当代码量剧增时,处理起来的难度会急速增大。

幸运的是,C ++引入了类的概念,使得用户更容易实现自动内存管理。同时,C ++与C完全兼容,所以不存在兼容性问题,这也使代码迁移更加容易。OpenCV 2.0引入了一种新的C++接口,无需考虑内存管理问题,使得代码更加简洁,即利用更少的代码量,能够实现更多的功能。C ++接口的主要缺点是:目前许多嵌入式开发系统只支持C。因此,除非是针对嵌入式平台,否则没有必要使用的以往的老方法(除非你是受虐狂程序员,在自找麻烦)。

在使用Mat 时,需要知道的第一件事情是:无需手动分配内存。对于不再使用的内存,无需进行释放。大多数OpenCV函数会自动分配其输出数据。更为便捷的是,如果需要传递Mat 对象,则已经给它分配好了内存空间,可以被重用。换句话说,在任何时候都只用到执行任务所需要的内存,而无需进行额外的操作。

Mat基础类包含两部分数据:矩阵头(包括矩阵大小,存储方法,矩阵存储地址等信息)和指向一个矩阵的指针,这个矩阵包含了像素值信息(根据所选定的不同存储方法而有不同的维度)。矩阵头大小是一个常量,不同大小的图像的矩阵大小各不相同,通常矩阵大小要比图像大小大几个数量级。

OpenCV是一个图像处理库,其中包含大量图像处理函数。为了解决计算难题,多数情况下选用库中的多个函数来实现计算功能,常见的做法是将图像传递给函数。而图像处理算法的计算量往往非常大,所以要通过避免不必要的图像复制来进一步提升程序的运行速度。

为了解决上述问题, OpenCV采用了一种引用计数系统。具体做法是,每个Mat 对象有其各自的头,两个Mat 对象可以通过将矩阵指针指向同一地址来共享一个矩阵,复制操作只复制Mat 头和指向矩阵的指针,而不是复制数据本身。

上述所有的对象均指向同一个数据矩阵,对矩阵的任何变动均会影响所有的对象。在实际示例中,不同的对象只是对同一数据的不同的访问方式,尽管如此,不同MAT 对象的头各不相同。真正有趣的是,可以创建仅指向部分数据分段的MAT 对象头。例如,为了创建一个图像的感兴趣区域(ROI),你只需要创建一个具有行列边界的新MAT 对象头:

那么问题来了 - 如果像素矩阵可以属于多个MAT 对象, 那么当它不需要再次被使用时,由谁来负责清空?答案是:通过引用计数机制(reference counting mechanism)来实现,由最后一个使用它的对象来清空。每次拷贝MAT 对象头时,计数器便会加一;当对MAT 对象头进行清空时,此计数器会减一。当计数器的值为零时,矩阵会被释放。当需要对矩阵自身进行复制时, OpenCV提供cv::Mat::clone() 和cv::Mat::copyTo() 函数。

修改F或者G不会影响A所指向的矩阵,需要记住以下几点:

  • Opencv函数,输出图像分配时是自动的(除非另行规定);

  • 无需考虑OpenCV中C ++接口的内存管理;

  • 赋值操作符和拷贝构造函数仅复制MAT 对象头;

  • 图像的基本矩阵可以利用cv::Mat::clone() 和cv::Mat::copyTo()两个函数进行复制。

存储方法

本小节的内容是关于如何存储像素值的。你可以选择色彩空间和使用的数据类型。色彩空间是指为给定的颜色编码的色彩分量组合,最简单的色彩空间是灰度,它的颜色空间只有黑色和白色,这两种颜色可以组合出多种灰度。

为了使图像色彩更加丰富,色彩空间可以有更多的选择。每个色彩空间均可将其分解为三到四个基本颜色,利用这三到四个基本颜色的组合来生成其它颜色。主流的色彩空间是RGB,人类的眼睛正是利用RGB构建出多种色彩。其基本的颜色是红色、绿色和蓝色,为了对透明度进行编码,添加了第四个元素:α(A)。

除了RGB外,还有多种其它的色彩空间,它们各有优势:

  • RGB是与人眼类似的最为常见的色彩空间,但需要切记的是:OpenCV标准显示系统使用的色彩空间是BGR(互换了红色和蓝色通道);

  • HSV和HLS将色彩分解为色调、饱和度和亮度分量,利用这些分量,可以更加自然地对色彩进行描述。例如,去除最后一个分量之后,算法便对输入图像的光照条件不太敏感了;

  • JPEG图像格式使用的是YCrCb色彩空间;

  •  CIE L * A * B *是一个感知均匀的色彩空间,可以用它来测量给定的颜色到另一种颜色之间的距离。

在OpenCV中,每个组件都有其各自的有效域,即采用何种数据类型。组件的存储方式定义了对其有效域的控制方式。最小的数据类型是char,即一个字节或8比特位,char可以是无符号的(值从0到255)或带符号的(值从-127到+127)。在三元组色彩空间(如RGB 色彩空间),可以表示出1600万种颜色。此外,还可以通过使用float数据类型(4字节= 32比特位)或double数据类型(8字节= 64比特位),对色彩实现更为精细的控制和表达。但是,增加组件数据类型长度的同时也会增加整个图片占用的内存大小。

创建Mat对象

在调用、修改和保存图像教程中&#xff0c;你已经学会了如何利用cv::imwrite()函数 将矩阵写入图像文件之中。然而&#xff0c;出于调试的目的&#xff0c;为了更加方便地看到矩阵的实际值&#xff0c;可以直接使用<<运算符。注意&#xff0c;这仅适用于二维矩阵。

Mat作为一个图像容器非常不错&#xff0c;但是它也是一个通用矩阵类。所以&#xff0c;可以是一个通用矩阵类。为此&#xff0c;它还可以创建和操作多维矩阵。你可以用多种方式来创建Mat对象&#xff1a;

cv::Mat::Mat 构造器

对于二维和多通道图像&#xff0c;首先定义出大小&#xff1a;按行和列计数。

然后指定用于存储元素的数据类型和每个矩阵点的通道数。按照以下约定&#xff0c;构造出多个定义&#xff1a;

例如&#xff0c;CV_8UC3是指&#xff1a;使用的是8位长的unsigned char数据类型&#xff0c;每个像素具有三个通道&#xff0c;可以预定义多达四个通道。cv::Scalar是一个包含四个元素的短矢量。可以通过指定cv::Scalar&#xff0c;将所有的矩阵点初始化为自定义的值。如果需要创建更多的图像矩阵&#xff0c;还可以利用宏来创建&#xff0c;按照下述方式&#xff0c;设置括号中的通道数目&#xff1a;

构造C / C &#43;&#43;数组&#xff0c;并对其进行初始化

上述例子说明了如何创建一个维数大于2维的矩阵。首先指定其维数大小&#xff0c;然后传递一个包含每个维度大小的指针&#xff0c;其余部分保持不变。

不能用这种结构初始化矩阵值&#xff0c;如果新的矩阵大小与先前的矩阵大小不一致&#xff0c;会对矩阵数据的存储重新进行分配。

MATLAB风格初始化&#xff1a;cv::Mat::zeros , cv::Mat::ones , cv::Mat::eye 。指定矩阵大小和数据类型&#xff1a;


对于比较小的矩阵&#xff0c;可以使用逗号分隔初始化值或初始化值列表&#xff08;支持C&#43;&#43; 11&#xff09;&#xff1a;

为现有的Mat对象创建一个新的Mat对象头&#xff1a;cv::Mat::clone or cv::Mat::copyTo。

可以利用CV :: RANDU&#xff08;&#xff09;函数&#xff0c;为矩阵写入随机值&#xff0c;此时需要给定随机值的下限和上限&#xff1a;

输出格式化

在上面的例子中&#xff0c;可以看到默认的格式设置选项。OpenCV允许对矩阵输出进行格式化&#xff1a;

默认

Python 

逗号分隔值 (CSV)

NumPy

C

其他常见的输出

OpenCV中提供了通过<<操作输出常见的OpenCV数据结构&#xff1a;

二维Point

三维Point

 cv::Mat的std::vector

std::vector Point

小型控制台应用程序中均包含了这里的大多数示例。可以从这里下载或在CPP示例程序中找到它们。你还可以到YouTube网站看相应的视频演示。

YouTube网站

https:/www.youtube.com/watch%3fv&#61;1tibU7vGWpk%22

编辑&#xff1a;王菁

校对&#xff1a;林亦霖

下一小节: 1.2 如何扫描图像、查找表和用OpenCV进行时间测量

译者简介

陈之炎&#xff0c;北京交通大学通信与控制工程专业毕业&#xff0c;获得工学硕士学位&#xff0c;历任长城计算机软件与系统公司工程师&#xff0c;大唐微电子公司工程师&#xff0c;现任北京吾译超群科技有限公司技术支持。目前从事智能化翻译教学系统的运营和维护&#xff0c;在人工智能深度学习和自然语言处理&#xff08;NLP&#xff09;方面积累有一定的经验。业余时间喜爱翻译创作&#xff0c;翻译作品主要有&#xff1a;IEC-ISO 7816、伊拉克石油工程项目、新财税主义宣言等等&#xff0c;其中中译英作品“新财税主义宣言”在GLOBAL TIMES正式发表。能够利用业余时间加入到THU 数据派平台的翻译志愿者小组&#xff0c;希望能和大家一起交流分享&#xff0c;共同进步

翻译组招募信息

工作内容&#xff1a;需要一颗细致的心&#xff0c;将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生&#xff0c;或在海外从事相关工作&#xff0c;或对自己外语水平有信心的朋友欢迎加入翻译小组。

你能得到&#xff1a;定期的翻译培训提高志愿者的翻译水平&#xff0c;提高对于数据科学前沿的认知&#xff0c;海外的朋友可以和国内技术应用发展保持联系&#xff0c;THU数据派产学研的背景为志愿者带来好的发展机遇。

其他福利&#xff1a;来自于名企的数据科学工作者&#xff0c;北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。

点击文末“阅读原文”加入数据派团队~

转载须知

如需转载&#xff0c;请在开篇显著位置注明作者和出处&#xff08;转自&#xff1a;数据派ID&#xff1a;DatapiTHU&#xff09;&#xff0c;并在文章结尾放置数据派醒目二维码。有原创标识文章&#xff0c;请发送【文章名称-待授权公众号名称及ID】至联系邮箱&#xff0c;申请白名单授权并按要求编辑。

发布后请将链接反馈至联系邮箱&#xff08;见下方&#xff09;。未经许可的转载以及改编者&#xff0c;我们将依法追究其法律责任。

点击“阅读原文”拥抱组织



推荐阅读
  • window下的python安装插件,Go语言社区,Golang程序员人脉社 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 结城浩(1963年7月出生),日本资深程序员和技术作家,居住在东京武藏野市。他开发了著名的YukiWiki软件,并在杂志上发表了大量程序入门文章和技术翻译作品。结城浩著有30多本关于编程和数学的书籍,其中许多被翻译成英文和韩文。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 利用REM实现移动端布局的高效适配技巧
    在移动设备上实现高效布局适配时,使用rem单位已成为一种流行且有效的技术。本文将分享过去一年中使用rem进行布局适配的经验和心得。rem作为一种相对单位,能够根据根元素的字体大小动态调整,从而确保不同屏幕尺寸下的布局一致性。通过合理设置根元素的字体大小,开发者可以轻松实现响应式设计,提高用户体验。此外,文章还将探讨一些常见的问题和解决方案,帮助开发者更好地掌握这一技术。 ... [详细]
  • 深入解析监督学习的核心概念与应用
    本文深入探讨了监督学习的基本原理及其广泛应用。监督学习作为机器学习的重要分支,通过利用带有标签的训练数据,能够有效构建预测模型。文章详细解析了监督学习的关键概念,如特征选择、模型评估和过拟合问题,并介绍了其在图像识别、自然语言处理等领域的实际应用。 ... [详细]
  • 利用Anaconda高效管理多版本Python环境
    通过Anaconda,可以高效地管理和切换不同版本的Python环境,为开发人员提供便捷的工具支持。此外,Anaconda还集成了丰富的科学计算和数据分析库,进一步提升了开发效率。对于Golang开发者而言,Anaconda同样是一个值得了解的工具,尽管其主要应用于Python生态。 ... [详细]
  • 如何精通编程语言:全面指南与实用技巧
    如何精通编程语言:全面指南与实用技巧 ... [详细]
  • 【图像分类实战】利用DenseNet在PyTorch中实现秃头识别
    本文详细介绍了如何使用DenseNet模型在PyTorch框架下实现秃头识别。首先,文章概述了项目所需的库和全局参数设置。接着,对图像进行预处理并读取数据集。随后,构建并配置DenseNet模型,设置训练和验证流程。最后,通过测试阶段验证模型性能,并提供了完整的代码实现。本文不仅涵盖了技术细节,还提供了实用的操作指南,适合初学者和有经验的研究人员参考。 ... [详细]
  • Python与R语言在功能和应用场景上各有优势。尽管R语言在统计分析和数据可视化方面具有更强的专业性,但Python作为一种通用编程语言,适用于更广泛的领域,包括Web开发、自动化脚本和机器学习等。对于初学者而言,Python的学习曲线更为平缓,上手更加容易。此外,Python拥有庞大的社区支持和丰富的第三方库,使其在实际应用中更具灵活性和扩展性。 ... [详细]
  • MATLAB实现Sobel边缘检测算法
    图像边缘是指图像中灰度值发生显著变化的区域。Sobel算子是一种常用的边缘检测方法,通过计算图像灰度值的梯度来检测边缘。本文介绍了Sobel算子的基本原理,并提供了基于MATLAB的实现代码。 ... [详细]
  • 本文详细介绍了如何使用Python中的smtplib库来发送带有附件的邮件,并提供了完整的代码示例。作者:多测师_王sir,时间:2020年5月20日 17:24,微信:15367499889,公司:上海多测师信息有限公司。 ... [详细]
  • 检查在所有可能的“?”替换中,给定的二进制字符串中是否出现子字符串“10”带 1 或 0 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
author-avatar
gloriamm_520
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有