Esempio n. 1
0
        public static Mat Extract(Mat src, FaceCorners corners, Guid jobId)
        {
            var widthA   = Math.Sqrt(Math.Pow(corners.BottomRight.X - corners.BottomLeft.X, 2) + Math.Pow(corners.BottomRight.Y - corners.BottomLeft.Y, 2));
            var widthB   = Math.Sqrt(Math.Pow(corners.TopRight.X - corners.TopLeft.X, 2) + Math.Pow(corners.TopRight.Y - corners.TopLeft.Y, 2));
            var maxWidth = Math.Max(widthA, widthB);

            var heightA   = Math.Sqrt(Math.Pow(corners.TopRight.X - corners.BottomRight.X, 2) + Math.Pow(corners.TopRight.Y - corners.BottomRight.Y, 2));
            var heightB   = Math.Sqrt(Math.Pow(corners.TopLeft.X - corners.BottomLeft.X, 2) + Math.Pow(corners.TopLeft.Y - corners.BottomLeft.Y, 2));
            var maxHeight = Math.Max(heightA, heightB);

            var perspectiveTransformationMatrix = Cv2.GetPerspectiveTransform(new List <Point2f> {
                corners.TopLeft, corners.TopRight, corners.BottomRight, corners.BottomLeft
            }, new List <Point2f> {
                new Point2f(0, 0),
                new Point2f((float)maxWidth - 1, 0),
                new Point2f((float)maxWidth - 1, (float)maxHeight - 1),
                new Point2f(0, (float)maxHeight - 1),
            });

            Mat warped = new Mat(new Size((float)maxWidth, (float)maxHeight), MatType.CV_16S);

            Cv2.WarpPerspective(src, warped, perspectiveTransformationMatrix, new Size((float)maxWidth, (float)maxHeight));

            var bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(warped);

            bitmap.Save($"Results\\{jobId}\\Extracted\\face-corners-" + Guid.NewGuid() + ".jpg", ImageFormat.Jpeg);

            return(warped);
        }
Esempio n. 2
0
        public static FaceCorners GetFaceCorners(Mat src, Mat tresh, Guid jobId, Window w = null)
        {
            FaceCorners result = null;

            var dst  = ImageUtil.GetCopy(src);
            var copy = ImageUtil.GetCopy(tresh);

            var matched_countours = ContourUtil.FindContours(copy);

            matched_countours = matched_countours.Distinct(new LambdaComparer <Point[]>((x, y) =>
            {
                var mx = GetMassCenter(x);
                var my = GetMassCenter(y);

                var dx          = Math.Abs(mx.X - my.X);
                var dy          = Math.Abs(mx.Y - my.Y);
                double distance = Math.Sqrt(dx * dx + dy * dy);

                return(mx == my || distance < 5 && distance > 0);
            })).ToList();

            //Cv2.DrawContours(dst, matched_countours, -1, Scalar.Purple, 2);

            foreach (var c in matched_countours)
            {
                var angle = ContourUtil.GetAngle(c, dst);
            }

            var cts = matched_countours.GroupBy(c => ContourUtil.GetAngle(c));

            int i = 1;

            foreach (var group in cts)
            {
                var count = group.Count();

                //foreach (var c in group)
                //{
                //    Cv2.PutText(dst, "g" + ((int)i).ToString() + " " + group.Key, new Point2f(c[0].X + 20, c[0].Y + 20), HersheyFonts.HersheyPlain, 1, Scalar.SpringGreen);
                //}
                //i++;

                var all = group.SelectMany(g => g).ToList();

                if (count == 9)
                {
                    //tl
                    var p1 = all.FirstOrDefault(pt => pt.X + pt.Y == all.Min(p => p.X + p.Y));
                    //br
                    var p2 = all.FirstOrDefault(pt => pt.X + pt.Y == all.Max(p => p.X + p.Y));
                    //tr
                    var p3 = all.FirstOrDefault(pt => pt.X - pt.Y == all.Min(p => p.X - p.Y));
                    //bl
                    var p4 = all.FirstOrDefault(pt => pt.X - pt.Y == all.Max(p => p.X - p.Y));

                    var points = new List <Point>()
                    {
                        p1, p2, p3, p4
                    };

                    points = points.Distinct(new LambdaComparer <Point>((a, b) =>
                    {
                        var dx          = Math.Abs(a.X - b.X);
                        var dy          = Math.Abs(a.Y - b.Y);
                        double distance = Math.Sqrt(dx * dx + dy * dy);

                        return(distance < 20 && distance > 0);
                    })).ToList();

                    // if two of the points from [tl,br,tr,bl] are ~ equal then we need to find alternatives
                    // like the most left or the most top element
                    if (points.Count < 4)
                    {
                        // top most
                        p1 = all.FirstOrDefault(pt => pt.Y == all.Min(p => p.Y));
                        // left most
                        p2 = all.FirstOrDefault(pt => pt.X == all.Min(p => p.X));
                        // right most
                        p3 = all.FirstOrDefault(pt => pt.X == all.Max(p => p.X));
                        // bottom most
                        p4 = all.FirstOrDefault(pt => pt.Y == all.Max(p => p.Y));

                        result = new FaceCorners {
                            Rotated = true, TopMost = p1, LeftMost = p2, RightMost = p3, BottomMost = p4
                        };
                    }
                    else
                    {
                        result = new FaceCorners {
                            TopLeft = p1, BottomRight = p2, TopRight = p3, BottomLeft = p4
                        };
                    }

                    Cv2.Circle(dst, p1, 10, Scalar.Red);
                    Cv2.Circle(dst, p2, 10, Scalar.Red);
                    Cv2.Circle(dst, p3, 10, Scalar.Red);
                    Cv2.Circle(dst, p4, 10, Scalar.Red);

                    var bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(dst);
                    bitmap.Save($"Results\\{jobId}\\Detected\\face-corners-" + Guid.NewGuid() + ".jpg", ImageFormat.Jpeg);
                }

                if (count >= 5 && count < 9)
                {
                    result = FindFaceCornersForContour(group.FirstOrDefault(), all.ToArray());

                    if (result != null)
                    {
                        Cv2.Circle(dst, result.TopLeft, 10, Scalar.Red);
                        Cv2.Circle(dst, result.BottomLeft, 10, Scalar.Red);
                        Cv2.Circle(dst, result.TopRight, 10, Scalar.Red);
                        Cv2.Circle(dst, result.BottomRight, 10, Scalar.Red);

                        var bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(dst);
                        bitmap.Save($"Results\\{jobId}\\Detected\\face-corners-" + Guid.NewGuid() + ".jpg", ImageFormat.Jpeg);
                    }
                }
            }

            if (w == null)
            {
                Cv2.ImShow("src", dst);
            }
            else
            {
                w.ShowImage(dst);
            }

            return(result);
        }