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;
}
}
}