Пример #1
0
        static void Main(string[] args)
        {
            using (var sourceMat = new Mat("source.jpg"))
                using (var destinationMat = new Mat("destination.jpg"))
                    using (var hc = new CascadeClassifier("HaarCascade.xml"))
                        using (var facemark = FacemarkLBF.Create())
                        {
                            Console.WriteLine("Face detection starting..");
                            var sourceFaceRects = hc.DetectMultiScale(sourceMat);
                            if (sourceFaceRects == null || sourceFaceRects.Length == 0)
                            {
                                Console.WriteLine($"Source image: No faces detected.");
                                return;
                            }
                            Console.WriteLine($"Source image: detected {sourceFaceRects.Length} faces.");

                            var destFaceRects = hc.DetectMultiScale(destinationMat);
                            if (destFaceRects == null || destFaceRects.Length == 0)
                            {
                                Console.WriteLine($"Destination image: No faces detected.");
                                return;
                            }
                            Console.WriteLine($"Destination image: detected {destFaceRects.Length} faces.");

                            facemark.LoadModel("lbfmodel.yaml");
                            using (var sourceInput = InputArray.Create(sourceFaceRects))
                                using (var destInput = InputArray.Create(destFaceRects))
                                {
                                    facemark.Fit(sourceMat, sourceInput, out Point2f[][] sourceLandmarks);
                                    var sourcePoints = sourceLandmarks[0];

                                    facemark.Fit(destinationMat, destInput, out Point2f[][] destLandmarks);
                                    var destPoints = destLandmarks[0];

                                    var triangles = destPoints.Take(60).GetDelaunayTriangles();
                                    var warps     = triangles.GetWarps(sourcePoints.Take(60), destPoints.Take(60));

                                    using (var warpedMat = sourceMat.ApplyWarps(destinationMat.Width, destinationMat.Height, warps))
                                        using (var mask = new Mat(destinationMat.Size(), MatType.CV_8UC3))
                                            using (var result = new Mat(destinationMat.Size(), MatType.CV_8UC3))
                                            {
                                                mask.SetTo(0);

                                                var convexHull = Cv2.ConvexHull(destPoints).Select(s => new Point(s.X, s.Y));
                                                Cv2.FillConvexPoly(mask, convexHull, Scalar.White);

                                                var rect   = Cv2.BoundingRect(convexHull);
                                                var center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);

                                                Cv2.SeamlessClone(warpedMat, destinationMat, mask, center, result, SeamlessCloneMethods.NormalClone);
                                                var blured = result.MedianBlur(5);
                                                blured.SaveImage("result.png");
                                            }
                                }
                        }
            Console.WriteLine("Done");
        }
Пример #2
0
        static void Main(string[] args)
        {
            //prepare images for averaging
            PrepareImages();

            //load facemark model
            _facemark = FacemarkLBF.Create();
            _facemark.LoadModel("lbfmodel.yaml");

            //collection for all found facemarks
            var allFaceMarks = new List <List <Point2f> >();

            //facemark search and save
            foreach (var image in Directory.GetFiles(TempDirName))
            {
                using (var mat = new Mat(image))
                {
                    var facesRects = _cascade.DetectMultiScale(mat);
                    using (var facesRectsArray = InputArray.Create(facesRects))
                    {
                        _facemark.Fit(mat, facesRectsArray, out Point2f[][] landmarks);
                        // only one face should be
                        allFaceMarks.Add(landmarks[0].ToList());
                    }
                }
            }

            //add static points
            foreach (var facemarks in allFaceMarks)
            {
                facemarks.Add(new Point2f(1, 1));
                facemarks.Add(new Point2f(1, _outputSize.Height / 2));
                facemarks.Add(new Point2f(1, _outputSize.Height - 1));
                facemarks.Add(new Point2f(_outputSize.Width - 1, 1));
                facemarks.Add(new Point2f(_outputSize.Width / 2, _outputSize.Height - 1));
                facemarks.Add(new Point2f(_outputSize.Width - 1, _outputSize.Height / 2));
                facemarks.Add(new Point2f(_outputSize.Width - 1, _outputSize.Height - 1));
            }

            //average Facemarks
            var averagePoints = new List <Point2f>();

            for (int i = 0; i < 75; i++)
            {
                float xSum = 0;
                float ySum = 0;
                for (int j = 0; j < allFaceMarks.Count; j++)
                {
                    var point = allFaceMarks[j][i];
                    xSum += point.X;
                    ySum += point.Y;
                }
                averagePoints.Add(new Point2f(xSum / allFaceMarks.Count, ySum / allFaceMarks.Count));
            }

            //calculate delaunay triangles
            var destinationTriangles = averagePoints.GetDelaunayTriangles();

            //create result mat
            var outputMat = new Mat(_outputSize, _matTypeDefault);

            outputMat.SetTo(0);

            // blending coeff
            var delta = 1.0 / allFaceMarks.Count;

            // warping and blending
            var files = Directory.GetFiles(TempDirName);

            for (int i = 0; i < files.Length; i++)
            {
                using (var mat = new Mat(files[i]))
                {
                    var landmarks = allFaceMarks[i];
                    var warps     = destinationTriangles.GetWarps(landmarks, averagePoints);
                    var warpedImg = mat.ApplyWarps(mat.Width, mat.Height, warps);
                    Cv2.AddWeighted(outputMat, 1, warpedImg, delta, 0, outputMat);
                }
            }

            //save
            outputMat.SaveImage("result.png");
            Console.WriteLine("Done.");
        }