OpenCV:向量<向量<Point>>向量的转换<Mat>,引用调用的问题
OpenCV: Conversion of vector<vector<Point>> to vector<Mat>, problems with call by reference
我试图使用OpenCV 2.4.9从图像中提取轮廓线。findContours
函数完成了大部分工作,但它返回轮廓线
作为类型CCD_ 2。我需要将它们转换为类型vector < Mat >
以供以后使用
我使用了Mat
类的构造函数来完成这项工作,一切都很好,直到我通过引用调用将结果从一个函数传递到另一个函数。以下代码再现错误:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void getCont(Mat& img, vector<Mat>& cLines, int thresh)
{
//binarize the image
Mat imgBin;
threshold(img, imgBin, thresh, 255, THRESH_BINARY_INV);
//find contour lines
vector<vector<Point>> contours;
findContours(imgBin, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
//convert vector<vector<Point>> to vector<Mat>
for (int i = 0; i < contours.size(); i++)
cLines.push_back(Mat(contours[i]));
cerr << "cLines[0] in getCont:n";
cerr << "cLines[0].rows: " << cLines[0].rows << "n";
cerr << "cLines[0].cols: " << cLines[0].cols << "n";
cerr << "cLines[0].channels(): " << cLines[0].channels() << "n";
cerr << "cLines[0].type(): " << cLines[0].type() << "n";
cerr << "cLines[0].row(0): " << cLines[0].row(0) << "n";
cerr << endl << endl;
}
int main()
{
Mat img = imread("leaf.jpg", 0);
int thresh = 124;
vector<Mat> cLines;
getCont(img, cLines, thresh);
cerr << "cLines[0] in main:n";
cerr << "cLines[0].rows: " << cLines[0].rows << "n";
cerr << "cLines[0].cols: " << cLines[0].cols << "n";
cerr << "cLines[0].channels(): " << cLines[0].channels() << "n";
cerr << "cLines[0].type(): " << cLines[0].type() << "n";
cerr << "cLines[0].row(0): " << cLines[0].row(0) << "n";
return 0;
}
当我试图打印出cLines
的第一个元素的第一行时,错误主要发生在return语句前的一行。对于不同的输入图像,我要么收到一条消息,告诉我.exe工作不正常,必须退出,要么实际打印出值,但它们与getCont
函数的输出不同(主要是,我得到负值,因此看起来有一些溢出)。我在Windows8/64位计算机上使用VisualStudio2013Express(但我使用的是OpenCV的x86 DLL库)。有人能在另一个系统上重现错误吗?
我认为有一些隐式类型转换,所以我在getCont
和main
中打印出了cLines
的大小和类型,但结果是相同的。当我将getCont
函数的代码放入main
时,不会发生错误,这样我就可以避免额外的函数调用。此外,当我更换环路时,一切都很好
for (int i = 0; i < contours.size(); i++)
cLines.push_back(Mat(contours[i]));
通过以下方式:
for (int i = 0; i < contours.size(); i++)
{
vector<Point> currPts = contours.at(i);
Mat currLine(currPts.size(), 1, CV_32SC2);
for (int j = 0; j < currPts.size(); j++)
{
currLine.at<Vec2i>(j, 0).val[0] = currPts.at(j).x;
currLine.at<Vec2i>(j, 0).val[1] = currPts.at(j).y;
}
cLines.push_back(currLine);
}
有人知道发生了什么事吗?
您使用了正确的构造函数,但错误地接受了第二个参数的默认值。以std::vector
为输入的Mat
构造函数的声明:
//! builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
cv::Mat构造函数的在线文档说明:
copyData
–用于指定STL矢量或旧样式CvMat或IplImage的基础数据是否应复制到(true)或与(false)新构建的矩阵共享的标志。复制数据时,使用Mat引用计数机制来管理分配的缓冲区。共享数据时,引用计数器为NULL,在矩阵未被破坏之前,不应解除分配数据。
你需要做:
cLines.push_back(Mat(contours[i],true));
否则,当您返回到main
时,向量将超出范围,并且getCont
中声明的vector<vector<Point>> contours
的数据缓冲区将被解除分配。
对于cv::Vec
、vector < vector < Point > >
0和Point3_
,与std::vector
不同,copyData
的默认值为true。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中