/// <summary> /// Return a bitmap that is a thresholded version of the given. The ultimate threashold value is a matter of /// emperical testing. 175 is used. /// </summary> /// <param name="s"></param> /// <returns></returns> protected Bitmap Threshold(Bitmap s) { // first threshold to the magic number Bitmap b = new Bitmap(s); ImageUtility.ThresholdImage(b, 175.0f / 255.0f); float[] kernel = ImageUtility.GetGaussianBlurKernel(3, 15); Bitmap b1 = ImageUtility.Convolve(b, kernel, 3); b.Dispose(); ImageUtility.ThresholdImage(b1, 1.0f / 255.0f); // return new image return(b1); }
/// <summary> /// Create a new image based on the given sub image with the candidate red eye removed /// </summary> /// <param name="b"></param> public Bitmap ProcessImage(Bitmap b) { // temporary images used to remove red eye Bitmap rednessMask = null, rednessThreshold = null, falseColor = null, noSmallIslands = null, noHoles = null, blured = null; // the image to return Bitmap newImage = null; try { // get a CIEMap of the image and the min/max CIE L values for the image double minL, maxL; CIELab[] cieMap = this.GetCIELABImage(b, out minL, out maxL); // get redness mask image rednessMask = this.GetMaskImage(cieMap, b.Width, b.Height); // get a threshold of the redness mask rednessThreshold = this.Threshold(rednessMask); // create a blob map from the threasholded image BlobMap blobmap = new BlobMap(rednessThreshold); // create a false color copy of the thresholded images falseColor = (Bitmap)rednessThreshold.Clone(); blobmap.ColorIslands(falseColor); // remove all islands meeting a certain size criteria noSmallIslands = (Bitmap)rednessThreshold.Clone(); blobmap.RemoveIslands(noSmallIslands); // create a version with the holes filled noHoles = this.FillHoles(noSmallIslands); // get a guassian blurred version of the final mask float[] kernel = ImageUtility.GetGaussianBlurKernel(3, 15); blured = ImageUtility.Convolve(noHoles, kernel, 3); // create new image newImage = this.GetNewImage(cieMap, // CIE Lab image of the source minL, maxL, // min/max CIE L* values in the map blured); // the final mask to be used // return new image return(newImage); } catch (Exception) { } finally { // cleanup any temporaries used if (rednessMask != null) { rednessMask.Dispose(); } if (rednessThreshold != null) { rednessThreshold.Dispose(); } if (falseColor != null) { falseColor.Dispose(); } if (noSmallIslands != null) { noSmallIslands.Dispose(); } if (noHoles != null) { noHoles.Dispose(); } if (blured != null) { blured.Dispose(); } } // return new image return(newImage); }