Mat in OpenCV英文文档

本文深入探讨了OpenCV中Mat类的使用,解释了其多维密集数组的存储方式、创建方法及元素访问特性,强调了与不同数据结构的兼容性,并提供了初始化和操作Mat类实例的实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenCV C++ n-dimensional dense array class The class "Mat" represents an n-dimensional dense numerical single-channel or multi-channel array. It can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms may be better stored in a "SparseMat"). The data layout of the array M is defined by the array "M.step[]", so that the address of element (i_0,...,i_(M.dims-1)), where 0 <= i_k= M.step[i+1]" (in fact, "M.step[i] >= M.step[i+1]*M.size[i+1]"). This means that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane, and so on. "M.step[M.dims-1]" is minimal and always equal to the element size "M.elemSize()". So, the data layout in "Mat" is fully compatible with "CvMat", "IplImage", and "CvMatND" types from OpenCV 1.x. It is also compatible with the majority of dense array types from the standard toolkits and SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, that is, with any array that uses *steps* (or *strides*) to compute the position of a pixel. Due to this compatibility, it is possible to make a "Mat" header for user-allocated data and process it in-place using OpenCV functions. There are many different ways to create a "Mat" object. The most popular options are listed below: * Use the "create(nrows, ncols, type)" method or the similar "Mat(nrows, ncols, type[, fillValue])" constructor. A new array of the specified size and type is allocated. "type" has the same meaning as in the "cvCreateMat" method. For example, "CV_8UC1" means a 8-bit single-channel array, "CV_32FC2" means a 2-channel (complex) floating-point array, and so on. As noted in the introduction to this chapter, "create()" allocates only a new array when the shape or type of the current array are different from the specified ones. * Create a multi-dimensional array: It passes the number of dimensions =1 to the "Mat" constructor but the created array will be 2-dimensional with the number of columns set to 1. So, "Mat.dims" is always >= 2 (can also be 0 when the array is empty). * Use a copy constructor or assignment operator where there can be an array or expression on the right side (see below). As noted in the introduction, the array assignment is an O(1) operation because it only copies the header and increases the reference counter. The "Mat.clone()" method can be used to get a full (deep) copy of the array when you need it. * Construct a header for a part of another array. It can be a single row, single column, several rows, several columns, rectangular region in the array (called a *minor* in algebra) or a diagonal. Such operations are also O(1) because the new header references the same data. You can actually modify a part of the array using this feature, for example: Due to the additional "datastart" and "dataend" members, it is possible to compute a relative sub-array position in the main *container* array using "locateROI()": As in case of whole matrices, if you need a deep copy, use the "clone()" method of the extracted sub-matrices. * Make a header for user-allocated data. It can be useful to do the following: #. Process "foreign" data using OpenCV (for example, when you implement a DirectShow* filter or a processing module for "gstreamer", and so on). For example: #. Quickly initialize small matrices and/or get a super-fast element access. Partial yet very common cases of this *user-allocated data* case are conversions from "CvMat" and "IplImage" to "Mat". For this purpose, there are special constructors taking pointers to "CvMat" or "IplImage" and the optional flag indicating whether to copy the data or not. Backward conversion from "Mat" to "CvMat" or "IplImage" is provided via cast operators "Mat.operator CvMat() const" and "Mat.operator IplImage()". The operators do NOT copy the data. * Use MATLAB-style array initializers, "zeros(), ones(), eye()", for example: * Use a comma-separated initializer: With this approach, you first call a constructor of the "Mat_" class with the proper parameters, and then you just put "<<" operator followed by comma-separated values that can be constants, variables, expressions, and so on. Also, note the extra parentheses required to avoid compilation errors. Once the array is created, it is automatically managed via a reference-counting mechanism. If the array header is built on top of user-allocated data, you should handle the data by yourself. The array data is deallocated when no one points to it. If you want to release the data pointed by a array header before the array destructor is called, use "Mat.release()". The next important thing to learn about the array class is element access. This manual already described how to compute an address of each array element. Normally, you are not required to use the formula directly in the code. If you know the array element type (which can be retrieved using the method "Mat.type()"), you can access the element M_(ij) of a 2-dimensional array as: assuming that M is a double-precision floating-point array. There are several variants of the method "at" for a different number of dimensions. If you need to process a whole row of a 2D array, the most efficient way is to get the pointer to the row first, and then just use the plain C operator "[]" : Some operations, like the one above, do not actually depend on the array shape. They just process elements of an array one by one (or elements from multiple arrays that have the same coordinates, for example, array addition). Such operations are called *element-wise*. It makes sense to check whether all the input/output arrays are continuous, namely, have no gaps at the end of each row. If yes, process them as a long single row: In case of the continuous matrix, the outer loop body is executed just once. So, the overhead is smaller, which is especially noticeable in case of small matrices. Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: The matrix iterators are random-access iterators, so they can be passed to any STL algorithm, including "std.sort()".

### 安装配置 对于希望在 Jetson Orin Nano 上利用 C++ 进行 OpenCV 开发的情况,首先需要确保安装的是带有 CUDA 支持的 OpenCV 版本。默认通过 JetPack 安装的 OpenCV 不支持 CUDA 加速[^2]。 为了获得更好的性能表现,在开始编写程序前应当按照特定指南来安装兼容板卡并支持 GPU 的 OpenCV 版本,例如可以参照 Q-engineering 提供的针对 Jetson Orin Nano 的 OpenCV 4.10.0 安装指导[^1]。 如果之前已经存在不带 CUDA 支持的 OpenCV,默认情况下可能会影响后续操作,因此建议先移除旧版再继续新版本的部署工作: ```bash sudo apt purge libopencv* sudo apt autoremove ``` 完成上述准备工作之后,可以根据官方文档或其他可靠资源指示完成对具备 CUDA 功能的新版 OpenCV 编译与设置过程。 ### 创建简单的图像捕获应用 一旦确认环境搭建完毕,则可以通过如下方式创建一个基础的应用实例用于验证开发环境是否正常运作以及熟悉基本 API 调用方法: ```cpp #include <iostream> #include <opencv2/opencv.hpp> int main(int argc, char **argv){ // 打开视频流设备 cv::VideoCapture cap(0); if (!cap.isOpened()){ std::cerr << "无法打开相机" << std::endl; return -1; } cv::Mat frame; while (true){ bool ret = cap.read(frame); if (!ret || frame.empty()){ std::cout << "无数据流!" << std::endl; break; } // 显示获取到的画面帧 cv::imshow("Camera Feed", frame); // 按下 'q' 键退出循环 if(cv::waitKey(30) >= 0) break; } // 清理释放资源 cap.release(); cv::destroyAllWindows(); return 0; } ``` 这段代码实现了从 USB 摄像头读取实时画面并将之显示出来的功能[^3]。需要注意的是 `cv::VideoCapture` 构造函数中的参数代表使用的摄像机索引号;如果有多个外接摄像头连接至设备,那么这个数值可能会有所不同(比如 `/dev/video1` 对应的就是编号为 1 的设备)。此外,还可以根据实际需求调整窗口大小、分辨率等属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值