コード例 #1
0
        /// <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();
                }
            }
        }
コード例 #2
0
ファイル: AdaptiveCircleFill.cs プロジェクト: eakova/resizer
        /// <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();
            }
        }
コード例 #3
0
ファイル: RedEyePlugin.cs プロジェクト: stukalin/ImageResizer
        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);
        }