c++ - opencv矩阵数据是否保证是连续的?

标签 c++ opencv

我知道 OpenCV 矩阵中包含的数据不能保证是连续的。为了清楚起见,这里有一段来自 Opencv documentation :

enter image description here

OpenCV 提供了一个名为 isContinuous() 的函数来测试给定矩阵的数据是否连续。我的问题是

  1. 如果我按如下方式创建一个新矩阵
cv::Mat img = cv::imread(img_name)

img中的数据是否保证连续?

  1. 我知道通过从现有矩阵中借用数据来创建新矩阵会导致数据不连续
cv::Mat small_mat = large_mat.col(0);

以上代码通过借用large_mat的第0th列创建了一个新的矩阵small_mat,导致small_mat中的数据不连续。那么问题来了,如果我创建一个全新的矩阵而不借用现有矩阵的数据,那么这个全新的矩阵会有连续数据还是不连续数据?

  1. 以下代码能否保证创建包含连续数据的矩阵?
cv::Mat mat(nRows, nCols, CV_32FC1);

最佳答案

您可以在 OpenCV 文档中查看 isContinuous :

The method returns true if the matrix elements are stored continuously without gaps at the end of each row. Otherwise, it returns false. Obviously, 1x1 or 1xN matrices are always continuous. Matrices created with Mat::create() are always continuous. But if you extract a part of the matrix using Mat::col(), Mat::diag() , and so on, or constructed a matrix header for externally allocated data, such matrices may no longer have this property.

因此,只要您正在创建一个新矩阵(即您正在调用 create ),您的矩阵就会是连续的。

create 的工作方式如下:

  1. 如果当前数组的形状和类型与新的匹配,则立即返回。否则,通过调用 Mat::release() 取消引用之前的数据。
  2. 初始化新 header 。
  3. 分配total()*elemSize()字节的新数据。
  4. 分配新的、与数据关联的、引用计数器并将其设置为 1。

这意味着当您(隐式)调用 create 时,矩阵将是连续的(第 3 步)。


您的问题

If I create a new matrix with imread is the data guaranteed to be continuous

,因为 imread 在内部调用 create

I know that creating a new matrix by borrowing data from existing matrix would result in incontinuous data.

正确,数据将不连续。要使新矩阵连续,可以调用clone(),它调用create来创建新矩阵。

if I create a brand new matrix without borrowing data from existing matrix, will the brand new matrix have incontinuous data?

是的,构造函数内部调用create

Matrix constructor is guaranteed to create a matrix with continuous data?

是的,构造函数内部调用create

这是一个总结的小例子:

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main()
{
    // Read image
    Mat img = imread("path_to_image");
    cout << "img is continuous? " << img.isContinuous() << endl; 
    // Yes, calls create internally

    // Constructed a matrix header for externally allocated data
    Mat small_mat = img.col(0);
    cout << "small_mat is continuous? " << small_mat.isContinuous() << endl; 
    // No, you're just creating a new header.

    // Matrix (self) expression
    small_mat = small_mat + 2;
    cout << "small_mat is continuous? " << small_mat.isContinuous() << endl; 
    // No, you're not even creating a new header

    // Matrix expression
    Mat expr = small_mat + 2;
    cout << "expr is continuous? " << expr.isContinuous() << endl; 
    // Yes, you're creating a new matrix

    // Clone
    Mat small_mat_cloned = img.col(0).clone();
    cout << "small_mat_cloned is continuous? " << small_mat_cloned.isContinuous() << endl; 
    // Yes, you're creating a new matrix

    // Create
    Mat mat(10, 10, CV_32FC1);
    cout << "mat is continuous? " << mat.isContinuous() << endl; 
    // Yes, you're creating a new matrix

    return 0;
}

关于c++ - opencv矩阵数据是否保证是连续的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33665241/

相关文章:

C++ 数据成员对齐和数组打包

c++ - C++ 中的 BST 搜索键

c++ - 为什么当它是一个 int 时我不能分配返回右值引用的函数,但当它是一个类时我可以?

android - 获取二值图像中非几何线的坐标

python - 使用 Get2D 在 OpenCV 中访问二维像素值时出现超出范围错误或返回值错误

c++ - 在 Raspberry Pi 2 上编译 OpenCV

opencv - 在 OpenCV 中裁剪一半图像

python - 破解一个闭源程序来帮助我使用 python/screenshot/OCR 对现实生活中的对象进行排序

c++ - 常量引用有何不同?

c++ - Microsoft C++ 异常:内存位置的 boost::archive::archive_exception(通过客户端服务器 Boost Udp 解析 Vector)