/// <summary> /// /// </summary> /// <param name="image"></param> /// <param name="start"></param> /// <param name="maxEyeRadius">Should be 2-3 percent of max(width/height)</param> /// <param name="maxPointSearchDistance">In source pixels, the max distance from 'start' from which to look for the starting point. Good default: roughly 24 display pixels.</param> public static void MarkEye(UnmanagedImage image, Point start, int maxEyeRadius, float maxPointSearchDistance = 0) { int maxRadius = maxEyeRadius * 2 + (int)Math.Ceiling(maxPointSearchDistance); //Find subset Rectangle subset = new Rectangle(start.X - maxRadius, start.Y - maxRadius, maxRadius * 2, maxRadius * 2); if (subset.X < 0) { subset.Width += subset.X; subset.X = 0; } if (subset.Y < 0) { subset.Height += subset.Y; subset.Y = 0; } if (subset.Right >= image.Width) { subset.Width -= (subset.Right - image.Width + 1); } if (subset.Bottom >= image.Height) { subset.Height -= (subset.Bottom - image.Height + 1); } start.X -= subset.X; start.Y -= subset.Y; //Skip processing if we're slightly out of bounds if (subset.X < 0 || subset.Y < 0 || subset.Width < 0 || subset.Height < 0 || subset.Right >= image.Width || subset.Bottom >= image.Height) { return; } UnmanagedImage red = null; try{ Point startAt = start; using (UnmanagedImage c = new Crop(subset).Apply(image)) { red = new RedEyeFilter(2).Apply(c); if (maxPointSearchDistance > 0) { startAt = new ManualSearcher().FindMaxPixel(c, start, maxPointSearchDistance); } } var fill = new AdaptiveCircleFill(red, startAt, start, maxEyeRadius * 2); fill.FirstPass(); fill.SecondPass(); fill.CorrectRedEye(image, subset.X, subset.Y); //fill.MarkFilledPixels(image, subset.X, subset.Y, new byte[] { 0, 255, 0, 0 }); //fill.SetPixel(image, startAt.X + subset.X, startAt.Y + subset.Y, new byte[] { 255, 255, 0, 0 }); }finally{ if (red != null) { red.Dispose(); } } }
/// <summary> /// /// </summary> /// <param name="image"></param> /// <param name="start"></param> /// <param name="maxEyeRadius">Should be 2-3 percent of max(width/height)</param> /// <param name="maxPointSearchDistance">In source pixels, the max distance from 'start' from which to look for the starting point. Good default: roughly 24 display pixels.</param> public static void MarkEye(UnmanagedImage image, Point start, int maxEyeRadius, float maxPointSearchDistance = 0) { int maxRadius = maxEyeRadius * 2 + (int)Math.Ceiling(maxPointSearchDistance); //Find subset Rectangle subset = new Rectangle(start.X - maxRadius,start.Y - maxRadius,maxRadius * 2, maxRadius * 2); if (subset.X < 0) { subset.Width += subset.X; subset.X = 0; } if (subset.Y < 0) { subset.Height += subset.Y; subset.Y = 0; } if (subset.Right >= image.Width) subset.Width -= (subset.Right - image.Width + 1); if (subset.Bottom >= image.Height) subset.Height -= (subset.Bottom - image.Height + 1); start.X -= subset.X; start.Y -= subset.Y; //Skip processing if we're slightly out of bounds if (subset.X < 0 || subset.Y < 0 || subset.Width < 0 || subset.Height < 0 || subset.Right >= image.Width || subset.Bottom >= image.Height) return; UnmanagedImage red = null; try{ Point startAt = start; using (UnmanagedImage c = new Crop(subset).Apply(image)) { red = new RedEyeFilter(2).Apply(c); if (maxPointSearchDistance > 0) startAt = new ManualSearcher().FindMaxPixel(c,start,maxPointSearchDistance); } var fill = new AdaptiveCircleFill(red, startAt, start, maxEyeRadius * 2); fill.FirstPass(); fill.SecondPass(); fill.CorrectRedEye(image, subset.X, subset.Y); //fill.MarkFilledPixels(image, subset.X, subset.Y, new byte[] { 0, 255, 0, 0 }); //fill.SetPixel(image, startAt.X + subset.X, startAt.Y + subset.Y, new byte[] { 255, 255, 0, 0 }); }finally{ if (red != null) red.Dispose(); } }
protected override RequestedAction Render(ImageState s) { if (base.Render(s) == RequestedAction.Cancel) { return(RequestedAction.Cancel); } bool detecteyes = s.settings.Get <bool>("r.detecteyes", false); bool getlayout = s.settings.Get <bool>("r.getlayout", false); if (detecteyes || getlayout) { var d = new DetectionResponse <ObjRect>(); try { //Only detect eyes if it was requested. if (detecteyes) { using (var ed = new EyeDetection()) { d.features = ed.DetectFeatures(s.sourceBitmap); } } } catch (TypeInitializationException e) { throw e; } catch (Exception e) { d.message = e.Message; } d.PopulateFrom(s); throw d.GetResponseException(s.settings["callback"]); } if (s.sourceBitmap == null) { return(RequestedAction.None); } if (!string.IsNullOrEmpty(s.settings["r.eyes"])) { double[] eyes = NameValueCollectionExtensions.GetList <double>(s.settings, "r.eyes", 0); // lock source bitmap data BitmapData data = s.sourceBitmap.LockBits( new Rectangle(0, 0, s.sourceBitmap.Width, s.sourceBitmap.Height), ImageLockMode.ReadWrite, s.sourceBitmap.PixelFormat); try { UnmanagedImage ui = new UnmanagedImage(data); for (var i = 0; i < eyes.Length / 5; i++) { var x = eyes[i * 5]; var y = eyes[i * 5 + 1]; var w = eyes[i * 5 + 2]; var h = eyes[i * 5 + 3]; var a = eyes[i * 5 + 4]; var cx = x + w / 2; var cy = y + h / 2; var radius = Math.Sqrt(w * w + h * h) / 2; AdaptiveCircleFill.MarkEye(ui, new System.Drawing.Point((int)cx, (int)cy), (int)Math.Ceiling(radius), (float)(a > 6 ? radius / 4 : radius)); } } finally { // unlock image s.sourceBitmap.UnlockBits(data); } } return(RequestedAction.None); }