我目前正在开发一个关于应用程序的项目,该应用程序能够从绘制的图像中创建可玩的游戏关卡(可在此处找到:Github)。为此,我使用openCV进行图像处理 我的问题是一个函数,它应该将检测到的线条(图像中的“墙”)绘制成图像。
void LineFinder::drawDetectedLines( cv::Scalar color)
{
for (auto it = Play::getInstance()->getFinder()->getLines().begin(); it != Play::getInstance()->getFinder()->getLines().end(); ++it)
{
// The lines are stored in an std::vector<cv::Vec4i>,
// so basically in a vector which contains vectors with 4 elements each
cv::Point pt1((*it)[0], (*it)[1]);
cv::Point pt2((*it)[2], (*it)[3]);
// draws a line from pt1 to pt2
cv::line(Play::getInstance()->getFinder()->getImage(), pt1, pt2, color);
++it;
}
}
当这个函数执行时,大多数时候我都会遇到分段错误,但有时它会起作用,结果就像我预期的那样。我知道矢量包含元素 那么你能想到的这种行为有什么可能的原因吗?
编辑:有趣的是,当使用此功能的功能已经成功执行一次时,我可以反复执行它并且不会发生错误。
EDIT2:我仍然不知道为什么我会用迭代器得到分段错误,但如果没有迭代器,它会以某种方式工作:
void LineFinder::drawDetectedLines( cv::Scalar color)
{
for (int i = 0; i < Play::getInstance()->getFinder()->getLines().size(); ++i)
{
cv::Point pt1(Play::getInstance()->getFinder()->getLines()[i][0], Play::getInstance()->getFinder()->getLines()[i][1]);
cv::Point pt2(Play::getInstance()->getFinder()->getLines()[i][2], Play::getInstance()->getFinder()->getLines()[i][3]);
cv::line(Play::getInstance()->getFinder()->getImage(), pt1, pt2, color);
}
}
答案 0 :(得分:5)
两次递增迭代器。来到这里:
for (auto it = Play::getInstance()->getFinder()->getLines().begin(); it != Play::getInstance()->getFinder()->getLines().end(); ++it)
并且在这里:
++it;
可能会超过end()
迭代器,导致未定义的行为。
编辑:
您的帖子中没有足够的信息来识别其他问题,尤其是我不知道所有变量和功能是什么。我也不想爬过整个git。
所以这里有一些可能的问题:
Play::getInstance()->getFinder()->getLines()
是否保证始终返回对同一容器的引用?
返回的容器是否保证在迭代时不被修改?
容器中存储的对象是否保证为array / vectors / ...至少包含4个元素?
EDIT2:
好吧,我仔细查看了您的存储库,linefinder.cpp中存在错误:
std::vector<cv::Vec4i> LineFinder::getLines()
{
return lines;
}
getLines()
不会返回对同一容器的引用,它会在每次调用时返回一个副本。所以你继续比较一个容器的迭代器和你的for循环中另一个容器的迭代器。将定义更改为引用返回:
std::vector<cv::Vec4i>& LineFinder::getLines()
{
return lines;
}
或在构造迭代器之前保存返回值:
auto lines = Play::getInstance()->getFinder()->getLines();
for (auto it = lines.begin(); it != lines.end(); ++it)
{