学校のプロジェクトで、私のグループは OpenCV を使用してビデオをキャプチャしています。これらの (トップダウン) 画像から、オブジェクトの位置が抽出され、ポイントのリストに変換されます。これらのポイントは、 http://code.google.com/p/poly2tri/を使用して三角形分割されます(非凸オブジェクトの可能性の問題を克服するため)。次に、三角形分割された地面ペインの座標を使用して、freeglut を使用して 3D でオブジェクトを描画します。(サイド ペインとトップ ペインは、グラウンド ペインの座標を使用して計算されます)。問題は、ポイントの古いリストを削除すると、アプリケーションがランダムにクラッシュすることです。1 秒後、30 秒後、数分後の場合もあります。表示されるエラーは「アクセス違反の書き込み場所 0xCCCCCCCC」です。
私たちのコード:
void WorldLayoutBuilder::update()
{
pointList.clear();
// Capture image
<code to capture image and get countours>
for(size_t i = 0; i < contours.size(); i++)
{
if(contours[i].size() > 50)
{
approxPolyDP(contours[i], approxShape, cv::arcLength(cv::Mat(contours[i]), true)*0.04, true);
drawContours(drawing, contours, i, cv::Scalar(255, 0, 0), 0);
std::vector<Point> newObject;
for(size_t j = 0; j < contours[i].size(); j++)
{
cv::Point newPoint = contours[i][j];
newObject.push_back(Point((float) newPoint.x / 100, 0.0f,(float) newPoint.y / 100));
}
pointList.push_back(newObject);
}
}
ObjectCreator3D::createObjects(&pointList);
contours.clear();
<code to release images, etc>
}
これは、画像をキャプチャし、オブジェクトの座標を取得してから、ObjectCreator3D::createObjects() を呼び出します。
void ObjectCreator3D::createObjects(std::list<std::vector<Point>>* inputList)
{
std::list<WorldObject>* tempObjects = new std::list<WorldObject>;
for(std::vector<Point>&pointObject : *inputList)
{
WorldObject worldObject(&pointObject);
tempObjects->push_back(worldObject);
}
DataStorage::getInstance()->setObjects(tempObjects);
}
すべてのオブジェクトは WorldObjects に変換されます。
#include <list>
#include <iostream>
#include <GL/glut.h>
#include <GL/freeglut.h>
#include <time.h>
#include "WorldObject.h"
#include "Point.h"
//Constant height - adjustable/randomized solution is partially implemented in the constructor.
const float WorldObject::HEIGHT = 5.0f;
template <class C> void FreeClear(C & cntr)
{
for(typename C::iterator it = cntr.begin(); it != cntr.end(); ++it)
{
delete * it;
}
cntr.clear();
}
WorldObject::WorldObject(std::vector<Point>* pointList)
{
//TODO, when we have time. Seems difficult because height will change each update...
/*srand (time(NULL));
float fGeneratedY = (rand() % 20 + 2) / 2.0f;*/
cdt = nullptr;
for (Point &point : *pointList)
//point.setY(fGeneratedY);
point.setY(HEIGHT);
this->pointList = pointList;
}
WorldObject::~WorldObject()
{
//Cleanup
delete cdt;
FreeClear(polyPoints);
}
/*
Author Tim Cocu & Bas Rops
Function for drawing the WorldObject
*/
void WorldObject::draw()
{
glPushMatrix();
glColor3f(0.8f, 0.8f, 0.8f);
//Calculate our bottom pane
calculateTriangles();
//BOTTOM PANE
for (unsigned int i = 0; i < calculatedTriangles.size(); i++)
{
p2t::Triangle& t = *calculatedTriangles[i];
p2t::Point& a = *t.GetPoint(0);
p2t::Point& b = *t.GetPoint(1);
p2t::Point& c = *t.GetPoint(2);
glBegin(GL_TRIANGLES);
glNormal3f(0, -1, 0);
glVertex3f((GLfloat)a.x, (GLfloat)0.0f, (GLfloat)a.y);
glVertex3f((GLfloat)b.x, (GLfloat)0.0f, (GLfloat)b.y);
glVertex3f((GLfloat)c.x, (GLfloat)0.0f, (GLfloat)c.y);
glEnd();
}
//TOP PANE
for (unsigned int i = 0; i < calculatedTriangles.size(); i++)
{
p2t::Triangle& t = *calculatedTriangles[i];
p2t::Point& a = *t.GetPoint(0);
p2t::Point& b = *t.GetPoint(1);
p2t::Point& c = *t.GetPoint(2);
glBegin(GL_TRIANGLES);
glNormal3f(0, 1, 0);
glVertex3f((GLfloat)a.x, (GLfloat)HEIGHT, (GLfloat)a.y);
glVertex3f((GLfloat)b.x, (GLfloat)HEIGHT, (GLfloat)b.y);
glVertex3f((GLfloat)c.x, (GLfloat)HEIGHT, (GLfloat)c.y);
glEnd();
}
glColor3f(1.0f, 1.0f, 1.0f);
//SIDE PANES
for(std::size_t iPaneCounter = 0; iPaneCounter < pointList->size(); iPaneCounter++)
{
Point firstPoint = (*pointList)[iPaneCounter];
Point secondPoint (0.0f, 0.0f, 0.0f);
if(iPaneCounter + 1 < pointList->size())
secondPoint.set((*pointList)[iPaneCounter + 1].getX(), (*pointList)[iPaneCounter + 1].getY(), (*pointList)[iPaneCounter + 1].getZ() );
else
secondPoint.set((*pointList)[0].getX(), (*pointList)[0].getY(), (*pointList)[0].getZ());
glBegin(GL_POLYGON);
float fNormalX = (firstPoint.getY() * secondPoint.getZ()) - (firstPoint.getZ() * secondPoint.getY());
float fNormalY = -((secondPoint.getZ() * firstPoint.getX()) - (secondPoint.getX() * firstPoint.getZ()));
float fNormalZ = (firstPoint.getX() * secondPoint.getY()) - (firstPoint.getY() * secondPoint.getX());
glNormal3f(fNormalX, fNormalY, fNormalZ);
glVertex3f(firstPoint.getX(), 0.0f, firstPoint.getZ());
glVertex3f(secondPoint.getX(), 0.0f, secondPoint.getZ());
glVertex3f(secondPoint.getX(), secondPoint.getY(), secondPoint.getZ());
glVertex3f(firstPoint.getX(), firstPoint.getY(), firstPoint.getZ());
glEnd();
}
}
/*
Calculates triangles that make a ground or top pane. Used for calculating possible non-convex objects
*/
void WorldObject::calculateTriangles()
{
//Empty the polyPoints list
if(polyPoints.size() > 0)
FreeClear(polyPoints);
//Convert our Points to p2t::Points
for(std::size_t iBottomIndex = 0; iBottomIndex < pointList->size(); iBottomIndex++)
polyPoints.push_back(new p2t::Point((*pointList)[iBottomIndex].getX(), (*pointList)[iBottomIndex].getZ()));
if(cdt == nullptr)
//Create CDT (Constrained Delaunay Triangulation) and add primary polyPoints
//NOTE: polyPoints must be a simple polygon. The polyPoints' points constitute constrained edges. No repeating points are allowed!
cdt = new p2t::CDT(polyPoints);
//Turn our polyPoints into p2t::Triangles
cdt->Triangulate();
//Set the triangles to use for drawing
calculatedTriangles = cdt->GetTriangles();
}
/*
Retrieve a pointer to a list of Points
*/
std::vector<Point>* WorldObject::getPoints()
{
return pointList;
}
/*
Retrieve a pointer to a list of p2t::Triangles
*/
std::vector<p2t::Triangle*> WorldObject::getCalculatedTriangles()
{
return calculatedTriangles;
}
すべての WorldObject が作成されると、DataStorage に格納され、DataStorage::getInstance()->setObjects() が呼び出されます。
void DataStorage::setObjects(std::list<WorldObject>* objectList)
{
delete this->objectList;
this->objectList = objectList;
}
this->objectList; を削除すると、アプリケーションがクラッシュするようです。したがって、アプリケーションは削除できないものを削除しようとしていると考えられます。
どんな助けでも大歓迎です、私たちはすでに数日間これに取り組んでいます