Exemplo n.º 1
0
Mesh Mesh::fromMap(const Map &depth, const Map &intensities, bool centralizeLoadedMesh)
{
    if ((depth.w != intensities.w) || (depth.h != intensities.h))
        throw FACELIB_EXCEPTION("incompatibile input map sizes");
    std::map<std::pair<int,int>, int> coordToIndex;

    VectorOfPoints points;
    Colors colors;
    int index = 0;
    for (int y = 0; y < depth.h; y++)
    {
        for (int x = 0; x < depth.w; x++)
        {
            if (depth.isSet(x,y))
            {
                if (!intensities.isSet(x,y)) throw FACELIB_EXCEPTION("intensities point is not valid");

                points.push_back(cv::Point3d(x, depth.h-y-1, depth.get(x,y)));

                uchar intensity = intensities.get(x, y);
                colors.push_back(cv::Vec3b(intensity, intensity, intensity));

                coordToIndex[std::pair<int,int>(x,y)] = index;
                index++;
            }
        }
    }

    Mesh mesh = Mesh::fromPointcloud(points, centralizeLoadedMesh, false);
    mesh.colors = colors;

    // triangles
    for (int y = 0; y < depth.h; y++)
    {
        for (int x = 0; x < depth.w; x++)
        {
            if (depth.isSet(x,y) &&
                depth.isValidCoord(x, y+1) && depth.isSet(x, y+1) &&
                depth.isValidCoord(x+1, y+1) && depth.isSet(x+1, y+1))
            {
                mesh.triangles.push_back(cv::Vec3i(coordToIndex[std::pair<int,int>(x,y)], coordToIndex[std::pair<int,int>(x,y+1)], coordToIndex[std::pair<int,int>(x+1,y+1)]));
            }

            if (depth.isSet(x,y) &&
                depth.isValidCoord(x+1, y+1) && depth.isSet(x+1, y+1) &&
                depth.isValidCoord(x+1, y) && depth.isSet(x+1, y))
            {
                mesh.triangles.push_back(cv::Vec3i(coordToIndex[std::pair<int,int>(x,y)], coordToIndex[std::pair<int,int>(x+1,y+1)], coordToIndex[std::pair<int,int>(x+1,y)]));
            }
        }
    }

    return mesh;
}
Exemplo n.º 2
0
XMeansClustering::VectorOfPoints XMeansClustering::GetPointsWithLabel(const unsigned int label)
{
  VectorOfPoints points;

  std::vector<unsigned int> indicesWithLabel = GetIndicesWithLabel(label);

  for(unsigned int i = 0; i < indicesWithLabel.size(); i++)
    {
    points.push_back(this->Points[indicesWithLabel[i]]);
    }

  return points;
}
Exemplo n.º 3
0
Mesh Mesh::fromXYZ(const std::string &filename, bool centralizeLoadedMesh)
{
    std::ifstream in(filename);
    if (!in.is_open())
        throw FACELIB_EXCEPTION("Can't open file " + filename);

    double x,y,z;
    VectorOfPoints points;
    while (in >> x >> y >> z)
    {
        cv::Point3d p(x, y, z);
        points.push_back(p);
    }

    return Mesh::fromPointcloud(points, centralizeLoadedMesh);
}
Exemplo n.º 4
0
Mesh Mesh::fromMap(const Map &depth, const MapConverter &converter)
{
	int w = depth.w;
	int h = depth.h;
	VectorOfPoints points;
	for (int y = 0; y < h; y++)
	{
		for (int x = 0; x < w; x++)
		{
			bool ok;
			cv::Point3d p = converter.MapToMeshCoords(depth, cv::Point2d(x, y), &ok);
			if (ok) points.push_back(p);
		}
	}

	return Mesh::fromPointcloud(points);
}
Exemplo n.º 5
0
Mesh Mesh::fromPointcloud(const VectorOfPoints &pointcloud, bool centralizeLoadedMesh, bool calculateTriangles)
{
    Mesh m;

    int n = pointcloud.size();
    m.pointsMat = Matrix(n, 3);
    for (int i = 0; i < n; i++)
    {
        const cv::Point3d &p = pointcloud.at(i);
        m.pointsMat(i, 0) = p.x;
        m.pointsMat(i, 1) = p.y;
        m.pointsMat(i, 2) = p.z;
    }

    if (calculateTriangles) m.calculateTriangles();
    m.recalculateMinMax();
    if (centralizeLoadedMesh) m.centralize();

    return m;
}
Exemplo n.º 6
0
void XMeansClustering::SplitClusters()
{
  assert(this->Points.size() > 0);

  VectorOfPoints newClusterCenters;

  for(unsigned int clusterId = 0; clusterId < this->ClusterCenters.size(); ++clusterId)
  {
    // Generate a random direction
    PointType randomUnitVector = EigenHelpers::RandomUnitVector<PointType>(this->Points[0].size());

    // Get the bounding box of the points that belong to this cluster
    PointType minCorner;
    PointType maxCorner;
    EigenHelpers::GetBoundingBox(this->Points, minCorner, maxCorner);

    // Scale the unit vector by the size of the region
    PointType splitVector = randomUnitVector * (maxCorner - minCorner) / 2.0f;
    PointType childCenter1 = this->ClusterCenters[clusterId] + splitVector;
    PointType childCenter2 = this->ClusterCenters[clusterId] + splitVector;

    // Compute the BIC of the original model
    float BIC_parent;

    // Compute the BIC of the new (split) model
    float BIC_children;

    // If the split was useful, keep it
    if(BIC_children < BIC_parent)
    {
      newClusterCenters.push_back(childCenter1);
      newClusterCenters.push_back(childCenter2);
    }
    else
    {
      newClusterCenters.push_back(this->ClusterCenters[clusterId]);
    }
  }

  this->ClusterCenters = newClusterCenters;
}
Exemplo n.º 7
0
Mesh Mesh::fromOBJ(const std::string &filename, bool centralizeLoadedMesh)
{
    std::ifstream in(filename);
    if (!in.is_open())
        throw FACELIB_EXCEPTION("Can't open file " + filename);

    VectorOfPoints points;
    Triangles triangles;
    std::string line;
    while (std::getline(in, line))
    {
        if (line.empty()) continue;

        if (line[0] == 'v')
        {
            Poco::StringTokenizer tokens(line, " ");
            double x = Poco::NumberParser::parseFloat(tokens[1]);
            double y = Poco::NumberParser::parseFloat(tokens[2]);
            double z = Poco::NumberParser::parseFloat(tokens[3]);

            points.push_back(cv::Point3d(x,y,z));
        }
        else if (line[0] == 'f')
        {
            Poco::StringTokenizer tokens(line, " ");
            int t1 = Poco::NumberParser::parse(tokens[1]) - 1;
            int t2 = Poco::NumberParser::parse(tokens[2]) - 1;
            int t3 = Poco::NumberParser::parse(tokens[3]) - 1;

            triangles.push_back(cv::Vec3i(t1, t2, t3));
        }
    }

    Mesh result = Mesh::fromPointcloud(points, centralizeLoadedMesh, false);
    result.triangles = triangles;
    return result;
}
Exemplo n.º 8
0
void MeshMassPropertiesTests::testClosedTetrahedronMesh() {
    // given a tetrahedron as a closed mesh of four tiangles
    // verify MeshMassProperties computes the right nubers
    
    // these numbers from the Tonon paper:
    VectorOfPoints points;
    points.push_back(btVector3(8.33220f, -11.86875f, 0.93355f));
    points.push_back(btVector3(0.75523f, 5.00000f, 16.37072f));
    points.push_back(btVector3(52.61236f, 5.00000f, -5.38580f));
    points.push_back(btVector3(2.00000f, 5.00000f, 3.00000f));

    btScalar expectedVolume = 1873.233236f;

    btMatrix3x3 expectedInertia;
    expectedInertia[0][0] = 43520.33257f;
    expectedInertia[1][1] = 194711.28938f;
    expectedInertia[2][2] = 191168.76173f;
    expectedInertia[1][2] = -4417.66150f;
    expectedInertia[2][1] = -4417.66150f;
    expectedInertia[0][2] = 46343.16662f;
    expectedInertia[2][0] = 46343.16662f;
    expectedInertia[0][1] = -11996.20119f;
    expectedInertia[1][0] = -11996.20119f;

    btVector3 expectedCenterOfMass = 0.25f * (points[0] + points[1] + points[2] + points[3]);

    VectorOfIndices triangles;
    pushTriangle(triangles, 0, 2, 1);
    pushTriangle(triangles, 0, 3, 2);
    pushTriangle(triangles, 0, 1, 3);
    pushTriangle(triangles, 1, 2, 3);

    // compute mass properties
    MeshMassProperties mesh(points, triangles);
    
    // verify
    QCOMPARE_WITH_ABS_ERROR(mesh._volume, expectedVolume, acceptableRelativeError * expectedVolume);
    QCOMPARE_WITH_ABS_ERROR(mesh._centerOfMass, expectedCenterOfMass, acceptableAbsoluteError);
    QCOMPARE_WITH_RELATIVE_ERROR(mesh._inertia, expectedInertia, acceptableRelativeError);

    // test again, but this time shift the points so that the origin is definitely OUTSIDE the mesh
    btVector3 shift = points[0] + expectedCenterOfMass;
    for (int i = 0; i < (int)points.size(); ++i) {
        points[i] += shift;
    }
    expectedCenterOfMass = 0.25f * (points[0] + points[1] + points[2] + points[3]);

    // compute mass properties
    mesh.computeMassProperties(points, triangles);

    // verify
//    QCOMPARE_WITH_ABS_ERROR(mesh._volume, expectedVolume, acceptableRelativeError * expectedVolume);
//    QCOMPARE_WITH_ABS_ERROR(mesh._centerOfMass, expectedCenterOfMass, acceptableAbsoluteError);
//    QCOMPARE_WITH_RELATIVE_ERROR(mesh._inertia, expectedInertia, acceptableRelativeError);
}
Exemplo n.º 9
0
void MeshMassPropertiesTests::testOpenTetrahedonMesh() {
    // given the simplest possible mesh (open, with one triangle) 
    // verify MeshMassProperties computes the right nubers

    // these numbers from the Tonon paper:
    VectorOfPoints points;
    points.push_back(btVector3(8.33220f, -11.86875f, 0.93355f));
    points.push_back(btVector3(0.75523f, 5.00000f, 16.37072f));
    points.push_back(btVector3(52.61236f, 5.00000f, -5.38580f));
    points.push_back(btVector3(2.00000f, 5.00000f, 3.00000f));

    btScalar expectedVolume = 1873.233236f;

    btMatrix3x3 expectedInertia;
    expectedInertia[0][0] = 43520.33257f;
    expectedInertia[1][1] = 194711.28938f;
    expectedInertia[2][2] = 191168.76173f;
    expectedInertia[1][2] = -4417.66150f;
    expectedInertia[2][1] = -4417.66150f;
    expectedInertia[0][2] = 46343.16662f;
    expectedInertia[2][0] = 46343.16662f;
    expectedInertia[0][1] = -11996.20119f;
    expectedInertia[1][0] = -11996.20119f;

    // test as an open mesh with one triangle
    VectorOfPoints shiftedPoints;
    shiftedPoints.push_back(points[0] - points[0]);
    shiftedPoints.push_back(points[1] - points[0]);
    shiftedPoints.push_back(points[2] - points[0]);
    shiftedPoints.push_back(points[3] - points[0]);
    VectorOfIndices triangles;
    pushTriangle(triangles, 1, 2, 3);
    btVector3 expectedCenterOfMass = 0.25f * (shiftedPoints[0] + shiftedPoints[1] + shiftedPoints[2] + shiftedPoints[3]);

    // compute mass properties
    MeshMassProperties mesh(shiftedPoints, triangles);

    // verify
    // (expected - actual) / expected > e   ==>  expected - actual  >  e * expected
    QCOMPARE_WITH_ABS_ERROR(mesh._volume, expectedVolume, acceptableRelativeError * expectedVolume);
    QCOMPARE_WITH_ABS_ERROR(mesh._centerOfMass, expectedCenterOfMass, acceptableAbsoluteError);
    QCOMPARE_WITH_RELATIVE_ERROR(mesh._inertia, expectedInertia, acceptableRelativeError);
}
Exemplo n.º 10
0
Mesh Mesh::fromABS(const std::string &filename, const std::string &texture, bool centralizeLoadedMesh)
{
    cv::Mat_<cv::Vec3b> image;
    if (!texture.empty())
        image = cv::imread(texture);

    std::ifstream in(filename);
    if (!in.is_open())
        throw FACELIB_EXCEPTION("can't open file " + filename);

    std::string line;

    int mapHeight;
    in >> mapHeight;
    std::getline(in, line);

    int mapwidth;
    in >> mapwidth;    
    std::getline(in, line);

    std::getline(in, line);
    int total = mapwidth*mapHeight;
    std::vector<int> flags(total);
    std::vector<double> xPoints(total);
    std::vector<double> yPoints(total);
    std::vector<double> zPoints(total);

    for (int i = 0; i < total; i++)
        in >> (flags[i]);
    for (int i = 0; i < total; i++)
        in >> (xPoints[i]);
    for (int i = 0; i < total; i++)
        in >> (yPoints[i]);
    for (int i = 0; i < total; i++)
        in >> (zPoints[i]);

    VectorOfPoints points;
    Colors colors;
    for (int i = 0; i < total; i++)
    {
        if (flags[i])
        {
            cv::Point3d p;
            p.x = xPoints[i];
            p.y = yPoints[i];
            p.z = zPoints[i];
            points.push_back(p);

            if (!texture.empty())
            {
                int x = i % 640;
                int y = i / 640;
                colors.push_back(image(y, x));
            }
        }
    }

    Mesh mesh = Mesh::fromPointcloud(points, centralizeLoadedMesh);
    mesh.colors = colors;
    return mesh;
}
Exemplo n.º 11
0
void MeshMassPropertiesTests::testBoxAsMesh() {
    // verify that a mesh box produces the same mass properties as the analytic box.
    
    // build a box:
    //                            /
    //                           y
    //                          /
    //            6-------------------------7
    //           /|                        /|
    //          / |                       / |
    //         /  2----------------------/--3
    //        /  /                      /  /
    //   |   4-------------------------5  /  --x--
    //   z   | /                       | /
    //   |   |/                        |/
    //       0 ------------------------1

    btScalar x(5.0f);
    btScalar y(3.0f);
    btScalar z(2.0f);

    VectorOfPoints points;
    points.reserve(8);

    points.push_back(btVector3(0.0f, 0.0f, 0.0f));
    points.push_back(btVector3(x, 0.0f, 0.0f));
    points.push_back(btVector3(0.0f, y, 0.0f));
    points.push_back(btVector3(x, y, 0.0f));
    points.push_back(btVector3(0.0f, 0.0f, z));
    points.push_back(btVector3(x, 0.0f, z));
    points.push_back(btVector3(0.0f, y, z));
    points.push_back(btVector3(x, y, z));

    VectorOfIndices triangles;
    pushTriangle(triangles, 0, 1, 4);
    pushTriangle(triangles, 1, 5, 4);
    pushTriangle(triangles, 1, 3, 5);
    pushTriangle(triangles, 3, 7, 5);
    pushTriangle(triangles, 2, 0, 6);
    pushTriangle(triangles, 0, 4, 6);
    pushTriangle(triangles, 3, 2, 7);
    pushTriangle(triangles, 2, 6, 7);
    pushTriangle(triangles, 4, 5, 6);
    pushTriangle(triangles, 5, 7, 6);
    pushTriangle(triangles, 0, 2, 1);
    pushTriangle(triangles, 2, 3, 1);

    // compute expected mass properties analytically
    btVector3 expectedCenterOfMass = 0.5f * btVector3(x, y, z);
    btScalar expectedVolume = x * y * z;
    btMatrix3x3 expectedInertia;
    computeBoxInertia(expectedVolume, btVector3(x, y, z), expectedInertia);

    // compute the mass properties using the mesh
    MeshMassProperties mesh(points, triangles);

    // verify
    
    QCOMPARE_WITH_ABS_ERROR(mesh._volume, expectedVolume, acceptableRelativeError * expectedVolume);
    QCOMPARE_WITH_ABS_ERROR(mesh._centerOfMass, expectedCenterOfMass, acceptableAbsoluteError);

    // test this twice: _RELATIVE_ERROR doesn't test zero cases (to avoid divide-by-zero); _ABS_ERROR does.
    QCOMPARE_WITH_ABS_ERROR(mesh._inertia, expectedInertia, acceptableAbsoluteError);
    QCOMPARE_WITH_RELATIVE_ERROR(mesh._inertia, expectedInertia, acceptableRelativeError);

    // These two macros impl this:
//    for (int i = 0; i < 3; ++i) {
//        for (int j = 0; j < 3; ++j) {
//            if (expectedInertia [i][j] == btScalar(0.0f)) {
//                error = mesh._inertia[i][j] - expectedInertia[i][j];                                  // COMPARE_WITH_ABS_ERROR
//                if (fabsf(error) > acceptableAbsoluteError) {
//                    std::cout << __FILE__ << ":" << __LINE__ << " ERROR : inertia[" << i << "][" << j << "] off by "
//                        << error << " absolute"<< std::endl;
//                }
//            } else {
//                error = (mesh._inertia[i][j] - expectedInertia[i][j]) / expectedInertia[i][j];        // COMPARE_WITH_RELATIVE_ERROR
//                if (fabsf(error) > acceptableRelativeError) {
//                    std::cout << __FILE__ << ":" << __LINE__ << " ERROR : inertia[" << i << "][" << j << "] off by "
//                        << error << std::endl;
//                }
//            }
//        }
//    }
}