【OpenCV】 OpenCV 入门介绍 (OpenCV Introduction)

Backto OpenCV Index


若未特殊注明, 本系列文章所用的 OpenCV 版本是 3.1.0.

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 opposite to the C-based OpenCV 1.x API. The latter is described in opencv1x.pdf.

OpenCV 采用模块儿化架构, 常用的比如

  • Core functionality - a compact module defining basic data structures, including the dense multi-dimensional array Mat and basic functions used by all other modules.
  • Image processing - 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.
  • calib3d - basic multiple-view geometry algorithms, single and stereo camera calibration, object pose estimation, stereo correspondence algorithms, and elements of 3D reconstruction.

后续都会一一说到.

这里首先介绍一下 OpenCV 的 API 规范, 方便理解和使用 OpenCV 提供的接口.

cv Namespace

All the OpenCV classes and functions are placed into the cv namespace. 但是绝对禁止使用 using namespace cv, 以防污染命名空间.

#include <opencv2\opencv.hpp>
...
cv::Mat H = cv::findHomography(points1, points2, CV_RANSAC, 5);
...

Automatic Memory Management

  • 浅复制, 仅构造一个新的 header, 指针指向原 body, 计数 + 1.
  • 深复制, 完整构造一个全新的 header + body, 使用 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();

对于指针操作, OpenCV 引入了 template class Ptr, 类似于 C++ 11 的 std::shared_ptr. Ptr<T> encapsulates a pointer to a T instance and a reference counter associated with the pointer. See the Ptr description for details, so

//DO NOT use this kind of plain pointers anymore
T* ptr = new T(...);

//DO use this way, fashion and safe
Ptr<T> ptr(new T(...));

//or, this way
Ptr<T> ptr = makePtr<T>(...);

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.
  • 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.

#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",1);
    for(;;)
    {
    //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. 
        cap >> frame;
        
        //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 COLOR_BGR2GRAY is passed,
         //   which means a color to grayscale conversion
        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;
}

Saturation Arithmetics

使用 saturate_cast关键字, 例如 8-bit image,

I.at<uchar>(y,x) = saturate_cast<uchar>(r)

, 计算过程是 I ( x , y ) = min ( max ( r o u n d ( r ) , 0 ) , 255 ) I(x,y) = \min (\max (round(r), 0), 255)

适用于 8-bit / 16-bit interger, 不适用于 32-bit interger.

Limited Use of Templates. Fixed Pixel Types.

  • Limited Use of Templates : the current OpenCV implementation is based on polymorphism and runtime dispatching over templates.
  • OpenCV 仅有 7 个 primitive data type
    • uchar : 8-bit unsigned integer
    • schar : 8-bit signed integer
    • ushort: 16-bit unsigned integer
    • short : 16-bit signed integer
    • int : 32-bit signed integer
    • float : 32-bit floating-point number
    • double : 64-bit floating-poing number
      当然, 为了防止和标准C++ 中的类型混淆, 实际中使用的是下面的 enumeration
enum{ CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6, CV_USRTYPE1 =7};

, 还有一个基本的复合数据类型

  • tuple : a tuple of several elements where all elements have the same type (one of the above). An array whose elements are such tuples, are called multi-channel arrays. The maximum possible number of channels is defined by the CV_CN_MAX constant, which is currently set to 512.
  • 对于 1/2/3/4 channels, 常用的数据类型已经定义好了, CV_8UC1,…, CV_64FC4
  • 对于多于 4 个channels 的,由用户自己创建, 使用宏 CV_MAKETYPE(CV_8U, n)

特殊地, 我们也可以从深度值中自动获取基础数据类型, 语法 CV_MAKETYPE(depth, n) == ((depth&7) + ((n-1)<<3), This means that the constant type is formed from the depth, taking the lowest 3 bits, and the number of channels minus 1, taking the next $\log_2 \text{(CV_CN_MAX)} $ bits. ,

例如,

 // make a 1-channel image of the same size and same channel type as img
Mat grayscale(image.size(), CV_MAKETYPE(image.depth(), 1));

, 很复杂, 不想用.

通常, OpenCV 里的函数越复杂, 支持的数据类型越少. Usually, the more complex the algorithm is, the smaller the supported subset of formats is

  • Basic functions, such as cv::add, support all types.
  • Color space conversion functions support 8-bit unsigned, 16-bit unsigned, and 32-bit floating-point types.
  • The face detection algorithm only works with 8-bit grayscale or color images.
  • Linear algebra functions and most of the machine learning algorithms work with floating-point arrays only.

InputArray and OutputArray

  • 通常, OpenCV 的输入输出都是 Mat, 但是有时候用 std::vector / Matx / Vec / Scalar 更好些, 为了防止多重复写, 引入了这些 proxy classes
  • 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.

Error Handling

  • OpenCV uses exceptions to signal critical errors
  • 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.
// To throw an exception
CV_Error(errcode, description);
CV_Error_(errcode, printf-spec, (printf-args)) ;
CV_Assert(condition); // checks the condition and throws an exception 
                                   // when it is not satisfied

CV_DbgAssert(condition) // only retained in the Debug configuration.


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

Multi-threading and Re-enterability

The current OpenCV implementation is fully re-enterable. That is,

  • the same function, the same constant method of a class instance,
  • or the same non-constant method of different class instances can be called from different threads.

Also, the same cv::Mat can be used in different threads because the reference-counting operations use the architecture-specific atomic instructions.


Ref

猜你喜欢

转载自blog.csdn.net/baishuo8/article/details/82817232