opencv2.4.8参考手册(一) 简介
简介 Opencv (Open Source Computer Vision Library: http://opencv.org)是一个包含几千个计算机视觉算法的开源库,本文档讲述的是所谓的OpenCV 2.X 接口,与基于C语言的OpenCV 1.X接口不同,这是一个基于C的编程接口。 opencv是库组织结构,也就是说Opencv
简介
Opencv (Open Source Computer Vision Library: http://opencv.org)是一个包含几千个计算机视觉算法的开源库,本文档讲述的是所谓的OpenCV 2.X 接口,与基于C语言的OpenCV 1.X接口不同,这是一个基于C++的编程接口。
opencv是库组织结构,也就是说Opencv包含一些共享或者静态的库。可用的库如下 :
core - 一个定义最基本数据结构的库,包括密集的多维矩阵Mat,和一些被其他库用到的基本函数
imgproc - 图像处理库,包含线性非线性的图像滤波,图像几何变换(调整尺寸,仿射变换,透视变换,基本的基于表格的重映射),颜色空间转换,直方图等
video - 视频分析库,包括运动估计,背景差值,和物体追踪算法
calib3d - 基本的多视角几何算法,单摄像机和立体摄像机的标定,物体姿态估测,立体匹配算法和元素的三维重建。
features2d - 特征探测子,描述子,以及描述子匹配
objdetect - 对于预定义类的实例或对象的检测(如人脸,眼睛,mugs,人,汽车等)
highgui - 简单易用的视频捕捉接口,图像'视频的编解码器,以及简单的UI函数
gpu - 不同opencv库中基于GPU加速的算法
... - 其他一些帮助库,如FLANN 和Google test wrappers,python绑定等
在后续的章节中会描述各个模块的函数功能,但是一开始你应该熟悉贯穿整个库中最基本的API概念。
1.1 API 概念
cv 命名空间
所有的opencv类和函数是被放置在cv命名空间的,所以为了在你的程序中使用它们,需要用cv::来指明或者直接这样using namespace cv;
#include "opencv2/core/core.hpp" ...
cv::Mat H = cv::findHomography(points1, points2, CV_RANSAC, 5); ... 或者
#include "opencv2/core/core.hpp" using namespace cv; ... Mat H = findHomography(points1, points2, CV_RANSAC, 5); ...
Mat a(100, 100, CV_32F); randu(a, Scalar::all(1), Scalar::all(std::rand())); cv::log(a, a); a /= std::log(2.);
opencv自动处理所有的内存。
首先,std::vector,Mat,和其他被函数或方法用到的数据结构会有在必要时释放相关内存的析构函数,析构函数并不总去释放内存,拿Mat来举例子,考虑到可能的数据共享,析构函数会递减矩阵数据缓冲区的引用计数器,而只有在引用计数器为0时,也就是没有其他的结构指向该缓冲区,缓冲区才会被释放,类似地,当一个Mat实例被复制,实际数据并没有真正被拷贝,相反,缓冲区的引用计数器递增来表明这个缓冲区被另一个拥有者所分享。当然也有Mat::clone方法是创建矩阵数据的整个拷贝,见下面的例子:
// create a big 8Mb matrix Mat A(1000, 1000, CV_64F); // create another header for the same matrix; // this is an instant operation, regardless of the matrix size. Mat B = A; // create another header for the 3-rd row of A; no data is copied either Mat C = B.row(3); // now create a separate copy of the matrix Mat D = B.clone(); // copy the 5-th row of B to C, that is, copy the 5-th row of A // to the 3-rd row of A. B.row(5).copyTo(C); // now let A and D share the data; after that the modified version // of A is still referenced by B and C. A = D; // now make B an empty matrix (which references no memory buffers), // but the modified version of A will still be referenced by C, // despite that C is just a single row of the original A B.release(); // finally, make a full copy of C. As a result, the big modified // matrix will be deallocated, since it is not referenced by anyone C = C.clone();
T* ptr = new T(...); you can use: Ptr<t> ptr = new T(...);</t>
输出数据的自动内存分配
opencv自动释放内存,同样大部分时候也为输出函数的参数自动分配内存,所以如果一个函数有一个或多个输入数组(cv::Mat 实例)和一些输出数组,输出数组会被自动分配或重分配内存。输出数组的大小和类型由输入数组决定。如果需要,函数还会接受额外参数来表明输出数组的属性
例子:
#include "cv.h" #include "highgui.h" using namespace cv; int main(int, char**) { VideoCapture cap(0); if(!cap.isOpened()) return -1; Mat frame, edges; namedWindow("edges",1); for(;;) { cap >> frame; cvtColor(frame, edges, CV_BGR2GRAY); GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5); Canny(edges, edges, 0, 30, 3); imshow("edges", edges); if(waitKey(30) >= 0) break; } return 0; }
这个技术的关键组件就是Mat::create方法,它接受期望的大小和类型,如果数组已经有特定的大小和类型,那么该方法什么也不做,否则它就会释放先前的分配的数据(递减引用计数器并与0比较),然后申请分配一块新的指定大小的事缓冲区。大部分函数都会为每一个输出数组调用Mat::create方法,这也是解释了输出数组的自动内存分配机制。
一些需要注意的特例就是cv::mixChannels, cv::RNG::fill和其他一些函数和方法,它们并不会为输出数组分配内存,所以你需要事先分配。
饱和算术
作为一个计算机视觉库,opencv经常要处理的图像像素点往往是紧凑的,8位或才16位每通道形式的数据,这样就要求限制数据的取值范围,进一步说,图像的特定操作(如颜色空间转换,亮度/对比度调整,锐化,复杂的内插(bi-cubic, Lanczos))会产生超出可接受的数据范围,如果你只能够存储结果的低8位抑或是16位,这会导致视觉缺陷或者更进一步影响到后续的分析处理,为了解决这个问题,所谓的饱和算术派上用场了,如,为了存储r(8位的图像数据),以下操作会让你在0~255内找到最接近真实值的值。
I(x; y) = min(max(round(r); 0); 255)
同样的规则也被用来处理有符号8位,有符号16位和无符号类型,这样的语义在库中随处可见,在C++语言中,用的是类标准C++中类型转换操作的saturate_cast,看下面对于 上面方程的实现:
I.at
cv::uchar是opencv中8位无符号类型,
固定的像素类型,限制使用模板
模板是c++中用来实现强大,高效并且安全数据结构和算法的伟大特征,但是过度的模板使用又会导致编译时间变长和代码量变大,此外,it is difficult to separate an interface and implementation when templates are used exclusively(??),当然这对基本的算法没什么问题,但是对于一个算法就拥有几千行代码的计算机视觉库来说,是不适用的,正因为如此,也因为简化与其他语言的绑定开发(像python,jave,matlab这些压根就没有模板的语言),当前的opencv是基于多态性的运行时动态绑定的实现,在这些动态绑定过慢(like pixel access operators),、不可能(generic Ptr implementation)或者压根就不方便(saturate_cast())的地方,opencv实现就介绍小的模板类、方法和函数,而opencv 的其他地方则限制了模板的使用。
因此,计算机视觉库可以操作的数据类型是一组有限的、固定的基本数据类型。那就是数组元素需要是以下类型:
? 8-bit unsigned integer (uchar)
? 8-bit signed integer (schar)
? 16-bit unsigned integer (ushort)
? 16-bit signed integer (short)
? 32-bit signed integer (int)
? 32-bit floating-point number (float)
? 64-bit floating-point number (double)
? 元组数据类型,元组里的元素的类型(以上一种)是一致的,图像数组就是元组的一种,被叫作多通道数组,以区分单通道数组。最大的可能通道数是用宏CV_CN_MAX定义的,当前版本设置为512
对于这此基本的类型,下面的枚举可以使用:
enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 };
多通道类型可以用下面选项来指定:
? CV_8UC1 ... CV_64FC4 常数(通道数据1-4)
? CV_8UC(n) ... CV_64FC(n) or CV_MAKETYPE(CV_8U, n) ... CV_MAKETYPE(CV_64F, n) 当通道数大于4或者编译时不可知即变量可用这些宏
注意:CV_32FC1 == CV_32F, CV_32FC2 == CV_32FC(2) == CV_MAKETYPE(CV_32F, 2), and
CV_MAKETYPE(depth, n) == ((x&7)
Mat mtx(3, 3, CV_32F); // make a 3x3 floating-point matrix Mat cmtx(10, 1, CV_64FC2); // make a 10x1 2-channel floating-point // matrix (10-element complex vector) Mat img(Size(1920, 1080), CV_8UC3); // make a 3-channel (color) image // of 1920 columns and 1080 rows. Mat grayscale(image.size(), CV_MAKETYPE(image.depth(), 1)); // make a 1-channel image of // the same size and same
更复杂元素的数组是不能被opencv构造或处理的,或者说,各个函数或方法只能处理上述数组类型的子集,一个算法越复杂,那么它所支持的类型子集就越小,看下面典型例子:
人脸检测算法只能处理8位的灰度图像或者彩色图像
线性代数函数和大部分机器学习算法只能处理浮点型数据
基本函数,如cv::add,支持所有类型
彩色空间转换函数支持8位无符号,16位无符号,和32位浮点类型。
各个函数的支持类型的子集根据实际应用而设定并且可以根据用户需求在以后来扩展
输入数组和输出数组
很多opencv函数能够处理2维或多维数值数组,通常,这些函数以cpp:class:Mat作为参数,但是在一些场合,用std::vector(如点集)或Matx(如3X3单应矩阵?)要更为方便一些,为了避免API的重复,特殊的“代理”类被引入,由InputArray派生的OutputArray是用来为函数指定一个输出数组。通常,你需要关心这些中间类型(但你不需要明确申明这些类型的变量):这些都是会自动完成任务的。你可以假设除了InputArray/OutputArray,你总可以用Mat, std::vector, Matx, Vec or Scalar。当一个函数有一个可选择的输入或者输出数组时,而你又不必或者不想定义该数组,你可以传入cv::noArray()。
错误处理
opencv利用异常来触发关键错误,当输入数据是正确的类型并且数据在指定范围内,但是算法由于某些原因没有成功,函数会返回特定的错误代码(通常,是一个布尔变量)
异常可以通过cv::Exception类来实例化,cv::Exception是由std::exception派生的,所以它很容易被标准C++库组件处理。
try { ... // call OpenCV } catch( cv::Exception& e ) { const char* err_msg = e.what(); std::cout <br> <br> <span>多线程和重入</span> <p>当前版本的OPENCV是完全支持重入的,也就是说,同样的函数,同样的类实例的常数方法,或者同样的不同类实例的非常数方法可以被不同的线程调用,当然,同样的cv::Mat也可以在不同的线程中调用,因为引用计数器的操作是基于架构的原子指令</p>

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

使用pip命令轻松安装OpenCV教程,需要具体代码示例OpenCV(OpenSourceComputerVisionLibrary)是一个开源的计算机视觉库,它包含了大量的计算机视觉算法和函数,可以帮助开发者快速构建图像和视频处理相关的应用程序。在使用OpenCV之前,我们需要先安装它。幸运的是,Python提供了一个强大的工具pip来管理第三方库

OpenCV是一种用于计算机视觉和图像处理的开源库,广泛应用于机器学习、图像识别、视频处理等领域。在使用OpenCV进行开发时,为了能够更好地调试和运行程序,很多开发者选择使用PyCharm这款强大的Python集成开发环境。本文将为PyCharm用户提供OpenCV的安装教程,并附上具体的代码示例。第一步:安装Python首先,确保您已经安装了Python

JavaOpenCV库的org.opencv.imgproc包包含一个名为Imgproc的类,该类提供了各种方法来处理输入图像。它提供了一组在图像上绘制几何形状的方法。要绘制一个带箭头的线条,您需要调用这个类的arrowedLine()方法。该方法接受以下参数:表示要在其上绘制线条的图像的Mat对象。表示线条之间的两个点的Point对象。drawn.表示线条颜色的Scalar对象。(BGR)表示线条厚度的整数(默认值:1)。示例importorg.opencv.core.Core;importo

对象关系映射(ORM)框架在python开发中扮演着至关重要的角色,它们通过在对象和关系数据库之间建立桥梁,简化了数据访问和管理。为了评估不同ORM框架的性能,本文将针对以下流行框架进行基准测试:sqlAlchemyPeeweeDjangoORMPonyORMTortoiseORM测试方法基准测试使用了一个包含100万条记录的SQLite数据库。测试对数据库执行了以下操作:插入:向表中插入10,000条新记录读取:读取表中的所有记录更新:更新表中所有记录的单个字段删除:删除表中的所有记录每个操作

PyCharm是一款由JetBrains公司开发的强大的Python集成开发环境(IDE),提供了丰富的功能和工具来帮助Python开发者编写代码、调试程序以及管理项目。在PyCharm中使用OpenCV这一强大的计算机视觉库,可以轻松地进行图像处理、视频处理等任务。本文将详细介绍在PyCharm中安装和配置OpenCV的步骤,并提供具体的代码示例。1.安

对象关系映射(ORM)是一种编程技术,允许开发人员使用对象编程语言来操作数据库,而无需直接编写sql查询。python中的ORM工具(例如SQLAlchemy、Peewee和DjangoORM)简化了大数据项目的数据库交互。优点代码简洁性:ORM消除了编写冗长的SQL查询的需要,这提高了代码简洁性和可读性。数据抽象:ORM提供了一个抽象层,将应用程序代码与数据库实现细节隔离开来,提高了灵活性。性能优化:ORM通常会使用缓存和批量操作来优化数据库查询,从而提高性能。可移植性:ORM允许开发人员在不

了解Java设计模式:常用的7种设计模式简介,需要具体代码示例Java设计模式是一种解决软件设计问题的通用解决方案,它提供了一套被广泛接受的设计思想与行为准则。设计模式帮助我们更好地组织和规划代码结构,使得代码具有更好的可维护性、可读性和可扩展性。在本文中,我们将介绍Java中常用的7种设计模式,并提供相应的代码示例。单例模式(SingletonPatte

您可以使用Hough线变换在给定的图像中检测直线。在OpenCV中有两种可用的Hough线变换方法,分别是标准Hough线变换和概率Hough线变换。您可以使用Imgproc类的HoughLines()方法应用标准Hough线变换。该方法接受以下参数:表示源图像和存储线条参数(r,Φ)的向量的两个Mat对象。表示参数r(像素)和Φ(弧度)的分辨率的两个double变量。表示“检测”一条线所需的最小交点数的整数。您可以使用Imgproc类的HoughLinesP()
