OpenCV 4.2.0 - Introduction

OpenCV 4.2.0 - Introduction

OpenCV 4.2.0 - Modules
https://docs.opencv.org/4.2.0/

OpenCV 4.2.0 - Introduction
https://docs.opencv.org/4.2.0/d1/dfb/intro.html

OpenCV (Open Source Computer Vision Library: http://opencv.org) is an open-source BSD-licensed library that includes several hundreds of computer vision algorithms. The document describes the so-called OpenCV 2.x API, which is essentially a C++ API, as opposed to the C-based OpenCV 1.x API (C API is deprecated and not tested with C compiler since OpenCV 2.4 releases)
OpenCV (Open Source Computer Vision Library: http://opencv.org) 是一个开源的 BSD 许可库,其中包含数百种计算机视觉算法。该文档描述了所谓的 OpenCV 2.x API,与基于 C 的 OpenCV 1.x API 相比,它实际上是 C++ API (自 OpenCV 2.4 发行以来,C API 已被弃用,并且未经 C 编译器进行测试)。

OpenCV has a modular structure, which means that the package includes several shared or static libraries. The following modules are available:
OpenCV 具有模块化结构,这意味着该程序包包含多个共享库或静态库。提供以下模块:

  • Core functionality (core) - a compact module defining basic data structures, including the dense multi-dimensional array Mat and basic functions used by all other modules.
    定义基本数据结构的紧凑模块,包括密集的多维数组 Mat 和所有其他模块使用的基本功能。

  • Image Processing (imgproc) - an image processing module that includes linear and non-linear image filtering, geometrical image transformations (resize, affine and perspective warping, generic table-based remapping), color space conversion, histograms, and so on.
    一个图像处理模块,包括线性和非线性图像过滤,几何图像转换 (resize,仿射和透视变形,基于常规表的重新映射),色彩空间转换,直方图等。

  • Video Analysis (video) - a video analysis module that includes motion estimation, background subtraction, and object tracking algorithms.
    视频分析模块,包括运动估计,背景减法和对象跟踪算法。

  • Camera Calibration and 3D Reconstruction (calib3d) - basic multiple-view geometry algorithms, single and stereo camera calibration, object pose estimation, stereo correspondence algorithms, and elements of 3D reconstruction.
    基本的多视图几何算法,单摄像机和立体摄像机校准,对象姿态估计,立体对应算法以及 3D 重构元素。

  • 2D Features Framework (features2d) - salient feature detectors, descriptors, and descriptor matchers.
    显着特征检测器,描述符和描述符匹配器。

  • Object Detection (objdetect) - detection of objects and instances of the predefined classes (for example, faces, eyes, mugs, people, cars, and so on).
    检测对象和预定义类的实例 (例如,面孔,眼睛,杯子,人,汽车等)。

  • High-level GUI (highgui) - an easy-to-use interface to simple UI capabilities.
    简单易用的 UI 功能界面。

  • Video I/O (videoio) - an easy-to-use interface to video capturing and video codecs.
    用于视频捕获和视频编解码器的易于使用的界面。

… some other helper modules, such as FLANN and Google test wrappers, Python bindings, and others.
…其他一些帮助器模块,例如 FLANN 和 Google 测试包装器,Python 绑定等。

The further chapters of the document describe functionality of each module. But first, make sure to get familiar with the common API concepts used thoroughly in the library.
本文档的其他章节介绍了每个模块的功能。但是首先,请确保熟悉该库中彻底使用的通用 API 概念。

salient [ˈseɪliənt]:adj. 显著的,突出的,跳跃的 n. 凸角,突出部分
allocation [ˌæləˈkeɪʃn]:n. 分配,配置,安置

1. API Concepts

1.1 cv Namespace

All the OpenCV classes and functions are placed into the cv namespace. Therefore, to access this functionality from your code, use the cv:: specifier or using namespace cv; directive:
所有的 OpenCV 类和函数都放在 cv 命名空间中。因此,要从您的代码访问此功能,请使用 cv:: 说明符或 using namespace cv; 指令:

#include "opencv2/core.hpp"
...
cv::Mat H = cv::findHomography(points1, points2, cv::RANSAC, 5);
...

or

#include "opencv2/core.hpp"
using namespace cv;
...
Mat H = findHomography(points1, points2, RANSAC, 5 );
...

Some of the current or future OpenCV external names may conflict with STL or other libraries. In this case, use explicit namespace specifiers to resolve the name conflicts:
当前或将来的某些 OpenCV 外部名称可能与 STL 或其他库冲突。在这种情况下,请使用显式命名空间说明符来解决名称冲突:

Mat a(100, 100, CV_32F);
randu(a, Scalar::all(1), Scalar::all(std::rand()));
cv::log(a, a);
a /= std::log(2.);

1.2 Error Handling

OpenCV uses exceptions to signal critical errors. When the input data has a correct format and belongs to the specified value range, but the algorithm cannot succeed for some reason (for example, the optimization algorithm did not converge), it returns a special error code (typically, just a boolean variable).
OpenCV 使用异常来表示严重错误。当输入数据具有正确的格式并属于指定的值范围时,但是由于某种原因该算法无法成功 (例如,优化算法未收敛),它将返回一个特殊的错误代码 (通常只是一个布尔变量)。

The exceptions can be instances of the cv::Exception class or its derivatives. In its turn, cv::Exception is a derivative of std::exception. So it can be gracefully handled in the code using other standard C++ library components.
异常可以是 cv::Exception 类或其派生类的实例。而 cv::Exceptionstd::exception 的派生形式。因此,可以使用其他标准 C++ 库组件在代码中优雅地对其进行处理。

The exception is typically thrown either using the CV_Error(errcode, description) macro, or its printf-like CV_Error_(errcode, (printf-spec, printf-args)) variant, or using the CV_Assert(condition) macro that checks the condition and throws an exception when it is not satisfied. For performance-critical code, there is CV_DbgAssert(condition) that is only retained in the Debug configuration. Due to the automatic memory management, all the intermediate buffers are automatically deallocated in case of a sudden error. You only need to add a try statement to catch exceptions, if needed:
通常使用 CV_Error(errcode, description) 宏或其类似 printf 的 CV_Error_(errcode, (printf-spec, printf-args)) 变体或使用 CV_Assert(condition) 引发该异常。检查条件并在不满足条件时引发异常的宏。对于性能至关重要的代码,有 CV_DbgAssert(condition) 仅保留在 Debug 配置中。由于具有自动内存管理功能,因此在发生突发错误时,所有中间缓冲区都将自动释放。您只需要添加一条 try 语句即可捕获异常:

try
{
    ... // call OpenCV
}
catch (const cv::Exception& e)
{
    const char* err_msg = e.what();
    std::cout << "exception caught: " << err_msg << std::endl;
}

1.3 Automatic Memory Management

OpenCV handles all the memory automatically.
OpenCV 自动处理所有内存。

First of all, std::vector, cv::Mat, and other data structures used by the functions and methods have destructors that deallocate the underlying memory buffers when needed. This means that the destructors do not always deallocate the buffers as in case of Mat. They take into account possible data sharing. A destructor decrements the reference counter associated with the matrix data buffer. The buffer is deallocated if and only if the reference counter reaches zero, that is, when no other structures refer to the same buffer. Similarly, when a Mat instance is copied, no actual data is really copied. Instead, the reference counter is incremented to memorize that there is another owner of the same data. There is also the Mat::clone method that creates a full copy of the matrix data. See the example below:
首先,std::vectorcv::Mat 以及函数和方法使用的其他数据结构具有析构函数,这些析构函数可以在需要时释放底层的内存缓冲区。这意味着析构函数并不总是像 Mat一样总是释放缓冲区。它们考虑了可能的数据共享。析构函数递减与矩阵数据缓冲区关联的参考计数器。当且仅当参考计数器达到零时,即没有其他结构引用同一缓冲区时,才释放缓冲区。同样,复制 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();

You see that the use of Mat and other basic structures is simple. But what about high-level classes or even user data types created without taking automatic memory management into account? For them, OpenCV offers the cv::Ptr template class that is similar to std::shared_ptr from C++11. So, instead of using plain pointers:
您会看到 Mat 和其他基本结构的使用很简单。但是在不考虑自动内存管理的情况下创建的高级类甚至用户数据类型呢?对于他们,OpenCV 提供了 cv::Ptr 模板类,类似于 C++ 11 中的 std::shared_ptr。因此,不要使用普通的指针:

T* ptr = new T(...);

you can use:

Ptr<T> ptr(new T(...));

or:

Ptr<T> ptr = makePtr<T>(...);

Ptr<T> encapsulates a pointer to a T instance and a reference counter associated with the pointer. See the cv::Ptr description for details.
Ptr<T> 封装了指向 T 实例的指针和与该指针关联的参考计数器。有关详细信息,请参见 cv::Ptr 描述。

instance [ˈɪnstəns]:n. 实例,情况,建议 vt. 举...为例

1.4 Automatic Allocation of the Output Data

OpenCV deallocates the memory automatically, as well as automatically allocates the memory for output function parameters most of the time. So, if a function has one or more input arrays (cv::Mat instances) and some output arrays, the output arrays are automatically allocated or reallocated. The size and type of the output arrays are determined from the size and type of input arrays. If needed, the functions take extra parameters that help to figure out the output array properties.
OpenCV 在大多数情况下会自动取消分配内存,并自动为输出函数参数分配内存。因此,如果一个函数具有一个或多个输入数组 (cv::Mat 实例) 和一些输出数组,则将自动分配或重新分配输出数组。输出数组的大小和类型由输入数组的大小和类型确定。如果需要,函数可以使用额外的参数来帮助确定输出数组的属性。

//============================================================================
// Name        : using namespace cv;
// Author      : Yongqiang Cheng
// Version     : Feb 22, 2020
// Copyright   : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"

using namespace cv;

int main(int, char**)
{
	VideoCapture cap(0);
	if (!cap.isOpened())
	{
		return -1;
	}

	Mat frame, edges;
	namedWindow("edges", WINDOW_AUTOSIZE);

	for (;;)
	{
		cap >> frame;
		cvtColor(frame, edges, COLOR_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;
}

在这里插入图片描述

The array frame is automatically allocated by the >> operator since the video frame resolution and the bit-depth is known to the video capturing module. The array edges is automatically allocated by the cvtColor function. It has the same size and the bit-depth as the input array. The number of channels is 1 because the color conversion code cv::COLOR_BGR2GRAY is passed, which means a color to grayscale conversion. Note that frame and edges are allocated only once during the first execution of the loop body since all the next video frames have the same resolution. If you somehow change the video resolution, the arrays are automatically reallocated.
array frame 是由 >> 操作符自动分配的,因为视频帧分辨率和位深度对于视频捕获模块是已知的。array edgescvtColor 函数自动分配。它具有与输入数组相同的大小和位深度。通道数为 1,因为传递了颜色转换代码 cv::COLOR_BGR2GRAY,这意味着从颜色到灰度转换。注意,在循环体的第一次执行期间,frame and edges 仅分配一次,因为所有下一个视频帧都具有相同的分辨率。如果您以某种方式更改视频分辨率,则会自动重新分配阵列。

The key component of this technology is the Mat::create method. It takes the desired array size and type. If the array already has the specified size and type, the method does nothing. Otherwise, it releases the previously allocated data, if any (this part involves decrementing the reference counter and comparing it with zero), and then allocates a new buffer of the required size. Most functions call the Mat::create method for each output array, and so the automatic output data allocation is implemented.
这项技术的关键部分是 Mat::create 方法。它采用所需的数组大小和类型。如果数组已经具有指定的大小和类型,则该方法不执行任何操作。否则,它将释放先前分配的数据 (如果有) (此部分涉及递减参考计数器并将其与零进行比较),然后分配所需大小的新缓冲区。大多数函数为每个输出数组调用 Mat::create 方法,因此实现了自动输出数据分配。

Some notable exceptions from this scheme are cv::mixChannels, cv::RNG::fill, and a few other functions and methods. They are not able to allocate the output array, so you have to do this in advance.
该方案中的一些值得注意的例外是 cv::mixChannels, cv::RNG::fill 和其他一些函数和方法。他们无法分配输出数组,因此您必须提前执行此操作。

1.5 Multi-threading and Re-enterability - 多线程和重入性

The current OpenCV implementation is fully re-enterable. That is, the same function or the same methods of different class instances can be called from different threads. Also, the same Mat can be used in different threads because the reference-counting operations use the architecture-specific atomic instructions.
当前的 OpenCV 实施完全可以重新输入。也就是说,可以从不同的线程调用不同类实例的相同函数或相同方法。同样,同一 Mat 可以在不同的线程中使用,因为引用计数操作使用特定于体系结构的原子指令。

1.6 InputArray and OutputArray

Many OpenCV functions process dense 2-dimensional or multi-dimensional numerical arrays. Usually, such functions take cppMat as parameters, but in some cases it’s more convenient to use std::vector<> (for a point set, for example) or cv::Matx<> (for 3x3 homography matrix and such). To avoid many duplicates in the API, special “proxy” classes have been introduced. The base “proxy” class is cv::InputArray. It is used for passing read-only arrays on a function input. The derived from InputArray class cv::OutputArray is used to specify an output array for a function. Normally, you should not care of those intermediate types (and you should not declare variables of those types explicitly) - it will all just work automatically. You can assume that instead of InputArray/OutputArray you can always use Mat, std::vector<>, cv::Matx<>, cv::Vec<> or cv::Scalar. When a function has an optional input or output array, and you do not have or do not want one, pass cv::noArray().
许多 OpenCV 函数处理密集的二维或多维数字数组。通常,此类函数将 cppMat 作为参数,但在某些情况下,使用 std::vector<> (例如用于点集) 或 cv::Matx<>(用于 3x3 单应矩阵和像这样的)。为了避免 API 中的许多重复项,引入了特殊的 代理 类。基本的 代理 类是 cv::InputArray。它用于在函数输入上传递只读数组。从 InputArray 类 cv::OutputArray 派生的用于指定函数的输出数组。通常,您不必理会这些中间类型 (也不必显式声明这些类型的变量),它们都将自动运行。您可以假设可以始终使用 Mat, std::vector<>, cv::Matx<>, cv::Vec<> or cv::Scalar 来代替 InputArray / OutputArray。当一个函数具有一个可选的输入或输出数组,而您又没有或不想一个数组时,则传递 cv::noArray()

发布了454 篇原创文章 · 获赞 1733 · 访问量 103万+

猜你喜欢

转载自blog.csdn.net/chengyq116/article/details/104441858