opencv是开源的图像算法库,包含几百种视觉相关的图像算法,Opencv2.x API是在C++上测试通过的api,并不像1.x是在C上测试通过的。
opencv包含以下几个模块:
1)Core functionality (core) :基础模块,主要定义包含数据基本存储单元的Mat等基本的数据类型,以及在其他模块中调用的基本函数
2)Image Processing (imgproc) :图像处理模块,包含线性、非线性的图像滤波算法、图像几何变换(如缩放、仿射变换、透射变换、查表重组等)、颜色空间转换、直方图等。
3)Video Analysis (video):视频分析模块:包含运动预估、背景提取以及目标跟踪算法等。
4)Camera Calibration and 3D Reconstruction (calib3d):基本的多目几何算法,单独的和立体相机校准、目标姿态估计、立体匹配算法以及三维重建。
5)2D Features Framework (features2d) :静态特征检测器、描述子以及特征匹配等。
6)Object Detection (objdetect):对于预定义的目标或者实例(如人脸、眼睛、下巴、人、汽车等)进行检测。
7)High-level GUI (highgui) :一个方便好用的UI接口。
8)Video I/O (videoio):视频处理接口以及视频编解码相关。
还有一些如dnn深度学习相关、ml机器学习相关、flann多维空间特征检测和匹配、Images stitching图像拼接相关等模块。下面先介绍一些opencv最基础的使用方法。
API Concepts
cv命名空间:
opencv所有相关的类、函数都是放置在cv命名空间下面,因此,要想在自己代码中使用opencv相关函数,必须使用cv::或者在cpp最开始定义命名空间using namespace cv;如下:
#include "opencv2/core.hpp"
...
cv::Mat H = cv::findHomography(points1, points2, cv::RANSAC, 5);
...
或者:
#include "opencv2/core.hpp"
using namespace cv;
...
Mat H = findHomography(points1, points2, RANSAC, 5 );
...
如果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.);
内存自动分配:
opencv处理自动处理所有与内存相关的操作(变量内存分配&释放)。
首先,用在其他函数及方法中,类似于std::vector,cv::Mat等数据结构自己包含有析构函数,当被需要的时候(变量不再被使用的时候),自行释放之前分配的资源。这也意味着,在Mat类型中,析构函数并不是一直在释放内存,它要考虑数据共享机制。如果一个Mat型变量使用结束,也就是没有其他变量再与此变量相关,或者函数运行结束了,析构函数才去释放此Mat型变量占用的资源。
如果拷贝一个Mat,(b = a.copy()),数据并没有真正进行拷贝,只不过增加了一个新的变量,新变量仍然指向此位置,如果对a/b任何一个操作,另外一个也随之变化。但是Mat::clone,克隆的话,就是重新分配空间,定义一个全新的变量了(完全拷贝,深复制,两个变量不再关联)。例子如下:
// 创建一个8M大小的矩阵
Mat A(1000, 1000, CV_64F);
// 为此矩阵创建一个新的头信息,B与A相同,改变一个矩阵内部值,另外一个也随之变化;
Mat B = A;
// 为B矩阵的第三行创建一个头信息,此处并不进行数据拷贝
Mat C = B.row(3);
// clone是创建新的完全独立的矩阵,两个不相关
Mat D = B.clone();
//把B的第五行拷贝到C里面,也就是把A的第五行拷贝到A的第三行
B.row(5).copyTo(C);
// 让A与D共享数据,修改之后,A同样与B和C静态关联
A = D;
// 释放B矩阵的内存信息,但是修改后的A仍然与C相关联,尽管C只是指向A的单独的一行,
B.release();
// 最终,将C自己进行深拷贝,就不再与A关联,此时A被完全释放
C = C.clone();
opencv可以通过类似于python的try...except....机制使用try ...catch...捕捉异常
try
{
... // call OpenCV
}
catch (const cv::Exception& e)
{
const char* err_msg = e.what();
std::cout << "exception caught: " << err_msg << std::endl;
}
通过CV_Assert(condition)判断输入条件是否准确,异常则直接卡死返回。