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; }
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); } ImageAnalyzer img = this.DataContext as ImageAnalyzer; if (img != null) { if (this.PerformOCRAnalysis && img.OcrResults == null) { await Task.WhenAll(img.AnalyzeImageAsync(detectCelebrities: true), img.RecognizeTextAsync()); } else if (img.AnalysisResult == null) { await img.AnalyzeImageAsync(detectCelebrities : true); } double renderedImageXTransform = this.imageControl.RenderSize.Width / this.bitmapImage.PixelWidth; double renderedImageYTransform = this.imageControl.RenderSize.Height / this.bitmapImage.PixelHeight; if (img.AnalysisResult.Faces != null) { foreach (Microsoft.ProjectOxford.Vision.Contract.Face face in img.AnalysisResult.Faces) { FaceIdentificationBorder faceUI = new FaceIdentificationBorder(); faceUI.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); faceUI.BalloonBackground = this.BalloonBackground; faceUI.BalloonForeground = this.BalloonForeground; faceUI.ShowFaceRectangle(face.FaceRectangle.Width * renderedImageXTransform, face.FaceRectangle.Height * renderedImageYTransform); faceUI.ShowIdentificationData(face.Age, face.Gender, 0, null); this.hostGrid.Children.Add(faceUI); double celebRecoConfidence = 0; string celebRecoName; this.GetCelebrityInfoIfAvailable(img, face.FaceRectangle, out celebRecoName, out 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); } } } if (this.PerformOCRAnalysis && img.OcrResults.Regions != null) { if (img.OcrResults.TextAngle.HasValue) { this.imageControl.RenderTransform = new RotateTransform { Angle = -img.OcrResults.TextAngle.Value, CenterX = this.imageControl.RenderSize.Width / 2, CenterY = this.imageControl.RenderSize.Height / 2 }; } foreach (Microsoft.ProjectOxford.Vision.Contract.Region ocrRegion in img.OcrResults.Regions) { foreach (var line in ocrRegion.Lines) { foreach (var word in line.Words) { OCRBorder ocrUI = new OCRBorder(); ocrUI.Margin = new Thickness((word.Rectangle.Left * renderedImageXTransform) + ((this.ActualWidth - this.imageControl.RenderSize.Width) / 2), (word.Rectangle.Top * renderedImageYTransform) + ((this.ActualHeight - this.imageControl.RenderSize.Height) / 2), 0, 0); ocrUI.SetData(word.Rectangle.Width * renderedImageXTransform, word.Rectangle.Height * renderedImageYTransform, word.Text); this.hostGrid.Children.Add(ocrUI); } } } } } this.progressIndicator.IsActive = false; }