将轮廓点向量复制到垫子中

Posted

技术标签:

【中文标题】将轮廓点向量复制到垫子中【英文标题】:Copy Vector of Contour Points into Mat 【发布时间】:2017-03-12 19:10:51 【问题描述】:

我正在使用带有 VS2012 C++/CLI 的 OpenCV 3.1。

我已将 finContours 调用的结果存储到:

std::vector<std::vector<Point>> Contours;

因此,Contours[0] 是第一个轮廓的轮廓点的向量。 Contours[1] 是第二个向量的轮廓点的向量,以此类推

现在,我想将其中一个轮廓加载到基于 Convert Mat to vector <float> and Vector<float> to mat in opencv 的 Mat 中,我认为这样的方法会起作用。

Mat testMat=Mat(Images->Contours[0].size(),2,CV_32FC1);    
memcpy(testMat.data,Images->Contours[0].data(),Images->Contours[0].size()*CV_32FC1);

我指定了两列,因为我每个底层品脱都必须由一个 X 点和一个 Y 点组成,并且每一个都应该是一个浮点数。但是,当我访问 Mat 元素时,我可以看到第一个元素不是基础数据,而是轮廓点的总数。

任何有关完成此任务的正确方法的帮助。

【问题讨论】:

【参考方案1】:

你可以这样做:

Mat testMat = Mat(Images->Contours[0]).reshape(1);

现在testMat 的类型为CV_32SC1,又名int。如果您需要float,您可以:

testMat.convertTo(testMat, CV_32F);

更多细节和变体...

您可以简单地使用接受std::vectorMat 构造函数:

vector<Point> v =  0,1, 2,3, 4,5 ;
Mat m(v);

这样,您将获得一个 2 通道矩阵,其中包含 v 中的基础数据。这意味着如果您更改v 中的值,m 中的值也会更改。

v[0].x = 7; // also 'm' changes

如果您想要值的副本,以便v 中的更改不会反映在m 中,您可以使用clone

Mat m2 = Mat(v).clone();

您的矩阵是CV_32SC2 类型,即int 的2 个通道矩阵(因为Point 使用int。将Point2f 用于float)。如果你想要一个 2 列单通道矩阵,你可以使用 reshape:

Mat m3 = m2.reshape(1);

如果要转换为float类型,需要使用convertTo

Mat m4;
m2.convertTo(m4, CV_32F);

这里有一些工作代码作为概念证明:

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

int main()

    vector<Point> v =  0,1, 2,3, 4,5 ;

    // changes in v affects m
    Mat m(v); 

    // changes in v doesn't affect m2
    Mat m2 = Mat(v).clone(); 

    // m is changed
    v[0].x = 7; 

    // m3 is a 2 columns single channel matrix
    Mat m3 = m2.reshape(1);

    // m4 is a matrix of floats
    Mat m4;
    m2.convertTo(m4, CV_32F);

    return 0;

【讨论】:

以上是关于将轮廓点向量复制到垫子中的主要内容,如果未能解决你的问题,请参考以下文章

在 OpenCV 中将向量复制到向量

创建垫子后从字节向量将图像加载到垫子上

将项目从一个向量复制到另一个向量

如何将字符复制到字符串向量中

C++ 将对象向量中的元素复制到具有此元素的向量中

提升精神:将结果复制到字符串向量中