/// <summary> /// Process the filter on the specified image. /// </summary> /// /// <param name="sourceData">Source image data.</param> /// <param name="destinationData">Destination image data.</param> /// protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData) { int width = sourceData.Width; int height = sourceData.Height; int pixelSize = System.Drawing.Image.GetPixelFormatSize(sourceData.PixelFormat) / 8; int srcStride = sourceData.Stride; int dstStride = destinationData.Stride; int srcOffset = srcStride - width * pixelSize; int dstOffset = dstStride - width * pixelSize; byte *src = (byte *)sourceData.ImageData.ToPointer(); byte *dst = (byte *)destinationData.ImageData.ToPointer(); // TODO: Move or cache the creation of those filters int[,] kernel = Accord.Math.Matrix.Create(radius * 2 + 1, radius * 2 + 1, 1); Convolution conv = new Convolution(kernel); FastVariance fv = new FastVariance(radius); // Mean filter UnmanagedImage mean = conv.Apply(sourceData); // Variance filter UnmanagedImage var = fv.Apply(sourceData); // do the processing job if (sourceData.PixelFormat == PixelFormat.Format8bppIndexed) { byte *srcVar = (byte *)var.ImageData.ToPointer(); byte *srcMean = (byte *)mean.ImageData.ToPointer(); // Store maximum value from variance. int maxV = Max(width, height, srcVar, srcOffset); // Store minimum value from image. int minG = Min(width, height, src, srcOffset); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, src++, srcMean++, srcVar++, dst++) { double mP = *srcMean; double vP = *srcVar; double threshold = (mP + k * ((Math.Sqrt(vP) / (double)maxV - 1.0) * (mP - (double)minG))); *dst = (byte)(*src > threshold ? 255 : 0); } src += srcOffset; srcMean += srcOffset; srcVar += srcOffset; dst += dstOffset; } } }
private void SetFilter() { if (fast) { ImageType = ImageTypes.Rgb24bpp; Af.FastVariance newFilter = new Af.FastVariance(); newFilter.Radius = radius; imageFilter = newFilter; } else { ImageType = ImageTypes.Rgb24bpp; Af.Variance newFilter = new Af.Variance(); newFilter.Radius = radius; imageFilter = newFilter; } }
/// <summary> /// Process the filter on the specified image. /// </summary> /// /// <param name="sourceData">Source image data.</param> /// <param name="destinationData">Destination image data.</param> /// protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData) { int width = sourceData.Width; int height = sourceData.Height; int pixelSize = System.Drawing.Image.GetPixelFormatSize(sourceData.PixelFormat) / 8; int srcStride = sourceData.Stride; int dstStride = destinationData.Stride; int srcOffset = srcStride - width * pixelSize; int dstOffset = dstStride - width * pixelSize; byte* src = (byte*)sourceData.ImageData.ToPointer(); byte* dst = (byte*)destinationData.ImageData.ToPointer(); // TODO: Move or cache the creation of those filters int[,] kernel = Accord.Math.Matrix.Create(radius * 2 + 1, radius * 2 + 1, 1); Convolution conv = new Convolution(kernel); FastVariance fv = new FastVariance(radius); // Mean filter UnmanagedImage mean = conv.Apply(sourceData); // Variance filter UnmanagedImage var = fv.Apply(sourceData); // do the processing job if (sourceData.PixelFormat == PixelFormat.Format8bppIndexed) { byte* srcVar = (byte*)var.ImageData.ToPointer(); byte* srcMean = (byte*)mean.ImageData.ToPointer(); // Store maximum value from variance. int maxV = Max(width, height, srcVar, srcOffset); // Store minimum value from image. int minG = Min(width, height, src, srcOffset); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, src++, srcMean++, srcVar++, dst++) { double mP = *srcMean; double vP = *srcVar; double threshold = (mP + k * ((Math.Sqrt(vP) / (double)maxV - 1.0) * (mP - (double)minG))); *dst = (byte)(*src > threshold ? 255 : 0); } src += srcOffset; srcMean += srcOffset; srcVar += srcOffset; dst += dstOffset; } } }