标签:scala 高级 called 信息 std 版本 his 原因 因此
core - a compact module defining basic data structures, including the dense multi-dimensional array Mat and basic functions used by all other modules.
core模块:基本数据类型的定义,包括多维数组Mat和在其他所有模块中用到的基本函数
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.
improc模块:图像处理模块。包括线性和非线性的图像滤波,图像几何变换(缩放,仿射变换和透视变换,通用的基于表的重映射),颜色空间转换,直方图等
video - a video analysis module that includes motion estimation, background subtraction,and object tracking algorithms.
video模块:视频分析模块。包括运动估计,背景减除,和物体追踪算法
calib3d - basic multiple-view geometry algorithms, single and stereo camera calibration,object pose estimation, stereo correspondence algorithms, and elements of 3D reconstruction.
calib3d模块:基本的多视点几何算法,单体和立体摄像机的标定,物体姿势估计,立体匹配算法,3D重建的元素
features2d - salient feature detectors, descriptors, and descriptor matchers.
features2d模块:显著特征探测器,描述子,和描述子匹配
objdetect - detection of objects and instances of the predefined classes (for example, faces, eyes, mugs, people, cars, and so on).
objdetect模块:物体检测和预定义类的实例(比如,人脸,眼睛,马克杯,人,汽车等)
highgui - an easy-to-use interface to simple UI capabilities.
highgui模块:一个易于使用的界面,简单的UI功能
videoio - an easy-to-use interface to video capturing and video
codecs.
videoio模块:一个易于使用的视频捕获和视频编解码的接口
gpu - GPU-accelerated algorithms from different OpenCV modules.
gpu模块:不同OpenCV模块的gpu加速算法
所有OpenCV类和函数都放在cv名称空间中,所以,如果你想在代码中访问这些函数,你需要使用cv::说明符,或者使用using namespace cv;
1 @code 2 #include "opencv2/core.hpp" 3 ... 4 cv::Mat H = cv::findHomography(points1, points2, CV_RANSAC, 5); 5 ... 6 @endcode 7 or : 8 ~~~ 9 #include "opencv2/core.hpp" 10 using namespace cv; 11 ... 12 Mat H = findHomography(points1, points2, CV_RANSAC, 5 ); 13 ... 14 ~~~
@表示注解,@code表示这是代码的注解,@endcode表示这是代码结束的注解。
有时候一些opencv的类名,函数名可能会和STL及其它库里的函数名冲突,此时需要显式使用该函数所在名称空间的说明符以避免冲突。
1 @code 2 Mat a(100, 100, CV_32F); 3 randu(a, Scalar::all(1), Scalar::all(std::rand())); 4 cv::log(a, a); 5 a /= std::log(2.); 6 @endcode
说明:使用名称空间说明符,和使用using编译命令,前者相对于后者来说,代码书写量上会繁琐一点,但是可以很直观的看出该函数是属于哪个名称空间的,同时也不会发生与其他第三方库发生冲突的情况,而后者相对于前者,则是只需要写一条语句则后面不需要在每个函数面前都写名称空间说明符,书写会简洁一点,但要注意冲突。
2. 动态内存管理
OpenCV自动管理所有内存
首先,一些函数和方法所用到的std::vector, Mat,和其它数据结构都有自己的析构函数,但是这些析构函数只在必要的时候才会释放底层内存缓冲区,这也就是说,当为Mat对象时析构函数并不总是会释放内存,它会考虑到数据共享。析构函数与矩阵数据缓冲区的引用计数器相关联,当且仅当该矩阵数据缓冲区的引用计数器为0时才会释放该缓冲区,即,当没有其它的结构引用相同的缓冲区时。相似地,当复制一个Mat对象时,真正的数据其实并没有被复制,我们只是使该内存缓冲区的引用计数器加1以表示同一数据的另一个拥有者,还有Mat :: clone方法可以创建矩阵数据的完整副本。
1 @code 2 // create a big 8Mb matrix 3 Mat A(1000, 1000, CV_64F); 4 5 // create another header for the same matrix; 6 // this is an instant operation, regardless of the matrix size. 7 Mat B = A; 8 // create another header for the 3-rd row of A; no data is copied either 9 Mat C = B.row(3); 10 // now create a separate copy of the matrix 11 Mat D = B.clone(); 12 // copy the 5-th row of B to C, that is, copy the 5-th row of A 13 // to the 3-rd row of A. 14 B.row(5).copyTo(C); 15 // now let A and D share the data; after that the modified version 16 // of A is still referenced by B and C. 17 A = D; 18 // now make B an empty matrix (which references no memory buffers), 19 // but the modified version of A will still be referenced by C, 20 // despite that C is just a single row of the original A 21 B.release(); 22 23 // finally, make a full copy of C. As a result, the big modified 24 // matrix will be deallocated, since it is not referenced by anyone 25 C = C.clone(); 26 @endcode
Mat和其它基本结构的使用很简单,但在不考虑自动内存管理的情况下,如何创建高级类甚至用户数据类型呢?对于这些,OpenCV提供了Ptr模板类来代替普通指针,这个模板类和C++11中的std::shared_ptr类似。
1 @code 2 T* ptr = new T(...); //instead by Ptr template class 3 @endcode 4 you can use: 5 @code 6 Ptr<T> ptr(new T(...)); 7 @endcode 8 or: 9 @code 10 Ptr<T> ptr = makePtr<T>(...); 11 @endcode
Ptr <T>封装一个指向T对象的指针和一个与指针相关的引用计数器。有关详细信息,请参阅Ptr说明。
3. 输出数据的自动分配
OpenCV自动释放内存,同样,大多数情况下自动为输出函数参数分配内存。所以,如果一个函数有一个或者多个输入矩阵(即cv::Mat对象)和一些输出矩阵,那么这些输出矩阵将自动分配或者重新分配内存,这些输出矩阵的大小和类型由输入矩阵的大小和类型确定,如果需要,函数还会使用一些额外的参数来帮助计算出输出矩阵的属性。
1 Example: 2 @code 3 #include "opencv2/imgproc.hpp" 4 #include "opencv2/highgui.hpp" 5 6 using namespace cv; 7 8 int main(int, char**) 9 { 10 VideoCapture cap(0); 11 if(!cap.isOpened()) return -1; 12 13 Mat frame, edges; 14 namedWindow("edges",1); 15 for(;;) 16 { 17 cap >> frame; 18 cvtColor(frame, edges, COLOR_BGR2GRAY); 19 GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5); 20 Canny(edges, edges, 0, 30, 3); 21 imshow("edges", edges); 22 if(waitKey(30) >= 0) break; 23 } 24 return 0; 25 } 26 @endcode
这个frame矩阵是由>>运算符自动分配的,因为视频帧的分辨率和位深度是视频捕获模块所知道的;edges矩阵是由cvtColor函数自动分配的,它和输入矩阵有着同样的大小和同样的位深度。通道数为1,因为使用了颜色转换代码COLOR_BGR2GRAY,这个代码表明将颜色转换为灰度模式。需要指出的是,frame和edges只在循环体的第一次执行期间分配一次,因为所有下一个视频帧具有相同的分辨率,如果你以某种方式改变了视频的分辨率,则该矩阵将会自动重新分配。
实现这项技术的关键组件是Mat :: create方法,它获取所需的矩阵的大小和类型,如果该矩阵已经具有指定的大小和类型,那么该方法将什么也不做;反之,它会释放先前已经分配的数据,否则,它将释放以前分配的数据,如果有的话(这部分包括对引用计数器进行递减并将其与0进行比较),然后分配所需大小的新缓冲区。大多数函数为每个输出数组调用Mat :: create方法,因而实现了输出矩阵自动分配。
这个方案中有一些值得注意的例外是cv :: mixChannels,cv :: RNG :: fill和其他一些函数和方法, 他们无法分配输出数组,因此您必须提前执行此操作。
4. 饱和算法
作为一个计算机视觉库,OpenCV处理大量的图像像素,这些图像像素通常以紧凑的8位或16位每通道编码格式进行编码,因此其值的范围是有限的。此外,图像上的某些操作,如颜色空间转换、亮度/对比度调整、锐化、复杂插值(bi-cubic, Lanczos)可以产生可用范围之外的值,那么此时,如果只存储结果的最低8(16)位,这将导致视觉缺陷(可视化组件?),并可能影响进一步的图像分析。为了解决这个问题,使用所谓的“饱和”算术,例如,要将一个操作的结果r存储到一个8位图像中时,我们可以在0到255范围内找到最接近它的值
I(x,y)= min ( max (textrm{round}(r), 0), 255)
类似的规则适用于8位有符号,16位有符号和无符号类型,这个语义在库中随处可见。在c++代码中,它使用了类似于标准c++ cast操作的saturate_cast<>函数。参见下面的公式的实现:
1 @code 2 I.at<uchar>(y, x) = saturate_cast<uchar>(r); 3 @endcode
其中cv :: uchar是一个OpenCV 8位无符号整数类型。 在优化的SIMD代码中,使用了paddusb,packuswb等SSE2指令, 它们帮助实现与C ++代码中完全相同的行为。注意,当结果是32为整型时不应用饱和度。
5. 固定的像素类型,有限使用的模板
模板是C ++的一个重要特性,可以实现非常强大,高效且安全的数据结构和算法。但是,大量使用模板可能会极大地增加编译时间和代码的大小,此外,当模板被单独使用时,很难将接口和实现分开。这对于基本算法来说是可以的,但是对于计算机视觉库来说却不是很好,因为单个算法可以跨越数千行代码。由于这一点,也为了简化其他语言的绑定开发,比如Python、Java、Matlab,它们根本没有模板,也没有有限的模板功能,所以当前的OpenCV实现是基于多态和运行时分派模板的。在那些运行时调度速度太慢(比如像素访问操作符),不可能(通用Ptr <>实现)或者非常不方便(saturate_cast <>())的地方,当前的实现引入了小的模板类,方法和函数, 目前的OpenCV版本中的其他任何地方使用的模板都是有限的。
因此,库可以操作的原始数据类型是有限的。也就是说,数组元素应该有以下类型之一:
1 - 8-bit unsigned integer (uchar) 2 - 8-bit signed integer (schar) 3 - 16-bit unsigned integer (ushort) 4 - 16-bit signed integer (short) 5 - 32-bit signed integer (int) 6 - 32-bit floating-point number (float) 7 - 64-bit floating-point number (double) 8 - a tuple of several elements where all elements have the same type (one of the above). An array 9 whose elements are such tuples, are called multi-channel arrays, as opposite to the 10 single-channel arrays, whose elements are scalar values. The maximum possible number of 11 channels is defined by the CV_CN_MAX constant, which is currently set to 512.
对于这些基本类型,应用以下枚举:
1 @code 2 enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 3 @endcode
可以使用以下选项指定多通道(n通道)类型:
1 - CV_8UC1 ... CV_64FC4 constants (for a number of channels from 1 to 4) 2 - CV_8UC(n) ... CV_64FC(n) or CV_MAKETYPE(CV_8U, n) ... CV_MAKETYPE(CV_64F, n) macros when 3 the number of channels is more than 4 or unknown at the compilation time. //在编译时,通道数大于4或者一个未知的宏
注意: `CV_32FC1 == CV_32F, CV_32FC2 == CV_32FC(2) == CV_MAKETYPE(CV_32F, 2)`, and `CV_MAKETYPE(depth, n) == ((depth&7) + ((n-1)<<3)``. 这意味着常数类型由深度构成,取最低3位,通道数减1,取下一个“log2(CV_CN_MAX)”位。
1 Examples: 2 @code 3 Mat mtx(3, 3, CV_32F); // make a 3x3 floating-point matrix 4 Mat cmtx(10, 1, CV_64FC2); // make a 10x1 2-channel floating-point 5 // matrix (10-element complex vector) 6 Mat img(Size(1920, 1080), CV_8UC3); // make a 3-channel (color) image 7 // of 1920 columns and 1080 rows. 8 Mat grayscale(image.size(), CV_MAKETYPE(image.depth(), 1)); // make a 1-channel image of 9 // the same size and same 10 // channel type as img 11 @endcode
使用OpenCV无法构建或处理具有更复杂元素的数组, 此外,每个函数或方法只能处理所有可能数组类型的子集,通常,算法越复杂,支持的格式子集越小。 以下是这些限制的典型例子:
1 //人脸检测算法仅适用于8位灰度或彩色图像 2 - The face detection algorithm only works with 8-bit grayscale or color images. 3 //线性代数函数和大多数机器学习算法仅适用于浮点数组 4 - Linear algebra functions and most of the machine learning algorithms work with floating-point 5 arrays only. 6 //基本功能,如cv::添加,支持所有类型 7 - Basic functions, such as cv::add, support all types. 8 //颜色空间转换函数支持8位无符号、16位无符号和32位浮点类型 9 - Color space conversion functions support 8-bit unsigned, 16-bit unsigned, and 32-bit 10 floating-point types.
每个函数的支持类型的子集已经从实际需求中定义,并且可以基于用户请求在将来进行扩展。
6. InputArray和OutputArray
许多OpenCV函数处理密集的二维或多维数值数组。通常,这些函数将cppMat作为参数,但在某些情况下,使用std :: vector <>(例如对于点集)或Matx <>(对于3x3单应矩阵等)更方便。为了避免API中的许多重复,引入了特殊的“proxy”类。 基本的“proxy”类是InputArray, 它用于在函数输入上传递只读数组。来自InputArray类OutputArray的派生函数用于指定函数的输出数组。通常,您不应该关心这些中间类型(并且您不应该显式地声明这些类型的变量)——它将自动地工作。你可以假设你总是可以使用Mat,std :: vector <>,Matx <>,Vec <>或Scalar代替InputArray / OutputArray。 当一个函数有一个可选的输入或输出数组,而你没有或不需要时,可以通过传递cv ::noArray()。
7. 错误处理
OpenCV使用异常来表示严重错误。 当输入数据的格式正确并且属于指定的值范围,但由于某种原因(例如,优化算法未收敛),该算法无法成功时,它会返回一个特殊的错误代码(通常只是一个布尔变量)。异常可以是cv :: Exception类或其派生类的实例。 反过来,cv :: Exception是std :: exception的衍生物。 所以可以使用其他标准c++库组件在代码中优雅地处理它。异常通常是使用CV_Error(errcode, description)宏,或者它的printf-like CV_Error_(errcode, printf-spec, (printf-args))变量,或者使用CV_Assert(条件)宏来检查条件,并在不满足的情况下抛出异常。对于性能关键的代码,只有保留在Debug配置中的CV _DbgAssert(condition),由于自动内存管理,所有中间缓冲区都会在突然出现错误时自动释放分配,如果需要的话,只需要添加一个try语句来捕获异常:
1 @code 2 try 3 { 4 ... // call OpenCV 5 } 6 catch( cv::Exception& e ) 7 { 8 const char* err_msg = e.what(); 9 std::cout << "exception caught: " << err_msg << std::endl; 10 } 11 @endcode
8. 多线程和可重入性
目前的OpenCV实现是完全可重入的, 也就是说,,同一个函数,同一个类实例的*constant*方法,或者不同的类实例的相同*non-constant*方法可以从不同的线程调用。此外,相同的cv :: Mat可以在不同的线程中使用,因为引用计数操作使用特定于体系结构的原子指令。
标签:scala 高级 called 信息 std 版本 his 原因 因此
原文地址:https://www.cnblogs.com/latup/p/8886385.html