Example #1
0
        public void TestMapping()
        {
            // Referenční soubor
            IFileReader            fileReader  = new ObjFileReader("");
            List <Vector <float> > referPoints = fileReader.ReadVertices();

            // Zdrojový soubor
            fileReader = new ObjFileReader("");
            List <Vector <float> > sourcePoints = fileReader.ReadVertices();

            // Doplnit maximální vzdálenost
            IPointMapping          bruteForceMapping      = new BruteForceMapping(referPoints, 50f);
            List <Vector <float> > bruteForceMappedPoints = bruteForceMapping.MapPoints(sourcePoints, out List <Vector <float> > mappedSourcePoints);

            // Doplnit maximální vzdálenost
            IPointMapping          kdMapping      = new KdTreeMapping(referPoints, 50f);
            List <Vector <float> > kdMappedPoints = kdMapping.MapPoints(sourcePoints, out mappedSourcePoints);

            Assert.AreEqual(bruteForceMappedPoints.Count, kdMappedPoints.Count);

            bool allEqual = true;

            for (int i = 0; i < bruteForceMappedPoints.Count; i++)
            {
                if (!bruteForceMappedPoints[i].Equals(kdMappedPoints[i]))
                {
                    allEqual = false;
                    break;
                }
            }

            Assert.IsTrue(allEqual);
        }
Example #2
0
        /// <summary>
        /// Registers source points to target points. It does not change just a position of source points but also deforms it.
        /// </summary>
        /// <param name="sourcePoints">Source points.</param>
        /// <param name="targetPoints">Target points.</param>
        /// <returns>Registered source points.</returns>
        public List <Vector <float> > ComputeRegistration(List <Vector <float> > sourcePoints, List <Vector <float> > targetPoints)
        {
            // Compute a rigid registration between source and target points so they overlap.
            Log.Info("Registering points.");
            List <Vector <float> > registeredSourcePoints = this.rigidRegistration.ComputeRegistration(sourcePoints, targetPoints);

            /*
             * Find mapped pairs between registered source points and target points (they overlap) because one can be smaller than the other and control points should
             * be generated only on the mapped part. For example imagine a head as source points and a face as target points. Control points should be generated
             * only on the face of source points.
             */
            Log.Info("Mapping points.");
            KdTreeMapping          treeMapping = new KdTreeMapping();
            List <Vector <float> > mappedSourcePoints;
            List <Vector <float> > mappedTargetPoints;

            treeMapping.MapPoints(registeredSourcePoints, targetPoints, out mappedSourcePoints, out mappedTargetPoints);

            // Selects random points (control points) from the mapped source points. Control points are used for mapping of deformed parts of a mesh.
            Log.Info("Generating control points.");
            ControlPointsGenerator pointsGenerator = new ControlPointsGenerator(mappedSourcePoints);
            List <Vector <float> > controlPoints   = pointsGenerator.GetRandomPoints();

            /*
             * Compute correction vectors for each control point. It is done by searching points in an area around the control point. Afterwards these searched points are
             * passed to the rigid registration which returns a transformation matrix for related to mapping between the area and the target points. This matrix is then used
             * to transform the control point and the correction vector is computed as difference between transformed control point and its original value.
             */
            Log.Info("Computing correction vectors.");
            List <Vector <float> > correctionVectors = new List <Vector <float> >();

            for (int i = 0; i < controlPoints.Count; i++)
            {
                List <Vector <float> > closePoints     = pointsGenerator.FindClosePoints(controlPoints[i]);
                Matrix <float>         transformMatrix = this.rigidRegistration.ComputeRegistrationMatrix(closePoints, targetPoints);
                Vector <float>         copyPoint       = controlPoints[i].Clone();
                copyPoint = transformMatrix * copyPoint;
                correctionVectors.Add(copyPoint - controlPoints[i]);
            }

            // Interpolate correction vectors for a whole registered source point cloud. Each point in the point cloud will get own correction vector.
            Log.Info("Interpolating correction vectors.");
            Rbf rbf = new Rbf();
            List <Vector <float> > interpolatedCorrectionVectors = rbf.Interpolate(registeredSourcePoints, controlPoints, correctionVectors);

            for (int i = 0; i < registeredSourcePoints.Count; i++)
            {
                registeredSourcePoints[i] = registeredSourcePoints[i] + interpolatedCorrectionVectors[i];
            }

            return(registeredSourcePoints);
        }