protected override void Algorithm(ref Cl3DModel p_Model) { Cl3DModel.Cl3DModelPointIterator CenterPoint = p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip); 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()); Complex z0 = new Complex(CenterPoint.U / distanceMax, CenterPoint.V / distanceMax); iter = p_Model.GetIterator(); do { Complex newPoint = Mobius(m_Theta, z0, new Complex((iter.U / distanceMax), (iter.V / distanceMax))); iter.U = (float)newPoint.Real * distanceMax; iter.V = (float)newPoint.Imag * distanceMax; } while (iter.MoveToNext()); }
protected override void Algorithm(ref Cl3DModel p_Model) { Cl3DModel.Cl3DModelPointIterator maxIter = p_Model.GetIterator(); Cl3DModel.Cl3DModelPointIterator iter = maxIter.CopyIterator(); while (iter.MoveToNext()) { if (maxIter.Z < iter.Z) { maxIter = iter.CopyIterator(); } } if (maxIter.IsValid()) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString(), maxIter); } }
protected override void Algorithm(ref Cl3DModel p_Model) { Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator(); int maxX = (int)iter.X; int minX = (int)iter.X; int maxY = (int)iter.Y; int minY = (int)iter.Y; do { if (maxX < iter.X) { maxX = (int)iter.X; } if (maxY < iter.Y) { maxY = (int)iter.Y; } if (minX > iter.X) { minX = (int)iter.X; } if (minY > iter.Y) { minY = (int)iter.Y; } } while (iter.MoveToNext()); int width = (maxX - minX) + 1; int height = (maxY - minY) + 1; List <Cl3DModel.Cl3DModelPointIterator>[,] map = new List <Cl3DModel.Cl3DModelPointIterator> [width, height]; iter = p_Model.GetIterator(); do { int x = (int)iter.X - minX; int y = (int)iter.Y - minY; if (map[x, y] == null) { map[x, y] = new List <Cl3DModel.Cl3DModelPointIterator>(); } map[x, y].Add(iter.CopyIterator()); } while (iter.MoveToNext()); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (map[x, y] != null) { int MeanR = 0; int MeanG = 0; int MeanB = 0; float MeanX = 0; float MeanY = 0; float MeanZ = 0; float MeanU = 0; float MeanV = 0; float MeanRangeX = 0; float MeanRangeY = 0; Dictionary <string, List <double> > MeanSpecificValues = new Dictionary <string, List <double> >(); Cl3DModel.Cl3DModelPointIterator MaxPoint = null; string specPoint = Cl3DModel.eSpecificPoints.UnspecifiedPoint.ToString(); bool isSpecific = false; foreach (Cl3DModel.Cl3DModelPointIterator point in map[x, y]) { point.AlreadyVisited = true; if (!isSpecific) { isSpecific = p_Model.IsThisPointInSpecificPoints(point, ref specPoint); } if (m_bMean) { MeanR += point.ColorR; MeanG += point.ColorG; MeanB += point.ColorB; MeanX += point.X; MeanY += point.Y; MeanZ += point.Z; MeanU += point.U; MeanV += point.V; MeanRangeX += point.RangeImageX; MeanRangeY += point.RangeImageY; List <string> listOfValuesNames = point.GetListOfSpecificValues(); foreach (string name in listOfValuesNames) { List <double> listOfValues = null; if (!MeanSpecificValues.TryGetValue(name, out listOfValues)) { listOfValues = new List <double>(); MeanSpecificValues.Add(name, listOfValues); } double val = point.GetSpecificValue(name); listOfValues.Add(val); } } else {// search for max Z if (MaxPoint == null) { MaxPoint = point; } else if (MaxPoint.Z < point.Z) { MaxPoint = point; } } } if (m_bMean) { MeanR /= map[x, y].Count; MeanG /= map[x, y].Count; MeanB /= map[x, y].Count; MeanX /= map[x, y].Count; MeanY /= map[x, y].Count; MeanZ /= map[x, y].Count; MeanU /= map[x, y].Count; MeanV /= map[x, y].Count; MeanRangeX /= map[x, y].Count; MeanRangeY /= map[x, y].Count; } else { MeanR = MaxPoint.ColorR; MeanG = MaxPoint.ColorG; MeanB = MaxPoint.ColorB; MeanX = MaxPoint.X; MeanY = MaxPoint.Y; MeanZ = MaxPoint.Z; MeanU = MaxPoint.U; MeanV = MaxPoint.V; MeanRangeX = MaxPoint.RangeImageX; MeanRangeY = MaxPoint.RangeImageY; } List <Cl3DModel.Cl3DModelPointIterator> connections = new List <Cl3DModel.Cl3DModelPointIterator>(); foreach (Cl3DModel.Cl3DModelPointIterator point in map[x, y]) { foreach (Cl3DModel.Cl3DModelPointIterator InnerPoint in point.GetListOfNeighbors()) { if (InnerPoint.AlreadyVisited == false) { connections.Add(InnerPoint); } } } Cl3DModel.Cl3DModelPointIterator pt = p_Model.AddPointToModel((int)MeanX, (int)MeanY, MeanZ, x, width - y); pt.Color = Color.FromArgb(MeanR, MeanG, MeanB); pt.U = MeanU; pt.V = MeanV; foreach (KeyValuePair <string, List <double> > kvValues in MeanSpecificValues) { string valueName = kvValues.Key; List <double> values = kvValues.Value; double meanVal = 0; foreach (double val in values) { meanVal += val; } meanVal /= values.Count; pt.AddSpecificValue("Mean_" + valueName, meanVal); } if (isSpecific) { p_Model.AddSpecificPoint(specPoint, pt); } List <Cl3DModel.Cl3DModelPointIterator> lista = map[x, y]; for (int i = 0; i < lista.Count; i++) { p_Model.RemovePointFromModel(lista[i]); } foreach (Cl3DModel.Cl3DModelPointIterator point in connections) { pt.AddNeighbor(point); } } } } }
protected override void Algorithm(ref Cl3DModel p_Model) { CORFile landmarkFile = ReadCORFile(p_Model.ModelFileFolder + p_Model.ModelFileName + ".cor"); //search for the closest point from the model to the read landmark Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator(); if (!iter.IsValid()) { throw new Exception("Iterator in the model is not valid!"); } Cl3DModel.Cl3DModelPointIterator SavedNoseTip = iter.CopyIterator(); float NoseTipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.NoseTip.X - SavedNoseTip.X, 2) + Math.Pow(landmarkFile.NoseTip.Y - SavedNoseTip.Y, 2) + Math.Pow(landmarkFile.NoseTip.Z - SavedNoseTip.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedLeftEyeRightCorner = iter.CopyIterator(); float LeftEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeRightCorner.X - SavedLeftEyeRightCorner.X, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Y - SavedLeftEyeRightCorner.Y, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Z - SavedLeftEyeRightCorner.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedRightEyeLeftCorner = iter.CopyIterator(); float RightEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeLeftCorner.X - SavedRightEyeLeftCorner.X, 2) + Math.Pow(landmarkFile.RightEyeLeftCorner.Y - SavedRightEyeLeftCorner.Y, 2) + Math.Pow(landmarkFile.RightEyeLeftCorner.Z - SavedRightEyeLeftCorner.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedRightEyeRightCorner = iter.CopyIterator(); float RightEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeRightCorner.X - SavedRightEyeRightCorner.X, 2) + Math.Pow(landmarkFile.RightEyeRightCorner.Y - SavedRightEyeRightCorner.Y, 2) + Math.Pow(landmarkFile.RightEyeRightCorner.Z - SavedRightEyeRightCorner.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedLeftEyeLeftCorner = iter.CopyIterator(); float LeftEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeLeftCorner.X - SavedLeftEyeLeftCorner.X, 2) + Math.Pow(landmarkFile.LeftEyeLeftCorner.Y - SavedLeftEyeLeftCorner.Y, 2) + Math.Pow(landmarkFile.LeftEyeLeftCorner.Z - SavedLeftEyeLeftCorner.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfNose = iter.CopyIterator(); float LeftCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfNose.X - SavedLeftCornerOfNose.X, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Y - SavedLeftCornerOfNose.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Z - SavedLeftCornerOfNose.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedRightCornerOfNose = iter.CopyIterator(); float RightCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfNose.X - SavedRightCornerOfNose.X, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Y - SavedRightCornerOfNose.Y, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Z - SavedRightCornerOfNose.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfLips = iter.CopyIterator(); float LeftCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLips.X - SavedLeftCornerOfLips.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Y - SavedLeftCornerOfLips.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Z - SavedLeftCornerOfLips.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedRightCornerOfLips = iter.CopyIterator(); float RightCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfLips.X - SavedRightCornerOfLips.X, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Y - SavedRightCornerOfLips.Y, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Z - SavedRightCornerOfLips.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedUpperLip = iter.CopyIterator(); float UpperLipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.UpperLip.X - SavedUpperLip.X, 2) + Math.Pow(landmarkFile.UpperLip.Y - SavedUpperLip.Y, 2) + Math.Pow(landmarkFile.UpperLip.Z - SavedUpperLip.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedBottomLip = iter.CopyIterator(); float BottomLipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.BottomLip.X - SavedBottomLip.X, 2) + Math.Pow(landmarkFile.BottomLip.Y - SavedBottomLip.Y, 2) + Math.Pow(landmarkFile.BottomLip.Z - SavedBottomLip.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedLeftEyeUpperEyelid = iter.CopyIterator(); float LeftEyeUpperEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeUpperEyelid.X - SavedLeftEyeUpperEyelid.X, 2) + Math.Pow(landmarkFile.LeftEyeUpperEyelid.Y - SavedLeftEyeUpperEyelid.Y, 2) + Math.Pow(landmarkFile.LeftEyeUpperEyelid.Z - SavedLeftEyeUpperEyelid.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedLeftEyeBottomEyelid = iter.CopyIterator(); float LeftEyeBottomEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeBottomEyelid.X - SavedLeftEyeBottomEyelid.X, 2) + Math.Pow(landmarkFile.LeftEyeBottomEyelid.Y - SavedLeftEyeBottomEyelid.Y, 2) + Math.Pow(landmarkFile.LeftEyeBottomEyelid.Z - SavedLeftEyeBottomEyelid.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedRightEyeUpperEyelid = iter.CopyIterator(); float RightEyeUpperEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeUpperEyelid.X - SavedRightEyeUpperEyelid.X, 2) + Math.Pow(landmarkFile.RightEyeUpperEyelid.Y - SavedRightEyeUpperEyelid.Y, 2) + Math.Pow(landmarkFile.RightEyeUpperEyelid.Z - SavedRightEyeUpperEyelid.Z, 2)); Cl3DModel.Cl3DModelPointIterator SavedRightEyeBottomEyelid = iter.CopyIterator(); float RightEyeBottomEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeBottomEyelid.X - SavedRightEyeBottomEyelid.X, 2) + Math.Pow(landmarkFile.RightEyeBottomEyelid.Y - SavedRightEyeBottomEyelid.Y, 2) + Math.Pow(landmarkFile.RightEyeBottomEyelid.Z - SavedRightEyeBottomEyelid.Z, 2)); do { float NewNoseTipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.NoseTip.X - iter.X, 2) + Math.Pow(landmarkFile.NoseTip.Y - iter.Y, 2) + Math.Pow(landmarkFile.NoseTip.Z - iter.Z, 2)); float NewLeftEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeRightCorner.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Z - iter.Z, 2)); float NewRightEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeLeftCorner.X - iter.X, 2) + Math.Pow(landmarkFile.RightEyeLeftCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightEyeLeftCorner.Z - iter.Z, 2)); float NewLeftEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeLeftCorner.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeLeftCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeLeftCorner.Z - iter.Z, 2)); float NewRightEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeRightCorner.X - iter.X, 2) + Math.Pow(landmarkFile.RightEyeRightCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightEyeRightCorner.Z - iter.Z, 2)); float NewLeftCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfNose.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Z - iter.Z, 2)); float NewRightCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfNose.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Z - iter.Z, 2)); float NewLeftCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLips.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Z - iter.Z, 2)); float NewRightCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfLips.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Z - iter.Z, 2)); float NewUpperLipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.UpperLip.X - iter.X, 2) + Math.Pow(landmarkFile.UpperLip.Y - iter.Y, 2) + Math.Pow(landmarkFile.UpperLip.Z - iter.Z, 2)); float NewBottomLipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.BottomLip.X - iter.X, 2) + Math.Pow(landmarkFile.BottomLip.Y - iter.Y, 2) + Math.Pow(landmarkFile.BottomLip.Z - iter.Z, 2)); float NewLeftEyeUpperEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeUpperEyelid.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeUpperEyelid.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeUpperEyelid.Z - iter.Z, 2)); float NewLeftEyeBottomEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeBottomEyelid.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeBottomEyelid.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeBottomEyelid.Z - iter.Z, 2)); float NewRightEyeUpperEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeUpperEyelid.X - iter.X, 2) + Math.Pow(landmarkFile.RightEyeUpperEyelid.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightEyeUpperEyelid.Z - iter.Z, 2)); float NewRightEyeBottomEyelidDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightEyeBottomEyelid.X - iter.X, 2) + Math.Pow(landmarkFile.RightEyeBottomEyelid.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightEyeBottomEyelid.Z - iter.Z, 2)); if (NewNoseTipDistance < NoseTipDistance) { NoseTipDistance = NewNoseTipDistance; SavedNoseTip = iter.CopyIterator(); } if (NewLeftEyeRightCornerDistance < LeftEyeRightCornerDistance) { LeftEyeRightCornerDistance = NewLeftEyeRightCornerDistance; SavedLeftEyeRightCorner = iter.CopyIterator(); } if (NewRightEyeLeftCornerDistance < RightEyeLeftCornerDistance) { RightEyeLeftCornerDistance = NewRightEyeLeftCornerDistance; SavedRightEyeLeftCorner = iter.CopyIterator(); } if (NewRightEyeRightCornerDistance < RightEyeRightCornerDistance) { RightEyeRightCornerDistance = NewRightEyeRightCornerDistance; SavedRightEyeRightCorner = iter.CopyIterator(); } if (NewLeftEyeLeftCornerDistance < LeftEyeLeftCornerDistance) { LeftEyeLeftCornerDistance = NewLeftEyeLeftCornerDistance; SavedLeftEyeLeftCorner = iter.CopyIterator(); } if (NewLeftCornerOfNoseDistance < LeftCornerOfNoseDistance) { LeftCornerOfNoseDistance = NewLeftCornerOfNoseDistance; SavedLeftCornerOfNose = iter.CopyIterator(); } if (NewRightCornerOfNoseDistance < RightCornerOfNoseDistance) { RightCornerOfNoseDistance = NewRightCornerOfNoseDistance; SavedRightCornerOfNose = iter.CopyIterator(); } if (NewLeftCornerOfLipsDistance < LeftCornerOfLipsDistance) { LeftCornerOfLipsDistance = NewLeftCornerOfLipsDistance; SavedLeftCornerOfLips = iter.CopyIterator(); } if (NewRightCornerOfLipsDistance < RightCornerOfLipsDistance) { RightCornerOfLipsDistance = NewRightCornerOfLipsDistance; SavedRightCornerOfLips = iter.CopyIterator(); } if (NewUpperLipDistance < UpperLipDistance) { UpperLipDistance = NewUpperLipDistance; SavedUpperLip = iter.CopyIterator(); } if (NewBottomLipDistance < BottomLipDistance) { BottomLipDistance = NewBottomLipDistance; SavedBottomLip = iter.CopyIterator(); } if (NewLeftEyeUpperEyelidDistance < LeftEyeUpperEyelidDistance) { LeftEyeUpperEyelidDistance = NewLeftEyeUpperEyelidDistance; SavedLeftEyeUpperEyelid = iter.CopyIterator(); } if (NewLeftEyeBottomEyelidDistance < LeftEyeBottomEyelidDistance) { LeftEyeBottomEyelidDistance = NewLeftEyeBottomEyelidDistance; SavedLeftEyeBottomEyelid = iter.CopyIterator(); } if (NewRightEyeUpperEyelidDistance < RightEyeUpperEyelidDistance) { RightEyeUpperEyelidDistance = NewRightEyeUpperEyelidDistance; SavedRightEyeUpperEyelid = iter.CopyIterator(); } if (NewRightEyeBottomEyelidDistance < RightEyeBottomEyelidDistance) { RightEyeBottomEyelidDistance = NewRightEyeBottomEyelidDistance; SavedRightEyeBottomEyelid = iter.CopyIterator(); } } while (iter.MoveToNext()); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, SavedNoseTip); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, SavedRightEyeLeftCorner); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, SavedLeftEyeRightCorner); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeLeftCorner, SavedLeftEyeLeftCorner); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeRightCorner, SavedRightEyeRightCorner); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, SavedLeftCornerOfNose); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, SavedRightCornerOfNose); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, SavedLeftCornerOfLips); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, SavedRightCornerOfLips); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.UpperLip, SavedUpperLip); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.BottomLip, SavedBottomLip); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeUpperEyelid, SavedLeftEyeUpperEyelid); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeBottomEyelid, SavedLeftEyeBottomEyelid); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeUpperEyelid, SavedRightEyeUpperEyelid); p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeBottomEyelid, SavedRightEyeBottomEyelid); }
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]); } } }
public override void Read(Cl3DModel p_mModel3D, string p_sFilePath) { try { using (StreamReader FileStream = File.OpenText(p_sFilePath)) { string line = ""; int NoOfVertexes = 0; int NoOfFaces = 0; if ((line = FileStream.ReadLine()) == null || !line.Equals("OFF")) { throw new Exception("Incorrect Header"); } if ((line = FileStream.ReadLine()) == null) { throw new Exception("Incerrect Header"); } string[] splitted = line.Split(' '); NoOfVertexes = Int32.Parse(splitted[0]); NoOfFaces = Int32.Parse(splitted[1]); for (int i = 0; i < NoOfVertexes; i++) { if ((line = FileStream.ReadLine()) == null) { throw new Exception("Incerrect Header"); } splitted = line.Split(' '); float X = float.Parse(splitted[0].Replace('.', ',')); float Y = float.Parse(splitted[1].Replace('.', ',')); float Z = float.Parse(splitted[2].Replace('.', ',')); p_mModel3D.AddPointToModel(X, Y, Z); } for (int i = 0; i < NoOfFaces; i++) { if ((line = FileStream.ReadLine()) == null) { throw new Exception("Incorrect Header"); } splitted = line.Split(' '); int noOfVect = int.Parse(splitted[0]); if (noOfVect != 3) { throw new Exception("Wrong number of vertexes in the face"); } int vertex1 = int.Parse(splitted[1]); int vertex2 = int.Parse(splitted[2]); int vertex3 = int.Parse(splitted[3]); Cl3DModel.Cl3DModelPointIterator iter = p_mModel3D.GetIterator(); Cl3DModel.Cl3DModelPointIterator iter2 = p_mModel3D.GetIterator(); if (!iter.MoveToPoint((uint)vertex1)) { throw new Exception("Cannot find the point with ID: " + vertex1.ToString()); } if (!iter2.MoveToPoint((uint)vertex2)) { throw new Exception("Cannot find the point with ID: " + vertex2.ToString()); } iter.AddNeighbor(iter2.CopyIterator()); if (!iter2.MoveToPoint((uint)vertex3)) { throw new Exception("Cannot find the point with ID: " + vertex3.ToString()); } iter.AddNeighbor(iter2.CopyIterator()); } } } catch (Exception) { p_mModel3D.ResetModel(); throw; } }
public override void Read(Cl3DModel p_mModel3D, string p_sFilePath) { try { using (StreamReader FileStream = File.OpenText(p_sFilePath)) { string line = ""; while ((line = FileStream.ReadLine()) != null) { if (line.Length == 0) { continue; } if (line[0] == '#') { continue; } string[] splitted = line.Split(' '); if (splitted[0].Equals("v")) { float X = float.Parse(splitted[1].Replace('.', ',')); float Y = float.Parse(splitted[2].Replace('.', ',')); float Z = float.Parse(splitted[3].Replace('.', ',')); p_mModel3D.AddPointToModel(X, Y, Z); } else if (splitted[0].Equals("f")) { if (splitted.Length != 4) { throw new Exception("Wrong number of vertexes in the face"); } int vertex1 = int.Parse(splitted[1]); int vertex2 = int.Parse(splitted[2]); int vertex3 = int.Parse(splitted[3]); Cl3DModel.Cl3DModelPointIterator iter = p_mModel3D.GetIterator(); Cl3DModel.Cl3DModelPointIterator iter2 = p_mModel3D.GetIterator(); if (!iter.MoveToPoint((uint)--vertex1)) { throw new Exception("Cannot find the point with ID: " + vertex1.ToString()); } if (!iter2.MoveToPoint((uint)--vertex2)) { throw new Exception("Cannot find the point with ID: " + vertex2.ToString()); } iter.AddNeighbor(iter2.CopyIterator()); if (!iter2.MoveToPoint((uint)--vertex3)) { throw new Exception("Cannot find the point with ID: " + vertex3.ToString()); } iter.AddNeighbor(iter2.CopyIterator()); } } } } catch (Exception) { p_mModel3D.ResetModel(); throw; } }
protected override void Algorithm(ref Cl3DModel p_Model) { Cl3DModel.Cl3DModelPointIterator NoseTip = null; if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, ref NoseTip)) { throw new Exception("Cannot find specific point NoseTip"); } Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator(); float MaxZ = float.MinValue; float MinZ = float.MaxValue; do { if (MaxZ < iter.Z) { MaxZ = iter.Z; } if (MinZ > iter.Z) { MinZ = iter.Z; } }while(iter.MoveToNext()); float step = 1f; int name = (int)step; List <Cl3DModel.Cl3DModelPointIterator> PointsToRemove = new List <Cl3DModel.Cl3DModelPointIterator>(); for (float Threshold = NoseTip.Z - step; Threshold > MinZ; Threshold -= step) { List <Cl3DModel.Cl3DModelPointIterator> PointsToCheck = new List <Cl3DModel.Cl3DModelPointIterator>(); List <Cl3DModel.Cl3DModelPointIterator> NewPoinsToCheck = new List <Cl3DModel.Cl3DModelPointIterator>(); List <Cl3DModel.Cl3DModelPointIterator> VisitedPoints = new List <Cl3DModel.Cl3DModelPointIterator>(); PointsToCheck.Add(NoseTip.CopyIterator()); while (PointsToCheck.Count != 0) { foreach (Cl3DModel.Cl3DModelPointIterator point in PointsToCheck) { if (point.IsSpecificValueCalculated("ToRemove")) { continue; } point.AlreadyVisited = true; VisitedPoints.Add(point.CopyIterator()); List <Cl3DModel.Cl3DModelPointIterator> Neighbors = point.GetListOfNeighbors(); foreach (Cl3DModel.Cl3DModelPointIterator Neighb in Neighbors) { if (Neighb.IsSpecificValueCalculated("ToRemove")) { continue; } if (Neighb.Z > Threshold && !Neighb.AlreadyVisited) { Neighb.AlreadyVisited = true; NewPoinsToCheck.Add(Neighb.CopyIterator()); } } } PointsToCheck = NewPoinsToCheck; NewPoinsToCheck = new List <Cl3DModel.Cl3DModelPointIterator>(); } Cl3DModel.Cl3DModelPointIterator unconnected = p_Model.GetIterator(); do { if (!unconnected.AlreadyVisited && unconnected.Z > Threshold && !unconnected.IsSpecificValueCalculated("ToRemove")) { if (m_SaveScreenShots) { unconnected.Color = Color.Red; } unconnected.AddSpecificValue("ToRemove", 1.0f); PointsToRemove.Add(unconnected.CopyIterator()); } } while (unconnected.MoveToNext()); foreach (Cl3DModel.Cl3DModelPointIterator pts in VisitedPoints) { if (m_SaveScreenShots) { pts.Color = Color.Green; } pts.AlreadyVisited = false; } if (m_SaveScreenShots) { Bitmap mapa; p_Model.GetBMPImage(out mapa, 1.0f); mapa.Save(p_Model.ModelFilePath + name.ToString() + ".bmp"); name += (int)step; } } List <Cl3DModel.Cl3DModelPointIterator> RemPointsVisited = new List <Cl3DModel.Cl3DModelPointIterator>(); foreach (Cl3DModel.Cl3DModelPointIterator RemPoint in PointsToRemove) { if (!RemPoint.IsValid() || RemPoint.AlreadyVisited) { continue; } List <Cl3DModel.Cl3DModelPointIterator> PointsToCheck = new List <Cl3DModel.Cl3DModelPointIterator>(); PointsToCheck.Add(RemPoint); bool remove = false; while (PointsToCheck.Count != 0) { List <Cl3DModel.Cl3DModelPointIterator> NewPtsToCheck = new List <Cl3DModel.Cl3DModelPointIterator>(); foreach (Cl3DModel.Cl3DModelPointIterator pt in PointsToCheck) { if (!pt.IsValid() || pt.AlreadyVisited) { continue; } pt.AlreadyVisited = true; RemPointsVisited.Add(pt); List <Cl3DModel.Cl3DModelPointIterator> Neighbors = pt.GetListOfNeighbors(); if (Neighbors.Count != 8) { remove = true; } else { foreach (Cl3DModel.Cl3DModelPointIterator ne in Neighbors) { if (ne.IsSpecificValueCalculated("ToRemove") && !ne.AlreadyVisited) { NewPtsToCheck.Add(ne); } } } } PointsToCheck = NewPtsToCheck; } if (remove) { foreach (Cl3DModel.Cl3DModelPointIterator ppt in RemPointsVisited) { p_Model.RemovePointFromModel(ppt); } } RemPointsVisited = new List <Cl3DModel.Cl3DModelPointIterator>(); } }
private void MarkHighCurvEdges(ref Cl3DModel Model) { Cl3DModel.Cl3DModelPointIterator NoseTip = Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip); Cl3DModel.Cl3DModelPointIterator LeftEye = Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner); Cl3DModel.Cl3DModelPointIterator RightEye = Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner); float diistance = (float)Math.Sqrt(Math.Pow(NoseTip - LeftEye, 2) + Math.Pow(NoseTip - RightEye, 2) + Math.Pow(LeftEye - RightEye, 2)) * 1.15f; List <Cl3DModel.Cl3DModelPointIterator> pointsIn = new List <Cl3DModel.Cl3DModelPointIterator>(); Cl3DModel.Cl3DModelPointIterator iter = Model.GetIterator(); do { float dist = (float)Math.Sqrt(Math.Pow((float)(iter - NoseTip), 2) + Math.Pow((float)(iter - LeftEye), 2) + Math.Pow((float)(iter - RightEye), 2)); if (dist < diistance) { pointsIn.Add(iter.CopyIterator()); } } while (iter.MoveToNext()); double MaxK1_10 = double.MinValue; double MinK1_10 = double.MaxValue; double MaxK1_15 = double.MinValue; double MinK1_15 = double.MaxValue; double MaxK1_20 = double.MinValue; double MinK1_20 = double.MaxValue; double MaxK1_25 = double.MinValue; double MinK1_25 = double.MaxValue; double MaxK1_55 = double.MinValue; double MinK1_40 = double.MaxValue; foreach (Cl3DModel.Cl3DModelPointIterator PointIn in pointsIn) { double valK1_10; if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_10, out valK1_10)) { ClInformationSender.SendInformation("K1 10 unavailable for the point " + PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText); continue; } double valK1_15; if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_15, out valK1_15)) { ClInformationSender.SendInformation("K1 15 unavailable for the point " + PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText); continue; } double valK1_20; if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_20, out valK1_20)) { ClInformationSender.SendInformation("K1 20 unavailable for the point " + PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText); continue; } double valK1_25; if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_25, out valK1_25)) { ClInformationSender.SendInformation("K1 25 unavailable for the point " + PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText); continue; } double valK1_40; if (!PointIn.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_40, out valK1_40)) { ClInformationSender.SendInformation("K1 40 unavailable for the point " + PointIn.PointID.ToString(), ClInformationSender.eInformationType.eDebugText); continue; } if (MinK1_10 > valK1_10) { MinK1_10 = valK1_10; } if (MaxK1_10 < valK1_10) { MaxK1_10 = valK1_10; } if (MinK1_15 > valK1_15) { MinK1_15 = valK1_15; } if (MaxK1_15 < valK1_15) { MaxK1_15 = valK1_15; } if (MinK1_20 > valK1_20) { MinK1_20 = valK1_20; } if (MaxK1_20 < valK1_20) { MaxK1_20 = valK1_20; } if (MinK1_25 > valK1_25) { MinK1_25 = valK1_25; } if (MaxK1_25 < valK1_25) { MaxK1_25 = valK1_25; } if (MinK1_40 > valK1_40) { MinK1_40 = valK1_40; } if (MaxK1_55 < valK1_40) { MaxK1_55 = valK1_40; } } iter = Model.GetIterator(); do { double valK1_10; if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_10, out valK1_10)) { continue; } double valK1_15; if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_15, out valK1_15)) { continue; } double valK1_20; if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_20, out valK1_20)) { continue; } double valK1_25; if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_25, out valK1_25)) { continue; } double valK1_40; if (!iter.GetSpecificValue(Cl3DModel.Cl3DModelPointIterator.eSpecificValues.K1_40, out valK1_40)) { continue; } if (valK1_10 < MinK1_10 || valK1_10 > MaxK1_10 || valK1_15 < MinK1_15 || valK1_15 > MaxK1_15 || valK1_20 < MinK1_20 || valK1_20 > MaxK1_20 || valK1_25 < MinK1_25 || valK1_25 > MaxK1_25 || valK1_40 < MinK1_40 || valK1_40 > MaxK1_55 ) { // iter.Color = Color.LightBlue; iter.AddSpecificValue("ToRemove_HighCurvature", 1.0f); } } while (iter.MoveToNext()); }
protected override void Algorithm(ref Cl3DModel p_Model) { if (p_Model.ModelType != "abs") { throw new Exception("Remove Half Of The Face works only for ABS files"); } Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator(); if (!iter.IsValid()) { throw new Exception("Model iterator not Valid"); } int MinX; int MaxX; int MinY; int MaxY; MinX = iter.RangeImageX; MaxX = iter.RangeImageX; MinY = iter.RangeImageY; MaxY = iter.RangeImageY; do { if (MinX > iter.RangeImageX) { MinX = iter.RangeImageX; } if (MaxX < iter.RangeImageX) { MaxX = iter.RangeImageX; } if (MinY > iter.RangeImageY) { MinY = iter.RangeImageY; } if (MaxY < iter.RangeImageY) { MaxY = iter.RangeImageY; } } while (iter.MoveToNext()); int Width = (MaxX - MinX) + 1; int Height = (MaxY - MinY) + 1; Cl3DModel.Cl3DModelPointIterator[,] map = new Cl3DModel.Cl3DModelPointIterator[Width, Height]; iter = p_Model.GetIterator(); do { map[iter.RangeImageX - MinX, iter.RangeImageY - MinY] = iter.CopyIterator(); } while (iter.MoveToNext()); int procent = (int)(Width * m_procentToRemove); for (int i = procent; i < Width; i++) { for (int j = 0; j < Height; j++) { p_Model.RemovePointFromModel(map[i, j]); } } }
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 SavedLeftEyeRightCorner = null; Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfRightEye = null; Cl3DModel.Cl3DModelPointIterator SavedNoseTip = null; if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner.ToString(), ref SavedLeftEyeRightCorner)) { throw new Exception("Cannot find specific point EyePoint"); } if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner.ToString(), ref SavedLeftCornerOfRightEye)) { throw new Exception("Cannot find specific point EyePoint"); } if (!p_Model.GetSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip.ToString(), ref SavedNoseTip)) { throw new Exception("Cannot find specific point NosePoint"); } // Normalized Generic Model (distance between eyes = 1) from IV2 Vector GenNoseTip = new Vector(new double[] { 0f, 0f, 0f }); Vector GenLeftEyeRightCorner = new Vector(new double[] { -0.5f, 0.88f, -1f }); Vector GenLeftCornerOfRightEye = new Vector(new double[] { 0.5f, 0.88f, -1f }); Vector GenLeftCornerOfLeftEye = new Vector(new double[] { -1.2f, 0.85f, -1f }); Vector GenRightCornerOfRightEye = new Vector(new double[] { 1.2f, 0.85f, -1f }); Vector GenLeftCornerOfNose = new Vector(new double[] { -0.45f, -0.05f, -0.73f }); Vector GenRightCornerOfNose = new Vector(new double[] { 0.45f, -0.05f, -0.73f }); Vector GenLeftCornerOfLips = new Vector(new double[] { -0.66f, -0.8f, -0.82f }); Vector GenRightCornerOfLips = new Vector(new double[] { 0.66f, -0.8f, -0.82f }); float DistBetweenEyes = (float)Math.Sqrt(Math.Pow(SavedLeftCornerOfRightEye.X - SavedLeftEyeRightCorner.X, 2) + Math.Pow(SavedLeftCornerOfRightEye.Y - SavedLeftEyeRightCorner.Y, 2) + Math.Pow(SavedLeftCornerOfRightEye.Z - SavedLeftEyeRightCorner.Z, 2)); float SavedDistBetweenEyeAndNose = (float)Math.Sqrt(Math.Pow(SavedNoseTip.X - SavedLeftEyeRightCorner.X, 2) + Math.Pow(SavedNoseTip.Y - SavedLeftEyeRightCorner.Y, 2) + Math.Pow(SavedNoseTip.Z - SavedLeftEyeRightCorner.Z, 2)); GenNoseTip *= DistBetweenEyes; GenLeftEyeRightCorner *= DistBetweenEyes; GenLeftCornerOfRightEye *= DistBetweenEyes; GenLeftCornerOfLeftEye *= DistBetweenEyes; GenRightCornerOfRightEye *= DistBetweenEyes; GenLeftCornerOfNose *= DistBetweenEyes; GenRightCornerOfNose *= DistBetweenEyes; GenLeftCornerOfLips *= DistBetweenEyes; GenRightCornerOfLips *= DistBetweenEyes; float DistBetweenEyeAndNoseAfterScale = (float)Math.Sqrt(Math.Pow(GenNoseTip[0] - GenLeftEyeRightCorner[0], 2) + Math.Pow(GenNoseTip[1] - GenLeftEyeRightCorner[1], 2) + Math.Pow(GenNoseTip[2] - GenLeftEyeRightCorner[2], 2)); float muntipltBy = SavedDistBetweenEyeAndNose / DistBetweenEyeAndNoseAfterScale; GenNoseTip *= muntipltBy; GenLeftEyeRightCorner[1] *= muntipltBy; GenLeftEyeRightCorner[2] *= muntipltBy; GenLeftCornerOfRightEye[1] *= muntipltBy; GenLeftCornerOfRightEye[2] *= muntipltBy; GenLeftCornerOfLeftEye[1] *= muntipltBy; GenLeftCornerOfLeftEye[2] *= muntipltBy; GenRightCornerOfRightEye[1] *= muntipltBy; GenRightCornerOfRightEye[2] *= muntipltBy; GenLeftCornerOfNose[1] *= muntipltBy; GenLeftCornerOfNose[2] *= muntipltBy; GenRightCornerOfNose[1] *= muntipltBy; GenRightCornerOfNose[2] *= muntipltBy; GenLeftCornerOfLips[1] *= muntipltBy; GenLeftCornerOfLips[2] *= muntipltBy; GenRightCornerOfLips[1] *= muntipltBy; GenRightCornerOfLips[2] *= muntipltBy; Vector MeanValOfGenModel = new Vector(new double[] { (GenNoseTip[0] + GenLeftEyeRightCorner[0] + GenLeftCornerOfRightEye[0]) / 3, (GenNoseTip[1] + GenLeftEyeRightCorner[1] + GenLeftCornerOfRightEye[1]) / 3, (GenNoseTip[2] + GenLeftEyeRightCorner[2] + GenLeftCornerOfRightEye[2]) / 3 }); Vector MeanValOfModel = new Vector(new double[] { (SavedNoseTip.X + SavedLeftEyeRightCorner.X + SavedLeftCornerOfRightEye.X) / 3, (SavedNoseTip.Y + SavedLeftEyeRightCorner.Y + SavedLeftCornerOfRightEye.Y) / 3, (SavedNoseTip.Z + SavedLeftEyeRightCorner.Z + SavedLeftCornerOfRightEye.Z) / 3 }); Iridium.Numerics.LinearAlgebra.Matrix Model = new Iridium.Numerics.LinearAlgebra.Matrix(3, 3); Iridium.Numerics.LinearAlgebra.Matrix ModelGen = new Iridium.Numerics.LinearAlgebra.Matrix(3, 3); // Row Column Model[0, 0] = (SavedNoseTip.X - MeanValOfModel[0]); Model[1, 0] = (SavedNoseTip.Y - MeanValOfModel[1]); Model[2, 0] = (SavedNoseTip.Z - MeanValOfModel[2]); Model[0, 1] = (SavedLeftEyeRightCorner.X - MeanValOfModel[0]); Model[1, 1] = (SavedLeftEyeRightCorner.Y - MeanValOfModel[1]); Model[2, 1] = (SavedLeftEyeRightCorner.Z - MeanValOfModel[2]); Model[0, 2] = (SavedLeftCornerOfRightEye.X - MeanValOfModel[0]); Model[1, 2] = (SavedLeftCornerOfRightEye.Y - MeanValOfModel[1]); Model[2, 2] = (SavedLeftCornerOfRightEye.Z - MeanValOfModel[2]); ModelGen[0, 0] = (GenNoseTip[0] - MeanValOfGenModel[0]); ModelGen[1, 0] = (GenNoseTip[1] - MeanValOfGenModel[1]); ModelGen[2, 0] = (GenNoseTip[2] - MeanValOfGenModel[2]); ModelGen[0, 1] = (GenLeftEyeRightCorner[0] - MeanValOfGenModel[0]); ModelGen[1, 1] = (GenLeftEyeRightCorner[1] - MeanValOfGenModel[1]); ModelGen[2, 1] = (GenLeftEyeRightCorner[2] - MeanValOfGenModel[2]); ModelGen[0, 2] = (GenLeftCornerOfRightEye[0] - MeanValOfGenModel[0]); ModelGen[1, 2] = (GenLeftCornerOfRightEye[1] - MeanValOfGenModel[1]); ModelGen[2, 2] = (GenLeftCornerOfRightEye[2] - MeanValOfGenModel[2]); ModelGen.Transpose(); 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] = MeanValOfGenModel[0]; MeanValOfGenModelMatrix[1, 0] = MeanValOfGenModel[1]; MeanValOfGenModelMatrix[2, 0] = MeanValOfGenModel[2]; Iridium.Numerics.LinearAlgebra.Matrix MeanValOfModelMatrix = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1); MeanValOfModelMatrix[0, 0] = MeanValOfModel[0]; MeanValOfModelMatrix[1, 0] = MeanValOfModel[1]; MeanValOfModelMatrix[2, 0] = MeanValOfModel[2]; Iridium.Numerics.LinearAlgebra.Matrix Translation = MeanValOfModelMatrix - Roatation * MeanValOfGenModelMatrix; Iridium.Numerics.LinearAlgebra.Matrix q = new Iridium.Numerics.LinearAlgebra.Matrix(3, 1); Iridium.Numerics.LinearAlgebra.Matrix NewQ = null; //------------- Code to show triangles created to check distance between them and features points ----------------------------------- /* * q[0, 0] = GenNoseTip.X; * q[1, 0] = GenNoseTip.Y; * q[2, 0] = GenNoseTip.Z; * NewQ = Roatation * q + Translation; * Cl3DModel.Cl3DModelPointIterator iter1 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]); * iter1.Color = Color.Green; * * q[0, 0] = GenLeftEyeRightCorner.X; * q[1, 0] = GenLeftEyeRightCorner.Y; * q[2, 0] = GenLeftEyeRightCorner.Z; * NewQ = Roatation * q + Translation; * Cl3DModel.Cl3DModelPointIterator iter2 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]); * iter2.Color = Color.White; * * q[0, 0] = GenLeftCornerOfRightEye.X; * q[1, 0] = GenLeftCornerOfRightEye.Y; * q[2, 0] = GenLeftCornerOfRightEye.Z; * NewQ = Roatation * q + Translation; * Cl3DModel.Cl3DModelPointIterator iter3 = p_Model.AddPointToModel((float)NewQ[0, 0], (float)NewQ[1, 0], (float)NewQ[2, 0]); * iter3.Color = Color.Orange; * * iter1.AddNeighbor(iter2); * iter1.AddNeighbor(iter3); * iter2.AddNeighbor(iter3); */ //--------------------------------------------------------------------------- Cl3DModel.Cl3DModelPointIterator iter = null; float MinDistance = 0; Cl3DModel.Cl3DModelPointIterator MinIter = null; //------------------ Code to correct nose tip and eyes position ----------------------------------- /* * GenNoseTip.X = (float)NewQ[0, 0]; * GenNoseTip.Y = (float)NewQ[1, 0]; * GenNoseTip.Z = (float)NewQ[2, 0]; * * iter = p_Model.GetIterator(); * MinDistance = (float)Math.Sqrt(Math.Pow(GenNoseTip.X - iter.X, 2) + Math.Pow(GenNoseTip.Y - iter.Y, 2) + Math.Pow(GenNoseTip.Z - iter.Z, 2)); * MinIter = iter; * do * { * float NewDistance = (float)Math.Sqrt(Math.Pow(GenNoseTip.X - iter.X, 2) + Math.Pow(GenNoseTip.Y - iter.Y, 2) + Math.Pow(GenNoseTip.Z - iter.Z, 2)); * if (NewDistance < MinDistance) * { * MinDistance = NewDistance; * MinIter = iter.CopyIterator(); * } * } while (iter.MoveToNext()); * p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, MinIter); * * q[0, 0] = GenLeftEyeRightCorner.X; * q[1, 0] = GenLeftEyeRightCorner.Y; * q[2, 0] = GenLeftEyeRightCorner.Z; * NewQ = Roatation * q + Translation; * GenLeftEyeRightCorner.X = (float)NewQ[0, 0]; * GenLeftEyeRightCorner.Y = (float)NewQ[1, 0]; * GenLeftEyeRightCorner.Z = (float)NewQ[2, 0]; * iter = p_Model.GetIterator(); * MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftEyeRightCorner.X - iter.X, 2) + Math.Pow(GenLeftEyeRightCorner.Y - iter.Y, 2) + Math.Pow(GenLeftEyeRightCorner.Z - iter.Z, 2)); * MinIter = iter; * do * { * float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftEyeRightCorner.X - iter.X, 2) + Math.Pow(GenLeftEyeRightCorner.Y - iter.Y, 2) + Math.Pow(GenLeftEyeRightCorner.Z - iter.Z, 2)); * if (NewDistance < MinDistance) * { * MinDistance = NewDistance; * MinIter = iter.CopyIterator(); * } * } while (iter.MoveToNext()); * p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, MinIter); * * q[0, 0] = GenLeftCornerOfRightEye.X; * q[1, 0] = GenLeftCornerOfRightEye.Y; * q[2, 0] = GenLeftCornerOfRightEye.Z; * NewQ = Roatation * q + Translation; * GenLeftCornerOfRightEye.X = (float)NewQ[0, 0]; * GenLeftCornerOfRightEye.Y = (float)NewQ[1, 0]; * GenLeftCornerOfRightEye.Z = (float)NewQ[2, 0]; * iter = p_Model.GetIterator(); * MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfRightEye.X - iter.X, 2) + Math.Pow(GenLeftCornerOfRightEye.Y - iter.Y, 2) + Math.Pow(GenLeftCornerOfRightEye.Z - iter.Z, 2)); * MinIter = iter; * do * { * float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfRightEye.X - iter.X, 2) + Math.Pow(GenLeftCornerOfRightEye.Y - iter.Y, 2) + Math.Pow(GenLeftCornerOfRightEye.Z - iter.Z, 2)); * if (NewDistance < MinDistance) * { * MinDistance = NewDistance; * MinIter = iter.CopyIterator(); * } * } while (iter.MoveToNext()); * p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, MinIter); */ //--------------------------------------------------------------------------------------------------------- q[0, 0] = GenLeftCornerOfLeftEye[0]; q[1, 0] = GenLeftCornerOfLeftEye[1]; q[2, 0] = GenLeftCornerOfLeftEye[2]; NewQ = Roatation * q + Translation; GenLeftCornerOfLeftEye[0] = (float)NewQ[0, 0]; GenLeftCornerOfLeftEye[1] = (float)NewQ[1, 0]; GenLeftCornerOfLeftEye[2] = (float)NewQ[2, 0]; iter = p_Model.GetIterator(); MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfLeftEye[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfLeftEye[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfLeftEye[2] - iter.Z, 2)); MinIter = iter; do { float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfLeftEye[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfLeftEye[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfLeftEye[2] - iter.Z, 2)); if (NewDistance < MinDistance) { MinDistance = NewDistance; MinIter = iter.CopyIterator(); } } while (iter.MoveToNext()); if (MinDistance < m_MinDistanceToAddPoint) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeLeftCorner, MinIter); } q[0, 0] = GenRightCornerOfRightEye[0]; q[1, 0] = GenRightCornerOfRightEye[1]; q[2, 0] = GenRightCornerOfRightEye[2]; NewQ = Roatation * q + Translation; GenRightCornerOfRightEye[0] = (float)NewQ[0, 0]; GenRightCornerOfRightEye[1] = (float)NewQ[1, 0]; GenRightCornerOfRightEye[2] = (float)NewQ[2, 0]; iter = p_Model.GetIterator(); MinDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfRightEye[0] - iter.X, 2) + Math.Pow(GenRightCornerOfRightEye[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfRightEye[2] - iter.Z, 2)); MinIter = iter; do { float NewDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfRightEye[0] - iter.X, 2) + Math.Pow(GenRightCornerOfRightEye[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfRightEye[2] - iter.Z, 2)); if (NewDistance < MinDistance) { MinDistance = NewDistance; MinIter = iter.CopyIterator(); } } while (iter.MoveToNext()); if (MinDistance < m_MinDistanceToAddPoint) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeRightCorner, MinIter); } q[0, 0] = GenLeftCornerOfNose[0]; q[1, 0] = GenLeftCornerOfNose[1]; q[2, 0] = GenLeftCornerOfNose[2]; NewQ = Roatation * q + Translation; GenLeftCornerOfNose[0] = (float)NewQ[0, 0]; GenLeftCornerOfNose[1] = (float)NewQ[1, 0]; GenLeftCornerOfNose[2] = (float)NewQ[2, 0]; iter = p_Model.GetIterator(); MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfNose[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfNose[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfNose[2] - iter.Z, 2)); MinIter = iter; do { float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfNose[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfNose[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfNose[2] - iter.Z, 2)); if (NewDistance < MinDistance) { MinDistance = NewDistance; MinIter = iter.CopyIterator(); } } while (iter.MoveToNext()); if (MinDistance < m_MinDistanceToAddPoint) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, MinIter); } q[0, 0] = GenRightCornerOfNose[0]; q[1, 0] = GenRightCornerOfNose[1]; q[2, 0] = GenRightCornerOfNose[2]; NewQ = Roatation * q + Translation; GenRightCornerOfNose[0] = (float)NewQ[0, 0]; GenRightCornerOfNose[1] = (float)NewQ[1, 0]; GenRightCornerOfNose[2] = (float)NewQ[2, 0]; iter = p_Model.GetIterator(); MinDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfNose[0] - iter.X, 2) + Math.Pow(GenRightCornerOfNose[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfNose[2] - iter.Z, 2)); MinIter = iter; do { float NewDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfNose[0] - iter.X, 2) + Math.Pow(GenRightCornerOfNose[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfNose[2] - iter.Z, 2)); if (NewDistance < MinDistance) { MinDistance = NewDistance; MinIter = iter.CopyIterator(); } } while (iter.MoveToNext()); if (MinDistance < m_MinDistanceToAddPoint) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, MinIter); } q[0, 0] = GenLeftCornerOfLips[0]; q[1, 0] = GenLeftCornerOfLips[1]; q[2, 0] = GenLeftCornerOfLips[2]; NewQ = Roatation * q + Translation; GenLeftCornerOfLips[0] = (float)NewQ[0, 0]; GenLeftCornerOfLips[1] = (float)NewQ[1, 0]; GenLeftCornerOfLips[2] = (float)NewQ[2, 0]; iter = p_Model.GetIterator(); MinDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfLips[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfLips[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfLips[2] - iter.Z, 2)); MinIter = iter; do { float NewDistance = (float)Math.Sqrt(Math.Pow(GenLeftCornerOfLips[0] - iter.X, 2) + Math.Pow(GenLeftCornerOfLips[1] - iter.Y, 2) + Math.Pow(GenLeftCornerOfLips[2] - iter.Z, 2)); if (NewDistance < MinDistance) { MinDistance = NewDistance; MinIter = iter.CopyIterator(); } } while (iter.MoveToNext()); if (MinDistance < m_MinDistanceToAddPoint) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, MinIter); } q[0, 0] = GenRightCornerOfLips[0]; q[1, 0] = GenRightCornerOfLips[1]; q[2, 0] = GenRightCornerOfLips[2]; NewQ = Roatation * q + Translation; GenRightCornerOfLips[0] = (float)NewQ[0, 0]; GenRightCornerOfLips[1] = (float)NewQ[1, 0]; GenRightCornerOfLips[2] = (float)NewQ[2, 0]; iter = p_Model.GetIterator(); MinDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfLips[0] - iter.X, 2) + Math.Pow(GenRightCornerOfLips[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfLips[2] - iter.Z, 2)); MinIter = iter; do { float NewDistance = (float)Math.Sqrt(Math.Pow(GenRightCornerOfLips[0] - iter.X, 2) + Math.Pow(GenRightCornerOfLips[1] - iter.Y, 2) + Math.Pow(GenRightCornerOfLips[2] - iter.Z, 2)); if (NewDistance < MinDistance) { MinDistance = NewDistance; MinIter = iter.CopyIterator(); } } while (iter.MoveToNext()); if (MinDistance < m_MinDistanceToAddPoint) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, MinIter); } }
protected override void Algorithm(ref Cl3DModel p_Model) { // if (!(p_Model.ModelType == "abs" || p_Model.ModelType == "binaryModel" || p_Model.ModelType == "model" || p_Model.ModelType == "bnt")) // throw new Exception("Remove Holes based on Range Image works only for ABS and BNT like aslo for binaryModel and model files with range image informations"); Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator(); if (!iter.IsValid()) { throw new Exception("Model iterator not Valid"); } int MinX; int MaxX; int MinY; int MaxY; MinX = iter.RangeImageX; MaxX = iter.RangeImageX; MinY = iter.RangeImageY; MaxY = iter.RangeImageY; do { if (MinX > iter.RangeImageX) { MinX = iter.RangeImageX; } if (MaxX < iter.RangeImageX) { MaxX = iter.RangeImageX; } if (MinY > iter.RangeImageY) { MinY = iter.RangeImageY; } if (MaxY < iter.RangeImageY) { MaxY = iter.RangeImageY; } } while (iter.MoveToNext()); int Width = (MaxX - MinX) + 1; int Height = (MaxY - MinY) + 1; Cl3DModel.Cl3DModelPointIterator[,] map = new Cl3DModel.Cl3DModelPointIterator[Width, Height]; iter = p_Model.GetIterator(); do { map[iter.RangeImageX - MinX, iter.RangeImageY - MinY] = iter.CopyIterator(); } while (iter.MoveToNext()); for (int y = 0; y < Height; y++) { bool bFoundHole = false; bool bFaceStarted = false; int iHoleBegin = 0; int iHoleEnd = 0; for (int x = 0; x < Width; x++) { if (map[x, y] == null && bFaceStarted) { // found hole begin iHoleBegin = x - 1; for (int j = x + 1; j < Width; j++) // try to find hole end { if (map[j, y] != null) { iHoleEnd = j; bFoundHole = true; break; } } } else if (bFaceStarted == false && map[x, y] != null) { bFaceStarted = true; } if (bFoundHole) { for (int ix = iHoleBegin + 1; ix < iHoleEnd; ix++) { float proc = (float)(ix - iHoleBegin) / (iHoleEnd - iHoleBegin); float addZ = InterpolateCubic(iHoleBegin, iHoleEnd, y, map, proc, Height, Width); float addX = LinearInterpolate(map[iHoleBegin, y].X, map[iHoleEnd, y].X, proc); int R = (int)LinearInterpolate(map[iHoleBegin, y].Color.R, map[iHoleEnd, y].Color.R, proc); int G = (int)LinearInterpolate(map[iHoleBegin, y].Color.G, map[iHoleEnd, y].Color.G, proc); int B = (int)LinearInterpolate(map[iHoleBegin, y].Color.B, map[iHoleEnd, y].Color.B, proc); map[ix, y] = p_Model.AddPointToModel(addX, map[iHoleBegin, y].Y, addZ, MinX + ix, MinY + y); map[ix, y].AlreadyVisited = true; map[ix, y].Color = Color.FromArgb(R, G, B); // map[ix, y].Color = Color.Green; Cl3DModel.Cl3DModelPointIterator testBegin = map[iHoleBegin, y]; Cl3DModel.Cl3DModelPointIterator testEnd = map[iHoleEnd, y]; if (ix - 1 > 0 && y - 1 > 0 && map[ix - 1, y - 1] != null) { map[ix - 1, y - 1].AddNeighbor(map[ix, y]); } if (ix - 1 > 0 && map[ix - 1, y] != null) { map[ix - 1, y].AddNeighbor(map[ix, y]); } if (ix - 1 > 0 && y + 1 < Height && map[ix - 1, y + 1] != null) { map[ix - 1, y + 1].AddNeighbor(map[ix, y]); } if (y - 1 > 0 && map[ix, y - 1] != null) { map[ix, y - 1].AddNeighbor(map[ix, y]); } if (y + 1 < Height && map[ix, y + 1] != null) { map[ix, y + 1].AddNeighbor(map[ix, y]); } if (ix + 1 < Width && y - 1 > 0 && map[ix + 1, y - 1] != null) { map[ix + 1, y - 1].AddNeighbor(map[ix, y]); } if (ix + 1 < Width && map[ix + 1, y] != null) { map[ix + 1, y].AddNeighbor(map[ix, y]); } if (ix + 1 < Width && y + 1 < Height && map[ix + 1, y + 1] != null) { map[ix + 1, y + 1].AddNeighbor(map[ix, y]); } } bFoundHole = false; } } } for (int x = 0; x < Width; x++) { bool bFoundHole = false; bool bFaceStarted = false; int iHoleBegin = 0; int iHoleEnd = 0; for (int y = 0; y < Height; y++) { if ((map[x, y] == null || map[x, y].AlreadyVisited) && bFaceStarted) { // found hole begin iHoleBegin = y - 1; for (int j = y + 1; j < Height; j++) // try to find hole end { if (map[x, j] != null) { if (map[x, j].AlreadyVisited) { continue; } iHoleEnd = j; bFoundHole = true; break; } } } else if (bFaceStarted == false && (map[x, y] != null)) { bFaceStarted = true; } if (bFoundHole) { for (int iy = iHoleBegin + 1; iy < iHoleEnd; iy++) { float proc = (float)(iy - iHoleBegin) / (iHoleEnd - iHoleBegin); float beforeBeginHoleVal = map[x, iHoleBegin].Z; float afterBeginHoleVal = map[x, iHoleEnd].Z; if (iHoleBegin > 2) { if (map[x, iHoleBegin - 1] != null) { beforeBeginHoleVal = map[x, iHoleBegin - 1].Z; } } if (iHoleEnd < Height - 1) { if (map[x, iHoleEnd + 1] != null) { afterBeginHoleVal = map[x, iHoleEnd + 1].Z; } } float addZ = CubicInterpolate(beforeBeginHoleVal, map[x, iHoleBegin].Z, map[x, iHoleEnd].Z, afterBeginHoleVal, proc); if (map[x, iy] == null) { float addY = LinearInterpolate(map[x, iHoleBegin].Y, map[x, iHoleEnd].Y, proc); map[x, iy] = p_Model.AddPointToModel(map[x, iHoleBegin].X, addY, addZ, MinX + x, MinY + iy); // map[x, iy].Color = Color.Red; int R = (int)LinearInterpolate(map[x, iHoleBegin].Color.R, map[x, iHoleEnd].Color.R, proc); int G = (int)LinearInterpolate(map[x, iHoleBegin].Color.G, map[x, iHoleEnd].Color.G, proc); int B = (int)LinearInterpolate(map[x, iHoleBegin].Color.B, map[x, iHoleEnd].Color.B, proc); map[x, iy].AlreadyVisited = true; map[x, iy].Color = Color.FromArgb(R, G, B); Cl3DModel.Cl3DModelPointIterator testBegin = map[x, iHoleBegin]; Cl3DModel.Cl3DModelPointIterator testEnd = map[x, iHoleEnd]; if (x - 1 > 0 && iy - 1 > 0 && map[x - 1, iy - 1] != null) { map[x - 1, iy - 1].AddNeighbor(map[x, iy]); } if (x - 1 > 0 && map[x - 1, iy] != null) { map[x - 1, iy].AddNeighbor(map[x, iy]); } if (x - 1 > 0 && iy + 1 < Height && map[x - 1, iy + 1] != null) { map[x - 1, iy + 1].AddNeighbor(map[x, iy]); } if (iy - 1 > 0 && map[x, iy - 1] != null) { map[x, iy - 1].AddNeighbor(map[x, iy]); } if (iy + 1 < Height && map[x, iy + 1] != null) { map[x, iy + 1].AddNeighbor(map[x, iy]); } if (x + 1 < Width && iy - 1 > 0 && map[x + 1, iy - 1] != null) { map[x + 1, iy - 1].AddNeighbor(map[x, iy]); } if (x + 1 < Width && map[x + 1, iy] != null) { map[x + 1, iy].AddNeighbor(map[x, iy]); } if (x + 1 < Width && iy + 1 < Height && map[x + 1, iy + 1] != null) { map[x + 1, iy + 1].AddNeighbor(map[x, iy]); } } else { map[x, iy].Z = (map[x, iy].Z + addZ) / 2; // map[x, iy].Color = Color.Orange; } } bFoundHole = false; } } } }
protected override void Algorithm(ref Cl3DModel p_Model) { CRRFile landmarkFile = ReadCRRFile(p_Model.ModelFileFolder + p_Model.ModelFileName + ".crr"); //search for the closest point from the model to the read landmark Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator(); if (!iter.IsValid()) { throw new Exception("Iterator in the model is not valid!"); } Cl3DModel.Cl3DModelPointIterator SavedNoseTip = null; Cl3DModel.Cl3DModelPointIterator SavedLeftEyeRightCorner = null; Cl3DModel.Cl3DModelPointIterator SavedRightEyeLeftCorner = null; Cl3DModel.Cl3DModelPointIterator SavedRightEyeRightCorner = null; Cl3DModel.Cl3DModelPointIterator SavedLeftEyeLeftCorner = null; Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfNose = null; Cl3DModel.Cl3DModelPointIterator SavedRightCornerOfNose = null; Cl3DModel.Cl3DModelPointIterator SavedLeftCornerOfLips = null; Cl3DModel.Cl3DModelPointIterator SavedRightCornerOfLips = null; float RightCornerOfLipsDistance = 0; float NoseTipDistance = 0; float LeftEyeRightCornerDistance = 0; float RightEyeLeftCornerDistance = 0; float RightEyeRightCornerDistance = 0; float LeftEyeLeftCornerDistance = 0; float LeftCornerOfNoseDistance = 0; float RightCornerOfNoseDistance = 0; float LeftCornerOfLipsDistance = 0; if (landmarkFile.NostTip != null) { SavedNoseTip = iter.CopyIterator(); NoseTipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.NostTip.X - SavedNoseTip.X, 2) + Math.Pow(landmarkFile.NostTip.Y - SavedNoseTip.Y, 2) + Math.Pow(landmarkFile.NostTip.Z - SavedNoseTip.Z, 2)); } if (landmarkFile.LeftEyeRightCorner != null) { SavedLeftEyeRightCorner = iter.CopyIterator(); LeftEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeRightCorner.X - SavedLeftEyeRightCorner.X, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Y - SavedLeftEyeRightCorner.Y, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Z - SavedLeftEyeRightCorner.Z, 2)); } if (landmarkFile.LeftCornerOfRightEye != null) { SavedRightEyeLeftCorner = iter.CopyIterator(); RightEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfRightEye.X - SavedRightEyeLeftCorner.X, 2) + Math.Pow(landmarkFile.LeftCornerOfRightEye.Y - SavedRightEyeLeftCorner.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfRightEye.Z - SavedRightEyeLeftCorner.Z, 2)); } if (landmarkFile.RightCornerOfRightEye != null) { SavedRightEyeRightCorner = iter.CopyIterator(); RightEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfRightEye.X - SavedRightEyeRightCorner.X, 2) + Math.Pow(landmarkFile.RightCornerOfRightEye.Y - SavedRightEyeRightCorner.Y, 2) + Math.Pow(landmarkFile.RightCornerOfRightEye.Z - SavedRightEyeRightCorner.Z, 2)); } if (landmarkFile.LeftCornerOfLeftEye != null) { SavedLeftEyeLeftCorner = iter.CopyIterator(); LeftEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLeftEye.X - SavedLeftEyeLeftCorner.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLeftEye.Y - SavedLeftEyeLeftCorner.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLeftEye.Z - SavedLeftEyeLeftCorner.Z, 2)); } if (landmarkFile.LeftCornerOfNose != null) { SavedLeftCornerOfNose = iter.CopyIterator(); LeftCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfNose.X - SavedLeftCornerOfNose.X, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Y - SavedLeftCornerOfNose.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Z - SavedLeftCornerOfNose.Z, 2)); } if (landmarkFile.RightCornerOfNose != null) { SavedRightCornerOfNose = iter.CopyIterator(); RightCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfNose.X - SavedRightCornerOfNose.X, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Y - SavedRightCornerOfNose.Y, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Z - SavedRightCornerOfNose.Z, 2)); } if (landmarkFile.LeftCornerOfLips != null) { SavedLeftCornerOfLips = iter.CopyIterator(); LeftCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLips.X - SavedLeftCornerOfLips.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Y - SavedLeftCornerOfLips.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Z - SavedLeftCornerOfLips.Z, 2)); } if (landmarkFile.RightCornerOfLips != null) { SavedRightCornerOfLips = iter.CopyIterator(); RightCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfLips.X - SavedRightCornerOfLips.X, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Y - SavedRightCornerOfLips.Y, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Z - SavedRightCornerOfLips.Z, 2)); } do { if (SavedNoseTip != null) { float NewNoseTipDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.NostTip.X - iter.X, 2) + Math.Pow(landmarkFile.NostTip.Y - iter.Y, 2) + Math.Pow(landmarkFile.NostTip.Z - iter.Z, 2)); if (NewNoseTipDistance < NoseTipDistance) { NoseTipDistance = NewNoseTipDistance; SavedNoseTip = iter.CopyIterator(); } } if (SavedLeftEyeRightCorner != null) { float NewLeftEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftEyeRightCorner.X - iter.X, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftEyeRightCorner.Z - iter.Z, 2)); if (NewLeftEyeRightCornerDistance < LeftEyeRightCornerDistance) { LeftEyeRightCornerDistance = NewLeftEyeRightCornerDistance; SavedLeftEyeRightCorner = iter.CopyIterator(); } } if (SavedRightEyeLeftCorner != null) { float NewRightEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfRightEye.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfRightEye.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfRightEye.Z - iter.Z, 2)); if (NewRightEyeLeftCornerDistance < RightEyeLeftCornerDistance) { RightEyeLeftCornerDistance = NewRightEyeLeftCornerDistance; SavedRightEyeLeftCorner = iter.CopyIterator(); } } if (SavedRightEyeRightCorner != null) { float NewRightEyeRightCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfRightEye.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfRightEye.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfRightEye.Z - iter.Z, 2)); if (NewRightEyeRightCornerDistance < RightEyeRightCornerDistance) { RightEyeRightCornerDistance = NewRightEyeRightCornerDistance; SavedRightEyeRightCorner = iter.CopyIterator(); } } if (SavedLeftEyeLeftCorner != null) { float NewLeftEyeLeftCornerDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLeftEye.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLeftEye.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLeftEye.Z - iter.Z, 2)); if (NewLeftEyeLeftCornerDistance < LeftEyeLeftCornerDistance) { LeftEyeLeftCornerDistance = NewLeftEyeLeftCornerDistance; SavedLeftEyeLeftCorner = iter.CopyIterator(); } } if (SavedLeftCornerOfNose != null) { float NewLeftCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfNose.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfNose.Z - iter.Z, 2)); if (NewLeftCornerOfNoseDistance < LeftCornerOfNoseDistance) { LeftCornerOfNoseDistance = NewLeftCornerOfNoseDistance; SavedLeftCornerOfNose = iter.CopyIterator(); } } if (SavedRightCornerOfNose != null) { float NewRightCornerOfNoseDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfNose.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfNose.Z - iter.Z, 2)); if (NewRightCornerOfNoseDistance < RightCornerOfNoseDistance) { RightCornerOfNoseDistance = NewRightCornerOfNoseDistance; SavedRightCornerOfNose = iter.CopyIterator(); } } if (SavedLeftCornerOfLips != null) { float NewLeftCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.LeftCornerOfLips.X - iter.X, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Y - iter.Y, 2) + Math.Pow(landmarkFile.LeftCornerOfLips.Z - iter.Z, 2)); if (NewLeftCornerOfLipsDistance < LeftCornerOfLipsDistance) { LeftCornerOfLipsDistance = NewLeftCornerOfLipsDistance; SavedLeftCornerOfLips = iter.CopyIterator(); } } if (SavedRightCornerOfLips != null) { float NewRightCornerOfLipsDistance = (float)Math.Sqrt(Math.Pow(landmarkFile.RightCornerOfLips.X - iter.X, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Y - iter.Y, 2) + Math.Pow(landmarkFile.RightCornerOfLips.Z - iter.Z, 2)); if (NewRightCornerOfLipsDistance < RightCornerOfLipsDistance) { RightCornerOfLipsDistance = NewRightCornerOfLipsDistance; SavedRightCornerOfLips = iter.CopyIterator(); } } } while (iter.MoveToNext()); if (SavedNoseTip != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.NoseTip, SavedNoseTip); } if (SavedRightEyeLeftCorner != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeLeftCorner, SavedRightEyeLeftCorner); } if (SavedLeftEyeRightCorner != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeRightCorner, SavedLeftEyeRightCorner); } if (SavedLeftEyeLeftCorner != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftEyeLeftCorner, SavedLeftEyeLeftCorner); } if (SavedRightEyeRightCorner != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightEyeRightCorner, SavedRightEyeRightCorner); } if (SavedLeftCornerOfNose != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfNose, SavedLeftCornerOfNose); } if (SavedRightCornerOfNose != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfNose, SavedRightCornerOfNose); } if (SavedLeftCornerOfLips != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.LeftCornerOfLips, SavedLeftCornerOfLips); } if (SavedRightCornerOfLips != null) { p_Model.AddSpecificPoint(Cl3DModel.eSpecificPoints.RightCornerOfLips, SavedRightCornerOfLips); } }
protected override void Algorithm(ref Cl3DModel p_Model) { // if (!(p_Model.ModelType == "abs" || p_Model.ModelType == "binaryModel" || p_Model.ModelType == "model")) // throw new Exception("Remove Holes based on Range Image works only for abs, binaryModel and model files"); Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator(); if (!iter.IsValid()) { throw new Exception("Model iterator not Valid"); } int MinX; int MaxX; int MinY; int MaxY; MinX = iter.RangeImageX; MaxX = iter.RangeImageX; MinY = iter.RangeImageY; MaxY = iter.RangeImageY; do { if (MinX > iter.RangeImageX) { MinX = iter.RangeImageX; } if (MaxX < iter.RangeImageX) { MaxX = iter.RangeImageX; } if (MinY > iter.RangeImageY) { MinY = iter.RangeImageY; } if (MaxY < iter.RangeImageY) { MaxY = iter.RangeImageY; } } while (iter.MoveToNext()); int Width = (MaxX - MinX) + 1; int Height = (MaxY - MinY) + 1; Cl3DModel.Cl3DModelPointIterator[,] map = new Cl3DModel.Cl3DModelPointIterator[Width, Height]; iter = p_Model.GetIterator(); do { map[iter.RangeImageX - MinX, iter.RangeImageY - MinY] = iter.CopyIterator(); foreach (Cl3DModel.Cl3DModelPointIterator pts in iter.GetListOfNeighbors()) { iter.RemoveNeighbor(pts); } } while (iter.MoveToNext()); for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { if (map[x, y] == null) { continue; } if (x - 1 >= 0 && y + 1 < Height && map[x - 1, y + 1] != null) { map[x, y].AddNeighbor(map[x - 1, y + 1]); } if (x - 1 >= 0 && map[x - 1, y] != null) { map[x, y].AddNeighbor(map[x - 1, y]); } if (x - 1 >= 0 && y - 1 >= 0 && map[x - 1, y - 1] != null) { map[x, y].AddNeighbor(map[x - 1, y - 1]); } if (y - 1 >= 0 && map[x, y - 1] != null) { map[x, y].AddNeighbor(map[x, y - 1]); } if (x + 1 < Width && y - 1 >= 0 && map[x + 1, y - 1] != null) { map[x, y].AddNeighbor(map[x + 1, y - 1]); } if (x + 1 < Width && map[x + 1, y] != null) { map[x, y].AddNeighbor(map[x + 1, y]); } if (x + 1 < Width && y + 1 < Height && map[x + 1, y + 1] != null) { map[x, y].AddNeighbor(map[x + 1, y + 1]); } if (y + 1 < Height && map[x, y + 1] != null) { map[x, y].AddNeighbor(map[x, y + 1]); } } } }
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()); }
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) { 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) { 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) { 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]); }
private void SampleUVParametriztion(Cl3DModel p_Model, out Cl3DModel.Cl3DModelPointIterator[,] SampledModel, int MatrixWidth, int MatrixHeight) { Cl3DModel.Cl3DModelPointIterator iter = p_Model.GetIterator(); float maxU = iter.U; float minU = iter.U; float maxV = iter.V; float minV = iter.V; do { if (maxU < iter.U) { maxU = iter.U; } if (maxV < iter.V) { maxV = iter.V; } if (minU > iter.U) { minU = iter.U; } if (minV > iter.V) { minV = iter.V; } } while (iter.MoveToNext()); List <Cl3DModel.Cl3DModelPointIterator>[,] SampledModelList = new List <Cl3DModel.Cl3DModelPointIterator> [MatrixWidth, MatrixHeight]; SampledModel = new Cl3DModel.Cl3DModelPointIterator[MatrixWidth, MatrixHeight]; iter = p_Model.GetIterator(); do { float U = iter.U - minU; float V = iter.V - minV; int RoundU = (int)((U / (maxU - minU)) * (MatrixWidth - 1)); int RoundV = (int)((V / (maxV - minV)) * (MatrixHeight - 1)); if (SampledModelList[RoundU, RoundV] == null) { SampledModelList[RoundU, RoundV] = new List <Cl3DModel.Cl3DModelPointIterator>(); } SampledModelList[RoundU, RoundV].Add(iter.CopyIterator()); } while (iter.MoveToNext()); for (int i = 0; i < MatrixWidth; i++) { for (int j = 0; j < MatrixHeight; j++) { if (SampledModelList[i, j] != null) { float x = 0; float y = 0; float z = 0; float u = 0; float v = 0; int ColorR = 0; int ColorG = 0; int ColorB = 0; string specPoint = Cl3DModel.eSpecificPoints.UnspecifiedPoint.ToString(); bool isSpecific = false; Dictionary <string, double> SumOfSpecificValues = new Dictionary <string, double>(); foreach (Cl3DModel.Cl3DModelPointIterator pts in SampledModelList[i, j]) { pts.AlreadyVisited = true; if (!isSpecific) { isSpecific = p_Model.IsThisPointInSpecificPoints(pts, ref specPoint); } List <string> specValues = pts.GetListOfSpecificValues(); foreach (string valueName in specValues) { double currentVal = 0; pts.GetSpecificValue(valueName, out currentVal); double countedVal = 0; SumOfSpecificValues.TryGetValue(valueName, out countedVal); SumOfSpecificValues.Remove(valueName); SumOfSpecificValues.Add(valueName, countedVal + currentVal); } x += pts.X; y += pts.Y; z += pts.Z; u += pts.U; v += pts.V; ColorR += pts.ColorR; ColorG += pts.ColorG; ColorB += pts.ColorB; } int Count = SampledModelList[i, j].Count; List <Cl3DModel.Cl3DModelPointIterator> connections = new List <Cl3DModel.Cl3DModelPointIterator>(); foreach (Cl3DModel.Cl3DModelPointIterator point in SampledModelList[i, j]) { foreach (Cl3DModel.Cl3DModelPointIterator InnerPoint in point.GetListOfNeighbors()) { if (InnerPoint.AlreadyVisited == false) { connections.Add(InnerPoint); } } } Cl3DModel.Cl3DModelPointIterator pt = p_Model.AddPointToModel(x / Count, y / Count, z / Count); pt.Color = Color.FromArgb(ColorR / Count, ColorG / Count, ColorB / Count); pt.U = (int)((u / SampledModelList[i, j].Count) / maxU * MatrixWidth); pt.V = (int)((v / SampledModelList[i, j].Count) / maxV * MatrixHeight); foreach (KeyValuePair <string, double> SpecVal in SumOfSpecificValues) { pt.AddSpecificValue(SpecVal.Key, SpecVal.Value / Count); } SampledModel[i, j] = pt; if (isSpecific) { p_Model.AddSpecificPoint(specPoint, pt); } foreach (Cl3DModel.Cl3DModelPointIterator point in SampledModelList[i, j]) { p_Model.RemovePointFromModel(point); } foreach (Cl3DModel.Cl3DModelPointIterator point in connections) { pt.AddNeighbor(point); } } } } }
public override void Read(Cl3DModel p_mModel3D, string p_sFilePath) { try { ReadTexture(p_sFilePath); // using ( cannot be used cause we open file stream once again StreamReader FileStream = File.OpenText(p_sFilePath); { bool foundTocken = FindTockenInFile("Coordinate", FileStream); if (!foundTocken) { FileStream = File.OpenText(p_sFilePath); foundTocken = FindTockenInFile("Coordinate3", FileStream); if (!foundTocken) { throw new Exception("Wrong file format, cannot find 'Coordinate' tocken"); } } bool finishReading = false; String line; int pointNO = 0; while ((line = FileStream.ReadLine()) != null && !finishReading) { if (line.Contains("point")) { continue; } string[] parts = line.Split(' '); for (int i = 0; i < parts.Length; i++) { if (parts[i].Contains("]")) { finishReading = true; break; } } if (finishReading) { break; } List <string> numbers = new List <string>(); foreach (string s in parts) { if (s.Equals("")) { continue; } else { numbers.Add(s); } } if (numbers.Count != 3) { throw new Exception("Wrong file format, less coordinates than expected"); } float X = Single.Parse(numbers[0].Replace(',', ' '), System.Globalization.CultureInfo.InvariantCulture); float Y = Single.Parse(numbers[1].Replace(',', ' '), System.Globalization.CultureInfo.InvariantCulture); float Z = Single.Parse(numbers[2].Replace(',', ' '), System.Globalization.CultureInfo.InvariantCulture); Cl3DModel.Cl3DModelPointIterator newPoint = p_mModel3D.AddPointToModel(X, Y, Z); if (texture != null && TextureCoord.Count != 0) { newPoint.Color = texture.GetPixel((int)(TextureCoord[pointNO].no1 * texture.Width), (int)(TextureCoord[pointNO].no2 * texture.Height)); newPoint.AddSpecificValue("Texture", newPoint.Color.ToArgb()); } pointNO++; } foundTocken = FindTockenInFile("coordIndex", FileStream); if (!foundTocken) { throw new Exception("Wrong file format, cannot find 'coordIndex' tocken"); } while ((line = FileStream.ReadLine()) != null) { if (line.Contains("]")) { break; } List <Cl3DModel.Cl3DModelPointIterator> points = new List <Cl3DModel.Cl3DModelPointIterator>(); Cl3DModel.Cl3DModelPointIterator iter = p_mModel3D.GetIterator(); string[] parts = line.Split(new Char [] { ' ', ',' }); bool EndOfLine = false; foreach (string part in parts) { if (part.Length == 0) { continue; } int no = Int32.Parse(part); if (no == -1) { EndOfLine = true; } if (EndOfLine) { for (int i = 0; i < points.Count; i++) { if (i == points.Count - 2) { points[i].AddNeighbor(points[i + 1]); points[i + 1].AddNeighbor(points[0]); break; } if (i == points.Count - 3) { points[i].AddNeighbor(points[i + 1]); points[i + 1].AddNeighbor(points[i + 2]); points[i + 2].AddNeighbor(points[i]); } else { points[i].AddNeighbor(points[i + 1]); points[i + 1].AddNeighbor(points[i + 2]); points[i + 2].AddNeighbor(points[i]); } } points.Clear(); EndOfLine = false; } else { if (!iter.MoveToPoint((uint)no)) { throw new Exception("Cannot find point no: " + no); } points.Add(iter.CopyIterator()); } } } } } catch (Exception) { p_mModel3D.ResetModel(); throw; } }