public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var pointsObj = converter.Convert(values, targetType, parameter, culture); if (pointsObj != null) { PointCollection pc = (PointCollection)pointsObj; //finding left-top corner var left2 = pc.OrderBy(p => p.X).Take(2); Point lefttop = left2.OrderBy(p => p.Y).Take(1).Single(); //finding ridgt-top corner var right2 = pc.OrderByDescending(p => p.X).Take(2); Point rigthtop = right2.OrderBy(p => p.Y).Take(1).Single(); //finding left-bottom corner Point leftbottom = left2.OrderByDescending(p => p.Y).Take(1).Single(); //finding right-bottom corner Point rigthbottom = right2.OrderByDescending(p => p.Y).Take(1).Single(); Point p1, p4; //special case if ((lefttop.X < leftbottom.X) && (leftbottom.X < rigthtop.X) && (rigthtop.X < rigthbottom.X) && ((lefttop - rigthtop).LengthSquared < (rigthtop - rigthbottom).LengthSquared)) { p4 = rigthtop; p1 = rigthbottom; } else { if ((lefttop - rigthtop).LengthSquared < (lefttop - leftbottom).LengthSquared) { p4 = leftbottom; p1 = lefttop; } else { p4 = lefttop; p1 = rigthtop; } } TranslateTransform tt = new TranslateTransform(p4.X, p4.Y); double angle = 0.0; if (Math.Abs(p1.X - p4.X) < 1e-6) //close to vertical { if (p1.Y > p4.Y) { angle = 90.0; } else { angle = -90; } } else { angle = Math.Atan((p1.Y - p4.Y) / (p1.X - p4.X)) / Math.PI * 180.0; } RotateTransform rt = new RotateTransform(angle); TransformGroup tg = new TransformGroup(); tg.Children.Add(rt); tg.Children.Add(tt); return(tg); } else { return(null); } }
private async Task DetectAndShowComputerVisionAnalysis() { this.progressIndicator.IsActive = true; this.imageControl.RenderTransform = null; foreach (var child in this.hostGrid.Children.Where(c => !(c is Image)).ToArray()) { this.hostGrid.Children.Remove(child); } if (this.DataContext is ImageAnalyzer img) { List <Task> tasks = new List <Task>(); if (img.AnalysisResult == null) { tasks.Add(img.AnalyzeImageAsync(new List <Details> { Details.Celebrities, Details.Landmarks })); } if (this.PerformOCRAnalysis && (img.TextOperationResult == null || img.TextRecognitionMode != this.TextRecognitionMode)) { tasks.Add(img.RecognizeTextAsync(this.TextRecognitionMode)); } if (this.PerformObjectDetection && img.DetectedObjects == null) { tasks.Add(img.DetectObjectsAsync()); } await Task.WhenAll(tasks); double renderedImageXTransform = this.imageControl.RenderSize.Width / this.bitmapImage.PixelWidth; double renderedImageYTransform = this.imageControl.RenderSize.Height / this.bitmapImage.PixelHeight; if (img.AnalysisResult.Faces != null) { foreach (FaceDescription face in img.AnalysisResult.Faces) { FaceIdentificationBorder faceUI = new FaceIdentificationBorder { Margin = new Thickness((face.FaceRectangle.Left * renderedImageXTransform) + ((this.ActualWidth - this.imageControl.RenderSize.Width) / 2), (face.FaceRectangle.Top * renderedImageYTransform) + ((this.ActualHeight - this.imageControl.RenderSize.Height) / 2), 0, 0), BalloonBackground = this.BalloonBackground, BalloonForeground = this.BalloonForeground }; faceUI.ShowFaceRectangle(face.FaceRectangle.Width * renderedImageXTransform, face.FaceRectangle.Height * renderedImageYTransform); var faceGender = Util.GetFaceGender(face.Gender); faceUI.ShowIdentificationData(face.Age, faceGender, 0, null); this.hostGrid.Children.Add(faceUI); this.GetCelebrityInfoIfAvailable(img, face.FaceRectangle, out string celebRecoName, out double celebRecoConfidence); if (!string.IsNullOrEmpty(celebRecoName)) { Border celebUI = new Border { Child = new TextBlock { Text = string.Format("{0} ({1}%)", celebRecoName, (uint)Math.Round(celebRecoConfidence * 100)), Foreground = this.BalloonForeground, FontSize = 14 }, Background = this.BalloonBackground, VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left }; celebUI.SizeChanged += (ev, ar) => { celebUI.Margin = new Thickness(faceUI.Margin.Left - (celebUI.ActualWidth - face.FaceRectangle.Width * renderedImageXTransform) / 2, faceUI.Margin.Top + 2 + face.FaceRectangle.Height * renderedImageYTransform, 0, 0); }; this.hostGrid.Children.Add(celebUI); } } } // Clean up any old results foreach (var child in this.hostGrid.Children.Where(c => (c is OCRBorder)).ToArray()) { this.hostGrid.Children.Remove(child); } // OCR request (Printed / Handwritten) if (this.PerformOCRAnalysis && img.TextOperationResult?.RecognitionResult?.Lines != null) { this.imageControl.RenderTransform = new RotateTransform { Angle = 0, CenterX = this.imageControl.RenderSize.Width / 2, CenterY = this.imageControl.RenderSize.Height / 2 }; foreach (Line line in img.TextOperationResult.RecognitionResult.Lines) { foreach (var word in line.Words) { double[] boundingBox = word?.BoundingBox?.ToArray() ?? new double[] { }; if (boundingBox.Length == 8) { double minLeft = renderedImageXTransform * (new List <double>() { boundingBox[0], boundingBox[2], boundingBox[4], boundingBox[6] }).Min(); double minTop = renderedImageYTransform * (new List <double>() { boundingBox[1], boundingBox[3], boundingBox[5], boundingBox[7] }).Min(); var points = new PointCollection() { new Windows.Foundation.Point(boundingBox[0] * renderedImageXTransform - minLeft, boundingBox[1] * renderedImageYTransform - minTop), new Windows.Foundation.Point(boundingBox[2] * renderedImageXTransform - minLeft, boundingBox[3] * renderedImageYTransform - minTop), new Windows.Foundation.Point(boundingBox[4] * renderedImageXTransform - minLeft, boundingBox[5] * renderedImageYTransform - minTop), new Windows.Foundation.Point(boundingBox[6] * renderedImageXTransform - minLeft, boundingBox[7] * renderedImageYTransform - minTop) }; // The four points (x-coordinate, y-coordinate) of the detected rectangle from the left-top corner and clockwise IEnumerable <Windows.Foundation.Point> leftPoints = points.OrderBy(p => p.X).Take(2); IEnumerable <Windows.Foundation.Point> rightPoints = points.OrderByDescending(p => p.X).Take(2); Windows.Foundation.Point leftTop = leftPoints.OrderBy(p => p.Y).FirstOrDefault(); Windows.Foundation.Point leftBottom = leftPoints.OrderByDescending(p => p.Y).FirstOrDefault(); Windows.Foundation.Point rightTop = rightPoints.OrderBy(p => p.Y).FirstOrDefault(); Windows.Foundation.Point rightBottom = rightPoints.OrderByDescending(p => p.Y).FirstOrDefault(); var orderedPoints = new PointCollection() { leftTop, rightTop, rightBottom, leftBottom }; // simple math to get angle of the text double diffWidth = Math.Abs(leftTop.X - rightTop.X); double diffHeight = Math.Abs(leftTop.Y - rightTop.Y); double sign = leftTop.Y > rightTop.Y ? -1 : 1; double angle = sign * Math.Atan2(diffHeight, diffWidth) * (180 / Math.PI); // angle in degrees OCRBorder ocrUI = new OCRBorder { Margin = new Thickness(minLeft + ((this.ActualWidth - this.imageControl.RenderSize.Width) / 2), minTop + ((this.ActualHeight - this.imageControl.RenderSize.Height) / 2), 0, 0) }; ocrUI.SetPoints(orderedPoints, word.Text, angle); this.hostGrid.Children.Add(ocrUI); } } } } if (this.PerformObjectDetection && img.DetectedObjects != null) { this.ShowObjectDetectionRegions(img.DetectedObjects); } } this.progressIndicator.IsActive = false; }
/// <summary> /// 画贝塞尔曲线 /// 曲线需要(开始点,结束点,控制点1,控制点2) /// </summary> /// <param name="canvas"></param> public static Path DrawPathBezierSegment(this Canvas canvas, PointCollection points, Color color, int ellipseSize = 10, bool isAddPoint = false) { if (!points.Any()) { return(new Path()); } var toDrawPoint = points.OrderBy(a => a.X).ToList(); var pf = new PathFigure { StartPoint = toDrawPoint[0] }; var toForCount = toDrawPoint.Count - 1; for (var i = 0; i < toForCount; i++) { int current = i, last = i - 1, next = i + 1, next2 = i + 2; if (last == -1) { last = 0; } if (next == toDrawPoint.Count) { next = toForCount; } if (next2 == toDrawPoint.Count) { next2 = toForCount; } var bzs = canvas.GetBezierSegment(toDrawPoint[current], toDrawPoint[last], toDrawPoint[next], toDrawPoint[next2], 0.7); pf.Segments.Add(bzs); } if (isAddPoint) { //画点的圆圈 foreach (var lipt in toDrawPoint) { var ellipse = new Ellipse { Width = ellipseSize, Height = ellipseSize, Margin = new Thickness(lipt.X - ellipseSize / 2, lipt.Y, 0, 0), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top, Fill = Brushes.Red, ToolTip = string.Format("x:{0},y:{1} ", lipt.X, lipt.Y) }; canvas.Children.Add(ellipse); } ; } //添加曲线到图上 var pfc = new PathFigureCollection { pf }; var pg = new PathGeometry(pfc); var path = new Path { StrokeThickness = 1, Stroke = new SolidColorBrush(color), Data = pg }; canvas.Children.Add(path); return(path); }