gpt4 book ai didi

c++ - OpenCV:vector> 到 vector 的转换,引用调用的问题

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:42:12 25 4
gpt4 key购买 nike

我尝试使用 OpenCV 2.4.9 从图像中提取轮廓线。
findContours函数完成大部分工作,但它返回轮廓线
作为类型 vector < vector < Point > > .我需要将它们转换为类型 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 的第一个元素的第一行时,错误发生在 main 中,在 return 语句之前的行中.对于不同的输入图像,我要么收到一条消息,告诉我 .exe 无法正常工作并且必须退出,要么实际打印出值,但它们与 getCont 的输出不同。函数(主要是,我得到负值,所以看起来有些溢出)。我在 Windows 8 64 位机器上使用 Visual Studio 2013 Express(但我使用的是 OpenCV 的 x86 DLL 库)。任何人都可以在不同的系统上重现错误吗?

我认为有一些隐式类型转换,所以我打印出 cLines 的大小和类型在getContmain ,但结果是一样的。当我输入 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);
}

有人知道这是怎么回事吗?

最佳答案

您使用了正确的构造函数,但错误地接受了第二个参数的默认值。 Mat 的声明构造函数 std::vector作为输入:

//! builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);

online documentation对于 cv::Mat 构造函数状态:

copyData – Flag to specify whether the underlying data of the STL vector or the old-style CvMat or IplImage should be copied to (true) or shared with (false) the newly constructed matrix. When the data is copied, the allocated buffer is managed using Mat reference counting mechanism. While the data is shared, the reference counter is NULL, and you should not deallocate the data until the matrix is not destructed.

你需要做的:

cLines.push_back(Mat(contours[i],<b>true</b>));

否则当您返回到main 时 vector 将超出范围和 vector<vector<Point>> contours 的数据缓冲区在 getCont 中声明将被释放。

对于 cv::Vec , Point_ , 和 Point3_ , 默认为 copyData是真的,不像 std::vector .

关于c++ - OpenCV:vector<vector<Point>> 到 vector<Mat> 的转换,引用调用的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26712662/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com