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;
        }
Esempio n. 3
0
        /// <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);
        }