コード例 #1
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator nose = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString());

            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(nose, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                double distance = 0;
                if (iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip, out distance))
                {
                    if (distance > m_fDistence)
                    {
                        iter = p_Model.RemovePointFromModel(iter);
                    }
                    else
                    {
                        if (!iter.MoveToNext())
                        {
                            break;
                        }
                    }
                }
                else
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
            }while(iter.IsValid());
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator NoseTip = null;

            if (!p_Model.GetSpecificPoint(m_NoseTipName, ref NoseTip))
            {
                throw new Exception("Cannot find specific point NoseTip");
            }

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            while (iter.IsValid())
            {
                bool isOk = false;
                if (ClTools.IsItInsideSphere(iter.X, iter.Y, iter.Z, NoseTip.X, NoseTip.Y, NoseTip.Z + m_fBottomSphereNoseTipZoffset, m_fBottomSphereRadious))
                {
                    if (ClTools.IsItInsideSphere(iter.X, iter.Y, iter.Z, NoseTip.X, NoseTip.Y, NoseTip.Z + m_fUpperSphereNoseTipZoffset, m_fUpperSphereRadious))
                    {
                        isOk = true;
                    }
                }

                if (!isOk)
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                {
                    if (!iter.MoveToNext())
                    {
                        break;
                    }
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator leftLipsCorner  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips);
            Cl3DModel.Cl3DModelPointIterator rightLipsCorner = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips);

            Cl3DModel.Cl3DModelPointIterator UpperLip  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.UpperLip);
            Cl3DModel.Cl3DModelPointIterator BottomLip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.BottomLip);

            Edge[] edges = new Edge[3];

            int Width   = 0;
            int Height  = 0;
            int OffsetX = 0;
            int OffsetY = 0;

            ClTools.CreateGridBasedOnRangeValues(p_Model, out Map, out Width, out Height, out OffsetX, out OffsetY);

            edges[0] = new Edge((int)leftLipsCorner.RangeImageX - OffsetX, (int)leftLipsCorner.RangeImageY - OffsetY, (int)UpperLip.RangeImageX - OffsetX, (int)UpperLip.RangeImageY - OffsetY);
            edges[1] = new Edge((int)UpperLip.RangeImageX - OffsetX, (int)UpperLip.RangeImageY - OffsetY, (int)BottomLip.RangeImageX - OffsetX, (int)BottomLip.RangeImageY - OffsetY);
            edges[2] = new Edge((int)BottomLip.RangeImageX - OffsetX, (int)BottomLip.RangeImageY - OffsetY, (int)leftLipsCorner.RangeImageX - OffsetX, (int)leftLipsCorner.RangeImageY - OffsetY);
            RemoveTriangle(edges);

            edges[0] = new Edge((int)UpperLip.RangeImageX - OffsetX, (int)UpperLip.RangeImageY - OffsetY, (int)rightLipsCorner.RangeImageX - OffsetX, (int)rightLipsCorner.RangeImageY - OffsetY);
            edges[1] = new Edge((int)rightLipsCorner.RangeImageX - OffsetX, (int)rightLipsCorner.RangeImageY - OffsetY, (int)BottomLip.RangeImageX - OffsetX, (int)BottomLip.RangeImageY - OffsetY);
            edges[2] = new Edge((int)BottomLip.RangeImageX - OffsetX, (int)BottomLip.RangeImageY - OffsetY, (int)UpperLip.RangeImageX - OffsetX, (int)UpperLip.RangeImageY - OffsetY);
            RemoveTriangle(edges);
        }
        private float CalculateWholeModelArea(Cl3DModel p_Model)
        {
            float Area = 0;
            List <ClTools.ClTriangle> Triangles = null;

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            if (iter.IsValid())
            {
                do
                {
                    ClTools.GetListOfTriangles(out Triangles, iter);
                    foreach (ClTools.ClTriangle triangle in Triangles)
                    {
                        if (triangle.AlreadyVisited)
                        {
                            continue;
                        }

                        Area += ClTools.CalculateTriangleArea(triangle);
                        triangle.AlreadyVisited = true;
                    }
                } while (iter.MoveToNext());
            }

            return(Area);
        }
コード例 #5
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            string name = p_Model.ModelFileFolder + p_Model.ModelFileName + m_sFilePostFix + ".Angle";

            Cl3DModel.Cl3DModelPointIterator NoseTip  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString());
            Cl3DModel.Cl3DModelPointIterator rightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner.ToString());
            Cl3DModel.Cl3DModelPointIterator leftEye  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner.ToString());

            float MeanX = (rightEye.X + leftEye.X) / 2;
            float MeanY = (rightEye.Y + leftEye.Y) / 2;

            float rotation = ClTools.GetAngle2D(MeanX, MeanY, 0, 1);

            rotation = rotation * ((float)Math.PI / 180);


            using (TextWriter tw = new StreamWriter(name, false))
            {
                tw.WriteLine(
                    NoseTip.X.ToString(System.Globalization.CultureInfo.InvariantCulture) + " " +
                    NoseTip.Y.ToString(System.Globalization.CultureInfo.InvariantCulture));

                tw.WriteLine(rotation.ToString(System.Globalization.CultureInfo.InvariantCulture));

                tw.Close();
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            List <Cl3DModel.Cl3DModelPointIterator>[,] Map = null;

            int   width        = 0;
            int   heinght      = 0;
            float MinusXoffset = 0.0f;
            float MinusYoffset = 0.0f;

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                foreach (Cl3DModel.Cl3DModelPointIterator neighbor in iter.GetListOfNeighbors())
                {
                    iter.RemoveNeighbor(neighbor);
                }
            } while (iter.MoveToNext());

            ClTools.CreateGridBasedOnRealXY(p_Model, out Map, out width, out heinght, out MinusXoffset, out MinusYoffset);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < heinght; y++)
                {
                    if (Map[x, y] != null)
                    {
                        float MeanValue = ClTools.CalculateMeanValue(Map[x, y]);

                        Cl3DModel.Cl3DModelPointIterator Point = Map[x, y][0];

                        foreach (Cl3DModel.Cl3DModelPointIterator pt in Map[x, y])
                        {
                            string label = "";
                            if (pt.IsLabeled(out label))
                            {
                                Point = pt;
                                break;
                            }
                        }
                        foreach (Cl3DModel.Cl3DModelPointIterator pt in Map[x, y])
                        {
                            if (pt.PointID != Point.PointID)
                            {
                                p_Model.RemovePointFromModel(pt);
                                //         Map[x, y].Remove(pt);
                            }
                        }

                        Point.RangeImageX = x;
                        Point.RangeImageY = y;
                        Point.Z           = MeanValue;
                        Point.X           = x + MinusXoffset;
                        Point.Y           = y + MinusYoffset;
                    }
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel ConformalModel = new Cl3DModel();

            ConformalModel.LoadModel(p_Model.ModelFileFolder + ConformalMapFolder + "\\" + p_Model.ModelFileName + ".m_Out.pos.m");

            Cl3DModel.Cl3DModelPointIterator iter      = p_Model.GetIterator();
            List <ClTools.ClTriangle>        Triangles = null;

            float ModelArea = CalculateWholeModelArea(p_Model);

            float ConformalMapArea = CalculateWholeModelArea(ConformalModel);

            if (iter.IsValid())
            {
                do
                {
                    float area3D = 0;
                    ClTools.GetListOfTriangles(out Triangles, iter);

                    //    if (Triangles.Count != 6)
                    //       continue;

                    foreach (ClTools.ClTriangle triangle in Triangles)
                    {
                        area3D += ClTools.CalculateTriangleArea(triangle);
                    }

                    area3D /= Triangles.Count;

                    iter.AddSpecificValue("ConnectedTrianglesArea", area3D);

                    Cl3DModel.Cl3DModelPointIterator ConformalIter = ConformalModel.GetIterator();
                    if (!ConformalIter.MoveToPoint(iter.PointID))
                    {
                        continue;//throw new Exception("Cannot find on conformal model point with no: " + iter.PointID.ToString());
                    }
                    float area2D = 0;
                    ClTools.GetListOfTriangles(out Triangles, ConformalIter);
                    foreach (ClTools.ClTriangle triangle in Triangles)
                    {
                        area2D += ClTools.CalculateTriangleArea(triangle);
                    }

                    area2D /= Triangles.Count;

                    float ConformalFactor = (area3D / ModelArea) / (area2D / ConformalMapArea);

                    ConformalIter.AddSpecificValue("ConformalFactor", ConformalFactor);
                } while (iter.MoveToNext());
            }

            p_Model = ConformalModel;
        }
コード例 #8
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator RightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner.ToString());
            Cl3DModel.Cl3DModelPointIterator LeftEye  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner.ToString());

            Cl3DModel.Cl3DModelPointIterator[,] Map = null;
            int Width, Height, Xoffset, Yoffset;

            ClTools.CreateGridBasedOnRangeValues(p_Model, out Map, out Width, out Height, out Xoffset, out Yoffset);

            int RightEyeX = RightEye.RangeImageX - Xoffset;
            int RightEyeY = RightEye.RangeImageY - Yoffset;
            int LeftEyeX  = LeftEye.RangeImageX - Xoffset;
            int LeftEyeY  = LeftEye.RangeImageY - Yoffset;

            int MiddleX = (RightEyeX + LeftEyeX) / 2;
            int MiddleY = (RightEyeY + LeftEyeY) / 2;

            Cl3DModel.Cl3DModelPointIterator MiddlePoint = Map[MiddleX, MiddleY];
            p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.UnspecifiedPoint, MiddlePoint);

            List <Cl3DModel.Cl3DModelPointIterator> Neighborhood = null;

            ClTools.GetNeighborhoodWithGeodesicDistance(out Neighborhood, MiddlePoint, m_fEyesPartRadious);
            foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
            {
                point.AlreadyVisited = true;
            }

            MiddlePoint.AlreadyVisited = true;

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                if (!iter.IsValid())
                {
                    break;
                }

                if (!iter.AlreadyVisited)
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                if (!iter.MoveToNext())
                {
                    break;
                }
            } while (true);
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            string fileName = ClTools.ExtractOryginalFileNameFRGC(p_Model.ModelFileName);

            string expression = "";

            if (!ClTools.ClExpressionFRGC.GetExpression(fileName, out expression))
            {
                throw new Exception("Cannot find Expression for file " + p_Model.ModelFilePath);
            }

            p_Model.ModelExpression = expression;

            ClInformationSender.SendInformation("Model has expression: " + p_Model.ModelExpression, ClInformationSender.eInformationType.eDebugText);
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            List <KeyValuePair <string, Cl3DModel.Cl3DModelPointIterator> > list = p_Model.GetAllSpecificPoints();

            foreach (KeyValuePair <string, Cl3DModel.Cl3DModelPointIterator> point in list)
            {
                List <Cl3DModel.Cl3DModelPointIterator> NeighborhoodList = null;
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out NeighborhoodList, point.Value, 2.0f);
                foreach (Cl3DModel.Cl3DModelPointIterator ppoint in NeighborhoodList)
                {
                    ppoint.Color = Color.Red;
                }
            }
        }
コード例 #11
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator NoseTip = null;
            if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString(), ref NoseTip))
            {
                throw new Exception("Cannot get Nose Tip");
            }

            List <Cl3DModel.Cl3DModelPointIterator> Neighborhood = null;

            ClTools.GetNeighborhoodWithGeodesicDistance(out Neighborhood, NoseTip, m_NeighborhoodSize);

            foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
            {
                point.Color = Color.Red;
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            // uint no = (uint)p_Model.ModelPointsCount / 2;

            //  if (!iter.MoveToPoint(no))
            //      throw new Exception("Cannot find point no: " + no.ToString());

            List <Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;

            ClTools.GetNeighborhoodWithGeodesicDistance(out PointNeighborhood, iter, m_SphereSize);
            foreach (Cl3DModel.Cl3DModelPointIterator p in PointNeighborhood)
            {
                p_Model.RemovePointFromModel(p);
            }
            p_Model.RemovePointFromModel(iter);
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            if (NormalsAdded.Count != 0)
            {
                foreach (Cl3DModel.Cl3DModelPointIterator pt in NormalsAdded)
                {
                    p_Model.RemovePointFromModel(pt);
                }

                NormalsAdded = new List <Cl3DModel.Cl3DModelPointIterator>();
            }

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                Vector NormalVector = null;
                if (UsePCA)
                {
                    ClTools.CalculateNormalVectorInPointUsingPCA(iter.X, iter.Y, iter.Z, iter.GetListOfNeighbors(), out NormalVector);
                }
                else
                {
                    ClTools.CalculateNormalVectorInPoint(iter.X, iter.Y, iter.Z, iter.GetListOfNeighbors(), out NormalVector);
                }

                double norm = Math.Sqrt(Math.Pow(NormalVector[0], 2) + Math.Pow(NormalVector[1], 2) + Math.Pow(NormalVector[2], 2));
                if (norm != 0)
                {
                    NormalVector[0] /= (float)norm;
                    NormalVector[1] /= (float)norm;
                    NormalVector[2] /= (float)norm;
                }
                iter.NormalVector = NormalVector;

                if (ShowNormals)
                {
                    Cl3DModel.Cl3DModelPointIterator point = p_Model.AddPointToModel(iter.X - (float)NormalVector[0] * 3, iter.Y - (float)NormalVector[1] * 3, iter.Z - (float)NormalVector[2] * 3);
                    iter.AddNeighbor(point);
                    NormalsAdded.Add(point);
                }
            } while (iter.MoveToNext());
        }
コード例 #14
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            if (m_bRandomX)
            {
                Random random = new Random();
                m_fAngleX = (int)random.Next(-45, 45);
            }
            if (m_bRandomY)
            {
                Random random = new Random();
                m_fAngleY = (int)random.Next(-90, 90);
            }
            if (m_bRandomZ)
            {
                Random random = new Random();
                m_fAngleZ = (int)random.Next(-30, 30);
            }

            ClInformationSender.SendInformation("ROTATIONS: X: " + m_fAngleX + " Y: " + m_fAngleY + " Z: " + m_fAngleZ, ClInformationSender.eInformationType.eDebugText);

            while (iter.IsValid())
            {
                float X = iter.X;
                float Y = iter.Y;
                float Z = iter.Z;
                ClTools.RotateXDirection(X, Y, Z, m_fAngleX * (float)(Math.PI / 180), out X, out Y, out Z);
                ClTools.RotateYDirection(X, Y, Z, m_fAngleY * (float)(Math.PI / 180), out X, out Y, out Z);
                ClTools.RotateZDirection(X, Y, Z, m_fAngleZ * (float)(Math.PI / 180), out X, out Y, out Z);

                iter.X = X;
                iter.Y = Y;
                iter.Z = Z;

                if (!iter.MoveToNext())
                {
                    break;
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            uint   current          = 0;
            string NeighborhoodSize = m_fNeighborhoodSize.ToString();

            if (m_bFirstNeighbor)
            {
                NeighborhoodSize = "1Neighb";
            }
            string ShapeIndexString = "ShapeIndex_" + NeighborhoodSize;

            if (iter.IsValid())
            {
                do
                {
                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H               = 0;
                    double K               = 0;
                    double k1              = 0;
                    double k2              = 0;
                    double ShapeIndex      = 0;
                    double CurvednessIndex = 0;
                    List <Cl3DModel.Cl3DModelPointIterator> ListOfneighborhood;
                    double dx;
                    double dy;
                    double dxy;
                    double dxx;
                    double dyy;

                    //------------------------- Neighborhood Custom --------------------------------------------------
                    if (!iter.IsSpecificValueCalculated(ShapeIndexString) || m_bRecalculateCurvature)
                    {
                        if (!m_bFirstNeighbor)
                        {
                            ClTools.GetNeighborhoodWithGeodesicDistance(out ListOfneighborhood, iter, m_fNeighborhoodSize);
                        }
                        else
                        {
                            ListOfneighborhood = iter.GetListOfNeighbors();
                        }

                        if (m_bNeighborhoodRotation)
                        {
                            Matrix Rotation = ClTools.CalculateRotationMatrix(iter.NormalVector, new Vector(new double[] { iter.NormalVector[0], iter.NormalVector[1], 1 }));
                            List <ClTools.MainPoint3D> Neighbors = new List <ClTools.MainPoint3D>();
                            foreach (Cl3DModel.Cl3DModelPointIterator Neighb in ListOfneighborhood)
                            {
                                Matrix after = Rotation * Neighb;
                                Neighbors.Add(new ClTools.MainPoint3D((float)after[0, 0], (float)after[1, 0], (float)after[2, 0], ""));
                            }

                            if (!ClTools.CountSurfaceCoefficients(Neighbors, ref A, ref B, ref C, ref D, ref E, ref F))
                            {
                                iter.RemoveSpecificValue("Gaussian_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("Mean_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("K1_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("K2_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("ShapeIndex_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("CurvednessIndex_" + NeighborhoodSize);
                                continue;
                            }
                        }
                        else
                        {
                            if (!ClTools.CountSurfaceCoefficients(ListOfneighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                            {
                                iter.RemoveSpecificValue("Gaussian_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("Mean_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("K1_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("K2_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("ShapeIndex_" + NeighborhoodSize);
                                iter.RemoveSpecificValue("CurvednessIndex_" + NeighborhoodSize);
                                continue;
                            }
                        }


                        dx  = B + 2 * D * iter.X + E * iter.Y;
                        dy  = C + E * iter.X + 2 * F * iter.Y;
                        dxy = E;
                        dxx = 2 * D;
                        dyy = 2 * F;
                        //Mean
                        H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                        //Gaussian
                        K               = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                        k1              = H + Math.Sqrt(Math.Pow(H, 2) - K);
                        k2              = H - Math.Sqrt(Math.Pow(H, 2) - K);
                        ShapeIndex      = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));
                        CurvednessIndex = Math.Sqrt(Math.Pow(k1, 2) + Math.Pow(k2, 2)) / 2;

                        iter.AddSpecificValue("Gaussian_" + NeighborhoodSize, K);
                        iter.AddSpecificValue("Mean_" + NeighborhoodSize, H);
                        iter.AddSpecificValue("K1_" + NeighborhoodSize, k1);
                        iter.AddSpecificValue("K2_" + NeighborhoodSize, k2);
                        iter.AddSpecificValue("ShapeIndex_" + NeighborhoodSize, ShapeIndex);
                        iter.AddSpecificValue("CurvednessIndex_" + NeighborhoodSize, CurvednessIndex);
                    }

                    ClInformationSender.SendInformation((current * 100 / p_Model.ModelPointsCount).ToString(System.Globalization.CultureInfo.InvariantCulture), ClInformationSender.eInformationType.eProgress);
                    current++;
                } while (iter.MoveToNext());
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator Center = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);

            Cl3DModel.Cl3DModelPointIterator        iter             = p_Model.GetIterator();
            List <Cl3DModel.Cl3DModelPointIterator> BoundaryVertexes = new List <Cl3DModel.Cl3DModelPointIterator>();

            Cl3DModel.Cl3DModelPointIterator BeginningPoint = null;
            do
            {
                if (iter.GetListOfNeighbors().Count <= 7)
                {
                    iter.AlreadyVisited = true;
                    // iter.Color = Color.Red;

                    if (BeginningPoint == null)
                    {
                        BeginningPoint = iter.CopyIterator();
                    }

                    BoundaryVertexes.Add(iter.CopyIterator());
                }
            } while (iter.MoveToNext());

            Cl3DModel.Cl3DModelPointIterator CurrentPoint = BeginningPoint.CopyIterator();
            Vector NormalVector   = new Vector(3);
            bool   IsNextInTheQue = false;
            float  CurrentNo      = 0;

            do
            {
                CurrentPoint.AlreadyVisited = false;
                Cl3DModel.Cl3DModelPointIterator NextPoint = null;
                IsNextInTheQue = false;
                foreach (Cl3DModel.Cl3DModelPointIterator neighbor in CurrentPoint.GetListOfNeighbors())
                {
                    if (neighbor.AlreadyVisited) // means next in the que
                    {
                        NextPoint      = neighbor.CopyIterator();
                        IsNextInTheQue = true;
                        break;
                    }
                }
                if (NextPoint == null)
                {
                    break;
                }

                Vector tmpVectorCurr = new Vector(new double[] { (CurrentPoint.X - Center.X), (CurrentPoint.Y - Center.Y), (CurrentPoint.Z - Center.Z) });
                Vector tmpVectorNext = new Vector(new double[] { (NextPoint.X - Center.X), (NextPoint.Y - Center.Y), (NextPoint.Z - Center.Z) });

                NormalVector[0] += (tmpVectorNext[1] * tmpVectorCurr[2] - tmpVectorNext[2] * tmpVectorCurr[1]);
                NormalVector[1] += (tmpVectorNext[2] * tmpVectorCurr[0] - tmpVectorNext[0] * tmpVectorCurr[2]);
                NormalVector[2] += (tmpVectorNext[0] * tmpVectorCurr[1] - tmpVectorNext[1] * tmpVectorCurr[0]);

                NormalVector      /= 2;
                CurrentPoint.Color = ClTools.GetColorRGB(CurrentNo / BoundaryVertexes.Count, 1f);
                CurrentNo++;

                CurrentPoint = NextPoint.CopyIterator();
            } while (IsNextInTheQue);

            //NormalVector = NormalVector.Normalize();
            Center.AddNeighbor(p_Model.AddPointToModel((float)NormalVector[0] + Center.X, (float)NormalVector[1] + Center.Y, (float)NormalVector[2] + Center.Z));


            /*   Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
             * while(iter.IsValid())
             * {
             *     float X = iter.X;
             *     float Y = iter.Y;
             *     float Z = iter.Z;
             *     ClTools.RotateXDirection(X, Y, Z, agnleX, out X, out Y, out Z);
             *     ClTools.RotateYDirection(X, Y, Z, angleY, out X, out Y, out Z);
             *     ClTools.RotateZDirection(X, Y, Z, agnleZ, out X, out Y, out Z);
             *
             *     iter.X = X;
             *     iter.Y = Y;
             *     iter.Z = Z;
             *
             *     if (!iter.MoveToNext())
             *         break;
             * }
             */
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            MarkHighCurvEdges(ref p_Model);

            p_Model.ResetVisitedPoints();
            //-------------------------------- Cropping
            Cl3DModel.Cl3DModelPointIterator NoseTip  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            Cl3DModel.Cl3DModelPointIterator LeftEye  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Cl3DModel.Cl3DModelPointIterator RightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);

            float distanceBetweenEyes = LeftEye - RightEye;
            float ossfest             = distanceBetweenEyes * 0.4f; //20% of distance between eyes will be taken as a stripe down to search for the mouth hole

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            Dictionary <uint, Cl3DModel.Cl3DModelPointIterator> pointsToRemove = new Dictionary <uint, Cl3DModel.Cl3DModelPointIterator>();

            do
            {
                if (iter.X > LeftEye.X + ossfest && iter.X < RightEye.X - ossfest && iter.Y < NoseTip.Y - 20 && iter.Y > NoseTip.Y - 43)
                {
                    // iter.Color = Color.LightBlue;
                    if (iter.IsSpecificValueCalculated("ToRemove_HighCurvature"))
                    {
                        pointsToRemove.Add(iter.PointID, iter.CopyIterator());
                    }
                }
            } while (iter.MoveToNext());

            List <List <Cl3DModel.Cl3DModelPointIterator> > ListOfRegions = new List <List <Cl3DModel.Cl3DModelPointIterator> >();

            while (pointsToRemove.Count != 0)
            {
                Cl3DModel.Cl3DModelPointIterator test = new List <Cl3DModel.Cl3DModelPointIterator>(pointsToRemove.Values)[0];
                pointsToRemove.Remove(test.PointID);

                bool toRemove = false;
                List <Cl3DModel.Cl3DModelPointIterator> CurrentList = new List <Cl3DModel.Cl3DModelPointIterator>();
                ListOfRegions.Add(CurrentList);

                List <Cl3DModel.Cl3DModelPointIterator> ToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();
                ToCheck.Add(test);
                test.AlreadyVisited = true;
                do
                {
                    List <Cl3DModel.Cl3DModelPointIterator> NewToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();
                    foreach (Cl3DModel.Cl3DModelPointIterator pt in ToCheck)
                    {
                        CurrentList.Add(pt.CopyIterator());

                        foreach (Cl3DModel.Cl3DModelPointIterator ptNb in pt.GetListOfNeighbors())
                        {
                            if (ptNb.IsSpecificValueCalculated("ToRemove_HighCurvature") && ptNb.AlreadyVisited == false)
                            {
                                ptNb.AlreadyVisited = true;
                                NewToCheck.Add(ptNb.CopyIterator());
                                pointsToRemove.Remove(ptNb.PointID);
                                List <Cl3DModel.Cl3DModelPointIterator> Neighbors = ptNb.GetListOfNeighbors();

                                //   if (Neighbors.Count < 8) // that means the points from marked region went to the end of the model very rare happens that the open mouth region is the externatl region
                                //       toRemove = true;
                            }
                        }
                    }
                    ToCheck    = NewToCheck;
                    NewToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();
                } while (ToCheck.Count != 0);
                if (toRemove)
                {
                    ListOfRegions.Remove(CurrentList);
                }
            }

            List <Cl3DModel.Cl3DModelPointIterator> BiggestRegion = null;
            int SizeOfTheBiggest = int.MinValue;

            for (int i = 0; i < ListOfRegions.Count; i++)
            {
                if (ListOfRegions[i].Count > SizeOfTheBiggest)
                {
                    SizeOfTheBiggest = ListOfRegions[i].Count;
                    BiggestRegion    = ListOfRegions[i];
                }
            }

            //------------------- Creating image of localized mouth part

            /*   int NoseX = NoseTip.RangeImageX;
             * int NoseY = NoseTip.RangeImageY;
             * //BiggestRegion
             * int[,] FMap = null;
             * if (!FaceMaps.TryGetValue(p_Model.m_sExpression, out FMap))
             * {
             *     FMap = new int[200, 200];
             *     FaceMaps.Add(p_Model.m_sExpression, FMap);
             * }
             * Cl3DModel.Cl3DModelPointIterator its = p_Model.GetIterator();
             * do
             * {
             *     int currX = its.RangeImageX;
             *     int currY = its.RangeImageY;
             *
             *
             *     int x = currX - NoseX + 100;
             *     int y = currY - NoseY + 100;
             *
             *     FMap[x, y]++;
             * } while (its.MoveToNext());
             *
             * int MaxF = int.MinValue;
             * for (int i = 0; i < 200; i++)
             *     for(int j=0; j< 200; j++)
             *         if (FMap[i, j] > MaxF)
             *             MaxF = FMap[i, j];
             *
             *
             * //-
             * int[,] FRem = null;
             * if (!RemovedMaps.TryGetValue(p_Model.m_sExpression, out FRem))
             * {
             *     FRem = new int[200, 200];
             *     RemovedMaps.Add(p_Model.m_sExpression, FRem);
             * }
             *
             * if (BiggestRegion != null)
             * {
             *     foreach (Cl3DModel.Cl3DModelPointIterator pp in BiggestRegion)
             *     {
             *         int currX = pp.RangeImageX;
             *         int currY = pp.RangeImageY;
             *
             *
             *         int x = currX - NoseX + 100;
             *         int y = currY - NoseY + 100;
             *
             *         FRem[x, y]++;
             *     }
             * }
             *
             * FRem[NoseTip.RangeImageX - NoseX + 100, NoseTip.RangeImageY - NoseY + 100]++;
             * //  FRem[LeftEye.RangeImageX - NoseX + 100, LeftEye.RangeImageY - NoseY + 100]++;
             * //  FRem[RightEye.RangeImageX - NoseX + 100, RightEye.RangeImageY - NoseY + 100]++;
             *
             *
             * int MaxR = int.MinValue;
             * for (int i = 0; i < 200; i++)
             *     for (int j = 0; j < 200; j++)
             *         if (FRem[i, j] > MaxR)
             *             MaxR = FRem[i, j];
             *
             *
             *
             *
             *
             *
             *
             *
             *
             * Bitmap map = new Bitmap(200, 200);
             * for (int i = 0; i < 200; i++)
             * {
             *     for (int j = 0; j < 200; j++)
             *     {
             *         map.SetPixel(i, j, ClTools.GetColorGray(((float)FMap[i, j]) / MaxF, 1.0f));
             *         if(FRem[i, j] != 0)
             *             map.SetPixel(i, j, ClTools.GetColorGray( 1 - ((float)FRem[i, j]) / MaxR, 1.0f));
             *     }
             * }
             * map.Save("d:\\" + p_Model.m_sExpression + ".bmp");
             * return;
             */
            //------------------------------------------------------------

            /*  TextWriter tw = new StreamWriter("d:\\MouthSizeBosphorus2.txt", false);
             *
             *
             * int ssize = 0;
             * if (BiggestRegion != null)
             *    ssize = BiggestRegion.Count;
             *
             * int[] OldSize;
             * if(!mouthSize.TryGetValue(p_Model.m_sExpression, out OldSize))
             * {
             *    OldSize = new int[2];
             *    mouthSize.Add(p_Model.m_sExpression, OldSize);
             * }
             * OldSize[0] += ssize;
             * OldSize[1]++;
             *
             * foreach(KeyValuePair<string, int[]> val in mouthSize)
             *    tw.WriteLine(val.Key+" "+ val.Value[0].ToString()+ " " + val.Value[1].ToString());
             *
             * tw.Close();
             *
             * return;
             */
            //----------------------------------------------------------------

            //---------------------- NO mouth REGION LOCALIZED
            if (BiggestRegion == null)
            {
                ClInformationSender.SendInformation("No mouth localized, normal Geodesic distance calculation", ClInformationSender.eInformationType.eDebugText);
                if (m_bRemoveRegions) // still there can be vertexes with high curvature (edges between hair and the face)
                {
                    Cl3DModel.Cl3DModelPointIterator remover = p_Model.GetIterator();
                    while (remover.IsValid())
                    {
                        if (remover.IsSpecificValueCalculated("ToRemove_HighCurvature"))
                        {
                            remover = p_Model.RemovePointFromModel(remover);
                        }
                        else
                        {
                            remover.MoveToNext();
                        }
                    }
                }

                ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());

                if (!m_bCrop)
                {
                    return;
                }

                iter = p_Model.GetIterator();
                while (iter.IsValid())
                {
                    if (!iter.IsSpecificValueCalculated(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip))
                    {
                        iter = p_Model.RemovePointFromModel(iter);
                    }
                    else
                    {
                        double distance = iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip);
                        if (distance > m_fDistence)
                        {
                            iter = p_Model.RemovePointFromModel(iter);
                        }
                        else
                        {
                            iter.MoveToNext();
                        }
                    }
                }
                return;
            }

            //------------------------- Mouth REGION LOCALiZED
            p_Model.ResetVisitedPoints();
            List <Cl3DModel.Cl3DModelPointIterator> BorderOfTheBigestRegion = new List <Cl3DModel.Cl3DModelPointIterator>();

            foreach (Cl3DModel.Cl3DModelPointIterator pts in BiggestRegion)
            {
                if (m_bMarkRegion)
                {
                    pts.Color = Color.Red;
                }

                List <Cl3DModel.Cl3DModelPointIterator> neighb = pts.GetListOfNeighbors();
                foreach (Cl3DModel.Cl3DModelPointIterator ppt in neighb)
                {
                    if (!ppt.AlreadyVisited && !ppt.IsSpecificValueCalculated("ToRemove_HighCurvature"))
                    {
                        BorderOfTheBigestRegion.Add(ppt);
                        ppt.AlreadyVisited = true;
                    }
                }
            }

            if (m_bRemoveRegions) // After we have border of the mouth region we can remove them
            {
                Cl3DModel.Cl3DModelPointIterator remover = p_Model.GetIterator();
                while (remover.IsValid())
                {
                    if (remover.IsSpecificValueCalculated("ToRemove_HighCurvature"))
                    {
                        remover = p_Model.RemovePointFromModel(remover);
                    }
                    else
                    {
                        remover.MoveToNext();
                    }
                }
            }

            Cl3DModel.Cl3DModelPointIterator MaxLeft  = BorderOfTheBigestRegion[0];
            Cl3DModel.Cl3DModelPointIterator MaxRight = BorderOfTheBigestRegion[0];
            foreach (Cl3DModel.Cl3DModelPointIterator pt in BorderOfTheBigestRegion)
            {
                if (pt.X < MaxLeft.X)
                {
                    MaxLeft = pt;
                }
                if (pt.X > MaxRight.X)
                {
                    MaxRight = pt;
                }
            }

            int size = (int)Math.Abs(MaxLeft.X - MaxRight.X) + 1;

            List <Cl3DModel.Cl3DModelPointIterator>[] histogram = new List <Cl3DModel.Cl3DModelPointIterator> [size];

            foreach (Cl3DModel.Cl3DModelPointIterator pt in BorderOfTheBigestRegion)
            {
                int pos = (int)(pt.X - MaxLeft.X);
                if (histogram[pos] == null)
                {
                    histogram[pos] = new List <Cl3DModel.Cl3DModelPointIterator>();
                }

                histogram[pos].Add(pt);
            }

            Dictionary <uint, uint> movingPoints = new Dictionary <uint, uint>();

            for (int i = 0; i < size; i++)
            {
                if (histogram[i] != null && histogram[i].Count != 0)
                {
                    //Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                    Cl3DModel.Cl3DModelPointIterator UpperPoint = histogram[i][0];
                    Cl3DModel.Cl3DModelPointIterator LowerPoint = histogram[i][0];
                    foreach (Cl3DModel.Cl3DModelPointIterator pts in histogram[i])
                    {
                        //  pts.Color = cl;
                        if (UpperPoint.Y < pts.Y)
                        {
                            UpperPoint = pts;
                        }
                        if (LowerPoint.Y > pts.Y)
                        {
                            LowerPoint = pts;
                        }
                    }
                    //UpperPoint from this one
                    if (UpperPoint.PointID != LowerPoint.PointID)
                    {
                        float distance = Math.Min(LowerPoint - MaxLeft, LowerPoint - MaxRight);
                        List <Cl3DModel.Cl3DModelPointIterator> neighborhood = null;
                        ClTools.GetNeighborhoodWithGeodesicDistance(out neighborhood, LowerPoint, distance);
                        Cl3DModel.Cl3DModelPointIterator ClosestPoint = LowerPoint;
                        float MinDistance = LowerPoint - UpperPoint;
                        foreach (Cl3DModel.Cl3DModelPointIterator ptNeighb in neighborhood)
                        {
                            // ptNeighb.Color = Color.Pink;
                            float newDistance = ptNeighb - UpperPoint;
                            if (newDistance < MinDistance)
                            {
                                MinDistance  = newDistance;
                                ClosestPoint = ptNeighb;
                            }
                        }
                        Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                        //    ClosestPoint.Color = cl;
                        //    UpperPoint.Color = cl;
                        movingPoints.Add(UpperPoint.PointID, ClosestPoint.PointID);
                    }
                }
            }

            //-------------------------------- Calculation of the geodesic using movement points
            p_Model.ResetVisitedPoints();
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPointsWithMovement(NoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString(), movingPoints);

            if (!m_bCrop)
            {
                return;
            }

            iter = p_Model.GetIterator();
            while (iter.IsValid())
            {
                if (!iter.IsSpecificValueCalculated(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip))
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                {
                    double distance = iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip);
                    if (distance > m_fDistence)
                    {
                        iter = p_Model.RemovePointFromModel(iter);
                    }
                    else
                    {
                        iter.MoveToNext();
                    }
                }
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            if (p_Model.ModelFileName.Equals("Neutral"))
            {
                NeutralModel = p_Model;
            }
            else
            {
                ExpressionModel = p_Model;
            }

            if (NeutralModel == null || ExpressionModel == null)
            {
                return;
            }

            Cl3DModel.Cl3DModelPointIterator NeutralSavedNoseTip = null;
            Cl3DModel.Cl3DModelPointIterator NeutralLeftEye      = null;
            Cl3DModel.Cl3DModelPointIterator NeutralRightEye     = null;

            if (!NeutralModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, ref NeutralSavedNoseTip) || !NeutralModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, ref NeutralLeftEye) || !NeutralModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, ref NeutralRightEye))
            {
                throw new Exception("Cannot get all specific points (Neutral model)");
            }

            Cl3DModel.Cl3DModelPointIterator ExpressionSavedNoseTip = null;
            Cl3DModel.Cl3DModelPointIterator ExpressionLeftEye      = null;
            Cl3DModel.Cl3DModelPointIterator ExpressionRightEye     = null;

            if (!ExpressionModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, ref ExpressionSavedNoseTip) || !ExpressionModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, ref ExpressionLeftEye) || !ExpressionModel.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, ref ExpressionRightEye))
            {
                throw new Exception("Cannot get all specific points (Exprssion model)");
            }

            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NeutralSavedNoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NeutralLeftEye, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToLeftEye.ToString());
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NeutralRightEye, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToRightEye.ToString());

            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(ExpressionSavedNoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(ExpressionLeftEye, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToLeftEye.ToString());
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(ExpressionRightEye, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToRightEye.ToString());

            Cl3DModel.Cl3DModelPointIterator iterNeutral = NeutralModel.GetIterator();
            do
            {
                // search for the closest point in distance geodesic distance domain
                Cl3DModel.Cl3DModelPointIterator iterExpression = ExpressionModel.GetIterator();
                Cl3DModel.Cl3DModelPointIterator ClossestPoint  = null;
                double ClosestPointDistance = 0;
                bool   first = true;
                double NoseDistanceNeutral     = 0;
                double LeftEyeDistanceNeutral  = 0;
                double RightEyeDistanceNeutral = 0;

                if (!iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip, out NoseDistanceNeutral) || !iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToLeftEye, out LeftEyeDistanceNeutral) || !iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToRightEye, out RightEyeDistanceNeutral))
                {
                    throw new Exception("Cannot get specific value");
                }

                double NoseDistanceExpression;
                double LeftEyeDistanceExpression;
                double RightEyeDistanceExpression;

                do
                {
                    if (!iterExpression.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip, out NoseDistanceExpression) || !iterExpression.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToLeftEye, out LeftEyeDistanceExpression) || !iterExpression.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToRightEye, out RightEyeDistanceExpression))
                    {
                        throw new Exception("Cannot get specific value");
                    }

                    double newClosestPointDistance = Math.Sqrt(Math.Pow(NoseDistanceNeutral - NoseDistanceExpression, 2) + Math.Pow(LeftEyeDistanceNeutral - LeftEyeDistanceExpression, 2) + Math.Pow(RightEyeDistanceNeutral - RightEyeDistanceExpression, 2));
                    if (first)
                    {
                        ClossestPoint        = iterExpression.CopyIterator();
                        ClosestPointDistance = newClosestPointDistance;
                        first = false;
                        continue;
                    }

                    if (ClosestPointDistance > newClosestPointDistance)
                    {
                        ClossestPoint        = iterExpression.CopyIterator();
                        ClosestPointDistance = newClosestPointDistance;
                    }
                } while (iterExpression.MoveToNext());


                double ValNatural;
                double ValExpression;

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.Mean_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.Mean_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_HCurvatures_25, ValNatural - ValExpression);

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.Gaussian_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.Gaussian_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_KCurvatures_25, ValNatural - ValExpression);

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_K1Curvatures_25, ValNatural - ValExpression);

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K2_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K2_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_K2Curvatures_25, ValNatural - ValExpression);

                iterNeutral.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.ShapeIndex_25, out ValNatural);
                ClossestPoint.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.ShapeIndex_25, out ValExpression);
                iterNeutral.AddSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.DifferenceBetween_ShapeIndexCurvatures_25, ValNatural - ValExpression);
            } while (iterNeutral.MoveToNext());
        }
コード例 #19
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            Cl3DModel.Cl3DModelPointIterator max = iter.CopyIterator();
            float distanceMax = 0;

            do
            {
                float distance = (float)Math.Sqrt(Math.Pow(iter.U, 2) + Math.Pow(iter.V, 2));
                if (distanceMax < distance)
                {
                    distanceMax = distance;
                }
            } while (iter.MoveToNext());

            iter = p_Model.GetIterator();
            do
            {
                iter.U = (iter.U / distanceMax) * m_RadiousOfConformalMap;
                iter.V = (iter.V / distanceMax) * m_RadiousOfConformalMap;
            } while (iter.MoveToNext());

            Cl3DModel.Cl3DModelPointIterator LeftEye  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Cl3DModel.Cl3DModelPointIterator RightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);
            Cl3DModel.Cl3DModelPointIterator NoseTip  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);

            Cl3DModel.Cl3DModelPointIterator tmp;
            if (LeftEye.X > RightEye.X)
            {
                tmp      = LeftEye.CopyIterator();
                RightEye = LeftEye.CopyIterator();
                LeftEye  = tmp.CopyIterator();
            }


            double EyesDistance         = Math.Sqrt(Math.Pow(LeftEye.U - RightEye.U, 2) + Math.Pow(LeftEye.V - RightEye.V, 2));
            double NoseLeftEyeDistance  = Math.Sqrt(Math.Pow(LeftEye.U - NoseTip.U, 2) + Math.Pow(LeftEye.V - NoseTip.V, 2));
            double NoseRightEyeDistance = Math.Sqrt(Math.Pow(NoseTip.U - RightEye.U, 2) + Math.Pow(NoseTip.V - RightEye.V, 2));

            double AverageNoseTipEyeDistance = (NoseLeftEyeDistance + NoseRightEyeDistance) / 2;


            Matrix GenModel = new Matrix(2, 3);

            GenModel[0, 0] = 0;
            GenModel[1, 0] = 0; // nose

            GenModel[0, 1] = (EyesDistance / 2);
            GenModel[1, 1] = AverageNoseTipEyeDistance; // left eye

            GenModel[0, 2] = -(EyesDistance / 2);
            GenModel[1, 2] = AverageNoseTipEyeDistance; // right eye

            Matrix Model = new Matrix(2, 3);

            Model[0, 0] = NoseTip.U;
            Model[1, 0] = NoseTip.V; // nose

            Model[0, 1] = LeftEye.U;
            Model[1, 1] = LeftEye.V; // left eye

            Model[0, 2] = RightEye.U;
            Model[1, 2] = RightEye.V; // right eye

            Matrix rotationMatrix    = null;
            Matrix translationMatrix = null;

            ClTools.CalculateRotationAndTranslation(GenModel, Model, out rotationMatrix, out translationMatrix);

            Iridium.Numerics.LinearAlgebra.Matrix q = new Iridium.Numerics.LinearAlgebra.Matrix(2, 1);
            iter = p_Model.GetIterator();
            do
            {
                q[0, 0] = iter.U;
                q[1, 0] = iter.V;
                Iridium.Numerics.LinearAlgebra.Matrix NewQ = rotationMatrix * q + translationMatrix;
                iter.U = (float)NewQ[0, 0];
                iter.V = (float)NewQ[1, 0];
            } while (iter.MoveToNext());

            float U = NoseTip.U;
            float V = NoseTip.V;

            iter = p_Model.GetIterator();
            do
            {
                iter.U -= U;
                iter.V -= V;
            } while (iter.MoveToNext());

            if (centerConformalMaps)
            {
                float middleU = 0;
                float middleV = 0;
                iter = p_Model.GetIterator();
                do
                {
                    middleU += iter.U;
                    middleV += iter.V;
                } while (iter.MoveToNext());

                middleU /= p_Model.ModelPointsCount;
                middleV /= p_Model.ModelPointsCount;
                iter     = p_Model.GetIterator();
                do
                {
                    iter.U -= middleU;
                    iter.V -= middleV;
                } while (iter.MoveToNext());
            }
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            // Looking for a hole and connecting points ---- Later should be removed
            Cl3DModel.Cl3DModelPointIterator NoseTip  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            Cl3DModel.Cl3DModelPointIterator LeftEye  = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Cl3DModel.Cl3DModelPointIterator RightEye = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);

            float distanceBetweenEyes = LeftEye - RightEye;
            float ossfest             = distanceBetweenEyes * 0.4f; //20% of distance between eyes will be taken as a stripe down to search for the mouth hole

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            Dictionary <uint, Cl3DModel.Cl3DModelPointIterator> pointsLowerBoundary = new Dictionary <uint, Cl3DModel.Cl3DModelPointIterator>();

            do
            {
                if (iter.X > LeftEye.X + ossfest && iter.X < RightEye.X - ossfest && iter.Y < NoseTip.Y - 20 && iter.Y > NoseTip.Y - 40)
                {
                    // iter.Color = Color.LightGreen;
                    if (iter.GetListOfNeighbors().Count != 8)
                    {
                        // iter.Color = Color.LightBlue;
                        pointsLowerBoundary.Add(iter.PointID, iter.CopyIterator());
                    }
                }
            } while (iter.MoveToNext());

            List <List <Cl3DModel.Cl3DModelPointIterator> > ListOfBoundarie = new List <List <Cl3DModel.Cl3DModelPointIterator> >();

            while (pointsLowerBoundary.Count != 0)
            {
                Cl3DModel.Cl3DModelPointIterator test = new List <Cl3DModel.Cl3DModelPointIterator>(pointsLowerBoundary.Values)[0];
                pointsLowerBoundary.Remove(test.PointID);

                bool toRemove = false;
                List <Cl3DModel.Cl3DModelPointIterator> CurrentList = new List <Cl3DModel.Cl3DModelPointIterator>();
                ListOfBoundarie.Add(CurrentList);

                List <Cl3DModel.Cl3DModelPointIterator> ToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();
                ToCheck.Add(test);
                test.AlreadyVisited = true;
                do
                {
                    List <Cl3DModel.Cl3DModelPointIterator> NewToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();
                    foreach (Cl3DModel.Cl3DModelPointIterator pt in ToCheck)
                    {
                        CurrentList.Add(pt.CopyIterator());
                        if (pt.Y > NoseTip.Y)
                        {
                            toRemove = true;
                        }

                        foreach (Cl3DModel.Cl3DModelPointIterator ptNb in pt.GetListOfNeighbors())
                        {
                            if (ptNb.GetListOfNeighbors().Count != 8 && ptNb.AlreadyVisited == false)
                            {
                                ptNb.AlreadyVisited = true;
                                NewToCheck.Add(ptNb.CopyIterator());
                                pointsLowerBoundary.Remove(ptNb.PointID);
                            }
                        }
                    }
                    ToCheck    = NewToCheck;
                    NewToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();
                } while (ToCheck.Count != 0);
                if (toRemove)
                {
                    ListOfBoundarie.Remove(CurrentList);
                }
            }

            List <Cl3DModel.Cl3DModelPointIterator> BiggestBoundary = null;
            int SizeOfTheBiggest = int.MinValue;

            for (int i = 0; i < ListOfBoundarie.Count; i++)
            {
                if (ListOfBoundarie[i].Count > SizeOfTheBiggest)
                {
                    SizeOfTheBiggest = ListOfBoundarie[i].Count;
                    BiggestBoundary  = ListOfBoundarie[i];
                }
            }

            if (BiggestBoundary == null)
            {
                ClTools.CalculateGeodesicDistanceFromSourcePointToAllPoints(NoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString());
                iter = p_Model.GetIterator();
                while (iter.IsValid())
                {
                    if (!iter.IsSpecificValueCalculated(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip))
                    {
                        iter = p_Model.RemovePointFromModel(iter);
                    }
                    else
                    {
                        double distance = iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip);
                        if (distance > m_fDistence)
                        {
                            iter = p_Model.RemovePointFromModel(iter);
                        }
                        else
                        {
                            iter.MoveToNext();
                        }
                    }
                }
                return;
            }

            Cl3DModel.Cl3DModelPointIterator MaxLeft  = BiggestBoundary[0];
            Cl3DModel.Cl3DModelPointIterator MaxRight = BiggestBoundary[0];
            foreach (Cl3DModel.Cl3DModelPointIterator pt in BiggestBoundary)
            {
                if (pt.X < MaxLeft.X)
                {
                    MaxLeft = pt;
                }
                if (pt.X > MaxRight.X)
                {
                    MaxRight = pt;
                }
            }

            int size = (int)Math.Abs(MaxLeft.X - MaxRight.X) + 1;

            List <Cl3DModel.Cl3DModelPointIterator>[] histogram = new List <Cl3DModel.Cl3DModelPointIterator> [size];

            foreach (Cl3DModel.Cl3DModelPointIterator pt in BiggestBoundary)
            {
                int pos = (int)(pt.X - MaxLeft.X);
                if (histogram[pos] == null)
                {
                    histogram[pos] = new List <Cl3DModel.Cl3DModelPointIterator>();
                }

                histogram[pos].Add(pt);
            }

            Dictionary <uint, uint> movingPoints = new Dictionary <uint, uint>();

            for (int i = 0; i < size; i++)
            {
                if (histogram[i] != null && histogram[i].Count != 0)
                {
                    //Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                    Cl3DModel.Cl3DModelPointIterator UpperPoint = histogram[i][0];
                    Cl3DModel.Cl3DModelPointIterator LowerPoint = histogram[i][0];
                    foreach (Cl3DModel.Cl3DModelPointIterator pts in histogram[i])
                    {
                        //  pts.Color = cl;
                        if (UpperPoint.Y < pts.Y)
                        {
                            UpperPoint = pts;
                        }
                        if (LowerPoint.Y > pts.Y)
                        {
                            LowerPoint = pts;
                        }
                    }
                    //UpperPoint from this one
                    if (UpperPoint.PointID != LowerPoint.PointID)
                    {
                        float distance = Math.Min(LowerPoint - MaxLeft, LowerPoint - MaxRight);
                        List <Cl3DModel.Cl3DModelPointIterator> neighborhood = null;
                        ClTools.GetNeighborhoodWithGeodesicDistance(out neighborhood, LowerPoint, distance);
                        Cl3DModel.Cl3DModelPointIterator ClosestPoint = LowerPoint;
                        float MinDistance = LowerPoint - UpperPoint;
                        foreach (Cl3DModel.Cl3DModelPointIterator ptNeighb in neighborhood)
                        {
                            // ptNeighb.Color = Color.Pink;
                            float newDistance = ptNeighb - UpperPoint;
                            if (newDistance < MinDistance)
                            {
                                MinDistance  = newDistance;
                                ClosestPoint = ptNeighb;
                            }
                        }
                        Color cl = ClTools.GetColorRGB(((float)i) / size, 1.0f);
                        ClosestPoint.Color = cl;
                        UpperPoint.Color   = cl;
                        movingPoints.Add(UpperPoint.PointID, ClosestPoint.PointID);
                    }
                }
            }
            p_Model.ResetVisitedPoints();
            ClTools.CalculateGeodesicDistanceFromSourcePointToAllPointsWithMovement(NoseTip, Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip.ToString(), movingPoints);

            iter = p_Model.GetIterator();
            while (iter.IsValid())
            {
                if (!iter.IsSpecificValueCalculated(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip))
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                {
                    double distance = iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.GeodesicDistanceToNoseTip);
                    if (distance > m_fDistence)
                    {
                        iter = p_Model.RemovePointFromModel(iter);
                    }
                    else
                    {
                        iter.MoveToNext();
                    }
                }
            }
            return;

            //------------------------ PCA ----------------------

            /*
             * float MeanX = 0;
             * float MeanY = 0;
             * float MeanZ = 0;
             * Matrix xy = new Matrix(3, BiggestBoundary.Count);
             * for (int i = 0; i < BiggestBoundary.Count; i++)
             * {
             *  xy[0,i] = BiggestBoundary[i].X;
             *  xy[1,i] = BiggestBoundary[i].Y
             *  xy[2, i] = BiggestBoundary[i].Z;
             *
             *  MeanX += BiggestBoundary[i].X;
             *  MeanY += BiggestBoundary[i].Y;
             *  MeanZ += BiggestBoundary[i].Z;
             *
             *  BiggestBoundary[i].Color = Color.Red;
             * }
             * MeanX /= BiggestBoundary.Count;
             * MeanY /= BiggestBoundary.Count;
             * MeanZ /= BiggestBoundary.Count;
             *
             * for (int i = 0; i < BiggestBoundary.Count; i++)
             * {
             *  xy[0, i] -= MeanX;
             *  xy[1, i] -= MeanY;
             *  xy[2, i] -= MeanZ;
             * }
             *
             *
             * Matrix Transpose = xy.Clone();
             * Transpose.Transpose();
             * Matrix Corelation = xy * Transpose;
             *
             * SingularValueDecomposition SVD = new SingularValueDecomposition(Corelation);
             *
             * Cl3DModel.Cl3DModelPointIterator point = p_Model.AddPointToModel(MeanX, MeanY, MeanZ);
             * Cl3DModel.Cl3DModelPointIterator point2 = p_Model.AddPointToModel(MeanX + (float)SVD.LeftSingularVectors[0, 0] * 10, MeanY + (float)SVD.LeftSingularVectors[1, 0] * 10, MeanZ + (float)SVD.LeftSingularVectors[2, 0] * 10);
             * Cl3DModel.Cl3DModelPointIterator point3 = p_Model.AddPointToModel(MeanX + (float)SVD.LeftSingularVectors[0, 1] * 10, MeanY + (float)SVD.LeftSingularVectors[1, 1] * 10, MeanZ + (float)SVD.LeftSingularVectors[2, 1] * 10);
             * Cl3DModel.Cl3DModelPointIterator point4 = p_Model.AddPointToModel(MeanX + (float)SVD.LeftSingularVectors[0, 2] * 10, MeanY + (float)SVD.LeftSingularVectors[1, 2] * 10, MeanZ + (float)SVD.LeftSingularVectors[2, 2] * 10);
             * point2.Color = Color.Red;
             * point3.Color = Color.Green;
             * point4.Color = Color.Blue;
             * point.AddNeighbor(point2);
             * point.AddNeighbor(point3);
             * point.AddNeighbor(point4);
             */
            //---------------------------------------------------------------------------
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator EyePoint1 = null;
            Cl3DModel.Cl3DModelPointIterator EyePoint2 = null;
            Cl3DModel.Cl3DModelPointIterator NosePoint = null;

            if (!p_Model.GetSpecificPoint(LeftEyeLabel, ref EyePoint1))
            {
                throw new Exception("Cannot find specific point labeled as: " + LeftEyeLabel);
            }
            if (!p_Model.GetSpecificPoint(RightEyeLabel, ref EyePoint2))
            {
                throw new Exception("Cannot find specific point labeled as: " + RightEyeLabel);
            }
            if (!p_Model.GetSpecificPoint(NoseLabel, ref NosePoint))
            {
                throw new Exception("Cannot find specific point labeled as: " + NoseLabel);
            }

            Matrix GenModel = new Matrix(3, 3);

            GenModel[0, 0] = 0;
            GenModel[1, 0] = 0; // nose
            GenModel[2, 0] = 0;

            GenModel[0, 1] = -22f;
            GenModel[1, 1] = 34f; // left eye
            GenModel[2, 1] = -35f;

            GenModel[0, 2] = 22f;
            GenModel[1, 2] = 34f; // right eye
            GenModel[2, 2] = -35f;

            Matrix Model = new Matrix(3, 3);

            Cl3DModel.Cl3DModelPointIterator point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            Model[0, 0] = point.X;
            Model[1, 0] = point.Y; // nose
            Model[2, 0] = point.Z;

            point       = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
            Model[0, 1] = point.X;
            Model[1, 1] = point.Y; // left eye
            Model[2, 1] = point.Z;

            point       = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);
            Model[0, 2] = point.X;
            Model[1, 2] = point.Y; // right eye
            Model[2, 2] = point.Z;

            Matrix rotationMatrix    = null;
            Matrix translationMatrix = null;

            ClTools.CalculateRotationAndTranslation(GenModel, Model, out rotationMatrix, out translationMatrix);

            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                Matrix V = rotationMatrix * iter + translationMatrix;
                iter.X = (float)V[0, 0];
                iter.Y = (float)V[1, 0];
                iter.Z = (float)V[2, 0];
            } while (iter.MoveToNext());

            point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
            float x = point.X;
            float y = point.Y;
            float z = point.Z;

            iter = p_Model.GetIterator();
            do
            {
                iter.X = iter.X - x;
                iter.Y = iter.Y - y;
                iter.Z = iter.Z - z;
            } while (iter.MoveToNext());
        }
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Matrix GenModel = new Matrix(3, 3);

            GenModel[0, 0] = 0;
            GenModel[1, 0] = 0; // nose
            GenModel[2, 0] = 0;

            GenModel[0, 1] = -22f;
            GenModel[1, 1] = 34f; // left eye
            GenModel[2, 1] = -35f;

            GenModel[0, 2] = 22f;
            GenModel[1, 2] = 34f; // right eye
            GenModel[2, 2] = -35f;
            Matrix Model = new Matrix(3, 3);

            Cl3DModel.Cl3DModelPointIterator point = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString());
            Model[0, 0] = point.X;
            Model[1, 0] = point.Y; // nose
            Model[2, 0] = point.Z;

            point       = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner.ToString());
            Model[0, 1] = point.X;
            Model[1, 1] = point.Y; // left eye
            Model[2, 1] = point.Z;

            point       = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner.ToString());
            Model[0, 2] = point.X;
            Model[1, 2] = point.Y; // right eye
            Model[2, 2] = point.Z;

            Matrix rotationMatrix    = null;
            Matrix translationMatrix = null;

            ClTools.CalculateRotationAndTranslation(GenModel, Model, out rotationMatrix, out translationMatrix);

            string name = p_Model.ModelFileFolder + p_Model.ModelFileName + ".rt";

            // List<KeyValuePair<string,Cl3DModel.Cl3DModelPointIterator>> specPoints = p_Model.GetAllSpecificPoints();
            using (TextWriter tw = new StreamWriter(name, false))
            {
                tw.WriteLine("@----------------------------------------");
                tw.WriteLine("@           3DModelsPreprocessing");
                tw.WriteLine("@      Przemyslaw Szeptycki LIRIS 2009");
                tw.WriteLine("@ Rotation and Translation Matrix to normalize face model");
                tw.WriteLine("@ Rotation:");
                tw.WriteLine(rotationMatrix.ToString());
                tw.WriteLine("@ Translation:");
                tw.WriteLine(translationMatrix.ToString());
                tw.Close();
            }

            /*
             * Iridium.Numerics.LinearAlgebra.Matrix q = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
             * Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
             * do
             * {
             *   q[0, 0] = iter.X;
             *   q[1, 0] = iter.Y;
             *   q[2, 0] = iter.Z;
             *   Iridium.Numerics.LinearAlgebra.Matrix NewQ = rotationMatrix * q + translationMatrix;
             *   iter.X = (float)NewQ[0, 0];
             *   iter.Y = (float)NewQ[1, 0];
             *   iter.Z = (float)NewQ[2, 0];
             * } while (iter.MoveToNext());
             */
        }
コード例 #23
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator[,] Map;
            int width   = 0;
            int height  = 0;
            int offsetX = 0;
            int offsetY = 0;

            ClTools.CreateGridBasedOnRangeValues(p_Model, out Map, out width, out height, out offsetX, out offsetY);

            double SumOfKernelMatrix = 0;

            double[,] Mask = GetGaussianMatrix(MaskSize, 2.0f, out SumOfKernelMatrix);

            int pointsFromCenter = (MaskSize / 2);

            for (int centX = 0; centX < width; centX++)
            {
                for (int centY = 0; centY < height; centY++)
                {
                    if (Map[centX, centY] == null)
                    {
                        continue;
                    }

                    int XBeginning = centX - pointsFromCenter;
                    int YBeginning = centY - pointsFromCenter;

                    double value    = 0;
                    bool   didBreak = false;
                    for (int xi = 0; xi < MaskSize; xi++)
                    {
                        for (int yi = 0; yi < MaskSize; yi++)
                        {
                            if (XBeginning + xi >= 0 && XBeginning + xi < width && YBeginning + yi >= 0 && YBeginning + yi < height &&
                                Map[XBeginning + xi, YBeginning + yi] != null)
                            {
                                value += Mask[xi, yi] * Map[XBeginning + xi, YBeginning + yi].Z;
                            }
                            else
                            {
                                Map[centX, centY].AlreadyVisited = true;
                                //  Map[centX, centY].Color = Color.Red;
                                didBreak = true;
                                break;
                            }
                        }
                        if (didBreak)
                        {
                            break;
                        }
                    }
                    if (!didBreak)
                    {
                        Map[centX, centY].Z = (float)(value / SumOfKernelMatrix);
                    }
                }
            }
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            do
            {
                if (iter.AlreadyVisited)
                {
                    iter = p_Model.RemovePointFromModel(iter);
                }
                else
                {
                    iter.MoveToNext();
                }
            } while (iter.IsValid());
        }
コード例 #24
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            //------------------- LeftCornerOfLips -------------------------
            Cl3DModel.Cl3DModelPointIterator        basicPoint = null;
            List <Cl3DModel.Cl3DModelPointIterator> Neighborhood;
            double max = 0;

            Cl3DModel.Cl3DModelPointIterator NewCorner = null;

            if (p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips.ToString(), ref basicPoint))
            {
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out Neighborhood, basicPoint, 15);

                Neighborhood.Add(basicPoint);

                max       = 0;
                NewCorner = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                {
                    List <Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;
                    ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out PointNeighborhood, point, 10);
                    point.Color = Color.Magenta;

                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H          = 0;
                    double K          = 0;
                    double k1         = 0;
                    double k2         = 0;
                    double ShapeIndex = 0;

                    if (!ClTools.CountSurfaceCoefficients(PointNeighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                    {
                        continue;
                    }

                    double dx  = B + 2 * D * point.X + E * point.Y;
                    double dy  = C + E * point.X + 2 * F * point.Y;
                    double dxy = E;
                    double dxx = 2 * D;
                    double dyy = 2 * F;

                    //Mean
                    H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                    //Gaussian
                    K          = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                    k1         = H + Math.Sqrt(Math.Pow(H, 2) - K);
                    k2         = H - Math.Sqrt(Math.Pow(H, 2) - K);
                    ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));

                    if (H > 0 && K > max)
                    {
                        max       = K;
                        NewCorner = point.CopyIterator();
                    }
                }
                if (NewCorner != null)
                {
                    p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, NewCorner);
                }
            }

            //------------------- RightCornerOfLips -------------------------
            if (p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, ref basicPoint))
            {
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out Neighborhood, basicPoint, 15);
                Neighborhood.Add(basicPoint);

                max       = 0;
                NewCorner = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                {
                    List <Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;
                    ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out PointNeighborhood, point, 10);
                    point.Color = Color.Magenta;

                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H          = 0;
                    double K          = 0;
                    double k1         = 0;
                    double k2         = 0;
                    double ShapeIndex = 0;

                    if (!ClTools.CountSurfaceCoefficients(PointNeighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                    {
                        continue;
                    }

                    double dx  = B + 2 * D * point.X + E * point.Y;
                    double dy  = C + E * point.X + 2 * F * point.Y;
                    double dxy = E;
                    double dxx = 2 * D;
                    double dyy = 2 * F;

                    //Mean
                    H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                    //Gaussian
                    K          = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                    k1         = H + Math.Sqrt(Math.Pow(H, 2) - K);
                    k2         = H - Math.Sqrt(Math.Pow(H, 2) - K);
                    ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));

                    if (H > 0 && K > max)
                    {
                        max       = K;
                        NewCorner = point.CopyIterator();
                    }
                }
                if (NewCorner != null)
                {
                    p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, NewCorner);
                }
            }
            //------------------- LeftCornerOfNose -------------------------
            if (p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, ref basicPoint))
            {
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out Neighborhood, basicPoint, 10);
                Neighborhood.Add(basicPoint);

                max       = 0;
                NewCorner = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                {
                    List <Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;
                    ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out PointNeighborhood, point, 10);
                    point.Color = Color.Orchid;

                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H          = 0;
                    double K          = 0;
                    double k1         = 0;
                    double k2         = 0;
                    double ShapeIndex = 0;

                    if (!ClTools.CountSurfaceCoefficients(PointNeighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                    {
                        continue;
                    }

                    double dx  = B + 2 * D * point.X + E * point.Y;
                    double dy  = C + E * point.X + 2 * F * point.Y;
                    double dxy = E;
                    double dxx = 2 * D;
                    double dyy = 2 * F;

                    //Mean
                    H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                    //Gaussian
                    K          = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                    k1         = H + Math.Sqrt(Math.Pow(H, 2) - K);
                    k2         = H - Math.Sqrt(Math.Pow(H, 2) - K);
                    ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));

                    if (H > 0 && K > max)
                    {
                        max       = K;
                        NewCorner = point.CopyIterator();
                    }
                }
                if (NewCorner != null)
                {
                    p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, NewCorner);
                }
            }
            //------------------- RightCornerOfNose -------------------------
            if (p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, ref basicPoint))
            {
                ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out Neighborhood, basicPoint, 10);
                Neighborhood.Add(basicPoint);

                max       = 0;
                NewCorner = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in Neighborhood)
                {
                    List <Cl3DModel.Cl3DModelPointIterator> PointNeighborhood;
                    ClTools.GetNeighborhoodWithEuclideanDistanceCheckNeighborhood(out PointNeighborhood, point, 10);
                    point.Color = Color.Orchid;

                    double A = 0;
                    double B = 0;
                    double C = 0;
                    double D = 0;
                    double E = 0;
                    double F = 0;

                    double H          = 0;
                    double K          = 0;
                    double k1         = 0;
                    double k2         = 0;
                    double ShapeIndex = 0;

                    if (!ClTools.CountSurfaceCoefficients(PointNeighborhood, ref A, ref B, ref C, ref D, ref E, ref F))
                    {
                        continue;
                    }

                    double dx  = B + 2 * D * point.X + E * point.Y;
                    double dy  = C + E * point.X + 2 * F * point.Y;
                    double dxy = E;
                    double dxx = 2 * D;
                    double dyy = 2 * F;

                    //Mean
                    H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d)));
                    //Gaussian
                    K          = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2));
                    k1         = H + Math.Sqrt(Math.Pow(H, 2) - K);
                    k2         = H - Math.Sqrt(Math.Pow(H, 2) - K);
                    ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2));

                    if (H > 0 && K > max)
                    {
                        max       = K;
                        NewCorner = point.CopyIterator();
                    }
                }
                if (NewCorner != null)
                {
                    p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, NewCorner);
                }
            }
        }
コード例 #25
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            RemoveUnconnectedParts(ref p_Model);
            p_Model.ResetVisitedPoints();
            List <List <Cl3DModel.Cl3DModelPointIterator> > listOfHoles = new List <List <Cl3DModel.Cl3DModelPointIterator> >();

            List <Cl3DModel.Cl3DModelPointIterator> ListToCheck    = new List <Cl3DModel.Cl3DModelPointIterator>();
            List <Cl3DModel.Cl3DModelPointIterator> newListToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();

            Cl3DModel.Cl3DModelPointIterator iter = null;
            int listNo = 0;

            while ((iter = GetRandomUnseenPointOfHole(ref p_Model)) != null)
            {
                ListToCheck.Add(iter);
                listOfHoles.Add(new List <Cl3DModel.Cl3DModelPointIterator>());
                do
                {
                    foreach (Cl3DModel.Cl3DModelPointIterator ElementFromListToCheck in ListToCheck)
                    {
                        if (!ElementFromListToCheck.AlreadyVisited && ElementFromListToCheck.GetListOfNeighbors().Count < 8)
                        {
                            listOfHoles[listNo].Add(ElementFromListToCheck);
                            ElementFromListToCheck.AlreadyVisited = true;
                            foreach (Cl3DModel.Cl3DModelPointIterator it in ElementFromListToCheck.GetListOfNeighbors())
                            {
                                if (!it.AlreadyVisited && it.GetListOfNeighbors().Count < 8)
                                {
                                    newListToCheck.Add(it);
                                }
                            }
                        }
                    }

                    ListToCheck.Clear();
                    foreach (Cl3DModel.Cl3DModelPointIterator it in newListToCheck)
                    {
                        ListToCheck.Add(it);
                    }
                    newListToCheck.Clear();
                } while (ListToCheck.Count != 0);
                ListToCheck.Clear();
                listNo++;
            }
            //-------------------------------- End of searching holes

            //-------------------------------- Removing the longest hole - border of the face
            if (listOfHoles.Count == 0)
            {
                return;
            }
            int maxCount = listOfHoles[0].Count;;
            int maxI     = 0;

            for (int i = 1; i < listOfHoles.Count; i++)
            {
                if (listOfHoles[i].Count > maxCount)
                {
                    maxI     = i;
                    maxCount = listOfHoles[i].Count;
                }
            }

            listOfHoles.RemoveAt(maxI);
            //-------------------------------- End of removing the longest hole

            if (m_bColorIt)
            {
                for (int i = 0; i < listOfHoles.Count; i++)
                {
                    for (int j = 0; j < listOfHoles[i].Count; j++)
                    {
                        listOfHoles[i][j].Color = Color.FromArgb(255, 0, 255);//ClTools.GetColorRGB(((float)i) / listOfHoles.Count, 1);
                    }
                }
            }

            p_Model.ResetVisitedPoints();
            //----------------- Fill holes
            foreach (List <Cl3DModel.Cl3DModelPointIterator> hole in listOfHoles)
            {
                double A = 0;
                double B = 0;
                double C = 0;
                double D = 0;
                double E = 0;
                double F = 0;
                List <Cl3DModel.Cl3DModelPointIterator> holeToEstimateSurface = new List <Cl3DModel.Cl3DModelPointIterator>();
                foreach (Cl3DModel.Cl3DModelPointIterator it in hole) // we are adding new points to other list becouse all the time its used to aproximate surface
                {
                    holeToEstimateSurface.Add(it.CopyIterator());
                    it.AlreadyVisited = true;
                    List <Cl3DModel.Cl3DModelPointIterator> Neighborhood;
                    ClTools.GetNeighborhoodWithGeodesicDistance(out Neighborhood, it, 20);
                    foreach (Cl3DModel.Cl3DModelPointIterator Neighbor in Neighborhood)
                    {
                        if (!Neighbor.AlreadyVisited)
                        {
                            holeToEstimateSurface.Add(Neighbor);
                            Neighbor.AlreadyVisited = true;
                        }
                    }
                }

                List <Cl3DModel.Cl3DModelPointIterator> PointsOfHole       = new List <Cl3DModel.Cl3DModelPointIterator>();
                List <Cl3DModel.Cl3DModelPointIterator> SortedPointsOfHole = new List <Cl3DModel.Cl3DModelPointIterator>();

                foreach (Cl3DModel.Cl3DModelPointIterator itOut in hole)
                {
                    SortedPointsOfHole.Add(itOut.CopyIterator());

                    foreach (Cl3DModel.Cl3DModelPointIterator itIn in hole)
                    {
                        if (itIn.PointID == itOut.PointID)
                        {
                            continue;
                        }

                        float NewPointX = itOut.X;
                        float NewPointY = itIn.Y;

                        bool exist = false;
                        Cl3DModel.Cl3DModelPointIterator ExistPoint = p_Model.GetIterator();
                        if (!ExistPoint.IsValid())
                        {
                            throw new Exception("Iterator in Model isn't valid");
                        }

                        do
                        {
                            if (Math.Abs(ExistPoint.X - NewPointX) < m_Delta && Math.Abs(ExistPoint.Y - NewPointY) < m_Delta)
                            {
                                exist = true;
                                break;
                            }
                        } while (ExistPoint.MoveToNext());

                        if (!exist)
                        {
                            if (!ClTools.CountSurfaceCoefficients(holeToEstimateSurface, ref A, ref B, ref C, ref D, ref E, ref F))
                            {
                                throw new Exception("Cannot calculate surface coefficients");
                            }

                            float NewPointZ = (float)(A + B * NewPointX + C * NewPointY + D * NewPointX * NewPointX + E * NewPointX * NewPointY + F * NewPointY * NewPointY);

                            Cl3DModel.Cl3DModelPointIterator newPoint = p_Model.AddPointToModel(NewPointX, NewPointY, NewPointZ);
                            holeToEstimateSurface.Add(newPoint.CopyIterator());

                            PointsOfHole.Add(newPoint.CopyIterator());
                            SortedPointsOfHole.Add(newPoint.CopyIterator());
                            if (m_bColorIt)
                            {
                                newPoint.Color = Color.Pink;
                            }
                        }
                    }
                }
                foreach (Cl3DModel.Cl3DModelPointIterator iterPoint in PointsOfHole)
                {
                    SortedPointsOfHole.Sort(new Compare2DDistance(iterPoint));
                    iterPoint.AddNeighbor(SortedPointsOfHole[1]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[2]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[3]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[4]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[5]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[6]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[7]);
                    iterPoint.AddNeighbor(SortedPointsOfHole[8]);
                }
            }
        }
コード例 #26
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            if (!iter.IsValid())
            {
                return;
            }

            List <Cl3DModel.Cl3DModelPointIterator> ListOfNosePoints = new List <Cl3DModel.Cl3DModelPointIterator>();
            List <Cl3DModel.Cl3DModelPointIterator> ListOfEyesPoints = new List <Cl3DModel.Cl3DModelPointIterator>();
            string gausString = "Gaussian_" + m_iNeighborhoodSize.ToString();
            string meanString = "Mean_" + m_iNeighborhoodSize.ToString();

            do
            {
                double H = 0;
                double K = 0;

                if (!iter.GetSpecificValue(gausString, out K))
                {
                    continue;
                }
                if (!iter.GetSpecificValue(meanString, out H))
                {
                    continue;
                }

                if (H < 0 && K > m_NoseThresholdK) //  Nose
                {
                    ListOfNosePoints.Add(iter.CopyIterator());
                }
                else if (H > 0 && K > m_EyesThresholdK) //  Eyes
                {
                    ListOfEyesPoints.Add(iter.CopyIterator());
                }
            }while (iter.MoveToNext());

            List <List <Cl3DModel.Cl3DModelPointIterator> > NoseRegions = null;
            List <List <Cl3DModel.Cl3DModelPointIterator> > EyesRegions = null;

            // NOSE
            DivideToTheRegions(ListOfNosePoints, out NoseRegions);

            // EYES
            DivideToTheRegions(ListOfEyesPoints, out EyesRegions);

            // COLOR IT

            /*for (int i = 0; i < NoseRegions.Count; i++)
             * {
             *  foreach (Cl3DModel.Cl3DModelPointIterator point in NoseRegions[i])
             *      point.Color = ClTools.GetColorRGB((float)i / (NoseRegions.Count + EyesRegions.Count), 1);
             * }
             * for (int i = 0; i < EyesRegions.Count; i++)
             * {
             *  foreach (Cl3DModel.Cl3DModelPointIterator point in EyesRegions[i])
             *      point.Color = ClTools.GetColorRGB((float)(i + NoseRegions.Count) / (EyesRegions.Count + NoseRegions.Count), 1);
             * }
             */

            // -----------------  NOSE
            // remove smallest regions leave only 3 biggest one
            List <Cl3DModel.Cl3DModelPointIterator> NoseTipsPoints = new List <Cl3DModel.Cl3DModelPointIterator>();

            if (NoseRegions.Count > m_iMaxCountOfNoseRegions)
            {
                NoseRegions.Sort(new ClCompareCount());
                for (int i = NoseRegions.Count - 1; i >= m_iMaxCountOfNoseRegions; i--)
                {
                    NoseRegions.RemoveAt(i);
                }
            }
            //----------- NOSE searching for one point in each region
            for (int i = 0; i < NoseRegions.Count; i++)
            {
                double MaxKVal = 0;
                Cl3DModel.Cl3DModelPointIterator MaxPoint = null;
                foreach (Cl3DModel.Cl3DModelPointIterator point in NoseRegions[i])
                {
                    double K;
                    if (!point.GetSpecificValue(gausString, out K))
                    {
                        continue;
                    }

                    if (MaxPoint == null)
                    {
                        MaxPoint = point;
                        MaxKVal  = K;
                        continue;
                    }

                    if (MaxKVal < K)
                    {
                        MaxKVal  = K;
                        MaxPoint = point;
                    }
                }
                NoseTipsPoints.Add(MaxPoint);
            }

            // ---------------  EYES
            // remove smallest regions leave only 5 biggest one
            List <Cl3DModel.Cl3DModelPointIterator> EyesPoints = new List <Cl3DModel.Cl3DModelPointIterator>();

            if (EyesRegions.Count > m_iMaxCountOfEyeRegions)
            {
                EyesRegions.Sort(new ClCompareCount());
                for (int i = EyesRegions.Count - 1; i >= m_iMaxCountOfEyeRegions; i--)
                {
                    EyesRegions.RemoveAt(i);
                }
            }
            //--------------------------- EYES searching for one point in each region
            for (int i = 0; i < EyesRegions.Count; i++)
            {
                double MaxKval = 0;
                Cl3DModel.Cl3DModelPointIterator MinPoint = null;

                foreach (Cl3DModel.Cl3DModelPointIterator point in EyesRegions[i])
                {
                    double val;
                    if (!point.GetSpecificValue(gausString, out val))
                    {
                        continue;
                    }

                    if (MinPoint == null)
                    {
                        MinPoint = point;
                        MaxKval  = val;
                        continue;
                    }

                    if (MaxKval < val)
                    {
                        MaxKval  = val;
                        MinPoint = point;
                    }
                }
                EyesPoints.Add(MinPoint);
            }
            //------------- Looking for three face points ------------------------------
            Iridium.Numerics.LinearAlgebra.Matrix Model    = new Iridium.Numerics.LinearAlgebra.Matrix(3, 3);
            Iridium.Numerics.LinearAlgebra.Matrix ModelGen = new Iridium.Numerics.LinearAlgebra.Matrix(3, 3);

            // Generic model
            Vector GenericNoseTip  = new Vector(new double[] { 0, 0, 0 });
            Vector GenericLeftEye  = new Vector(new double[] { -21f, 40.5f, -41.5f });
            Vector GenericRightEye = new Vector(new double[] { 21f, 40.5f, -41.5f });

            Vector GenLeftCornerOfLeftEye   = new Vector(new double[] { -44f, 40f, -44f });
            Vector GenRightCornerOfRightEye = new Vector(new double[] { 44f, 40f, -44f });

            Vector GenLeftCornerOfNose  = new Vector(new double[] { -20f, -2f, -31f });
            Vector GenRightCornerOfNose = new Vector(new double[] { 20f, -2f, -31f });

            Vector GenLeftCornerOfLips  = new Vector(new double[] { -28f, -32f, -34f });
            Vector GenRightCornerOfLips = new Vector(new double[] { 28f, -32f, -34f });


            Vector MeanGenericModel = new Vector(new double[] { (GenericNoseTip[0] + GenericLeftEye[0] + GenericRightEye[0]) / 3,
                                                                (GenericNoseTip[1] + GenericLeftEye[1] + GenericRightEye[1]) / 3,
                                                                (GenericNoseTip[2] + GenericLeftEye[2] + GenericRightEye[2]) / 3 });

            // Centered generic model (generic model - mean)
            ModelGen[0, 0] = (GenericNoseTip[0] - MeanGenericModel[0]);
            ModelGen[1, 0] = (GenericNoseTip[1] - MeanGenericModel[1]);
            ModelGen[2, 0] = (GenericNoseTip[2] - MeanGenericModel[2]);

            ModelGen[0, 1] = (GenericLeftEye[0] - MeanGenericModel[0]);
            ModelGen[1, 1] = (GenericLeftEye[1] - MeanGenericModel[1]);
            ModelGen[2, 1] = (GenericLeftEye[2] - MeanGenericModel[2]);

            ModelGen[0, 2] = (GenericRightEye[0] - MeanGenericModel[0]);
            ModelGen[1, 2] = (GenericRightEye[1] - MeanGenericModel[1]);
            ModelGen[2, 2] = (GenericRightEye[2] - MeanGenericModel[2]);
            ModelGen.Transpose();

            List <KeyValuePair <float, List <Cl3DModel.Cl3DModelPointIterator> > > deltaOfDistanceBetweenModelAndPoints = new List <KeyValuePair <float, List <Cl3DModel.Cl3DModelPointIterator> > >();

            for (int iEye = 0; iEye < EyesPoints.Count - 1; iEye++)
            {
                for (int jEye = iEye + 1; jEye < EyesPoints.Count; jEye++)
                {
                    for (int iNose = 0; iNose < NoseTipsPoints.Count; iNose++)
                    {
                        Cl3DModel.Cl3DModelPointIterator eyeLeft  = EyesPoints[iEye];
                        Cl3DModel.Cl3DModelPointIterator eyeRight = EyesPoints[jEye];
                        Cl3DModel.Cl3DModelPointIterator noseTip  = NoseTipsPoints[iNose];

                        if (eyeLeft.Y < noseTip.Y || eyeRight.Y < noseTip.Y)
                        {
                            continue;
                        }

                        for (int c = 0; c < 2; c++)
                        {
                            if (c == 1)
                            {
                                eyeLeft  = EyesPoints[jEye]; // zmiana oczu nie wiemy ktore punkty to oczy prawdziwe sa
                                eyeRight = EyesPoints[iEye];
                            }

                            float MeanValX = (noseTip.X + eyeLeft.X + eyeRight.X) / 3.0f;
                            float MeanValY = (noseTip.Y + eyeLeft.Y + eyeRight.Y) / 3.0f;
                            float MeanValZ = (noseTip.Z + eyeLeft.Z + eyeRight.Z) / 3.0f;

                            Model[0, 0] = (noseTip.X - MeanValX);
                            Model[1, 0] = (noseTip.Y - MeanValY);
                            Model[2, 0] = (noseTip.Z - MeanValZ);

                            Model[0, 1] = (eyeLeft.X - MeanValX);
                            Model[1, 1] = (eyeLeft.Y - MeanValY);
                            Model[2, 1] = (eyeLeft.Z - MeanValZ);

                            Model[0, 2] = (eyeRight.X - MeanValX);
                            Model[1, 2] = (eyeRight.Y - MeanValY);
                            Model[2, 2] = (eyeRight.Z - MeanValZ);


                            //----------------- Finding best rotation and translation SVD algorithm

                            Iridium.Numerics.LinearAlgebra.Matrix Covariance = Model * ModelGen;

                            Iridium.Numerics.LinearAlgebra.SingularValueDecomposition SVD = new Iridium.Numerics.LinearAlgebra.SingularValueDecomposition(Covariance);
                            Iridium.Numerics.LinearAlgebra.Matrix U = SVD.LeftSingularVectors;
                            Iridium.Numerics.LinearAlgebra.Matrix V = SVD.RightSingularVectors;

                            Iridium.Numerics.LinearAlgebra.Matrix s = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1.0);

                            if (Covariance.Rank() < 2)
                            {
                                throw new Exception("Cannot allign generic model (cov rank is less than 2)");
                            }

                            if (Covariance.Rank() == 2) // m-1 where m is dimension space (3D)
                            {
                                double detU = Math.Round(U.Determinant());
                                double detV = Math.Round(V.Determinant());
                                double detC = Covariance.Determinant();
                                if ((int)detU * (int)detV == 1)
                                {
                                    s[2, 2] = 1;
                                }
                                else if ((int)detU * (int)detV == -1)
                                {
                                    s[2, 2] = -1;
                                }
                                else
                                {
                                    throw new Exception("Determinant of U and V are not in conditions");
                                }
                            }
                            else
                            {
                                if (Covariance.Determinant() < 0)
                                {
                                    s[2, 2] = -1;
                                }
                            }

                            V.Transpose();
                            Iridium.Numerics.LinearAlgebra.Matrix Roatation = U * s * V;

                            Iridium.Numerics.LinearAlgebra.Matrix MeanValOfGenModelMatrix = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
                            MeanValOfGenModelMatrix[0, 0] = MeanGenericModel[0];
                            MeanValOfGenModelMatrix[1, 0] = MeanGenericModel[1];
                            MeanValOfGenModelMatrix[2, 0] = MeanGenericModel[2];

                            Iridium.Numerics.LinearAlgebra.Matrix MeanValOfModelMatrix = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
                            MeanValOfModelMatrix[0, 0] = MeanValX;
                            MeanValOfModelMatrix[1, 0] = MeanValY;
                            MeanValOfModelMatrix[2, 0] = MeanValZ;

                            Iridium.Numerics.LinearAlgebra.Matrix Translation = MeanValOfModelMatrix - Roatation * MeanValOfGenModelMatrix;

                            //--------------------------- End now we have translation and rotation

                            float GenericModelDistance = 0;;

                            Iridium.Numerics.LinearAlgebra.Matrix q = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1);
                            q[0, 0] = GenericNoseTip[0];
                            q[1, 0] = GenericNoseTip[1];
                            q[2, 0] = GenericNoseTip[2];
                            Iridium.Numerics.LinearAlgebra.Matrix NewQ = Roatation * q + Translation;
                            GenericModelDistance += (float)Math.Sqrt(Math.Pow(noseTip.X - NewQ[0, 0], 2) + Math.Pow(noseTip.Y - NewQ[1, 0], 2) + Math.Pow(noseTip.Z - NewQ[2, 0], 2));
                            //---------
                            //    Cl3DModel.Cl3DModelPointIterator it1 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
                            //it1.AddNeighbor(noseTip);
                            //    it1.Color = Color.Green;
                            //---------
                            q[0, 0] = GenericLeftEye[0];
                            q[1, 0] = GenericLeftEye[1];
                            q[2, 0] = GenericLeftEye[2];
                            NewQ    = Roatation * q + Translation;
                            GenericModelDistance += (float)Math.Sqrt(Math.Pow(eyeLeft.X - NewQ[0, 0], 2) + Math.Pow(eyeLeft.Y - NewQ[1, 0], 2) + Math.Pow(eyeLeft.Z - NewQ[2, 0], 2));
                            //---------
                            //    Cl3DModel.Cl3DModelPointIterator it2 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
                            //it2.AddNeighbor(eyeLeft);
                            //    it2.Color = Color.White;
                            //---------

                            q[0, 0] = GenericRightEye[0];
                            q[1, 0] = GenericRightEye[1];
                            q[2, 0] = GenericRightEye[2];
                            NewQ    = Roatation * q + Translation;
                            GenericModelDistance += (float)Math.Sqrt(Math.Pow(eyeRight.X - NewQ[0, 0], 2) + Math.Pow(eyeRight.Y - NewQ[1, 0], 2) + Math.Pow(eyeRight.Z - NewQ[2, 0], 2));
                            //---------
                            //    Cl3DModel.Cl3DModelPointIterator it3 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]);
                            //it3.AddNeighbor(eyeRight);
                            //    it3.Color = Color.Orange;

                            //    it1.AddNeighbor(it2);
                            //    it1.AddNeighbor(it3);
                            //    it2.AddNeighbor(it3);
                            //---------

                            // ---------- Rest of generic model to find closest points and count distance;
                            q[0, 0] = GenLeftCornerOfLeftEye[0];
                            q[1, 0] = GenLeftCornerOfLeftEye[1];
                            q[2, 0] = GenLeftCornerOfLeftEye[2];
                            NewQ    = Roatation * q + Translation;
                            Cl3DModel.Cl3DModelPointIterator closestPoint = null;
                            float MinDistance;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenRightCornerOfRightEye[0];
                            q[1, 0] = GenRightCornerOfRightEye[1];
                            q[2, 0] = GenRightCornerOfRightEye[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenLeftCornerOfNose[0];
                            q[1, 0] = GenLeftCornerOfNose[1];
                            q[2, 0] = GenLeftCornerOfNose[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenRightCornerOfNose[0];
                            q[1, 0] = GenRightCornerOfNose[1];
                            q[2, 0] = GenRightCornerOfNose[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenLeftCornerOfLips[0];
                            q[1, 0] = GenLeftCornerOfLips[1];
                            q[2, 0] = GenLeftCornerOfLips[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;

                            q[0, 0] = GenRightCornerOfLips[0];
                            q[1, 0] = GenRightCornerOfLips[1];
                            q[2, 0] = GenRightCornerOfLips[2];
                            NewQ    = Roatation * q + Translation;
                            ClTools.FindClosestPointInModel(p_Model, (float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0], out closestPoint, out MinDistance);
                            GenericModelDistance += MinDistance;
                            // ----------


                            ClInformationSender.SendInformation("One of distances between generic model and face before thresholding: " + GenericModelDistance.ToString(System.Globalization.CultureInfo.InvariantCulture), ClInformationSender.eInformationType.eDebugText);

                            if (GenericModelDistance > m_fDistanceMinValueFromGenModel)
                            {
                                continue;
                            }

                            // Check if between eyes and nose there is other region (it should be not)

                            /*bool isBetweenNoseRegion = false;
                             * foreach (Cl3DModel.Cl3DModelPointIterator noseTmp in NoseTipsPoints)
                             * {
                             *  if (noseTmp.PointID == noseTip.PointID)
                             *      continue;
                             *
                             *  if (noseTmp.X > eyeLeft.X && noseTmp.X < eyeRight.X && noseTmp.Y > noseTip.Y && (noseTip.Y < eyeLeft.Y || noseTip.Y < eyeRight.Y))
                             *      isBetweenNoseRegion = true;
                             * }
                             * if (isBetweenNoseRegion)
                             *  continue;
                             */
                            List <Cl3DModel.Cl3DModelPointIterator> list = new List <Cl3DModel.Cl3DModelPointIterator>();
                            list.Add(noseTip);
                            list.Add(eyeLeft);
                            list.Add(eyeRight);

                            KeyValuePair <float, List <Cl3DModel.Cl3DModelPointIterator> > KeyVal = new KeyValuePair <float, List <Cl3DModel.Cl3DModelPointIterator> >(GenericModelDistance, list);

                            deltaOfDistanceBetweenModelAndPoints.Add(KeyVal);
                        }
                    }
                }
            }

            if (deltaOfDistanceBetweenModelAndPoints.Count == 0)
            {
                throw new Exception("Cannot find nose and eyes points");
            }

            float min = deltaOfDistanceBetweenModelAndPoints[0].Key;
            int   no  = 0;

            for (int i = 1; i < deltaOfDistanceBetweenModelAndPoints.Count; i++)
            {
                if (deltaOfDistanceBetweenModelAndPoints[i].Key < min)
                {
                    min = deltaOfDistanceBetweenModelAndPoints[i].Key;
                    no  = i;
                }
            }

            ClInformationSender.SendInformation("Correct MIN distance between generic model and face: " + min.ToString(System.Globalization.CultureInfo.InvariantCulture), ClInformationSender.eInformationType.eDebugText);

            p_Model.AddSpecificPoint(NameOfNoseTip, deltaOfDistanceBetweenModelAndPoints[no].Value[0]);
            p_Model.AddSpecificPoint(NameLeftEyeRightCorner, deltaOfDistanceBetweenModelAndPoints[no].Value[1]);
            p_Model.AddSpecificPoint(NameRightEyeLeftCorner, deltaOfDistanceBetweenModelAndPoints[no].Value[2]);
        }
コード例 #27
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator tmpIter = p_Model.GetIterator();

            while (tmpIter.IsValid())
            {
                if (tmpIter.GetListOfNeighbors().Count <= 1)
                {
                    tmpIter = p_Model.RemovePointFromModel(tmpIter);
                }
                else
                {
                    if (!tmpIter.MoveToNext())
                    {
                        break;
                    }
                }
            }

            List <List <Cl3DModel.Cl3DModelPointIterator> > listOfRegions = new List <List <Cl3DModel.Cl3DModelPointIterator> >();

            List <Cl3DModel.Cl3DModelPointIterator> ListToCheck    = new List <Cl3DModel.Cl3DModelPointIterator>();
            List <Cl3DModel.Cl3DModelPointIterator> newListToCheck = new List <Cl3DModel.Cl3DModelPointIterator>();

            Cl3DModel.Cl3DModelPointIterator iter = null;
            int listNo = 0;

            while ((iter = findNextUnseenElement(ref p_Model)) != null)
            {
                ListToCheck.Add(iter);
                listOfRegions.Add(new List <Cl3DModel.Cl3DModelPointIterator>());
                do
                {
                    foreach (Cl3DModel.Cl3DModelPointIterator ElementFromListToCheck in ListToCheck)
                    {
                        if (!ElementFromListToCheck.AlreadyVisited)
                        {
                            listOfRegions[listNo].Add(ElementFromListToCheck);
                            ElementFromListToCheck.AlreadyVisited = true;
                            foreach (Cl3DModel.Cl3DModelPointIterator it in ElementFromListToCheck.GetListOfNeighbors())
                            {
                                if (!it.AlreadyVisited)
                                {
                                    newListToCheck.Add(it);
                                }
                            }
                        }
                    }

                    ListToCheck.Clear();
                    foreach (Cl3DModel.Cl3DModelPointIterator it in newListToCheck)
                    {
                        ListToCheck.Add(it);
                    }
                    newListToCheck.Clear();
                } while (ListToCheck.Count != 0);
                ListToCheck.Clear();
                listNo++;
            }

            if (listOfRegions.Count <= 1)
            {
                return;
            }

            int maxCount = listOfRegions[0].Count;;
            int maxI     = 0;

            for (int i = 1; i < listOfRegions.Count; i++)
            {
                if (listOfRegions[i].Count > maxCount)
                {
                    maxI     = i;
                    maxCount = listOfRegions[i].Count;
                }
            }

            if (m_bColorIt)
            {
                for (int i = 0; i < listOfRegions.Count; i++)
                {
                    if (i == maxI)
                    {
                        continue;
                    }

                    for (int j = 0; j < listOfRegions[i].Count; j++)
                    {
                        listOfRegions[i][j].Color = ClTools.GetColorRGB(((float)i) / listOfRegions.Count, 1);
                    }
                }
            }
            else
            {
                for (int i = 0; i < listOfRegions.Count; i++)
                {
                    if (i == maxI)
                    {
                        continue;
                    }

                    for (int j = 0; j < listOfRegions[i].Count; j++)
                    {
                        p_Model.RemovePointFromModel(listOfRegions[i][j]);
                    }
                }
            }
        }
コード例 #28
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();

            if (!iter.IsValid())
            {
                throw new Exception("Iter is not valid");
            }

            if (m_ResetColor)
            {
                do
                {
                    iter.Color = Color.White;
                } while (iter.MoveToNext());
                return;
            }

            if (!m_bMinMaxPreset)
            {
                bool firstTime = true;
                do
                {
                    double Value;

                    if (m_RangeColor)
                    {
                        Value = iter.Z;
                    }
                    else if (!iter.GetSpecificValue(m_SpecificValue, out Value))
                    {
                        continue;
                    }

                    if (firstTime)
                    {
                        m_dMaxValue = Value;
                        m_dMinValue = Value;
                        firstTime   = false;
                        continue;
                    }

                    if (Value > m_dMaxValue)
                    {
                        m_dMaxValue = Value;
                    }
                    if (Value < m_dMinValue)
                    {
                        m_dMinValue = Value;
                    }
                } while (iter.MoveToNext());
            }


            if (m_SpecificValue.Contains("ShapeIndex") && !m_RangeColor)
            {
                m_dMinValue = 0;
                m_dMaxValue = 1;
            }


            if (m_bMaxMinFromNoseAndEyes)
            {
                Cl3DModel.Cl3DModelPointIterator        NoseTip          = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);
                List <Cl3DModel.Cl3DModelPointIterator> NeighborhoodNose = null;
                ClTools.GetNeighborhoodWithGeodesicDistance(out NeighborhoodNose, NoseTip, 10f);

                if (m_sMinValuePointName.Equals("Nose"))
                {
                    m_dMinValue = NoseTip.GetSpecificValue(m_SpecificValue);
                    foreach (Cl3DModel.Cl3DModelPointIterator nb in NeighborhoodNose)
                    {
                        double currVal = nb.GetSpecificValue(m_SpecificValue);
                        if (currVal < m_dMinValue)
                        {
                            m_dMinValue = currVal;
                        }
                    }
                }
                else if (m_sMaxValuePointName.Equals("Nose"))
                {
                    m_dMaxValue = NoseTip.GetSpecificValue(m_SpecificValue);
                    foreach (Cl3DModel.Cl3DModelPointIterator nb in NeighborhoodNose)
                    {
                        double currVal = nb.GetSpecificValue(m_SpecificValue);
                        if (currVal > m_dMaxValue)
                        {
                            m_dMaxValue = currVal;
                        }
                    }
                }
                NeighborhoodNose = null;

                Cl3DModel.Cl3DModelPointIterator        Eye1             = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner);
                Cl3DModel.Cl3DModelPointIterator        Eye2             = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner);
                List <Cl3DModel.Cl3DModelPointIterator> NeighborhoodEye1 = null;
                List <Cl3DModel.Cl3DModelPointIterator> NeighborhoodEye2 = null;
                ClTools.GetNeighborhoodWithGeodesicDistance(out NeighborhoodEye1, Eye1, 10f);
                ClTools.GetNeighborhoodWithGeodesicDistance(out NeighborhoodEye2, Eye2, 10f);

                NeighborhoodEye1.Add(Eye2);
                foreach (Cl3DModel.Cl3DModelPointIterator ne in NeighborhoodEye2)
                {
                    NeighborhoodEye1.Add(ne);
                }


                if (m_sMinValuePointName.Equals("Eye"))
                {
                    m_dMinValue = Eye1.GetSpecificValue(m_SpecificValue);
                    foreach (Cl3DModel.Cl3DModelPointIterator nb in NeighborhoodEye1)
                    {
                        double currVal = nb.GetSpecificValue(m_SpecificValue);
                        if (currVal < m_dMinValue)
                        {
                            m_dMinValue = currVal;
                        }
                    }
                }
                else if (m_sMaxValuePointName.Equals("Eye"))
                {
                    m_dMaxValue = Eye1.GetSpecificValue(m_SpecificValue);
                    foreach (Cl3DModel.Cl3DModelPointIterator nb in NeighborhoodEye1)
                    {
                        double currVal = nb.GetSpecificValue(m_SpecificValue);
                        if (currVal > m_dMaxValue)
                        {
                            m_dMaxValue = currVal;
                        }
                    }
                }
            }

            iter = p_Model.GetIterator();
            do
            {
                double Value;
                if (m_RangeColor)
                {
                    Value = iter.Z;
                }
                else if (!iter.GetSpecificValue(m_SpecificValue, out Value))
                {
                    continue;
                }


                double divide = 1;
                if (m_dMaxValue != m_dMinValue)
                {
                    divide = (m_dMaxValue - m_dMinValue);
                }

                if (m_Color == ColorType.RGB)
                {
                    iter.Color = ClTools.GetColorRGB((float)((Value - m_dMinValue) / divide), 1.0f);
                }
                else if (m_Color == ColorType.Gray)
                {
                    iter.Color = ClTools.GetColorGray((float)((Value - m_dMinValue) / divide), 1.0f);
                }
                else if (m_Color == ColorType.R)
                {
                    Color PartialColor = ClTools.GetColorRGB((float)((Value - m_dMinValue) / divide), 1.0f);

                    int R = 0; R = (R << 8) + (int)PartialColor.R;
                    int G = 0; G = (G << 8) + (int)PartialColor.G;
                    int B = 0; B = (B << 8) + (int)PartialColor.B;

                    Color newColor = Color.FromArgb((R + G + B) / 3, iter.Color.G, iter.Color.B);

                    iter.Color = newColor;
                }
                else if (m_Color == ColorType.G)
                {
                    Color PartialColor = ClTools.GetColorRGB((float)((Value - m_dMinValue) / divide), 1.0f);

                    int R = 0; R = (R << 8) + (int)PartialColor.R;
                    int G = 0; G = (G << 8) + (int)PartialColor.G;
                    int B = 0; B = (B << 8) + (int)PartialColor.B;

                    Color newColor = Color.FromArgb(iter.Color.R, (R + G + B) / 3, iter.Color.B);
                    iter.Color = newColor;
                }
                else if (m_Color == ColorType.B)
                {
                    Color PartialColor = ClTools.GetColorRGB((float)((Value - m_dMinValue) / divide), 1.0f);

                    int R = 0; R = (R << 8) + (int)PartialColor.R;
                    int G = 0; G = (G << 8) + (int)PartialColor.G;
                    int B = 0; B = (B << 8) + (int)PartialColor.B;

                    Color newColor = Color.FromArgb(iter.Color.R, iter.Color.G, (R + G + B) / 3);
                    iter.Color = newColor;
                }
            } while (iter.MoveToNext());
            ClInformationSender.SendInformation(m_SpecificValue.ToString() + " Max: " + m_dMaxValue.ToString() + " Min: " + m_dMinValue.ToString(), ClInformationSender.eInformationType.eColorMapChanged);
        }
コード例 #29
0
        protected override void Algorithm(ref Cl3DModel p_Model)
        {
            Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator();
            float maxX = iter.X;
            float minX = iter.X;
            float maxY = iter.Y;
            float minY = iter.Y;

            do
            {
                if (maxX < iter.X)
                {
                    maxX = iter.X;
                }
                if (maxY < iter.Y)
                {
                    maxY = iter.Y;
                }

                if (minX > iter.X)
                {
                    minX = iter.X;
                }
                if (minY > iter.Y)
                {
                    minY = iter.Y;
                }
            } while (iter.MoveToNext());


            int width  = (int)(maxX - minX) + 1;
            int height = (int)(maxY - minY) + 1;


            Bitmap map = new Bitmap(width, height);

            ClRaserizer rasterizer = new ClRaserizer(map, width, height);

            List <ClTools.ClTriangle> triangles = null;

            iter = p_Model.GetIterator();
            do
            {
                ClTools.GetListOfTriangles(out triangles, iter);

                foreach (ClTools.ClTriangle triangle in triangles)
                {
                    int x1 = (int)(((triangle.m_point1.X - minX) / (maxX - minX)) * (width - 1));
                    int y1 = (int)(((triangle.m_point1.Y - minY) / (maxY - minY)) * (height - 1));

                    int x2 = (int)(((triangle.m_point2.X - minX) / (maxX - minX)) * (width - 1));
                    int y2 = (int)(((triangle.m_point2.Y - minY) / (maxY - minY)) * (height - 1));

                    int x3 = (int)(((triangle.m_point3.X - minX) / (maxX - minX)) * (width - 1));
                    int y3 = (int)(((triangle.m_point3.Y - minY) / (maxY - minY)) * (height - 1));


                    rasterizer.DrawTriangle(triangle.m_point1.Color, x1, y1,
                                            triangle.m_point2.Color, x2, y2,
                                            triangle.m_point3.Color, x3, y3
                                            );
                }
            } while (iter.MoveToNext());


            if (CenterFaceBasedOnNoseTip)
            {
                Cl3DModel.Cl3DModelPointIterator NoseTip = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip);

                int NoseTipX = (int)(((NoseTip.X - minX) / (maxX - minX)) * (width - 1));
                int NoseTipY = (int)(((NoseTip.Y - minY) / (maxY - minY)) * (height - 1));

                int MaxDistanceFromTheNoseTip = (int)Math.Max(Math.Max(NoseTipX, NoseTipY), Math.Max(Math.Abs(width - NoseTipX), Math.Abs(height - NoseTipY)));

                int OffsetX = (int)((MaxDistanceFromTheNoseTip) - NoseTipX);
                int OffsetY = (int)((MaxDistanceFromTheNoseTip) - NoseTipY);

                Bitmap NewMap = new Bitmap((MaxDistanceFromTheNoseTip * 2), (MaxDistanceFromTheNoseTip * 2));

                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        NewMap.SetPixel(OffsetX + i, OffsetY + j, map.GetPixel(i, j));
                    }
                }

                map = NewMap;
            }

            if (m_FixedSize)
            {
                Bitmap   bmp     = new Bitmap(NewWidth, NewHeight);
                Graphics graphic = Graphics.FromImage((Image)bmp);
                graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphic.DrawImage(map, 0, 0, NewWidth, NewHeight);
                graphic.Dispose();
                map = bmp;
            }

            if (rotate180)
            {
                map.RotateFlip(RotateFlipType.Rotate180FlipNone);
            }
            map.Save(p_Model.ModelFilePath + m_sFilePostFix + ".bmp");
        }