public void Reset() { VertexValue = 0; Vertices.Clear(); Edges.Clear(); Faces.Clear(); }
protected virtual void UpdatePoints() { double x = Width / 2; double z = Length / 2; List <Point3D> points = new List <Point3D>(); points.Add(new Point3D(-x, 0, -z)); // bottom points.Add(new Point3D(-x, 0, z)); points.Add(new Point3D(x, 0, 0)); points.Add(new Point3D(x, 0, 0)); points.Add(new Point3D(-x, Height, -z)); // top points.Add(new Point3D(-x, Height, z)); points.Add(new Point3D(x, Height, 0)); points.Add(new Point3D(x, Height, 0)); Faces.Clear(); Faces.Add(new Face(new Point3D[] { points[7], points[4], points[0] })); Faces.Add(new Face(new Point3D[] { points[0], points[3], points[7] })); Faces.Add(new Face(new Point3D[] { points[6], points[7], points[3] })); Faces.Add(new Face(new Point3D[] { points[2], points[6], points[3] })); Faces.Add(new Face(new Point3D[] { points[5], points[6], points[2] })); Faces.Add(new Face(new Point3D[] { points[1], points[5], points[2] })); Faces.Add(new Face(new Point3D[] { points[4], points[5], points[1] })); Faces.Add(new Face(new Point3D[] { points[0], points[4], points[1] })); Faces.Add(new Face(new Point3D[] { points[2], points[3], points[0] })); Faces.Add(new Face(new Point3D[] { points[1], points[2], points[0] })); Faces.Add(new Face(new Point3D[] { points[6], points[4], points[7] })); Faces.Add(new Face(new Point3D[] { points[6], points[5], points[4] })); // итого 12 = 6х2 faces на box }
private void UpdatePoints() { double x = Width / 2; double z = Length / 2; List <Point3D> points = new List <Point3D>(); points.Add(new Point3D(-x, 0, -z)); points.Add(new Point3D(-x, 0, z)); points.Add(new Point3D(x, 0, z)); points.Add(new Point3D(x, 0, -z)); points.Add(new Point3D(-x, Height, -z)); points.Add(new Point3D(-x, Height, z)); points.Add(new Point3D(x, Height, z)); points.Add(new Point3D(x, Height, -z)); Faces.Clear(); Faces.Add(new Face(new Point3D[] { points[7], points[4], points[0] })); Faces.Add(new Face(new Point3D[] { points[0], points[3], points[7] })); Faces.Add(new Face(new Point3D[] { points[6], points[7], points[3] })); Faces.Add(new Face(new Point3D[] { points[2], points[6], points[3] })); Faces.Add(new Face(new Point3D[] { points[5], points[6], points[2] })); Faces.Add(new Face(new Point3D[] { points[1], points[5], points[2] })); Faces.Add(new Face(new Point3D[] { points[4], points[5], points[1] })); Faces.Add(new Face(new Point3D[] { points[0], points[4], points[1] })); Faces.Add(new Face(new Point3D[] { points[2], points[3], points[0] })); Faces.Add(new Face(new Point3D[] { points[1], points[2], points[0] })); Faces.Add(new Face(new Point3D[] { points[6], points[4], points[7] })); Faces.Add(new Face(new Point3D[] { points[6], points[5], points[4] })); }
public void Clear() { Vertices.Clear(); HalfEdges.Clear(); Faces.Clear(); UnboundedFace = null; }
public void Reload(Shape shape, Mesh mesh) { //Load indices into the group var indices = mesh.GetIndices().ToArray(); Faces.Clear(); for (int i = 0; i < indices.Length; i++) { Faces.Add(indices[i]); } if (!PrimitiveTypes.ContainsKey(mesh.PrimitiveType)) { throw new Exception($"Unsupported primitive type! {mesh.PrimitiveType}"); } //Set the primitive type PrimitiveType = PrimitiveTypes[mesh.PrimitiveType];; switch (Stride) { case 2: DrawElementsType = DrawElementsType.UnsignedShort; break; case 4: DrawElementsType = DrawElementsType.UnsignedInt; break; case 1: DrawElementsType = DrawElementsType.UnsignedByte; break; } }
private void UpdatePoints() { int quater = Math.Max(SegmentsCount / 4 - 1, 1); double angle = 360.0 / SegmentsCount; double sin = Math.Sin(MathHelp.DegreesToRadians(-angle)); double cos = Math.Cos(MathHelp.DegreesToRadians(-angle)); Point3D[,] points = new Point3D[quater, SegmentsCount + 1]; points[0, 0] = new Point3D(-Radius, 0, 0); for (int i = 1; i < quater; ++i) { double x = points[i - 1, 0].X * cos - points[i - 1, 0].Y * sin; double y = points[i - 1, 0].X * sin + points[i - 1, 0].Y * cos; points[i, 0] = new Point3D(x, y, 0); } Faces.Clear(); for (int i = 1; i <= SegmentsCount; ++i) { for (int j = 0; j < quater; ++j) { double x = points[j, i - 1].X * cos - points[j, i - 1].Z * sin; double z = points[j, i - 1].X * sin + points[j, i - 1].Z * cos; points[j, i] = new Point3D(x, points[j, i - 1].Y, z); if (i > 0) { if (j > 0) { Faces.Add(new Face(new Point3D[] { new Point3D(points[j - 1, i - 1].X, points[j - 1, i - 1].Y, points[j - 1, i - 1].Z), new Point3D(points[j - 1, i].X, points[j - 1, i].Y, points[j - 1, i].Z), new Point3D(points[j, i - 1].X, points[j, i - 1].Y, points[j, i - 1].Z) })); Faces.Add(new Face(new Point3D[] { new Point3D(points[j, i - 1].X, points[j, i - 1].Y, points[j, i - 1].Z), new Point3D(points[j, i].X, points[j, i].Y, points[j, i].Z), new Point3D(points[j - 1, i].X, points[j - 1, i].Y, points[j - 1, i].Z) })); } else if (closeBottom) { Faces.Add(new Face(new Point3D[] { new Point3D(points[j, i - 1].X, points[j, i - 1].Y, points[j, i - 1].Z), new Point3D(points[j, i].X, points[j, i].Y, points[j, i].Z), new Point3D(0, 0, 0) })); } if (j == quater - 1) { Faces.Add(new Face(new Point3D[] { new Point3D(points[j, i - 1].X, points[j, i - 1].Y, points[j, i - 1].Z), new Point3D(points[j, i].X, points[j, i].Y, points[j, i].Z), new Point3D(0, Radius, 0) })); } } } } }
public void Clear() { Faces.Clear(); _lazyExitedEdges.isValeChanged = true; _lazyAllEdges.isValeChanged = true; _lazyAllPoints.isValeChanged = true; }
public Mesh(List <Vector3Float> v, FaceList f) { Vertices.Clear(); Vertices.AddRange(v); Faces.Clear(); Faces.AddRange(f); }
public void Clear() { Faces.Clear(); Points.Clear(); Edges.Clear(); CachedPoints.Clear(); CachedEdgePoints.Clear(); m_CurrId = 0; }
/// <summary> /// Creates a model of the tetrahedron. Transparency is applied to the color. /// </summary> /// <param name="color"></param> /// <param name="radius"></param> /// <returns>A model representing the tetrahedron</returns> public override void CreateFaces(Mesh mesh) { var points = new Point3DCollection(Enumerable.Range(0, 4).Select(i => GetPosition(i, mesh))); Faces.Clear(); Faces.Add(new Triangle(points[0].ToLocationTimeValue(), points[1].ToLocationTimeValue(), points[2].ToLocationTimeValue())); Faces.Add(new Triangle(points[0].ToLocationTimeValue(), points[1].ToLocationTimeValue(), points[3].ToLocationTimeValue())); Faces.Add(new Triangle(points[0].ToLocationTimeValue(), points[2].ToLocationTimeValue(), points[3].ToLocationTimeValue())); Faces.Add(new Triangle(points[1].ToLocationTimeValue(), points[2].ToLocationTimeValue(), points[3].ToLocationTimeValue())); }
/// <summary> /// Incrementally update the existing hull using provided points. /// </summary> /// <param name="points">Points used to update the hull.</param> public void Update(IList <Vector3> points) { var visible = new VisibleFaces(); var working_set = new LinkedList <Face>(Faces); var final_set = new LinkedList <Face>(); sort_points(points, Faces); Faces.Clear(); while (working_set.Count > 0) { Face f = working_set.Pop(); //if the face was dropped, skip it if (f.Dropped) { continue; } //if the face has no visible points it belongs to the hull if (f.VisiblePoints.Count == 0) { final_set.AddFirst(f); continue; } //if not, build the visible set of faces and the horizon for the furthest visible point visible.Clear(); build_horizon(f.Furthest, visible, f); //create new faces var new_faces = make_pyramid(f.Furthest, visible.Horizon); //add points from visible faces to the new faces for (int i = 0; i < visible.Count; i++) { sort_points(visible[i].VisiblePoints, new_faces); } //add new faces to the working set for (int i = 0; i < new_faces.Count; i++) { working_set.AddFirst(new_faces[i]); } } //filter out faces that are still visible Faces.AddRange(from f in final_set where !f.Dropped select f); //build a list of unique hull points Volume = Area = 0; var _Points = new HashSet <Vector3>(); for (int i = 0; i < Faces.Count; i++) { var f = Faces[i]; float area; Volume += f.Volume(out area); Area += area; _Points.Add(f.v0); _Points.Add(f.v1); _Points.Add(f.v2); } Points = new List <Vector3>(_Points.Count); Points.AddRange(_Points); }
/// <summary> /// Creates a model of the hexahedron /// </summary> /// <param name="color"></param> /// <param name="radius"></param> /// <returns>A model representing the tetrahedron</returns> public override void CreateFaces(Mesh mesh) { LocationTimeValue[] vert = GetVertices(mesh); int xMinIndex = vert.Min(x => x.MeshIndex[0]); int xMaxIndex = vert.Max(x => x.MeshIndex[0]); int yMinIndex = vert.Min(x => x.MeshIndex[1]); int yMaxIndex = vert.Max(x => x.MeshIndex[1]); int zMinIndex = vert.Min(x => x.MeshIndex[2]); int zMaxIndex = vert.Max(x => x.MeshIndex[2]); LocationTimeValue[] XZFrontFaceVertices = vert.Where(x => x.MeshIndex[1] == yMinIndex).ToArray(); LocationTimeValue[] XZBackFaceVertices = vert.Where(x => x.MeshIndex[1] == yMaxIndex).ToArray(); LocationTimeValue[] YZFrontFaceVertices = vert.Where(x => x.MeshIndex[0] == xMinIndex).ToArray(); LocationTimeValue[] YZBackFaceVertices = vert.Where(x => x.MeshIndex[0] == xMaxIndex).ToArray(); LocationTimeValue[] XYFrontFaceVertices = vert.Where(x => x.MeshIndex[2] == zMinIndex).ToArray(); LocationTimeValue[] XYBackFaceVertices = vert.Where(x => x.MeshIndex[2] == zMaxIndex).ToArray(); Faces.Clear(); Faces.Add(new Quadrilateral(XZFrontFaceVertices[0], XZFrontFaceVertices[1], XZFrontFaceVertices[3], XZFrontFaceVertices[2]) { FaceType = FaceType.Quadrilateral }); Faces.Add(new Quadrilateral(XZBackFaceVertices[0], XZBackFaceVertices[1], XZBackFaceVertices[3], XZBackFaceVertices[2]) { FaceType = FaceType.Quadrilateral }); Faces.Add(new Quadrilateral(YZFrontFaceVertices[0], YZFrontFaceVertices[1], YZFrontFaceVertices[2], YZFrontFaceVertices[3]) { FaceType = FaceType.Quadrilateral }); Faces.Add(new Quadrilateral(YZBackFaceVertices[0], YZBackFaceVertices[1], YZBackFaceVertices[2], YZBackFaceVertices[3]) { FaceType = FaceType.Quadrilateral }); Faces.Add(new Quadrilateral(XYFrontFaceVertices[0], XYFrontFaceVertices[1], XYFrontFaceVertices[3], XYFrontFaceVertices[2]) { FaceType = FaceType.Quadrilateral }); Faces.Add(new Quadrilateral(XYBackFaceVertices[0], XYBackFaceVertices[1], XYBackFaceVertices[3], XYBackFaceVertices[2]) { FaceType = FaceType.Quadrilateral }); }
public override void Paste(MapObject o, IDGenerator generator) { PasteBase(o, generator); var e = o as Solid; if (e == null) { return; } Faces.Clear(); foreach (var f in e.Faces.Select(x => x.Copy(generator))) { f.Parent = this; Faces.Add(f); f.UpdateBoundingBox(); } }
public override void Unclone(MapObject o) { PasteBase(o, null, true); var e = o as Solid; if (e == null) { return; } Faces.Clear(); foreach (var f in e.Faces.Select(x => x.Clone())) { f.Parent = this; Faces.Add(f); f.UpdateBoundingBox(); } UpdateBoundingBox(); }
public List <Triangle> FindTrianglesInBox(Vector3 pMin, Vector3 pMax) { var faceInBox = new List <Triangle>(); var faceNotInBox = new List <Triangle>(); foreach (var face in Faces) { if (face.IsTriangleInBox(pMin, pMax)) { faceInBox.Add(face); } else { faceNotInBox.Add(face); } } Faces.Clear(); Faces.AddRange(faceNotInBox); return(faceInBox); }
private void UpdatePoints() { double angle = 360.0 / SegmentsCount; double sin = Math.Sin(MathHelpers.FromDegreesToRadians(angle)); double cos = Math.Cos(MathHelpers.FromDegreesToRadians(angle)); Point3D[] points = new Point3D[SegmentsCount + 1]; points[0] = new Point3D(-Radius, 0, 0); Faces.Clear(); for (int i = 1; i <= SegmentsCount; ++i) { double x = points[i - 1].X * cos - points[i - 1].Z * sin; double z = points[i - 1].X * sin + points[i - 1].Z * cos; points[i] = new Point3D(x, 0, z); if (i > 0) { Faces.Add(new Face(new Point3D[] { new Point3D(points[i - 1].X, 0, points[i - 1].Z), new Point3D(points[i].X, 0, points[i].Z), new Point3D(0, 0, 0) })); Faces.Add(new Face(new Point3D[] { new Point3D(points[i - 1].X, Height, points[i - 1].Z), new Point3D(points[i].X, Height, points[i].Z), new Point3D(0, Height, 0) })); Faces.Add(new Face(new Point3D[] { new Point3D(points[i - 1].X, Height, points[i - 1].Z), new Point3D(points[i].X, Height, points[i].Z), new Point3D(points[i - 1].X, 0, points[i - 1].Z) })); Faces.Add(new Face(new Point3D[] { new Point3D(points[i - 1].X, 0, points[i - 1].Z), new Point3D(points[i].X, 0, points[i].Z), new Point3D(points[i].X, Height, points[i].Z) })); } } }
private void Rebuild() { Faces.Clear(); Vertices.Clear(); HollowCylinderBuilder.Build(Radius, Height, SegmentAngle, this); }
private void SetFaces() { Point3d p1 = Point3d.Origin; Point3d p2 = Point3d.Origin; Point3d p3 = Point3d.Origin; Point3d p4 = Point3d.Origin; Point3d p5 = Point3d.Origin; Point3d p6 = Point3d.Origin; Point3d p7 = Point3d.Origin; Point3d p8 = Point3d.Origin; if (!this.MachinePoint.IsRotated) { p1 = new Point3d(0, 0, 0); p2 = new Point3d(0, 0, Thickness); p3 = new Point3d(0, Width, 0); p4 = new Point3d(0, Width, Thickness); p5 = new Point3d(Length, Width, 0); p6 = new Point3d(Length, Width, Thickness); p7 = new Point3d(Length, 0, 0); p8 = new Point3d(Length, 0, Thickness); } else { p1 = new Point3d(0, 0, 0); p2 = new Point3d(0, 0, Thickness); p3 = new Point3d(0, Length, 0); p4 = new Point3d(0, Length, Thickness); p5 = new Point3d(Width, Length, 0); p6 = new Point3d(Width, Length, Thickness); p7 = new Point3d(Width, 0, 0); p8 = new Point3d(Width, 0, Thickness); } //将p1-p8从MP坐标系转换成为世界坐标系下的坐标 p1 = p1.TransformBy(Matrix3d.AlignCoordinateSystem(new Point3d(), Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, MPPoint, MPXAxis, MPYAxis, MPZAxis)); p2 = p2.TransformBy(Matrix3d.AlignCoordinateSystem(new Point3d(), Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, MPPoint, MPXAxis, MPYAxis, MPZAxis)); p3 = p3.TransformBy(Matrix3d.AlignCoordinateSystem(new Point3d(), Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, MPPoint, MPXAxis, MPYAxis, MPZAxis)); p4 = p4.TransformBy(Matrix3d.AlignCoordinateSystem(new Point3d(), Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, MPPoint, MPXAxis, MPYAxis, MPZAxis)); p5 = p5.TransformBy(Matrix3d.AlignCoordinateSystem(new Point3d(), Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, MPPoint, MPXAxis, MPYAxis, MPZAxis)); p6 = p6.TransformBy(Matrix3d.AlignCoordinateSystem(new Point3d(), Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, MPPoint, MPXAxis, MPYAxis, MPZAxis)); p7 = p7.TransformBy(Matrix3d.AlignCoordinateSystem(new Point3d(), Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, MPPoint, MPXAxis, MPYAxis, MPZAxis)); p8 = p8.TransformBy(Matrix3d.AlignCoordinateSystem(new Point3d(), Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, MPPoint, MPXAxis, MPYAxis, MPZAxis)); p1 = MathHelper.GetRotatedAndMovedPoint(p1, TXRotation, TYRotation, TZRotation, CenterVector); p2 = MathHelper.GetRotatedAndMovedPoint(p2, TXRotation, TYRotation, TZRotation, CenterVector); p3 = MathHelper.GetRotatedAndMovedPoint(p3, TXRotation, TYRotation, TZRotation, CenterVector); p4 = MathHelper.GetRotatedAndMovedPoint(p4, TXRotation, TYRotation, TZRotation, CenterVector); p5 = MathHelper.GetRotatedAndMovedPoint(p5, TXRotation, TYRotation, TZRotation, CenterVector); p6 = MathHelper.GetRotatedAndMovedPoint(p6, TXRotation, TYRotation, TZRotation, CenterVector); p7 = MathHelper.GetRotatedAndMovedPoint(p7, TXRotation, TYRotation, TZRotation, CenterVector); p8 = MathHelper.GetRotatedAndMovedPoint(p8, TXRotation, TYRotation, TZRotation, CenterVector); //注意这些点的顺序,按顺时针或逆时针,不要乱序 FaceOne = new PartFace(p1, p2, p8, p7, 1, this); FaceTwo = new PartFace(p3, p4, p6, p5, 2, this); FaceThree = new PartFace(p1, p2, p4, p3, 3, this); FaceFour = new PartFace(p5, p6, p8, p7, 4, this); FaceFive = new PartFace(p1, p3, p5, p7, 5, this); FaceSix = new PartFace(p2, p4, p6, p8, 6, this); Faces.Clear(); Faces.Add(FaceOne); Faces.Add(FaceTwo); Faces.Add(FaceThree); Faces.Add(FaceFour); Faces.Add(FaceFive); Faces.Add(FaceSix); }
private void Load(string path) { var numberRegex = new Regex(@"-?[\d]+(?:\.[\d]*)?(e[-|+]?\d+)?", RegexOptions.IgnoreCase); var faceRegex = new Regex(@"(\d+)/([\d]*)/([\d]*)", RegexOptions.IgnoreCase); Vertices.Clear(); Normals.Clear(); Textures.Clear(); Faces.Clear(); foreach (var line in File.ReadLines(path).Where(line => numberRegex.IsMatch(line))) { var matches = numberRegex.Matches(line); if (line.StartsWith("v ")) { if (matches.Count != 3) { throw new FileLoadException("Error parsing vertices."); } Vertices.Add( new Vector4 { X = float.Parse(matches[0].Value), Y = float.Parse(matches[1].Value), Z = float.Parse(matches[2].Value), W = 1f }); } else if (line.StartsWith("vt ")) { if (matches.Count != 2) { throw new FileLoadException("Error parsing textures."); } Textures.Add( new Vector2 { X = float.Parse(matches[0].Value), Y = float.Parse(matches[1].Value) }); } else if (line.StartsWith("vn ")) { if (matches.Count != 3) { throw new FileLoadException("Error parsing normals."); } Normals.Add( Vector3.Normalize(new Vector3 { X = float.Parse(matches[0].Value), Y = float.Parse(matches[1].Value), Z = float.Parse(matches[2].Value) })); } else if (line.StartsWith("f ")) { matches = faceRegex.Matches(line); if (matches.Count != 4) { throw new FileLoadException("Error parsing faces."); } var face = new Face(); foreach (var i in Enumerable.Range(0, 4)) { var point = new Point { PositionIndex = int.Parse(matches[i].Groups[1].Value) - 1, TextureIndex = matches[i].Groups[2].Value == String.Empty ? 0 : int.Parse(matches[i].Groups[2].Value) - 1, NormalIndex = int.Parse(matches[i].Groups[3].Value) - 1 }; face.Points.Add(point); _pointIndexLookUp[point] = (uint)(Faces.Count * 4 + i); } Faces.Add(face); var patch = new AccPatch { Points = new List <Point>(face.Points), Prefixes = new List <int>(), Valences = new List <int>() }; foreach (var point in face.Points) { if (_pointNeighborLookUp.ContainsKey(point.PositionIndex)) { _pointNeighborLookUp[point.PositionIndex].Add(patch); } else { _pointNeighborLookUp[point.PositionIndex] = new List <AccPatch> { patch } }; } AccPatches.Add(patch); } } }
void Timer_Tick(object sender, EventArgs e) { //Тестить, фиксить try { CurrentFrame = Capture.QueryFrame().ToImage <Bgr, Byte>(); } catch (Exception) { try { Thread.Sleep(100); Capture = new VideoCapture(CameraIndex); } catch (Exception) { CameraDisconected.Visibility = Visibility.Visible; StartStopButton_Click(null, null); } return; } string reportLog = "", log = String.Format("{0} - {1}: ", DateTime.Now.ToString(), CameraName.Content); Image <Bgr, Byte> image = CurrentFrame.Copy(); using (UMat ugray = new UMat()) { CvInvoke.CvtColor(image, ugray, ColorConversion.Bgr2Gray); CvInvoke.EqualizeHist(ugray, ugray); Faces.Clear(); Faces = new List <System.Drawing.Rectangle>(); Faces.AddRange(MainWindow.HaarCascade.DetectMultiScale(ugray, 1.1, 10, new System.Drawing.Size(20, 20))); int recognizeCount = 0; foreach (var face in Faces) { image.Draw(face, new Bgr(0, 0, 255), 3); if (MainWindow.PeopleData.Face.Count() != 0) { var result = MainWindow.FaceRecognizer.Predict(ugray.ToImage <Gray, Byte>().Copy(face).Resize(100, 100, Inter.Cubic)); if (result.Label > 0 && result.Distance <= 100) { recognizeCount++; string name = MainWindow.PeopleData.Name[result.Label - 1]; image.Draw(100 - (int)result.Distance + " " + name, new System.Drawing.Point(face.X, face.Y - 10), FontFace.HersheyComplex, 0.8, new Bgr(0, 0, 255)); reportLog += name + "; "; } } } int unknownFaces = Faces.Count() - recognizeCount; if (unknownFaces > 0) { reportLog += unknownFaces + " неизвестных"; } else if (reportLog == "") { reportLog = " ---"; } if (reportLog != prevReportLog) { MainWindow.Logs.Add(log + reportLog); } prevReportLog = reportLog; } VideoStream.Source = Watcher.ToBitmapSource(image); RecognizeCount.Content = "(" + Faces.Count() + ")"; }
/// <summary> /// Pick folder, then group detected faces by similarity /// </summary> /// <param name="sender">Event sender</param> /// <param name="e">Event arguments</param> private async void Grouping_Click(object sender, RoutedEventArgs e) { // Show folder picker FolderBrowserDialog dlg = new FolderBrowserDialog(); var result = dlg.ShowDialog(); // Set the suggestion count is intent to minimum the data preparetion step only, // it's not corresponding to service side constraint const int SuggestionCount = 10; if (result == DialogResult.OK) { // User picked one folder List <Task> tasks = new List <Task>(); int processCount = 0; bool forceContinue = false; // Clear previous grouping result GroupedFaces.Clear(); Faces.Clear(); Output = Output.AppendLine("Request: Preparing faces for grouping, detecting faces in choosen folder."); foreach (var img in Directory.EnumerateFiles(dlg.SelectedPath, "*.jpg", SearchOption.AllDirectories)) { tasks.Add(Task.Factory.StartNew( async(obj) => { var imgPath = obj as string; // Detect faces in image using (var fStream = File.OpenRead(imgPath)) { try { var faces = await App.Instance.DetectAsync(fStream); return(new Tuple <string, ClientContract.Face[]>(imgPath, faces)); } catch (ClientException) { // Here we simply ignore all detection failure in this sample // You may handle these exceptions by check the Error.Code and Error.Message property for ClientException object return(new Tuple <string, ClientContract.Face[]>(imgPath, null)); } } }, img).Unwrap().ContinueWith((detectTask) => { // Update detected faces on UI var res = detectTask.Result; if (res.Item2 == null) { return; } foreach (var f in res.Item2) { this.Dispatcher.Invoke( new Action <ObservableCollection <Face>, string, ClientContract.Face>(UIHelper.UpdateFace), Faces, res.Item1, f); } })); if (processCount >= SuggestionCount && !forceContinue) { var continueProcess = System.Windows.Forms.MessageBox.Show("Found many images under choosen folder, may take long time if proceed. Continue?", "Warning", MessageBoxButtons.YesNo); if (continueProcess == DialogResult.Yes) { forceContinue = true; } else { break; } } } await Task.WhenAll(tasks); Output = Output.AppendLine(string.Format("Response: Success. Total {0} faces are detected.", Faces.Count)); try { Output = Output.AppendLine(string.Format("Request: Grouping {0} faces.", Faces.Count)); // Call grouping, the grouping result is a group collection, each group contains similar faces var groupRes = await App.Instance.GroupAsync(Faces.Select(f => Guid.Parse(f.FaceId)).ToArray()); // Update grouping results for rendering foreach (var g in groupRes.Groups) { var gg = new GroupingResult() { Faces = new ObservableCollection <Face>(), IsMessyGroup = false, }; foreach (var fr in g) { gg.Faces.Add(Faces.First(f => f.FaceId == fr.ToString())); } GroupedFaces.Add(gg); } // MessyGroup contains all faces which are not similar to any other faces. // Take an extreme case for exampe: // On grouping faces which are not similar to any other faces, the grouping result will contains only one messy group if (groupRes.MessyGroup.Length > 0) { var messyGroup = new GroupingResult() { Faces = new ObservableCollection <Face>(), IsMessyGroup = true }; foreach (var messy in groupRes.MessyGroup) { messyGroup.Faces.Add(Faces.First(f => f.FaceId == messy.ToString())); } GroupedFaces.Add(messyGroup); } Output = Output.AppendLine(string.Format("Response: Success. {0} faces are grouped into {1} groups.", Faces.Count, GroupedFaces.Count)); } catch (ClientException ex) { Output = Output.AppendLine(string.Format("Response: {0}. {1}", ex.Error.Code, ex.Error.Message)); } } }
// отрисовка по методу "нарисуй кучу колец, потом соедини точки" private void UpdatePoints() { // Я могу получать точки, как в основании цилиндра, затем идти вверх/вниз и добавлять эти круги. Потом пройтись по циклу и добавить faces между ними. // разбил радиус по кол-ву сементов, чтобы был понятен радиус колец int levelsCount = SegmentsCount / 2; // от среднего уровня, где R кольца = max R, до нижнего уровня, где R кольца = 0;. Где R кольца = 0, мы не считаем, потому что будем рисовать нижний уровень как треугольники. double maxR = Radius; double dh = maxR / levelsCount; // изменение высоты (т.е. Y) на каждом кольце. double[] tempRs = new double[levelsCount * 2]; // from 0 to R, (from R to 0 but R) // заполнение 1 половины for (var i = 0; i < tempRs.Length / 2; i++) // до radiuses.Length не доходит { // здесь k будет максимальная // k is удаленность хорды от радиуса double k = ((double)tempRs.Length / 2 - i); k *= dh; var r = GetHordaRadiusByHeight(maxR, k); tempRs[i] = r; } // заполнение 2 половины for (var i = tempRs.Length / 2; i < tempRs.Length; i++) { double k = i - tempRs.Length / 2; k *= dh; var r = GetHordaRadiusByHeight(maxR, k); tempRs[i] = r; } var radiuses = new List <double>(tempRs); radiuses.Add(0); // last 0. Без этого не катит( var pointsByLevels = new List <Point3D[]>(radiuses.Count); for (var i = 0; i < radiuses.Count; i++) { var r = radiuses[i]; //points on the level circle var ps = GetCirclePoints(r, SegmentsCount, i * dh); pointsByLevels.Add(ps); } // все, заполнили PointsByLevels, теперь триангулируем. Faces.Clear(); // вроде все ок, теперь надо нарисовать на бумажке эти level circles с соединить точки for (var j = 0; j < pointsByLevels.Count - 1; j++) // { var array1 = pointsByLevels[j]; var array2 = pointsByLevels[j + 1]; for (var i = 0; i < array1.Length - 1; i++) { Point3D p11, p12, p21, p22; p11 = array1[i]; p12 = array1[i + 1]; p21 = array2[i]; p22 = array2[i + 1]; Face f1, f2; f1 = new Face(p11, p12, p21); f2 = new Face(p21, p12, p22); Faces.Add(f1); Faces.Add(f2); } } }
/// <summary> /// Detector /// </summary> /// <param name="inputTexture">Input Unity texture</param> /// <param name="texParams">Texture parameters (flipped, rotated etc.)</param> /// <param name="detect">Flag signalling whether we need detection on this frame</param> public virtual void ProcessTexture(T texture, Unity.TextureConversionParams texParams, bool detect = true) { // convert Unity texture to OpenCv::Mat ImportTexture(texture, texParams); // detect if (detect) { double invF = 1.0 / appliedFactor; DataStabilizer.ThresholdFactor = invF; // convert to grayscale and normalize Mat gray = new Mat(); Cv2.CvtColor(processingImage, gray, ColorConversionCodes.BGR2GRAY); // fix shadows Cv2.EqualizeHist(gray, gray); /*Mat normalized = new Mat(); * CLAHE clahe = CLAHE.Create(); * clahe.TilesGridSize = new Size(8, 8); * clahe.Apply(gray, normalized); * gray = normalized;*/ // detect matching regions (faces bounding) Rect[] rawFaces = cascadeFaces.DetectMultiScale(gray, 1.2, 6); if (Faces.Count != rawFaces.Length) { Faces.Clear(); } // now per each detected face draw a marker and detect eyes inside the face rect int facesCount = 0; for (int i = 0; i < rawFaces.Length; ++i) { Rect faceRect = rawFaces[i]; Rect faceRectScaled = faceRect * invF; using (Mat grayFace = new Mat(gray, faceRect)) { // another trick: confirm the face with eye detector, will cut some false positives if (cutFalsePositivesWithEyesSearch && null != cascadeEyes) { Rect[] eyes = cascadeEyes.DetectMultiScale(grayFace); if (eyes.Length == 0 || eyes.Length > 2) { continue; } } // get face object DetectedFace face = null; if (Faces.Count < i + 1) { face = new DetectedFace(DataStabilizer, faceRectScaled); Faces.Add(face); } else { face = Faces[i]; face.SetRegion(faceRectScaled); } // shape facesCount++; if (null != shapeFaces) { Point[] marks = shapeFaces.DetectLandmarks(gray, faceRect); // we have 68-point predictor if (marks.Length == 68) { // transform landmarks to the original image space converted = new List <Point>(); foreach (Point pt in marks) { converted.Add(pt * invF); } // save and parse landmarks face.SetLandmarks(converted.ToArray()); } } } } // log //UnityEngine.Debug.Log(String.Format("Found {0} faces", Faces.Count)); } }
/// <summary> /// Pick folder, then group detected faces by similarity /// </summary> /// <param name="sender">Event sender</param> /// <param name="e">Event arguments</param> private async void Grouping_Click(object sender, RoutedEventArgs e) { // Show folder picker System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog(); var result = dlg.ShowDialog(); // Set the suggestion count is intent to minimum the data preparation step only, // it's not corresponding to service side constraint const int SuggestionCount = 10; if (result == System.Windows.Forms.DialogResult.OK) { // User picked one folder List <Task> tasks = new List <Task>(); int processCount = 0; bool forceContinue = false; // Clear previous grouping result GroupedFaces.Clear(); Faces.Clear(); MainWindow mainWindow = Window.GetWindow(this) as MainWindow; string subscriptionKey = mainWindow._scenariosControl.SubscriptionKey; string endpoint = mainWindow._scenariosControl.SubscriptionEndpoint; var faceServiceClient = new FaceServiceClient(subscriptionKey, endpoint); MainWindow.Log("Request: Preparing faces for grouping, detecting faces in chosen folder."); var imageList = new ConcurrentBag <string>( Directory.EnumerateFiles(dlg.SelectedPath, "*.*", SearchOption.AllDirectories) .Where(s => s.ToLower().EndsWith(".jpg") || s.ToLower().EndsWith(".png") || s.ToLower().EndsWith(".bmp") || s.ToLower().EndsWith(".gif"))); string img; while (imageList.TryTake(out img)) { tasks.Add(Task.Factory.StartNew( async(obj) => { var imgPath = obj as string; // Detect faces in image using (var fStream = File.OpenRead(imgPath)) { try { var faces = await faceServiceClient.DetectAsync(fStream); return(new Tuple <string, ClientContract.Face[]>(imgPath, faces)); } catch (FaceAPIException ex) { // if operation conflict, retry. if (ex.ErrorCode.Equals("ConcurrentOperationConflict")) { imageList.Add(imgPath); return(null); } // Here we simply ignore all detection failure in this sample // You may handle these exceptions by check the Error.Error.Code and Error.Message property for ClientException object return(new Tuple <string, ClientContract.Face[]>(imgPath, null)); } } }, img).Unwrap().ContinueWith((detectTask) => { // Update detected faces on UI var res = detectTask?.Result; if (res?.Item2 == null) { return; } foreach (var f in res.Item2) { this.Dispatcher.Invoke( new Action <ObservableCollection <Face>, string, ClientContract.Face>(UIHelper.UpdateFace), Faces, res.Item1, f); } })); if (processCount >= SuggestionCount && !forceContinue) { var continueProcess = System.Windows.Forms.MessageBox.Show("Found many images under chosen folder, may take long time if proceed. Continue?", "Warning", System.Windows.Forms.MessageBoxButtons.YesNo); if (continueProcess == System.Windows.Forms.DialogResult.Yes) { forceContinue = true; } else { break; } } if (tasks.Count >= _maxConcurrentProcesses || imageList.IsEmpty) { await Task.WhenAll(tasks); tasks.Clear(); } } MainWindow.Log("Response: Success. Total {0} faces are detected.", Faces.Count); try { MainWindow.Log("Request: Grouping {0} faces.", Faces.Count); // Call grouping, the grouping result is a group collection, each group contains similar faces var groupRes = await faceServiceClient.GroupAsync(Faces.Select(f => Guid.Parse(f.FaceId)).ToArray()); // Update grouping results for rendering foreach (var g in groupRes.Groups) { var gg = new GroupingResult() { Faces = new ObservableCollection <Face>(), IsMessyGroup = false, }; foreach (var fr in g) { gg.Faces.Add(Faces.First(f => f.FaceId == fr.ToString())); } GroupedFaces.Add(gg); } // MessyGroup contains all faces which are not similar to any other faces. // Take an extreme case for example: // On grouping faces which are not similar to any other faces, the grouping result will contains only one messy group if (groupRes.MessyGroup.Length > 0) { var messyGroup = new GroupingResult() { Faces = new ObservableCollection <Face>(), IsMessyGroup = true }; foreach (var messy in groupRes.MessyGroup) { messyGroup.Faces.Add(Faces.First(f => f.FaceId == messy.ToString())); } GroupedFaces.Add(messyGroup); } MainWindow.Log("Response: Success. {0} faces are grouped into {1} groups.", Faces.Count, GroupedFaces.Count); } catch (FaceAPIException ex) { MainWindow.Log("Response: {0}. {1}", ex.ErrorCode, ex.ErrorMessage); } } GC.Collect(); }
private void UpdatePoints() { double angle = 360.0 / SegmentsCount; double sin = Math.Sin(MathHelp.DegreesToRadians(angle)); double cos = Math.Cos(MathHelp.DegreesToRadians(angle)); Point3D[,,] points = new Point3D[2, 2, SegmentsCount + 1]; points[BOTTOM, INSIDE, 0] = new Point3D(-BottomRadius, 0, 0); points[BOTTOM, OUTSIDE, 0] = new Point3D(-(BottomRadius + Thickness), 0, 0); points[TOP, INSIDE, 0] = new Point3D(-TopRadius, Height, 0); points[TOP, OUTSIDE, 0] = new Point3D(-(TopRadius + Thickness), Height, 0); Faces.Clear(); for (int i = 1; i <= SegmentsCount; ++i) { double x = points[BOTTOM, INSIDE, i - 1].X * cos - points[BOTTOM, INSIDE, i - 1].Z * sin; double z = points[BOTTOM, INSIDE, i - 1].X * sin + points[BOTTOM, INSIDE, i - 1].Z * cos; points[BOTTOM, INSIDE, i] = new Point3D(x, 0, z); x = points[BOTTOM, OUTSIDE, i - 1].X * cos - points[BOTTOM, OUTSIDE, i - 1].Z * sin; z = points[BOTTOM, OUTSIDE, i - 1].X * sin + points[BOTTOM, OUTSIDE, i - 1].Z * cos; points[BOTTOM, OUTSIDE, i] = new Point3D(x, 0, z); x = points[TOP, INSIDE, i - 1].X * cos - points[TOP, INSIDE, i - 1].Z * sin; z = points[TOP, INSIDE, i - 1].X * sin + points[TOP, INSIDE, i - 1].Z * cos; points[TOP, INSIDE, i] = new Point3D(x, Height, z); x = points[TOP, OUTSIDE, i - 1].X * cos - points[TOP, OUTSIDE, i - 1].Z * sin; z = points[TOP, OUTSIDE, i - 1].X * sin + points[TOP, OUTSIDE, i - 1].Z * cos; points[TOP, OUTSIDE, i] = new Point3D(x, Height, z); if (i > 0) { Faces.Add(new Face(new Point3D[] { points[TOP, OUTSIDE, i - 1], points[TOP, OUTSIDE, i], points[BOTTOM, OUTSIDE, i - 1] })); Faces.Add(new Face(new Point3D[] { points[BOTTOM, OUTSIDE, i - 1], points[BOTTOM, OUTSIDE, i], points[TOP, OUTSIDE, i] })); Faces.Add(new Face(new Point3D[] { points[TOP, INSIDE, i - 1], points[TOP, INSIDE, i], points[BOTTOM, INSIDE, i - 1] })); Faces.Add(new Face(new Point3D[] { points[BOTTOM, INSIDE, i - 1], points[BOTTOM, INSIDE, i], points[TOP, INSIDE, i] })); Faces.Add(new Face(new Point3D[] { points[TOP, INSIDE, i - 1], points[TOP, INSIDE, i], points[TOP, OUTSIDE, i - 1] })); Faces.Add(new Face(new Point3D[] { points[TOP, OUTSIDE, i - 1], points[TOP, OUTSIDE, i], points[TOP, INSIDE, i] })); Faces.Add(new Face(new Point3D[] { points[BOTTOM, INSIDE, i - 1], points[BOTTOM, INSIDE, i], points[BOTTOM, OUTSIDE, i - 1] })); Faces.Add(new Face(new Point3D[] { points[BOTTOM, OUTSIDE, i - 1], points[BOTTOM, OUTSIDE, i], points[BOTTOM, INSIDE, i] })); } } }