Sign in to follow this  
Followers 0
Tanel

Red Eye Quick Fix plugin (beta) - updated to V1.1 2008/08/27

14 posts in this topic

This is my early version of improved red eye removal (the need for this was revealed during a discussion here).

It is supposed to provide great results with minimum effort. Just select the eyes and run the plugin. Default setting should be suitable in most cases. Usually it is okay to select both eyes together with a coarse rectangle selection and keep skin tones untouched by little threshold adjustment. But the more precise selection you make around eye pupils, the more there is room for adustment.

Edit: new version with better speed performance:

RedEyeQuickFix1.1.zip

Below is the parade of before-and-after samples I tested. Most of those were fixed with default setting. All were fixed with coarse selection (whole upper face selected).

I'm very much interested in your feedback and also examples where this plugin didn't work.

redeye_samples.jpg

0

Share this post


Link to post
Share on other sites

Wow :shock: Those are seriously impressive results from default or near default settings!

I'm going to have to add this to my PDN toolbox.

Thanks!

0

Share this post


Link to post
Share on other sites

Well, I'd like to have "red" eye removal for animals, too. This was requested before, but I will not spend my time searching the thread :)

I'm no coder, but it's just yellow-green instead of red... :shock:

The pictures above look really impressive...

0

Share this post


Link to post
Share on other sites

Thanks for your comments! :)

Well, I'd like to have "red" eye removal for animals, too. This was requested before, but I will not spend my time searching the thread :)

I'm no coder, but it's just yellow-green instead of red... :shock:

It's not that simple, the eyeshine phenomenon has quite different character color wise. I couldn't even find any good PS tutorial for that, other than ones suggesting to paint it over.

I would say it is doable but should be a separate plugin. This one must keep UI as light as possible IMO.

0

Share this post


Link to post
Share on other sites

Hey Tanel, can you explain how this is better than the built-in Red Eye Removal? I'm genuinely interested in the mathematical details :)

0

Share this post


Link to post
Share on other sites
Hey Tanel, can you explain how this is better than the built-in Red Eye Removal? I'm genuinely interested in the mathematical details :)

Heh, mabye in 3.40 we'll have Tanel's version of Red Eye Removal built in :)

0

Share this post


Link to post
Share on other sites
Hey Tanel, can you explain how this is better than the built-in Red Eye Removal? I'm genuinely interested in the mathematical details :)
I think the greatest value of the new plugin is providing good result with less effort = better user experience. :)

You can best learn the behaviour by using it on the colorwheel screenshot, or this testimage.

I tried to find the best "color cut" between eye-red and pink skin tones. Then bound that cut-line to UI control (threshold).

I was looking for some feedback before posting the source code. I'll clean it up and post it here tomorrow.

0

Share this post


Link to post
Share on other sites

Update posted today - fixed the speed issues.

Here comes the Codelab source:

#region UICode
int Amount1 = 0; // [-30,30] Threshold
#endregion
UserBlendOps.NormalBlendOp normalBlendOp = new UserBlendOps.NormalBlendOp();

unsafe void Render(Surface dst, Surface src, Rectangle rect)
{
   for (int y = rect.Top; y < rect.Bottom; y++)
   {
       ColorBgra* srcPtr = src.GetPointAddressUnchecked(rect.Left, y);            
       ColorBgra* dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

       for (int x = rect.Left; x < rect.Right; x++)
       {
           ColorBgra CurrentPixel = *srcPtr;

           int Amount2 = 0; // removed Hue Range control from preliminary version
           // Fine-tune input parameters, we may drop this block in the future by writing the "good" values directly into the formulas
           int Amount1x = Amount1;
           Amount1x += -10;
           int Amount2x = -Amount2;
           Amount2x += 2;

           byte r = CurrentPixel.R;                            
           byte g = CurrentPixel.G;                            
           byte b = CurrentPixel.B;                            
           double ai = (double)CurrentPixel.A;                            

           HsvColor hsvColor = HsvColor.FromColor(CurrentPixel.ToColor());                            
           int hue = hsvColor.Hue;                            
           int sat = hsvColor.Saturation;
           //int value = hsvColor.Value;            

           hue += Amount2x;
           if(hue > 360)
           hue -= 360;
           if(hue < 0)
           hue += 360;

           // STEPS OF PROCESS:
           // Take a copy of src surface, 
           // "Cut out" the eye-red color using alpha channel,
           // Replace red channel values with green,
           // Blend the result with original

           // Create alpha multiplier from Hue (alpha multipliers will act as our scissors):
           // 1.0 for hue above 270; 0 for hue below 260; gradual 10 steps between hue 260 - 270
           double axh = 1.0;
           if(hue > 259 && hue < 270)
               axh = (hue - 259.0) / 10.0;


       // Create alpha multiplier from Saturation:
       // if hue > 259 then it is 1.0 for saturation above 45; 0 for saturation below 40; gradual 5 steps between 40 and 45
       // if hue < 260 then it is more complex "curve", based on combination of hue and saturation

       double axs = 1.0;
       if (hue > 259)
       {
           if (sat < Amount1x + 40)
           axs = 0;
           if (sat > Amount1x + 39 && sat < Amount1x + 45)
           axs = (sat - ((double)Amount1x + 39.0)) / 5.0;
       }                                        

       if (hue < 260)
       {
           if (sat < hue * 2 + Amount1x + 40)
           axs = 0;
           if (sat > hue * 2 + Amount1x + 39 && sat < hue * 2 + Amount1x + 50)
           axs = (sat - ((double)hue * 2.0 + (double)Amount1x + 39.0)) / 10.0;
       }

           // Merge the alpha multipliers:
           axh *= axs;            

           // Calculate final alpha based on original and multiplier:
           ai *= axh;
           byte a = Utility.ClampToByte(ai);

           // replace red channel with green and apply new alpha:
           CurrentPixel  =  ColorBgra.FromBgra(b, g, g, a);

           // Blend with original
           CurrentPixel = normalBlendOp.Apply(*srcPtr, CurrentPixel);
           *dstPtr = CurrentPixel;

           ++srcPtr;
           ++dstPtr;
       }
   }
}

1

Share this post


Link to post
Share on other sites

Wow! B)

I'm impressed.

It is fast, MUCH better than the built-in effect, and easier to use.

I tried it on a bunch of my own pictures (I never use red-eye flash) and it worked perfectly. I rarely had to change it from the default setting. It just did the job.

0

Share this post


Link to post
Share on other sites

The samples look really great.

Just looked for a picture where it does not work (because you'd asked), but the problem seems to be more the bad quality of the image than the plugin.

29070_c3b6fbdc7bfa1fa13f85909981ccb564

The whole image changes, but not the eyes.

Here another sample which seems to be tricky (glass wearer, side view):

29070_7f22e0fc795773b1c09a3d9ae81e6e9d

0

Share this post


Link to post
Share on other sites

I know, this is not a request forum, but could you code a Green Eye Quick Fix plugin, too (occures often on cat-photos)? Here are two samples:

29070_248a7e0e1f8c2b1c7e0ee55c70b96c80

29070_1f88f24b16e2628d37956a5643cae3ca

Greetings, pdn-user

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0