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) 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 integerschar
: 8-bit signed integerushort
: 16-bit unsigned integershort
: 16-bit signed integerint
: 32-bit signed integerfloat
: 32-bit floating-point numberdouble
: 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 ofstd::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
- Intro OpenCV3.1.0 : 本文摘录于此.