Opencv 2.* 和 1. * 的区别:2.* 主要是c++的接口,1.* 主要是c接口。
API概念
1. cv命名空间
using namespace cv;
2. 自动内存管理
Mat等大的数据类型都是通过引用计数管理内存。你可以利用Mat::clone真的进行复制。
// 创建一个8M的矩阵
Mat A(1000, 1000, CV_64F);
// 创建同一个矩阵的一个引用,是即时生效的
Mat B = A;
// 创建对A的第三行引用,同样不进行复制
Mat C = B.row(3);
// 真的复制
Mat D = B.clone();
// 复制A的第五行到第3行
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 即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 即 A 被释放掉
C = C.clone();
对于其他没有把自动销毁考虑在内的数据类型,可以利用Ptr模板。
//不是这样:T* ptr = new T(...);
Ptr ptr(new T(...));
Ptr ptr = makePtr(...);
这样就可以进行引用计数了。
3. 输出的自动分配
#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(;;)
{
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;
}
frame,edges是自动分配的输出矩阵。除非类型、大小变化,否则只分配一次。
有个别方法不符合自动分配机制,比如 cv::mixChannels, cv::RNG::fill 。你需要自己事先分配。
4. 饱和运算
常用的像素类型是uchar
就支持饱和运算:I(x,y)=min(max(round(r),0),255)
。opencv代码是I.at
。对于8s,16s和u类型同样适用。不适用32位整数。
5. 固定的像素类型,有限的模板
只有少数的简单模板。像generic Ptr<> implementation , saturate_cast<>()
还有一些像素接触操作。
基础数据类型:
8-bit unsigned integer (uchar)
8-bit signed integer (schar)
16-bit unsigned integer (ushort)
16-bit signed integer (short)
32-bit signed integer (int)
32-bit floating-point number (float)
64-bit floating-point number (double)
枚举:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 };
Mat mtx(3, 3, CV_32F); // make a 3x3 floating-point matrix
Mat cmtx(10, 1, CV_64FC2); // make a 10x1 2-channel floating-point
// matrix (10-element complex vector)
Mat img(Size(1920, 1080), CV_8UC3); // make a 3-channel (color) image
// of 1920 columns and 1080 rows.
Mat grayscale(image.size(), CV_MAKETYPE(image.depth(), 1)); // make a 1-channel image of
// the same size and same
// channel type as img
越复杂的算法支持的数据类型越少,如人脸识别只支持8位的灰度或彩色图像。
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 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 InputArray.