Example #1
0
bool MFReconstruct::runReconstruction()
{
    bool runSucess = false;

    ///加载相机标定参数及所采集图像
    for(int i = 0; i < 2; i++){
        camsPixels[i] = new cv::vector<double>[cameraHeight * cameraWidth];//将每个相机图像中的每个像素在投影区域中的横坐标记录

        runSucess = loadCamImgs(scanFolder[i], imgPrefix[i], imgSuffix);

        ///对指针存储器camsPixels赋值,camsPixels[i]的地址就是camPixel的地址
        camPixels = camsPixels[i];

        ///截至这一步,实例camera的position、width、height属性已被赋值,camera对应cameras[i]
        if(!runSucess)//如果加载图片失败,中断
            break;
        else{
            computeShadows();
            decodePatterns();
            unloadCamImgs();
        }
    }

    if(runSucess){
        points3DProjView = new PointCloudImage(cameraWidth, cameraHeight, haveColor); //最后一个bool值代表是否上色,这里改为false
        triangulation(camsPixels[0],camsPixels[1]);
    }
    return runSucess;
}
Example #2
0
QcPolygonTriangulation::QcPolygonTriangulation(const QcPathDouble & path)
  : m_path(path)
{
  int number_of_vertexes = path.number_of_vertexes();
  int number_of_segments = number_of_vertexes -2; // Fixme: true ?

  double vertexes[number_of_vertexes][2];
  int i = 0;
  for (const auto & vertex : path.vertexes()) {
    qInfo() << vertex;
    vertexes[i][0] = vertex.x();
    vertexes[i][1] = vertex.y();
    i++;
  }

  int triangles[number_of_segments][3];
  for (int i = 0; i < number_of_segments; i++) {
    for (int j = 0; j < 3; j++)
      triangles[i][j] = 0;
  }

  QcSeidlerPolygonTriangulation triangulation(number_of_vertexes, vertexes, triangles);

  for (int i = 0; i < number_of_segments; i++) {
    qInfo() << triangles[i][0] << triangles[i][1] << triangles[i][2];
    m_triangles << QcTriangleIndex(triangles[i][0] -1,
                                   triangles[i][1] -1,
                                   triangles[i][2] -1);
  }
}
std::vector<int> collectInnerPointsIDs(std::vector<Point_3> points)
{
	DEBUG_START;
	Delaunay::Lock_data_structure locking_ds(
			CGAL::Bbox_3(-1000., -1000., -1000., 1000.,
				1000., 1000.), 50);
	Delaunay triangulation(points.begin(), points.end(),
			&locking_ds);
	auto infinity = triangulation.infinite_vertex();

	std::vector<int> outerPlanesIDs;
	int numPlanes = points.size();
	for (int i = 0; i < numPlanes; ++i)
	{
		Point_3 point = points[i];
		Delaunay::Locate_type lt;
		int li, lj;
		Delaunay::Cell_handle c = triangulation.locate(point,
				lt, li, lj);

		auto vertex = c->vertex(li);
		ASSERT(lt == Delaunay::VERTEX
					&& vertex->point() == point);
		if (!triangulation.is_edge(vertex, infinity, c, li, lj))
		{
			outerPlanesIDs.push_back(i);
		}
	}
	DEBUG_END;
	return outerPlanesIDs;
}
Example #4
0
	tree<T,P,M,N,impl_type> & operator=(const graph<T,P,M,N, impl_type> &g) {
		typedef graph<T,P,M,N,impl_type> super;
		// we make first a copy of the graph where we subsequently apply "moralization" and "triangulation"
		super::operator=(g);
		moralization();
		triangulation();
		return *this;
	}
// This test case is based on the example presented on page 725 of the
// paper: "Three dimensional triganulations from local transformations"
// by Barry Joe (Siam J. Sci. Stat. Comput. Vol 10, No 4, 1989).
void DelaunayTriangulationTest::joe89()
{
    std::vector<chemkit::Point3> points;
    points.push_back(chemkit::Point3(0.054f, 0.099f, 0.993f));
    points.push_back(chemkit::Point3(0.066f, 0.756f, 0.910f));
    points.push_back(chemkit::Point3(0.076f, 0.578f, 0.408f));
    points.push_back(chemkit::Point3(0.081f, 0.036f, 0.954f));
    points.push_back(chemkit::Point3(0.082f, 0.600f, 0.726f));
    points.push_back(chemkit::Point3(0.085f, 0.327f, 0.731f));
    points.push_back(chemkit::Point3(0.123f, 0.666f, 0.842f));
    points.push_back(chemkit::Point3(0.161f, 0.303f, 0.975f));

    chemkit::DelaunayTriangulation triangulation(points);
    QCOMPARE(triangulation.vertexCount(), 8);
    QCOMPARE(triangulation.tetrahedronCount(), 13);

    QList<QVector<int> > expectedTetrahedra;
    expectedTetrahedra.append(QVector<int>() << 0 << 1 << 2 << 4);
    expectedTetrahedra.append(QVector<int>() << 0 << 1 << 4 << 5);
    expectedTetrahedra.append(QVector<int>() << 0 << 1 << 5 << 7);
    expectedTetrahedra.append(QVector<int>() << 0 << 2 << 3 << 5);
    expectedTetrahedra.append(QVector<int>() << 0 << 2 << 4 << 5);
    expectedTetrahedra.append(QVector<int>() << 0 << 3 << 5 << 7);
    expectedTetrahedra.append(QVector<int>() << 1 << 2 << 4 << 6);
    expectedTetrahedra.append(QVector<int>() << 1 << 4 << 5 << 7);
    expectedTetrahedra.append(QVector<int>() << 1 << 4 << 6 << 7);
    expectedTetrahedra.append(QVector<int>() << 2 << 3 << 5 << 7);
    expectedTetrahedra.append(QVector<int>() << 2 << 4 << 5 << 6);
    expectedTetrahedra.append(QVector<int>() << 2 << 5 << 6 << 7);
    expectedTetrahedra.append(QVector<int>() << 4 << 5 << 6 << 7);

    std::vector<std::vector<int> > tetrahedra = triangulation.tetrahedra();
    QCOMPARE(tetrahedra.size(), size_t(expectedTetrahedra.size()));

    for(unsigned int i = 0; i < tetrahedra.size(); i++){
        std::vector<int> tetrahedron = tetrahedra[i];
        std::sort(tetrahedron.begin(), tetrahedron.end());

        int foundCount = 0;

        for(int j = 0; j < expectedTetrahedra.size(); j++){
            QVector<int> expectedTetrahedron = expectedTetrahedra[j];

            if(tetrahedron == expectedTetrahedron.toStdVector()){
                foundCount++;
            }
        }

        if(foundCount != 1){
            qDebug() << "tetrahedron (index " << i << ") was not found. verticies: " << QVector<int>::fromStdVector(tetrahedron);
        }

        QCOMPARE(foundCount, 1);
    }
}
void DelaunayTriangulationTest::serine()
{
    // coordinates of the atoms
    std::vector<chemkit::Point3> points;
    points.push_back(chemkit::Point3(-0.1664, -1.0370, 0.4066));
    points.push_back(chemkit::Point3(1.2077, -0.5767, -0.0716));
    points.push_back(chemkit::Point3(-0.6079, -1.5894, -0.3173));
    points.push_back(chemkit::Point3(1.1440, -0.3456, -1.0571));
    points.push_back(chemkit::Point3(2.2495, -1.7077, 0.1008));
    points.push_back(chemkit::Point3(1.6659, 0.7153, 0.7175));
    points.push_back(chemkit::Point3(1.7844, 0.4727, 1.7759));
    points.push_back(chemkit::Point3(0.8959, 1.5129, 0.6034));
    points.push_back(chemkit::Point3(2.8918, 1.1700, 0.2007));
    points.push_back(chemkit::Point3(3.1444, 1.9558, 0.6711));
    points.push_back(chemkit::Point3(1.8101, -2.8570, 0.2804));
    points.push_back(chemkit::Point3(3.4579, -1.3878, 0.0035));
    points.push_back(chemkit::Point3(-0.0600, -1.6097, 1.2601));
    points.push_back(chemkit::Point3(-0.7527, -0.2118, 0.6162));

    // calculate delaunay triangulation
    chemkit::DelaunayTriangulation triangulation(points);
    QCOMPARE(triangulation.vertexCount(), 14);
    QCOMPARE(triangulation.edgeCount(), 60);
    QCOMPARE(triangulation.triangleCount(), 140);
    QCOMPARE(triangulation.tetrahedronCount(), 39);

    // weights (squared van der waals radii)
    std::vector<chemkit::Real> weights;
    weights.push_back(2.4025);
    weights.push_back(2.90);
    weights.push_back(1.44);
    weights.push_back(1.44);
    weights.push_back(2.90);
    weights.push_back(2.90);
    weights.push_back(1.44);
    weights.push_back(1.44);
    weights.push_back(2.3104);
    weights.push_back(1.44);
    weights.push_back(2.3104);
    weights.push_back(2.3104);
    weights.push_back(1.44);
    weights.push_back(1.44);

    // calculate weighted delaunay triangulation
    chemkit::DelaunayTriangulation weightedTriangulation(points, weights);
    QCOMPARE(weightedTriangulation.vertexCount(), 14);
    QCOMPARE(weightedTriangulation.edgeCount(), 60);
    QCOMPARE(weightedTriangulation.triangleCount(), 140);
    QCOMPARE(weightedTriangulation.tetrahedronCount(), 39);
}
void StereoReconstructor::RestructPointCloud(bool objSpace, bool undistort, std::string pcfilename) {
  //载入2个虚拟摄像机
  VirtualCamera vc1;
  VirtualCamera vc2;
  //载入内参
  vc1.loadCameraMatrix("reconstruct\\LeftMatrix.txt");
  vc1.loadDistortion("reconstruct\\LeftDistortion.txt");
  vc1.rotationMatrix = cv::Mat::eye(3, 3, CV_32FC1);
  vc1.translationVector = cv::Mat::zeros(3, 1, CV_32FC1);
  vc2.loadCameraMatrix("reconstruct\\RightMatrix.txt");
  vc2.loadDistortion("reconstruct\\RightDistortion.txt");
  vc2.loadRotationMatrix("reconstruct\\R.txt");
  vc2.loadTranslationVector("reconstruct\\T.txt");

  vc1.loadKeyPoints("left.txt");					//载入角点
  vc2.loadKeyPoints("right.txt");

  //重建3d点
  std::vector<RestructPoint> ret;
  ret = triangulation(vc1, vc2, undistort);	//true进行畸变矫正,false表示不进行

  //保存结果
  std::vector<StereoReconstructor::RestructPoint> ans;
  for (size_t i = 0; i != ret.size(); ++i)
    ans.push_back(StereoReconstructor::RestructPoint(ret[i].point, ret[i].distance));

  plyFileGenerate(ans,
                  pcfilename,					//ply文件
                  "_calPointsDis.txt",			//3d点+相交距离
                  "_calPoints.txt");				//3d点

  //转换到物体坐标系
  if (objSpace) {
    translateCoordinate(
      "Coordinate.txt",				//棋盘格坐标系
      "_calPoints.txt",				//要转换的3D点
      "Points_obj.txt");				//在棋盘格坐标系下的坐标calPoints_ObjSpace.txt

    //生成物体坐标系下的ply文件
    std::vector<cv::Point3f> pointcloud = Utilities::load3dPoints("Points_obj.txt");
    Utilities::savePly(pointcloud, "PointsObj.ply");
  }
}
Example #8
0
bool NNormalSurfaceList::saveCSVEdgeWeight(const char* filename,
        int additionalFields) {
    std::ofstream out(filename);
    if (! out)
        return false;

    unsigned long n = triangulation()->countEdges();

    unsigned long i, j;

    // Write the CSV header.
    writePropHeader(out, additionalFields);
    for (i = 0; i < n; ++i) {
        out << 'E' << i;

        if (i < n - 1)
            out << ',';
    }
    out << std::endl;

    // Write the data for individual surfaces.
    unsigned long tot = size();
    const NNormalSurface* s;
    for (i = 0; i < tot; ++i) {
        s = surface(i);

        writePropData(out, s, additionalFields);

        for (j = 0; j < n; ++j) {
            out << s->edgeWeight(j);

            if (j < n - 1)
                out << ',';
        }
        out << std::endl;
    }

    // All done!
    return true;
}
void Reconstructor::runReconstruction()
{
	for(int i=0; i< numOfCams; i++)
	{
		if(cameras[i].distortion.empty())
		{
			std::cout<<"Camera "<<i<< "is not set.\n";
			exit(-1);
		}

		if(pathSet[i] == false)
		{
			std::cout<<"Image path for camera "<< i <<" is not set.";
			exit(-1);
		}
	}

	GrayCodes grays(proj_w,proj_h);

	numOfColBits = grays.getNumOfColBits();
	numOfRowBits = grays.getNumOfRowBits();
	numberOfImgs = grays.getNumOfImgs();
	

	for(int i=0; i < numOfCams; i++)
	{

		//findProjectorCenter();
		cameras[i].position = cv::Point3f(0,0,0);
		cam2WorldSpace(cameras[i],cameras[i].position);
	
		camera = &cameras[i];
		camsPixels[i] = new cv::vector<cv::Point>[proj_h*proj_w];
		camPixels = camsPixels[i];

		loadCamImgs(camFolder[i],imgPrefix[i],imgSuffix[i]);

		colorImgs.push_back(cv::Mat());
		colorImgs[i] = color;
		computeShadows();
		if(saveShadowMask_)
		{
			std::stringstream path;
			path<<"cam"<<i+1<<"Mask.png";
			saveShadowImg(path.str().c_str());
		}
		
		decodePaterns();

		unloadCamImgs();
	}
	
	//reconstruct 
	points3DProjView = new PointCloudImage( proj_w, proj_h , true );
	
	for(int i = 0; i < numOfCams; i++)
	{
		for(int j=i+1; j< numOfCams; j++)
			triangulation(camsPixels[i],cameras[i],camsPixels[j],cameras[j],i,j);
	}

}
/**
 * Function for reading the input from a OFF file.
 * @param *infile FILE, the file to be read.
 * @param NVertices int, the number of vertices.
 * @param NFaces int, the total amount of faces.
 * @param NEdges int, the total amount of edges.
 * @param *allVectors, one pointer to one array of struct type myVector.
 * @return a pointer to a triangledFaces struct.
 */
triangledFaces *readFromFile(FILE *inFile, int NVertices, int NFaces,
						int NEdges, myVector *allVectors, objectData *allData){

	setlocale(LC_ALL,"C");

	char readLine[256], *temp;
	int  i,j, colorCounter, totNrOfTriangles = 0;
	faces *(allFaces[NFaces]);

	/*reading and storing all the vertices.*/
	for(i=0;i<NVertices;i++){
		fgets(readLine,256,inFile);

		/*dont read lines that doesn't contain anything.*/
		if(strlen(readLine)>2){
			//putting in the vector values in a struct.
			sscanf(readLine,"%f%f%f",&allVectors[i].x,&allVectors[i].y,
										&allVectors[i].z);

			/*saving the smallest/biggest values for calculating the origo.*/
			if(allVectors[i].x > allData->biggestX){
				allData->biggestX = allVectors[i].x;
			}
			if(allVectors[i].x < allData->smallestX){
				allData->smallestX = allVectors[i].x;
			}
			if(allVectors[i].y > allData->biggestY){
				allData->biggestY = allVectors[i].y;
			}
			if(allVectors[i].y < allData->smallestY){
				allData->smallestY = allVectors[i].y;
			}
			if(allVectors[i].z > allData->biggestZ){
				allData->biggestZ = allVectors[i].z;
			}
			if(allVectors[i].z < allData->smallestZ){
				allData->smallestZ = allVectors[i].z;
			}
		}else{
			i--;
		}
	}

	/*allocating and calculating the origo for the object (a + ((b-a)/2) ).*/
	allData->origoForObject = (myVector*) malloc(sizeof(myVector));

	allData->origoForObject->x = (allData->smallestX +
									((allData->biggestX-allData->smallestX)/2));
	allData->origoForObject->y = (allData->smallestY +
									((allData->biggestY-allData->smallestY)/2));
	allData->origoForObject->z = (allData->smallestZ +
									((allData->biggestZ-allData->smallestZ)/2));

	/*getting all the edges*/
	for (i=0;i<NFaces;i++){
		fgets(readLine,256,inFile);
		faces *oneFace = (faces*) malloc(sizeof(faces));

		//putting all the edge values in a struct. observe token=space and tab.
		temp = strtok(readLine," \t");
		oneFace-> nrOfvertices = atoi(temp);
		totNrOfTriangles = totNrOfTriangles + (atoi(temp) -2);

		//make sure that the polygon values fits in array vertices[].
		if(oneFace->nrOfvertices < 128){

			for(j=0;j<(oneFace->nrOfvertices);j++){
				temp = strtok(NULL," \t");
				oneFace->vertices[j] = &allVectors[atoi(temp)];
				oneFace->vertexIndeces[j] = atoi(temp);
			}
			colorCounter = 0;

			//reading in color (if any).
			while((temp = strtok(NULL," ")) != NULL){
				oneFace->colours[colorCounter] =  atof(temp);
				colorCounter++;
			}
			allFaces[i] = oneFace;
		}else{

			printf("ERROR! one polygon has too many vertices ");
			printf("to fit in the program.\n");
			printf("closing program.\n");
			return NULL;
		}
	}

	triangledFaces *triangles = (triangledFaces*) calloc(totNrOfTriangles,
									sizeof (triangledFaces));

	//call function for triangulation.
	triangulation(allFaces, NFaces, triangles);
	nrOfTrianglePolygons = totNrOfTriangles;
	return triangles;
}
Example #11
0
bool NNormalSurfaceList::saveCSVStandard(const char* filename,
        int additionalFields) {
    std::ofstream out(filename);
    if (! out)
        return false;

    unsigned long n = triangulation()->size();

    unsigned long i, j;

    // Write the CSV header.
    writePropHeader(out, additionalFields);
    for (i = 0; i < n; ++i) {
        out << 'T' << i << ":0,";
        out << 'T' << i << ":1,";
        out << 'T' << i << ":2,";
        out << 'T' << i << ":3,";
        out << 'Q' << i << ":01/23,";
        out << 'Q' << i << ":02/13,";
        out << 'Q' << i << ":03/12";

        if (! allowsAlmostNormal()) {
            if (i < n - 1)
                out << ',';
            continue;
        }
        out << ',';

        out << 'K' << i << ":01/23,";
        out << 'K' << i << ":02/13,";
        out << 'K' << i << ":03/12";

        if (i < n - 1)
            out << ',';
    }
    out << std::endl;

    // Write the data for individual surfaces.
    unsigned long tot = size();
    const NNormalSurface* s;
    for (i = 0; i < tot; ++i) {
        s = surface(i);

        writePropData(out, s, additionalFields);

        for (j = 0; j < n; ++j) {
            out << s->triangles(j, 0) << ',';
            out << s->triangles(j, 1) << ',';
            out << s->triangles(j, 2) << ',';
            out << s->triangles(j, 3) << ',';
            out << s->quads(j, 0) << ',';
            out << s->quads(j, 1) << ',';
            out << s->quads(j, 2);

            if (! allowsAlmostNormal()) {
                if (j < n - 1)
                    out << ',';
                continue;
            }
            out << ',';

            out << s->octs(j, 0) << ',';
            out << s->octs(j, 1) << ',';
            out << s->octs(j, 2);

            if (j < n - 1)
                out << ',';
        }
        out << std::endl;
    }

    // All done!
    return true;
}
void StereoReconstructor::RestructCalibrationPointsFromImage(std::string leftFilename, std::string rightFilename, int x, int y, int squareLength) {
  //计算角点
  bool f1, f2;
  CameraCalibration::findCorners(leftFilename, f1, x, y);
  CameraCalibration::findCorners(rightFilename, f2, x, y);
  
  if (!f1 || !f2) {
    std::cout << "角点没找到" << std::endl;
    return;
  }

  //载入2个虚拟摄像机
  VirtualCamera vc1;
  VirtualCamera vc2;
  //载入内参
  vc1.loadCameraMatrix("reconstruct\\LeftMatrix.txt");
  vc1.loadDistortion("reconstruct\\LeftDistortion.txt");
  vc1.rotationMatrix = cv::Mat::eye(3, 3, CV_32FC1);
  vc1.translationVector = cv::Mat::zeros(3, 1, CV_32FC1);
  vc2.loadCameraMatrix("reconstruct\\RightMatrix.txt");
  vc2.loadDistortion("reconstruct\\RightDistortion.txt");
  vc2.loadRotationMatrix("reconstruct\\R.txt");
  vc2.loadTranslationVector("reconstruct\\T.txt");

  //载入角点	
  vc1.loadKeyPoints(leftFilename + "_imgCorners.txt");
  vc2.loadKeyPoints(rightFilename + "_imgCorners.txt");

  //重建3d点
  std::vector<RestructPoint> ret;
  ret = triangulation(vc1, vc2, true);	//进行畸变矫正,false表示不进行

  //保存结果
  //生成点云文件
  plyFileGenerate(ret,
                  leftFilename + ".ply",		//ply文件
                  "_calPointsDis.txt",		//3d点+相交距离
                  "_calPoints.txt");			//3d点
  //评估长度误差
  resultEvaluate(ret,
                 "_calLineLength.txt",		//157条线段的误差calLineLength.txt
                 "_calLineLengthDist.txt",	//线段的长度的概率分布
                 x, y, squareLength);
  //计算棋盘格坐标系
  computeCoordinate(
    "_calPoints.txt",			//读取棋盘格坐标
    "_coordinate.txt",			//计算坐标系,保存到Coordinate.txt
    x, y);						//水平方向和垂直方向的角点个数
  //转换到棋盘格坐标系
  translateCoordinate(
    "_coordinate.txt",			//棋盘格坐标系
    "_calPoints.txt",			//要转换的3D点
    "_calPoints_ObjSpace.txt");	//在棋盘格坐标系下的坐标calPoints_ObjSpace.txt

  //生成物体坐标系下的ply文件
  std::vector<cv::Point3f> pointcloud = Utilities::load3dPoints("_calPoints_ObjSpace.txt");
  Utilities::savePly(pointcloud, "ObjSpace" + leftFilename + ".ply");

  //生成棋盘格物体空间坐标,并载入
  Utilities::generateObjCorners("_chessbordCorner.txt", x, y, squareLength);
  std::vector<cv::Point3f> ideaPts = Utilities::load3dPoints("_chessbordCorner.txt");
  std::vector<cv::Point3f> realPts = Utilities::load3dPoints("_calPoints_ObjSpace.txt");
  //计算到角点的绝对距离,并保存
  std::ofstream absDis("_absCornerDistance.txt");
  for (int i = 0; i < ideaPts.size(); i++) {
    cv::Point3f idea = ideaPts[i];
    cv::Point3f real = realPts[i];
    float dis = cv::norm((idea - real));
    absDis << dis << std::endl;
  }
  absDis.close();

}
void mousePtPlot(GLint button, GLint action, GLint xMouse, GLint yMouse){
	EDGE *ptr;
	int j=0;
	PLG *PLGptr;

	if(flag == 9) return;

	//按下左鍵
	if(button == GLUT_LEFT_BUTTON && action == GLUT_DOWN){
		//第二個點
		if(flag == 1){
			//存入邊
			listhead = listLink(listhead, &current, previousX, previousY, xMouse, winHeight - yMouse, 1);
			counti++;
			//畫出外框
			
			glColor3f(0.0,  1.0,  0.0);
			glBegin(GL_LINES);
				glVertex2i(previousX,  previousY);
				glVertex2i(xMouse,	winHeight - yMouse);
			glEnd();
		}
		//第一個點
		if(flag == 0){
			//紀錄起始點
			startX = xMouse;
			startY = winHeight - yMouse;
			flag = 1;
		}
		//紀錄上一個點

		else if(flag == 4){

			printf("triangle start\n");
			PLGptr = polygonlist;
			
			for(j=1;;j++){
				triangulation(PLGptr->list, trianglehead);
				PLGptr = PLGptr->next;
				if(PLGptr == NULL)	break;
			}
			PrintTRG(trianglehead);
			glFlush();

			printf("triangle finish\n");
			flag = 5;

		}
		else if(flag == 5){
			printf("drawing start\n");
			fillcollor(trianglehead);
			printf("drawing finish\n");
			flag = 9;
		}
		if(flag != 5 || flag != 9){
			previousX = xMouse;
			previousY = winHeight - yMouse;
			plotPoint(xMouse,  winHeight - yMouse);
		}
		if(flag == 3)	flag = 4;
	}
	//按下右鍵
	if(button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN && doneflag == 0){
		//把最後一個點和起始點連接
		listhead = listLink(listhead, &current, previousX, previousY,startX, startY, 1);
		polygonlist = polygon_link(polygonlist, listhead, &PLGcurrent);
			glColor3f(0.0,  1.0,  0.0);
			glBegin(GL_LINES);
				glVertex2i(previousX,  previousY);
				glVertex2i(startX,	startY);
			glEnd();		
		flag = 4;
		//畫出外框
		glFlush();
		printf("draw contour finish\n");
		doneflag = 1;
	}
	glFlush();
}
Example #14
0
/* Function: main
 * 
 * Description: Main function to extract frames from 2 video files and runs the
 *     rest of the program using them. Takes at least 10 commandline arguments, 
 *     in the order: 
 *        <number of camera pairs>
 *        <pair 1 camera 1 filename>
 *        <pair 1 camera 1 frame number>
 *        <pair 1 camera 2 filename>
 *        <pair 1 camera 2 frame number>
 *        <pair 1 view name>
 *        <pair 1 camera coefficients filename>
 *        ...
 *        <TPS smoothing parameter>
 *        <feature detector>
 *        <output directory>
 * 
 * Parameters:
 *     argc: number of commandline arguments
 *     argv: string array of commandline arguments
 * 
 * Returns: 0 on success, 1 on error.
 */
int main (int argc, char *argv[])
{    
    // check for minimum number of commandline arguments
    if (argc < 11)
    {
        printf("Usage:\nvideos\n\t<number of camera pairs>\n\t<pair 1 camera 1 filename>\n\t<pair 1 camera 1 frame number>\n\t<pair 1 camera 2 filename>\n\t<pair 1 camera 2 frame number>\n\t<pair 1 view name>\n\t<pair 1 camera coefficients filename>\n\t...\n\t<TPS smoothing parameter>\n\t<feature detector>\n\t<output directory>\n");
        exit(1);
    }
    
    // get the number of camera pairs
    int numCameraPairs = atoi(argv[1]);
    
    if (numCameraPairs <= 0)
    {
        printf("Invalid number of camera pairs.\n");
        exit(1);
    }
    
    // number of commandline arguments should be numCameraPairs*6 + 5
    if (argc != numCameraPairs*6 + 5)
    {
        printf("Usage:\nvideos\n\t<number of camera pairs>\n\t<pair 1 camera 1 filename>\n\t<pair 1 camera 1 frame number>\n\t<pair 1 camera 2 filename>\n\t<pair 1 camera 2 frame number>\n\t<pair 1 view name>\n\t<pair 1 camera coefficients filename>\n\t...\n\t<TPS smoothing parameter>\n\t<feature detector>\n\t<output directory>\n");
        exit(1);
    }
    
    // allocate memory to store information for camera pairs
    char **camera1Filenames = (char **)malloc(numCameraPairs * sizeof(char *));
    int *camera1Frames = (int *)malloc(numCameraPairs * sizeof(int));
    
    if (camera1Filenames == NULL || camera1Frames == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    char **camera2Filenames = (char **)malloc(numCameraPairs * sizeof(char *));
    int *camera2Frames = (int *)malloc(numCameraPairs * sizeof(int));
    
    if (camera2Filenames == NULL || camera2Frames == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    char **cameraNames = (char **)malloc(numCameraPairs * sizeof(char *));
    
    if (cameraNames == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    char **cameraCoefficientsFilenames = (char **)malloc(numCameraPairs * sizeof(char *));
    
    if (cameraCoefficientsFilenames == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    int argIndex = 2;
    
    for (int i = 0; i < numCameraPairs; i++)
    {        
        camera1Filenames[i] = argv[argIndex];    
        camera1Frames[i] = atoi(argv[argIndex+1]);
        camera2Filenames[i] = argv[argIndex+2];
        camera2Frames[i] = atoi(argv[argIndex+3]);
        cameraNames[i] = argv[argIndex+4];
        cameraCoefficientsFilenames[i] = argv[argIndex+5];
        
        // make sure input video frames are valid
        if (camera1Frames[i] <= 0)
        {
            printf("Invalid frame number for pair %d camera 1.\n", i+1);
            exit(1);
        }
        
        if (camera2Frames[i] <= 0)
        {
            printf("Invalid frame number for pair %d camera 1.\n", i+1);
            exit(1);
        }
        
        // make sure input filenames are valid
        if (!fileExists(camera1Filenames[i]))
        {
            printf("Could not open pair %d camera 1 video file.\n", i+1);
            exit(1);
        }
        
        if (!fileExists(camera2Filenames[i]))
        {
            printf("Could not open pair %d camera 2 video file.\n", i+1);
            exit(1);
        }
        
        if (!fileExists(cameraCoefficientsFilenames[i]))
        {
            printf("Could not open pair %d camera coefficients file.\n", i+1);
            exit(1);
        }
        
        argIndex += 6;
    }
    
    double regularization = atof(argv[argIndex]);
    char *featureDetector = argv[argIndex+1];
    char *outputDirectory = argv[argIndex+2];
            
    // make sure input feature dectector is recognized
    if (strcasecmp(featureDetector, FAST_FEATURE_DETECTOR) &&        
        strcasecmp(featureDetector, GFTT_FEATURE_DETECTOR) &&      
        strcasecmp(featureDetector, SURF_FEATURE_DETECTOR) &&
        strcasecmp(featureDetector, SIFT_FEATURE_DETECTOR) &&
        strcasecmp(featureDetector, SPEEDSIFT_FEATURE_DETECTOR))
    {
        printf("Feature Detector not recognized. Please select from the following:\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n",
               FAST_FEATURE_DETECTOR,
               GFTT_FEATURE_DETECTOR,
               SURF_FEATURE_DETECTOR,
               SIFT_FEATURE_DETECTOR,
               SPEEDSIFT_FEATURE_DETECTOR);
        
        exit(1);
    }
    
    // make sure regularization parameter for TPS is valid
    if (regularization <= 0.0 || regularization == HUGE_VAL)
    {
        printf("Invalid smoothing parameter value.\n");
        exit(1);
    }
    
    // if output directory doesn't end with '/' char, append '/' to the string.
    // this is so we can later append a filename to the directory when we want 
    // to write the file to that directory
    if (outputDirectory[strlen(outputDirectory)-1] != '/')
    {
        strcat(outputDirectory, "/");
    }
    
    DIR *dir = opendir(outputDirectory);
    
    // if output directory does not exist, create it with correct permissions
    if (dir == NULL)
    {
        printf("Output directory does not exist.\n");
        
        if (mkdir(outputDirectory, S_IRWXO | S_IRWXG | S_IRWXU))
        {
            printf("Could not create output directory.\n");
            exit(1);
        }
        else
        {
            printf("Created output directory.\n");
        }
    }
    else
    {
        closedir(dir);
    }    
    
    // string for the MATLAB commands
    char command[500]; 
    
    Engine *matlabEngine;
    
    // open MATLAB engine
    if (!(matlabEngine = engOpen("\0")))
    {
        printf("Can't start MATLAB engine\n");        
        exit(1);
    }
    
    // create MATLAB arrays to retrieve values from MATLAB workspace
    mxArray **c1ImageData = (mxArray **)malloc(numCameraPairs * sizeof(mxArray *));
    mxArray **c1ImageDimensions = (mxArray **)malloc(numCameraPairs * sizeof(mxArray *));
    mxArray **c1ImagePaddedWidths = (mxArray **)malloc(numCameraPairs * sizeof(mxArray *));
    
    if (c1ImageData == NULL || c1ImageDimensions == NULL || c1ImagePaddedWidths == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    mxArray **c2ImageData = (mxArray **)malloc(numCameraPairs * sizeof(mxArray *));
    mxArray **c2ImageDimensions = (mxArray **)malloc(numCameraPairs * sizeof(mxArray *));
    mxArray **c2ImagePaddedWidths = (mxArray **)malloc(numCameraPairs * sizeof(mxArray *));
    
    if (c2ImageData == NULL || c2ImageDimensions == NULL || c2ImagePaddedWidths == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    // create IplImage arrays for camera 1 and 2 images for all camera pairs
    IplImage **c1Images = (IplImage **)malloc(numCameraPairs * sizeof(IplImage *));
    IplImage **c2Images = (IplImage **)malloc(numCameraPairs * sizeof(IplImage *));
    
    if (c1Images == NULL || c2Images == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    // for each camera pair, get the specified frames from cameras 1 and 2, using
    // MATLAB functions
    for (int i = 0; i < numCameraPairs; i++)
    {
        char video1Extension[6];
        
        // get the video file extension for the first video file
        if (getVideoFileExtension(camera1Filenames[i], video1Extension) == INVALID_VIDEO_FILE_EXTENSION_ERROR)
        {
            printf("Video files must be of extension .mrf or .cine.\n");
            exit(1);
        }
        
        // call appropriate MATLAB function depending on whether video file is .cine 
        // or .mrf to extract the frame as a MATLAB image. If neither, error.
        if ((strcasecmp(video1Extension, ".cine") == 0) || (strcasecmp(video1Extension, ".cin") == 0))
        {
            sprintf(command, "c1 = cineRead('%s', %d);", camera1Filenames[i], camera1Frames[i]);
            engEvalString(matlabEngine, command);
        }
        else if (strcasecmp(video1Extension, ".mrf") == 0)
        {
            sprintf(command, "c1 = mrfRead('%s', %d);", camera1Filenames[i], camera1Frames[i]);
            engEvalString(matlabEngine, command);
        }
        else
        {
            printf("Videos must be of extension .mrf or .cine.\n");
            exit(1);
        }
        
        char video2Extension[6];
        
        // get the video file extension for the second video file
        if (getVideoFileExtension(camera2Filenames[i], video2Extension) == INVALID_VIDEO_FILE_EXTENSION_ERROR)
        {
            printf("Video files must be of extension .mrf or .cine.\n");
            exit(1);
        }
        
        // call appropriate MATLAB function depending on whether video file is .cine 
        // or .mrf to extract the frame as a MATLAB image. If neither, error.
        if ((strcasecmp(video2Extension, ".cine") == 0) || (strcasecmp(video2Extension, ".cin") == 0))
        {
            sprintf(command, "c2 = cineRead('%s', %d);", camera2Filenames[i], camera2Frames[i]);
            engEvalString(matlabEngine, command);
        }
        else if (strcasecmp(video2Extension, ".mrf") == 0)
        {
            sprintf(command, "c2 = mrfRead('%s', %d);", camera2Filenames[i], camera2Frames[i]);
            engEvalString(matlabEngine, command);
        }
        else
        {
            printf("Videos must be of extension .mrf or .cine.\n");
            exit(1);
        }
        
        // call MATLAB function convert_image_matlab2cv_gs on MATLAB images to convert
        // them into a format that will be compatible with the IplImages of OpenCV
        sprintf(command, "[c1_img c1_dim c1_padded_width] = convert_image_matlab2cv_gs(c1);");    
        engEvalString(matlabEngine, command);
        
        sprintf(command, "[c2_img c2_dim c2_padded_width] = convert_image_matlab2cv_gs(c2);");
        engEvalString(matlabEngine, command);
        
        // retrieve the image data, image dimensions, and image padded width variables 
        // from MATLAB for both camera images
        c1ImageData[i] = engGetVariable(matlabEngine, "c1_img");
        c1ImageDimensions[i] = engGetVariable(matlabEngine, "c1_dim");
        c1ImagePaddedWidths[i] = engGetVariable(matlabEngine, "c1_padded_width");
        
        c2ImageData[i] = engGetVariable(matlabEngine, "c2_img");
        c2ImageDimensions[i] = engGetVariable(matlabEngine, "c2_dim");
        c2ImagePaddedWidths[i] = engGetVariable(matlabEngine, "c2_padded_width");    
        
        if (c1ImageData[i] == NULL || 
            c1ImageDimensions[i] == NULL || 
            c1ImagePaddedWidths[i] == NULL)
        {        
            printf("Could not retrieve all necessary information for pair %d camera 1 frame %d from MATLAB.\n", i+1, camera1Frames[i]);
            exit(1);
        }
        
        if (c2ImageData[i] == NULL || 
            c2ImageDimensions[i] == NULL || 
            c2ImagePaddedWidths[i] == NULL)
        {        
            printf("Could not retrieve all necessary information for pair %d camera 2 frame %d from MATLAB.\n", i+1, camera2Frames[i]);
            exit(1);
        }
        
        int c1Status, c2Status;
        
        ImageInfo c1ImageInfo, c2ImageInfo;            
        
        // extract the image information from the MATLAB variables in the form of 
        // mxArrays, and store in ImageInfo structs
        c1Status = getInputImageInfo(&c1ImageInfo, c1ImageData[i], c1ImageDimensions[i], c1ImagePaddedWidths[i]);
        c2Status = getInputImageInfo(&c2ImageInfo, c2ImageData[i], c2ImageDimensions[i], c2ImagePaddedWidths[i]);
        
        if (c1Status == IMAGE_INFO_DATA_ERROR)
        {
            printf("Pair %d camera 1: Images must have two dimensions.\n", i+1);
            exit(1);
        }
        
        if (c2Status == IMAGE_INFO_DATA_ERROR)
        {
            printf("Pair %d camera 2: Images must have two dimensions.\n", i+1);
            exit(1);
        }
        
        if (c1Status == IMAGE_INFO_DIMENSIONS_ERROR)
        {
            printf("Pair %d camera 1: Image dimension vectors must contain two elements: [width, height].\n", i+1);
            exit(1);
        }
        
        if (c2Status == IMAGE_INFO_DIMENSIONS_ERROR)
        {
            printf("Pair %d camera 2: Image dimension vectors must contain two elements: [width, height].\n", i+1);
            exit(1);
        }
        
        if (c1Status == IMAGE_INFO_PADDED_WIDTH_ERROR)
        {
            printf("Pair %d camera 1: Padded image widths must be scalars.\n", i+1);
            exit(1);
        }
        
        if (c2Status == IMAGE_INFO_PADDED_WIDTH_ERROR)
        {
            printf("Pair %d camera 2: Padded image widths must be scalars.\n", i+1);
            exit(1);
        }
        
        if (c1Status == IMAGE_DEPTH_ERROR)
        {
            printf("Pair %d camera 1: Images must be represented by 8 or 16-bit integers.\n", i+1);
            exit(1);
        }
        
        if (c2Status == IMAGE_DEPTH_ERROR)
        {
            printf("Pair %d camera 2: Images must be represented by 8 or 16-bit integers.\n", i+1);
            exit(1);
        }
        
        // create IplImages using values in ImageInfo structs
        c1Status = createIplImageFromImageInfo(&(c1Images[i]), c1ImageInfo);
        c2Status = createIplImageFromImageInfo(&(c2Images[i]), c2ImageInfo);
        
        if (c1Status == OUT_OF_MEMORY_ERROR ||
            c2Status == OUT_OF_MEMORY_ERROR)
        {
            printf("Out of memory error.\n");
            exit(1);
        }
        
        // flip the images over the y-axis to compensate for the differences in axial
        // labels between MATLAB and OpenCV (camera coefficients would not correctly
        // correspond to image otherwise)
        cvFlip(c1Images[i], NULL, 1);
        cvFlip(c2Images[i], NULL, 1);
    }
    
    char errorMessage[500];
    
    int numContours;
    char **contourNames;
    CvPoint3D32f **features3D;
    char **validFeatureIndicator;
    int *numFeaturesInContours;
    
    char contoursFilename[MAX_FILENAME_LENGTH];
    
    // for each camera pair, run features and triangulation
    for (int i = 0; i < numCameraPairs; i++)
    {
        // create the output 2D features filename as "frame<frame number>_features2D_<camera name>.txt"
        char features2DFilename[MAX_FILENAME_LENGTH];    
        sprintf(features2DFilename, "%sframe%d_features2D_%s.txt", outputDirectory, camera1Frames[i], cameraNames[i]);
        
        // create the output contours filename as "frame<frame number>_contours_<camera name>.txt"
        char tempContoursFilename[MAX_FILENAME_LENGTH];    
        sprintf(tempContoursFilename, "%sframe%d_contours_%s.txt", outputDirectory, camera1Frames[i], cameraNames[i]);
        
        printf("Camera pair for %s view:\n", cameraNames[i]);
        
        // run the features program to extract matching 2D features from the 2 
        // images within user defined contour
        if (features(c1Images[i], c2Images[i], features2DFilename, tempContoursFilename, featureDetector, errorMessage))
        {
            printf("Features: %s\n", errorMessage);
            exit(1);
        }
        
        // we only need to save the contour(s) for the first camera pair, as that 
        // is the one we will use to create the meshes, and we only use the contours
        // with the same name(s) in subsequent camera pairs
        if (i == 0)
        {
            strcpy(contoursFilename, tempContoursFilename);
            
            // get the contour names of the contours selected in features function for
            // output file naming and contour matching in other camera pairs
            int status = readContourNamesFromInputFile(&numContours, &contourNames, contoursFilename);
            
            if (status == INPUT_FILE_OPEN_ERROR)
            {
                printf("Could not open contour vertices file.\n");
                exit(1);
            }
            
            if (status == INCORRECT_INPUT_FILE_FORMAT_ERROR)
            {
                printf("Contour vertices file has incorrect format.\n");
                exit(1);
            }
            
            if (status == OUT_OF_MEMORY_ERROR)
            {
                printf("Out of memory error.\n");
                exit(1);
            }
            
            // allocate memory for 3D features
            features3D = (CvPoint3D32f **)malloc(numContours * sizeof(CvPoint3D32f *));
            validFeatureIndicator = (char **)malloc(numContours * sizeof(char *));
            numFeaturesInContours = (int *)malloc(numContours * sizeof(int));
            
            if (features3D == NULL || numFeaturesInContours == NULL || validFeatureIndicator == NULL)
            {
                printf("Out of memory error.\n");
                exit(1);
            }
            
            for (int j = 0; j < numContours; j++)
            {
                features3D[j] = (CvPoint3D32f *)malloc(MAX_FEATURES_IN_CONTOUR * sizeof(CvPoint3D32f));
                validFeatureIndicator[j] = (char *)malloc(MAX_FEATURES_IN_CONTOUR * sizeof(char));
                
                if (features3D[j] == NULL || validFeatureIndicator[j] == NULL)
                {
                    printf("Out of memory error.\n");
                    exit(1);
                }
                
                numFeaturesInContours[j] = 0;
            }
        }
        
        // create the output 3D features filename as "frame<frame number>_features3D_<camera name>.txt"
        char features3DFilename[MAX_FILENAME_LENGTH];    
        sprintf(features3DFilename, "%sframe%d_features3D_%s.txt", outputDirectory, camera1Frames[i], cameraNames[i]);
        
        // triangulate the matching 2D features between cameras to find the 3D coordinates 
        // of the features, and remove invalid features
        if (triangulation(cameraCoefficientsFilenames[i], features2DFilename, features3DFilename, c1Images[i], errorMessage))
        {
            printf("Triangulation: %s\n", errorMessage);
            exit(1);
        }
        
        // if features from triangulation lie within contours that have the same
        // names as those defined for the first camera pair, add them to the
        // 3D features array for mesh creation
        int status = read3DFeaturesFromFileForMatchingContours(features3DFilename, features3D, numFeaturesInContours, numContours, contourNames);
        
        if (status == INPUT_FILE_OPEN_ERROR)
        {
            printf("Could not open 3D features file.\n");
            exit(1);
        }
        
        if (status == INVALID_NUM_CONTOURS_ERROR)
        {
            printf("At least 1 contour region required.\n");
            exit(1);
        }
        
        if (status == INCORRECT_INPUT_FILE_FORMAT_ERROR)
        {
            printf("3D features file has incorrect format.\n");
            exit(1);
        }
    }        
    
    // for each contour (defined for the first camera pair), perform RANSAC on
    // the cumulative 3D features from all camera pairs that lie within the contour
    for (int i = 0; i < numContours; i++)
    {    
        memset(validFeatureIndicator[i], 1, numFeaturesInContours[i] * sizeof(char));

        // perform RANSAC to remove points that lie too far off a best-fit surface
        if (ransac(features3D[i], validFeatureIndicator[i], numFeaturesInContours[i], errorMessage))
        {
            printf("RANSAC: %s\n", errorMessage);
            exit(1);
        }
        
        int numValidFeatures = 0;
        
        for (int j = 0; j < numFeaturesInContours[i]; j++)
        {
            if (validFeatureIndicator[i][j])
            {
                numValidFeatures++;
            }
        }
        
        printf("Total valid features after RANSAC for contour %s: %d\n", contourNames[i], numValidFeatures);

    }
    
    // create the output 3D features filename for all camera pairs as 
    // "frame<frame number>_features3D.txt", and write the result of RANSAC to
    // the file
    char features3DFilename[MAX_FILENAME_LENGTH];    
    sprintf(features3DFilename, "%sframe%d_features3D.txt", outputDirectory, camera1Frames[0]);
    
    int status = write3DFeaturesToFile(features3D, validFeatureIndicator, numFeaturesInContours, contourNames, numContours, features3DFilename);
    
    if (status == OUTPUT_FILE_OPEN_ERROR)
    {
        sprintf(errorMessage, "Could not open output file.");
        return 1;
    }
    
    char **meshFilenames = (char **)malloc(numContours * sizeof(char *));
    
    if (meshFilenames == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    // for each contour, create a different mesh output file
    for (int i = 0; i < numContours; i++)
    {
        meshFilenames[i] = (char *)malloc(MAX_FILENAME_LENGTH * sizeof(char));
        
        if (meshFilenames[i] == NULL)
        {
            printf("Out of memory error.\n");
            exit(1);
        }
        
        // create the output mesh filename as "frame<frame number>_mesh_<contour name>_<camera name>.txt"
        sprintf(meshFilenames[i], "%sframe%d_mesh_%s.txt", outputDirectory, camera1Frames[0], contourNames[i]);
    }
    
    // create the wing meshes from the triangulated 3D points and the user-selected
    // contours, and write each mesh to a different file for each contour
    if (mesh(features3DFilename, contoursFilename, cameraCoefficientsFilenames[0], meshFilenames, numContours, regularization, errorMessage))
    {
        printf("Mesh: %s\n", errorMessage);
        exit(1);
    }
    
    // we only calculate the flow of a wing mesh if there is a mesh file with the
    // same contour name in the output directory for the previous video frame
    char **flowFilenames = (char **)malloc(numContours * sizeof(char *));
    
    if (flowFilenames == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    for (int i = 0; i < numContours; i++)
    {
        flowFilenames[i] = NULL;
    }
    
    int numFilesInDirectory;
    char **filenamesInDirectory = (char **)malloc(MAX_FILES_IN_DIRECTORY * sizeof(char *));
    
    if (filenamesInDirectory == NULL)
    {
        printf("Out of memory error.\n");
        exit(1);
    }
    
    for (int i = 0; i < MAX_FILES_IN_DIRECTORY; i++)
    {
        filenamesInDirectory[i] = (char *)malloc(MAX_FILENAME_LENGTH * sizeof(char));
        
        if (filenamesInDirectory[i] == NULL)
        {
            printf("Out of memory error.\n");
            exit(1);
        }
    }
    
    // get all files in the output directory
    getAllFilenamesInDirectory(outputDirectory, &numFilesInDirectory, filenamesInDirectory);
     
    // for each contour check if previous frame mesh file for same contour exists
    // in output directory
    for (int i = 0; i < numContours; i++)
    {
        // set substring indicating match to be "frame<previous frame number>_mesh_<contour name>.txt"
        char filenameToMatch[MAX_FILENAME_LENGTH];
        sprintf(filenameToMatch, "frame%d_mesh_%s.txt", camera1Frames[0]-1, contourNames[i]);
        
        // try to find a filename from the output directory that contains the
        // substring indicating a match for a previous frame mesh for the same
        // contour
        int fileExists = getIndexOfMatchingString(filenamesInDirectory, numFilesInDirectory, filenameToMatch);
        
        // if filename was found, create a flow output file for current contour 
        // and call flow to calculate the flow between previous contour mesh and 
        // current contour mesh
        if (fileExists != -1)
        {
            flowFilenames[i] = (char *)malloc(MAX_FILENAME_LENGTH * sizeof(char));
            
            if (flowFilenames[i] == NULL)
            {
                printf("Out of memory error.\n");
                exit(1);
            }
            
            // create the output flow filename as "frame<frame number>_flow_<contour name>_<camera name>.txt"
            sprintf(flowFilenames[i], "%sframe%d_flow_%s.txt", outputDirectory, camera1Frames[0], contourNames[i]);
            
            // add the output directory name to the beginning of the previous mesh
            // filename
            char prevFrameMeshFile[MAX_FILENAME_LENGTH];
            sprintf(prevFrameMeshFile, "%s%s", outputDirectory, filenameToMatch);
            
            // call flow to find the flow between the previous mesh file and the
            // current mesh file for each mesh point current contour
            if (flow(prevFrameMeshFile, meshFilenames[i], flowFilenames[i], errorMessage))
            {
                printf("Flow: %s\n", errorMessage);
                exit(1);
            }
        }
        
        else
        {
            printf("Mesh points file for previous frame not found for contour %s. Unable to calculate flow.\n", contourNames[i]);
        }
    }
    
    sprintf(command, "hold on;");
    engEvalString(matlabEngine, command);
    
    // for each contour, display MATLAB 3D plot of the mesh, as well as the flow 
    // for the mesh, if applicable
    for (int i = 0; i < numContours; i++)
    {        
        if (flowFilenames[i] != NULL)
        {
            sprintf(command, "flows = load('%s');", flowFilenames[i]);
            engEvalString(matlabEngine, command);
            
            // plot the flows of the mesh points
            sprintf(command, "quiver3(flows(:,1), flows(:,2), flows(:,3), flows(:,4), flows(:,5), flows(:,6), 4, 'r-');");
            engEvalString(matlabEngine, command);
            
        }
        
        sprintf(command, "mesh = importdata('%s', ' ', 1);", meshFilenames[i]);
        engEvalString(matlabEngine, command);
        
        // plot the mesh points
        sprintf(command, "plot3(mesh.data(:,1), mesh.data(:,2), mesh.data(:,3), 'b.');");
        engEvalString(matlabEngine, command);
    }
    
    // reverse the z and y coordinates in the display
    sprintf(command, "set(gca,'zdir','reverse','ydir','reverse');");
    engEvalString(matlabEngine, command);
    
    // scale the axes to be equal
    sprintf(command, "axis equal");
    engEvalString(matlabEngine, command);
    
    // wait for the user to hit enter
    printf("Hit return to continue.\n");
    fgetc(stdin);
    
    // close MATLAB engine
    engClose(matlabEngine);
    
    // cleanup
    free(camera1Filenames);
    free(camera1Frames);
    free(camera2Filenames);
    free(camera2Frames);
    free(cameraNames);
    free(cameraCoefficientsFilenames);
    
    for (int i = 0; i < numCameraPairs; i++)
    {
        mxDestroyArray(c1ImageData[i]);
        mxDestroyArray(c1ImageDimensions[i]);
        mxDestroyArray(c1ImagePaddedWidths[i]);
        
        mxDestroyArray(c2ImageData[i]);
        mxDestroyArray(c2ImageDimensions[i]);
        mxDestroyArray(c2ImagePaddedWidths[i]);
        
        free(c1Images[i]->imageData);
        cvReleaseImageHeader(&c1Images[i]);
        
        free(c2Images[i]->imageData);
        cvReleaseImageHeader(&c2Images[i]);
    }
    
    free(c1ImageData);
    free(c1ImageDimensions);
    free(c1ImagePaddedWidths);
    
    free(c2ImageData);
    free(c2ImageDimensions);
    free(c2ImagePaddedWidths);
    
    free(c1Images);
    free(c2Images);
    
    for (int i = 0; i < MAX_FILES_IN_DIRECTORY; i++)
    {
        free(filenamesInDirectory[i]);
    }
    
    free(filenamesInDirectory);
    
    for (int i = 0; i < numContours; i++)
    {
        free(contourNames[i]);
        free(features3D[i]);
        free(validFeatureIndicator[i]);
                
        free(meshFilenames[i]);
        
        if (flowFilenames[i] != NULL)
        {
            free(flowFilenames[i]);
        }
    }
    
    free(contourNames);
    free(features3D);
    free(validFeatureIndicator);
    free(numFeaturesInContours);
    
    free(meshFilenames);
    free(flowFilenames);
    
    exit(0);
}
Example #15
0
	// To assign a graph to a tree requires pruning all edges which makes it not
	// a tree. We perform here the junction tree algorithm.
	tree(const graph<T,P,M,N,impl_type> &g) {
		typedef graph<T,P,M,N,impl_type> super;
		super::operator=(g);
		moralization();
		triangulation();
	}