コード例 #1
0
ファイル: DLibHog.cs プロジェクト: coenm/FaceDetection
        public async Task <IEnumerable <Face> > ProcessAsync(string inputFilename)
        {
            if (!File.Exists(inputFilename))
            {
                throw new FileNotFoundException(nameof(inputFilename));
            }

            using var img = await DlibHelpers.LoadRotatedImage(imageRotationService, inputFilename);

            var faces = detector.Operator(img);

            foreach (var rect in faces)
            {
                Dlib.DrawRectangle(img, rect, new RgbPixel(0, 255, 0), 8U);
            }

            // var origFilename = new FileInfo(inputFilename).Name;
            // var outputFilename = Path.Combine(outputDirectory, $"{origFilename}_{Name}.jpg");

            // Dlib.SaveJpeg(img, outputFilename, 25);

            return(faces.Select(x => new Face
            {
                Position = new RectangleDto
                {
                    Top = x.Top,
                    Right = x.Right,
                    Left = x.Left,
                    Bottom = x.Bottom,
                }.ToRectangle(),
                Confidence = null
            }).ToList());
        }
コード例 #2
0
        public async Task <MatrixFloatDto[]> GetFaceDescriptors(string filename, System.Drawing.Rectangle[] faces)
        {
            var inputFilename = filename;
            var chips         = new List <Matrix <RgbPixel> >();

            using var img = await DlibHelpers.LoadRotatedImage(imageRotationService, inputFilename);

            foreach (var face in faces.Select(x => new Rectangle(x.Left, x.Top, x.Right, x.Bottom)))
            {
                // detect landmarks
                var shape = predictor.Detect(img, face);

                // extract normalized and rotated 150x150 face chip
                var faceChipDetail = Dlib.GetFaceChipDetails(shape, 150, 0.25);
                var faceChip       = Dlib.ExtractImageChip <RgbPixel>(img, faceChipDetail);

                // convert the chip to a matrix and store
                var matrix = new Matrix <RgbPixel>(faceChip);
                chips.Add(matrix);
            }

            if (!chips.Any())
            {
                return(Array.Empty <MatrixFloatDto>());
            }

            // put each fae in a 128D embedding space
            // similar faces will be placed close together
            var descriptors = dnn.Operator(chips);

            return(descriptors
                   .Select(x => new MatrixFloatDto
            {
                Data = x.ToArray(),
                Row = x.Rows,
                Columns = x.Columns,
            })
                   .ToArray());
        }
コード例 #3
0
        public async Task ProcessAsync(string[] inputFilenames)
        {
            var chips        = new List <Matrix <RgbPixel> >();
            var faces        = new List <Rectangle>();
            var filename     = new List <string>();
            var jsonFilename = inputFilenames.First() + ".json";

            foreach (var inputFilename in inputFilenames)
            {
                if (!File.Exists(inputFilename))
                {
                    break;
                }

                if (File.Exists(jsonFilename))
                {
                    continue;
                }

                // load the image
                using var img = await DlibHelpers.LoadRotatedImage(imageRotationService, inputFilename);

                // Dlib.SaveJpeg(img, inputFilename + "__1.jpg", 25);
                // Dlib.SaveJpeg(img, inputFilename + "__2.jpg", 25);

                // detect all faces
                foreach (var face in detector.Operator(img))
                {
                    // detect landmarks
                    var shape = predictor.Detect(img, face);

                    // extract normalized and rotated 150x150 face chip
                    var faceChipDetail = Dlib.GetFaceChipDetails(shape, 150, 0.25);
                    var faceChip       = Dlib.ExtractImageChip <RgbPixel>(img, faceChipDetail);

                    // convert the chip to a matrix and store
                    var matrix = new Matrix <RgbPixel>(faceChip);
                    chips.Add(matrix);
                    faces.Add(face);
                    filename.Add(inputFilename);
                }
            }

            if (!File.Exists(jsonFilename))
            {
                var ffd = new FoundFacesData
                {
                    // Chips = chips,
                    Faces     = faces,
                    Filenames = filename,
                };

                OutputLabels <Matrix <float> > descriptors = null;
                if (chips.Any())
                {
                    // put each fae in a 128D embedding space
                    // similar faces will be placed close together
                    // Console.WriteLine("Recognizing faces...");
                    descriptors     = dnn.Operator(chips);
                    ffd.Descriptors = descriptors.ToList();
                }
                else
                {
                    ffd.Descriptors = new List <Matrix <float> >(0);
                }

                var dto = new FoundFacesDataDto
                {
                    Faces = ffd.Faces
                            .Select(f => new RectangleDto
                    {
                        Bottom = f.Bottom,
                        Left   = f.Left,
                        Top    = f.Top,
                        Right  = f.Right,
                    })
                            .ToList(),

                    Filenames = ffd.Filenames,

                    Descriptors = ffd.Descriptors
                                  .Select(x => new MatrixFloatDto
                    {
                        Data    = x.ToArray(),
                        Row     = x.Rows,
                        Columns = x.Columns,
                    })
                                  .ToList()
                };

                var x = JsonConvert.SerializeObject(dto);
                File.WriteAllText(jsonFilename, JsonConvert.SerializeObject(dto));
            }

            FoundFacesData items;

            using (var r = new StreamReader(jsonFilename))
            {
                var json     = r.ReadToEnd();
                var itemsdto = JsonConvert.DeserializeObject <FoundFacesDataDto>(json);
                items = new FoundFacesData
                {
                    Faces       = itemsdto.Faces.Select(f => new Rectangle(f.Left, f.Top, f.Right, f.Bottom)).ToList(),
                    Filenames   = itemsdto.Filenames.ToList(),
                    Descriptors = itemsdto.Descriptors.Select(d => new Matrix <float>(d.Data, d.Row, d.Columns)).ToList(),
                };
            }

            if (items.Faces.Count <= 0)
            {
                return;
            }

            // // compare each face with all other faces
            var edges = new List <SamplePair>();

            // for (uint i = 0; i < descriptors.Count; ++i)
            // for (var j = i; j < descriptors.Count; ++j)
            //
            //     // record every pair of two similar faces
            //     // faces are similar if they are less than 0.6 apart in the 128D embedding space
            //     if (Dlib.Length(descriptors[i] - descriptors[j]) < 0.5)
            //         edges.Add(new SamplePair(i, j));
            //
            // // use the chinese whispers algorithm to find all face clusters
            // Dlib.ChineseWhispers(edges, 100, out var clusters, out var labels);
            // // Console.WriteLine($"   Found {clusters} unique person(s) in the image");
            //
            // // draw rectangles on each face using the cluster color
            // for (var i = 0; i < faces.Count; i++)
            // {
            //     var color = new RgbPixel(255, 255, 255);
            //     if (labels[i] < palette.Length)
            //         color = palette[labels[i]];
            //
            //     using var img = Dlib.LoadImage<RgbPixel>(filename[i] + "__1.jpg");
            //     Dlib.DrawRectangle(img, faces[i], color: color, thickness: 4);
            //     Dlib.SaveJpeg(img, filename[i] + "__1.jpg", 25);
            // }
            //
            // Console.WriteLine("end 1");

            // compare each face with all other faces
            edges = new List <SamplePair>();
            for (var i = 0; i < items.Descriptors.Count; ++i)
            {
                for (var j = i; j < items.Descriptors.Count; ++j)
                {
                    // record every pair of two similar faces
                    // faces are similar if they are less than 0.6 apart in the 128D embedding space
                    if (Dlib.Length(items.Descriptors[i] - items.Descriptors[j]) < 0.4)
                    {
                        edges.Add(new SamplePair((uint)i, (uint)j));
                    }
                }
            }

            // use the chinese whispers algorithm to find all face clusters
            Dlib.ChineseWhispers(edges, 100, out var clusters2, out var labels2);
            // Console.WriteLine($"   Found {clusters} unique person(s) in the image");

            // draw rectangles on each face using the cluster color
            for (var i = 0; i < items.Faces.Count; i++)
            {
                var color = palette[0];
                if (labels2[i] < palette.Length)
                {
                    color = palette[labels2[i]];
                }

                if (!File.Exists(items.Filenames[i] + $"_x{labels2[i]}.jpg"))
                {
                    using var img2 = await DlibHelpers.LoadRotatedImage(imageRotationService, items.Filenames[i]);

                    Dlib.SaveJpeg(img2, items.Filenames[i] + $"_x{labels2[i]}.jpg", 25);
                }

                using var img = Dlib.LoadImage <RgbPixel>(items.Filenames[i] + $"_x{labels2[i]}.jpg");
                Dlib.DrawRectangle(img, items.Faces[i], color: color, thickness: 4);
                Dlib.SaveJpeg(img, items.Filenames[i] + $"_x{labels2[i]}.jpg", 25);
            }

            // var origFilename = new FileInfo(inputFilename).Name;
            // var outputFilename = Path.Combine(outputDirectory, $"{origFilename}_Identification.jpg");

            // Dlib.SaveJpeg(img, inputFilename, 75);
        }