OpenCV 3D 垫到矢量

标签 opencv vector 3d reshape mat

我有 3D Mat 并想将其转换为 Vector。我尝试了 opencv 的 reshape() 函数,但它似乎不适用于维度超过 2 的矩阵。如何将 3D Mat 转换为 Vector ?我可以通过访问 Mat 中的所有元素来做到这一点。有什么有效的方法吗?

最佳答案

如果我们有以下 3D 矩阵:

const int ROWS=2, COLS=3, PLANES=4;
int dims[3] = {ROWS, COLS, PLANES};
cv::Mat m = cv::Mat(3, dims, CV_32SC1);   // works with other types (e.g. float, double,...)

这仅适用于连续垫对象(即 m.isContinuous() == true)

获取包含相同元素的相同类型的向量:

  1. 使用重载的 STL 向量构造函数:

    声明和初始化一个与矩阵相同类型的向量并复制所有 mat 元素:

    const int* p3 = m3.ptr<int>(0);
    std::vector<int> flat0(p3, p3+m3.total());
    
  2. 使用 OpenCV 的 reshape :

    这与第一个解决方案的不同之处在于元素最终的布局方式。 最初来自这篇文章:How to divide 3D matrix into bunches of 2D matrix with opencv C++ 如果可能的话,我同意他关于将您的维度定义为 channel 的建议。 OpenCV 处理 channel 比处理维度更好。当然,如果您打算拥有超过 4 个维度,这可能不适用。

    cv::Mat m2(ROWS, COLS*PLANES, CV_32SC1, m3.data); // no copying happening here
    cv::Mat m2xPlanes = m2.reshape(PLANES); // not sure if this involves a copy
    std::vector<Mat> planes;
    cv::split(m2xPlanes, planes); // usually used for splitting multi-channel matrices
    
    std::vector<int> flat;
    for(size_t i=0; i<planes.size(); i++) {
        cv::Mat plane_i = planes[i];
        const int* plane_i_ptr = plane_i.ptr<int>(0);
        flat.insert(flat.end(), plane_i_ptr, plane_i_ptr+plane_i.total());
    }
    

对于这两种解决方案,所有元素都会被考虑在内,只是它们的排序方式不同,因此访问方式也不同。 首先,您通过访问行、列、平面的元素

int index = row * COLS * PLANES + col * PLANES + p

在第二个你的元素是按平面排序的。

选择哪种解决方案可能取决于您将如何为向量建立索引。

关于OpenCV 3D 垫到矢量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27702231/

相关文章:

c++ - 从人 vector 插入和读取文件时出错

3d - 在 OGRE 中获取对象方向

python - 使用 Python 图像处理分割生物样本的照片以提取感兴趣的圆形区域

python - 更改值时Opencv重绘图像

c++ - boost 共享内存 : the volume of a file has been externally altered and open file is not longer valid

cocoa - 在类似 itunes 的应用程序中全屏显示 (cocoa OSX)

3d - 计算任意网格的平面 UV 坐标

python - 不重叠的圆检测

python - opencv错误断言失败python

.net - 从字体中提取几何图形