Lighten Darken Skin tone in C# and Silverlight for #windowsphone #wpdev

I started Cool Camera as a stop gap application trying to figure my way around SatNav app (which started while i was answering some posts on AppHub forums). Current availble version stands at 1.6 and 1.7 is with Microsoft.

It has come a long way since 1.0 – which only supported: Taking pictures and a camera style HUD. The picture viewer was very basic. Just display the image in Image control. Since then i have * added support for filters, added video recording and playback, added album viewer. I have worked a bit more on image processing and i am a bit better at image processing.

The first set of filters were added to app thanks to René Schulte – http://kodierer.blogspot.co.uk/. I remember coming across http://picfx.codeplex.com a while back and it provided very handy way to creating and applying effects to WriteableBitmaps. I used the few supplied to get stared however before long i was asked if i could provide a way of making images darker. The most common scenario is when you use flash and the images are too white – especially faces. As i started, i remembered face detection post by Rene. http://channel9.msdn.com/coding4fun/articles/FaceLight–Silverlight-4-Real-Time-Face-Detection.

I started with Rene’s YCbCr code and the first pass to detect whether color falls into skin tone range. The first pass for skin tone detection worked just fine, how search began on how to increase or decrease luminance of image. I came across HSLColor which had an ligthen / darken method but that did’t work so eventually, i used Lerp

public int[] Process(int[] inputPixels, int width, int height)
      {
          var resultPixels = new int[inputPixels.Length];

          // Threshold every pixel
          for (int i = 0; i < inputPixels.Length; i++)
          {
              int c = inputPixels[i];

              var ycbcr = YCbCrColor.FromArgbColori(c);
              if (ycbcr.Y >= LowerThreshold.Y && ycbcr.Y <= UpperThreshold.Y
               && ycbcr.Cb >= LowerThreshold.Cb && ycbcr.Cb <= UpperThreshold.Cb
               && ycbcr.Cr >= LowerThreshold.Cr && ycbcr.Cr <= UpperThreshold.Cr)
              {
                  // skin tone match 
                  System.Windows.Media.Color sc = System.Windows.Media.Color.FromArgb((byte)(c >> 24), (byte)(c >> 16), (byte)(c >> 8), (byte)c);

                  Microsoft.Xna.Framework.Color xc = new Microsoft.Xna.Framework.Color(sc.R, sc.G, sc.B, sc.A);
                  xc = Color.Lerp(xc, Color, Amout);

                  c = (255 << 24) | ((byte)(xc.R > 255 ? 255 : xc.R) << 16) | ((byte)(xc.G > 255 ? 255 : xc.G) << 8) | (byte)(xc.B > 255 ? 255 : xc.B);
              }
              
              resultPixels[i] = c;
          }

          return resultPixels;
      }

Now all you need to do is pass the amount to Lerp and the color. To Darken you pass Black, to lighten, you pass White.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s