コード例 #1
0
        public ContentResult ToggleTagImage(long tagId, long thumbnailId)
        {
            try
            {
                var tag = Context.Tags.Include(t => t.TagThumbnails).FirstOrDefault(p => p.Id == tagId);
                if (tag == null)
                {
                    return(AjaxFailedResult("Tag not found."));
                }

                var thumbnail = Context.Thumbnails.FirstOrDefault(t => t.Id == thumbnailId);
                if (thumbnail == null)
                {
                    return(AjaxFailedResult("Image not found."));
                }

                var tagged = tag.TagThumbnails.FirstOrDefault(t => t.ThumbnailId == thumbnail.Id && t.TagId == tagId);
                if (tagged != null)
                {
                    tag.TagThumbnails.Remove(tagged);
                    Context.Entry(tag).State = EntityState.Modified;
                    Context.SaveChanges();
                    return(AjaxResult <bool>(false, $"Removed {thumbnail.FileName} from {tag.Name}"));
                }
                tagged = new TagThumbnail {
                    Tag = tag, TagId = tagId, Thumbnail = thumbnail, ThumbnailId = thumbnailId
                };
                tag.TagThumbnails.Add(tagged);
                Context.Entry(tag).State = EntityState.Modified;
                Context.SaveChanges();
                return(AjaxResult <bool>(true, $"Added {thumbnail.FileName} to {tag.Name}"));
            }
            catch (Exception ex)
            {
                Logger.Error(ex, $"Failed to toggle tag {tagId} for image {thumbnailId}. {ex.Message}: {ex}");
                return(AjaxFailedResult($"Failed to toggle tag {tagId} for image {thumbnailId}: {ex.Message}"));
            }
        }
コード例 #2
0
        private int _ScanImages(List <long> imagesToScan)
        {
            var numNewFaces = 0;

            using (var context = GetNewDataContext())
                using (var recognizer = SetupFacialRecognition(context))
                {
                    foreach (var id in imagesToScan)
                    {
                        var thumbnail = context.Thumbnails
                                        .Include(t => t.FileSystemFolder)
                                        .Include(t => t.Faces)
                                        .Include(t => t.TagThumbnails)
                                        .ThenInclude(tt => tt.Tag)
                                        .ThenInclude(tag => tag.TagType)
                                        .First(t => t.Id == id);
                        thumbnail.Scanned = true;
                        context.Entry(thumbnail).State = EntityState.Modified;

                        using (var img = Image.Load(GetFullPath(thumbnail)))
                        {
                            ExifRotate(img);
                            using (var imageStream = new MemoryStream())
                            {
                                img.SaveAsBmp(imageStream);


                                Logger.Trace($"Scanning image {thumbnail.FileName} for faces");
                                foreach (var unknown in thumbnail.Faces
                                         .Where(f => f.TagId == Base.Constants.Tags.UnknownTagId && !f.IsValid && f.NeedsValidation).ToList())
                                {
                                    //re-evaluate non-validated faces
                                    double dist;
                                    var    tagId = recognizer.Recognize(unknown.Bytes, out dist);
                                    if (tagId.HasValue && tagId.Value != Base.Constants.Tags.UnknownTagId &&
                                        dist <= _minDistanceForFacialRecognition)
                                    {
                                        unknown.TagId    = tagId.Value;
                                        unknown.Distance = dist;
                                    }
                                }

                                var foundRectangles = thumbnail.Faces.Select(f => f.Rectangle)
                                                      .ToList();
                                var faces     = recognizer.Recognize(foundRectangles, imageStream);
                                var sideFaces = recognizer.Recognize(foundRectangles, imageStream,
                                                                     FacialRecognition.HaarCascadeSideProfile);

                                using (var flippedStream = new MemoryStream())
                                {
                                    img.Mutate(x => x.RotateFlip(RotateMode.None, FlipMode.Horizontal));
                                    img.SaveAsBmp(flippedStream);

                                    var flipped = foundRectangles.Select(k =>
                                                                         new System.Drawing.Rectangle(k.X + k.Width + thumbnail.ImageWidth, k.Y, k.Width, k.Height)).ToList();
                                    var leftSideFaces = recognizer.Recognize(flipped, flippedStream, FacialRecognition.HaarCascadeSideProfile);
                                    foreach (var face in leftSideFaces)
                                    {
                                        //need to flip the images back.
                                        face.RectX = thumbnail.ImageWidth - face.RectWidth - face.RectX;
                                    }
                                    Logger.Trace($"Found {leftSideFaces.Count} flipped faces. {sideFaces.Count}");

                                    faces.AddRange(sideFaces);
                                    faces.AddRange(leftSideFaces);
                                }

                                var filtered = new List <Face>();
                                foreach (var face in faces)
                                {
                                    if ((face.Distance <= _minDistanceForFacialRecognition || face.RectWidth > _minWidthForOverride || face.RectHeight > _minHeightForOverride) && !filtered.Any(f =>
                                                                                                                                                                                                 f.Rectangle.Contains(face.Rectangle) || face.Rectangle.Contains(f.Rectangle) ||
                                                                                                                                                                                                 Overlaps(f.Rectangle, face.Rectangle, 70)))
                                    {
                                        if (face.Distance <= _minDistanceForFacialRecognition)
                                        {
                                            face.TagId = Base.Constants.Tags.UnknownTagId;
                                        }
                                        filtered.Add(face);
                                    }
                                    else if (_writeImagesToLocal)
                                    {
                                        var filePath = Path.Combine(_imagesToLocalPath, "Skipped");
                                        if (!Directory.Exists(filePath))
                                        {
                                            Directory.CreateDirectory(filePath);
                                        }

                                        using (var tmp = Image.Load(new MemoryStream(face.Bytes)))
                                        {
                                            tmp.Save(Path.Combine(filePath, $"{(int)face.Distance}_{face.TagId}_{face.RectWidth}_{face.RectHeight}_{Guid.NewGuid():N}.jpg"));
                                        }
                                    }
                                }

                                var groups = filtered.GroupBy(f =>
                                                              !thumbnail.Faces.Any(i =>
                                                                                   f.Rectangle.Contains(i.Rectangle) ||
                                                                                   i.Rectangle.Contains(f.Rectangle) ||
                                                                                   (i.Rectangle.IntersectsWith(f.Rectangle) &&
                                                                                    (i.TagId == f.TagId || Overlaps(i.Rectangle, f.Rectangle, 70)))
                                                                                   )).ToList();
                                var newFaces = groups.Where(g => g.Key).SelectMany(v => v).ToList();
                                var oldFaces = groups.Where(g => !g.Key).SelectMany(v => v).Where(f => f.TagId != Base.Constants.Tags.UnknownTagId).ToList();

                                Logger.Trace($"Updating the old faces for {thumbnail.FileName}");
                                foreach (var face in thumbnail.Faces.Where(i => i.TagId == Base.Constants.Tags.UnknownTagId && !i.IsValid && i.NeedsValidation))
                                {
                                    var matches = oldFaces.Where(f =>
                                                                 f.Rectangle.Contains(face.Rectangle) || face.Rectangle.Contains(f.Rectangle) ||
                                                                 (face.Rectangle.IntersectsWith(f.Rectangle) &&
                                                                  Overlaps(face.Rectangle, f.Rectangle, 70))).ToList();
                                    if (matches.Any() && matches.Select(m => m.TagId).Distinct().Count() == 1)
                                    {
                                        face.TagId                = matches.First().TagId;
                                        face.Distance             = matches.First().Distance;
                                        context.Entry(face).State = EntityState.Modified;
                                    }
                                }

                                Logger.Trace($"Adding new faces for {thumbnail.FileName}");
                                foreach (var face in newFaces)
                                {
                                    numNewFaces++;
                                    face.Thumbnail   = thumbnail;
                                    face.ThumbnailId = thumbnail.Id;

                                    if (_writeImagesToLocal)
                                    {
                                        var filePath = Path.Combine(_imagesToLocalPath, "Added");
                                        if (!Directory.Exists(filePath))
                                        {
                                            Directory.CreateDirectory(filePath);
                                        }

                                        using (var tmp = Image.Load(new MemoryStream(face.Bytes)))
                                        {
                                            tmp.Save(Path.Combine(filePath, $"{face.TagId}_{Guid.NewGuid():N}.jpg"));
                                        }
                                    }
                                    thumbnail.Faces.Add(face);
                                    context.Faces.Add(face);
                                }
                                Logger.Trace($"Updating the people tags for {thumbnail.FileName}");
                                var tagIds = thumbnail.Faces.Where(f => f.TagId.HasValue && f.TagId != Base.Constants.Tags.UnknownTagId && !f.IsHidden).Select(f => f.TagId.Value).Distinct().ToList();
                                foreach (var tagId in tagIds)
                                {
                                    if (!context.TagThumbnails.Any(tt => tt.ThumbnailId == thumbnail.Id && tt.TagId == tagId && tt.Tag.TagTypeId == Constants.Tags.PersonTagTypeId))
                                    {
                                        var tag = context.Tags.FirstOrDefault(t =>
                                                                              t.Id == tagId && t.TagTypeId == Constants.Tags.PersonTagTypeId);
                                        if (tag != null)
                                        {
                                            var tagThumbnail = new TagThumbnail {
                                                Tag = tag, TagId = tag.Id, Thumbnail = thumbnail, ThumbnailId = thumbnail.Id
                                            };
                                            thumbnail.TagThumbnails.Add(tagThumbnail);
                                        }
                                        else
                                        {
                                            Logger.Error($"Tag id not found {tagId}.");
                                        }
                                    }
                                }
                            }
                            Logger.Trace($"{thumbnail.FileName} complete");
                        }
                    }

                    context.SaveChanges();
                }

            return(numNewFaces);
        }