/// <summary> /// /// </summary> /// <param name="img"></param> /// <param name="configs"></param> /// <returns></returns> public override byte[,] ApplyFilter(byte[,] img, SortedDictionary<string, object> configs) { byte[,] ret = null; FourierTransform ft = new FourierTransform(); // Preprocess image. int width = img.GetLength(0), height = img.GetLength(1), x, y; double[,] imgProcessed = new double[width, height]; const double magic = 0.5; //double min = double.MaxValue; //// Find min. //for (x = 0; x < width; ++x) //{ // for (y = 0; y < height; ++y) // { // min = Math.Min(img[x, y], min); // } //} // "normalize" for (x = 0; x < width; ++x) { for (y = 0; y < height; ++y) { imgProcessed[x, y] = Math.Log(img[x, y] + magic, Math.E); } } // Take fourier transform. ComplexImage homomorph = ft.ApplyTransformBase(imgProcessed); // (x)(a) Perform butterworth high pass to select reflectance; // perform butterworth low pass to select illuminance. // **** OR **** // (b) Apply butterworth-generated weigth to select reflectance (1.0 in center) // Apply (1.0 - butterworth-generated weigth) to select illuminance (0.0 in center) // **** OR **** // (c) Apply high pass buttwerworth. only. SortedDictionary<string, object> hConfigs = reflectGetter.GetDefaultConfigs(); hConfigs["D0"] = configs["Butterworth-D0"]; hConfigs["n"] = configs["Butterworth-n"]; ComplexImage reflect = reflectGetter.ApplyFilter(homomorph, hConfigs); ComplexImage illumin = illuminGetter.ApplyFilter(homomorph, hConfigs); // (1, 1) = imagem original // (1, 0) = high pass // (0, 1) = low pass double alpha = double.Parse(configs["Alpha"].ToString()); double beta = double.Parse(configs["Beta"].ToString()); // Generate new, Homomorphic-treated image //(c) //homomorph = illumin; // Split into reflectance and illuminance // - Sharp reflectance, smooth illuminance // - sum for (x = 0; x < homomorph.Width; ++x) { for (y = 0; y < homomorph.Height; ++y) { //(a) homomorph[x, y] = new Complex( reflect[x, y].real * beta + // Reflectance part illumin[x, y].real * alpha // Illuminance part , reflect[x, y].imag * beta + // Reflectance part illumin[x, y].imag * alpha // Illuminance part ); } } // ... back to spatial domain. imgProcessed = ft.ApplyReverseTransformBase(homomorph); // Pos-process image. ret = new byte[width, height]; for (x = 0; x < width; ++x) { for (y = 0; y < height; ++y) { ret[x, y] = (byte)Math.Max(byte.MinValue, Math.Min(byte.MaxValue, Math.Exp(imgProcessed[x, y]) - magic)); } } return ret; }