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>(); } }
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(); uint current = 0; string NeighborhoodSize = m_fNeighborhoodSize.ToString(); if (m_bFirstNeighbor) { NeighborhoodSize = "1Neighb"; } string ShapeIndexString = "ShapeIndex_" + NeighborhoodSize; if (iter.IsValid()) { do { double A = 0; double B = 0; double C = 0; double D = 0; double E = 0; double F = 0; double H = 0; double K = 0; double k1 = 0; double k2 = 0; double ShapeIndex = 0; double CurvednessIndex = 0; List <Cl3DModel.Cl3DModelPointIterator> ListOfneighborhood; double dx; double dy; double dxy; double dxx; double dyy; //------------------------- Neighborhood Custom -------------------------------------------------- if (!iter.IsSpecificValueCalculated(ShapeIndexString) || m_bRecalculateCurvature) { if (!m_bFirstNeighbor) { ClTools.GetNeighborhoodWithGeodesicDistance(out ListOfneighborhood, iter, m_fNeighborhoodSize); } else { ListOfneighborhood = iter.GetListOfNeighbors(); } if (m_bNeighborhoodRotation) { Matrix Rotation = ClTools.CalculateRotationMatrix(iter.NormalVector, new Vector(new double[] { iter.NormalVector[0], iter.NormalVector[1], 1 })); List <ClTools.MainPoint3D> Neighbors = new List <ClTools.MainPoint3D>(); foreach (Cl3DModel.Cl3DModelPointIterator Neighb in ListOfneighborhood) { Matrix after = Rotation * Neighb; Neighbors.Add(new ClTools.MainPoint3D((float)after[0, 0], (float)after[1, 0], (float)after[2, 0], "")); } if (!ClTools.CountSurfaceCoefficients(Neighbors, ref A, ref B, ref C, ref D, ref E, ref F)) { iter.RemoveSpecificValue("Gaussian_" + NeighborhoodSize); iter.RemoveSpecificValue("Mean_" + NeighborhoodSize); iter.RemoveSpecificValue("K1_" + NeighborhoodSize); iter.RemoveSpecificValue("K2_" + NeighborhoodSize); iter.RemoveSpecificValue("ShapeIndex_" + NeighborhoodSize); iter.RemoveSpecificValue("CurvednessIndex_" + NeighborhoodSize); continue; } } else { if (!ClTools.CountSurfaceCoefficients(ListOfneighborhood, ref A, ref B, ref C, ref D, ref E, ref F)) { iter.RemoveSpecificValue("Gaussian_" + NeighborhoodSize); iter.RemoveSpecificValue("Mean_" + NeighborhoodSize); iter.RemoveSpecificValue("K1_" + NeighborhoodSize); iter.RemoveSpecificValue("K2_" + NeighborhoodSize); iter.RemoveSpecificValue("ShapeIndex_" + NeighborhoodSize); iter.RemoveSpecificValue("CurvednessIndex_" + NeighborhoodSize); continue; } } dx = B + 2 * D * iter.X + E * iter.Y; dy = C + E * iter.X + 2 * F * iter.Y; dxy = E; dxx = 2 * D; dyy = 2 * F; //Mean H = ((((1 + Math.Pow(dy, 2)) * dxx) - (2 * dx * dy * dxy) + ((1 + Math.Pow(dx, 2)) * dyy)) / (2 * Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 3.0d / 2.0d))); //Gaussian K = (((dxx * dyy) - Math.Pow(dxy, 2)) / Math.Pow((1 + Math.Pow(dx, 2) + Math.Pow(dy, 2)), 2)); k1 = H + Math.Sqrt(Math.Pow(H, 2) - K); k2 = H - Math.Sqrt(Math.Pow(H, 2) - K); ShapeIndex = 0.5d - (1 / Math.PI) * Math.Atan((k1 + k2) / (k1 - k2)); CurvednessIndex = Math.Sqrt(Math.Pow(k1, 2) + Math.Pow(k2, 2)) / 2; iter.AddSpecificValue("Gaussian_" + NeighborhoodSize, K); iter.AddSpecificValue("Mean_" + NeighborhoodSize, H); iter.AddSpecificValue("K1_" + NeighborhoodSize, k1); iter.AddSpecificValue("K2_" + NeighborhoodSize, k2); iter.AddSpecificValue("ShapeIndex_" + NeighborhoodSize, ShapeIndex); iter.AddSpecificValue("CurvednessIndex_" + NeighborhoodSize, CurvednessIndex); } ClInformationSender.SendInformation((current * 100 / p_Model.ModelPointsCount).ToString(System.Globalization.CultureInfo.InvariantCulture), ClInformationSender.eInformationType.eProgress); current++; } while (iter.MoveToNext()); } }
protected override void Algorithm(ref Cl3DModel p_Model) { // 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); */ //--------------------------------------------------------------------------- }