I've got a bunch of scanned microfiches in 1bpp format, all rather big,
about 6000 x 4000 pixels. Some of the fiches are in handwriting, and this
is why I want to make an algorithm that converts and smooths them into 8bpp
grayscale. After reading Bob Powells excellent "Understanding LockBits" I
was able to come up with this (initialization details omitted):
Bitmap bmOrg; // Format1bppIndexed image
Bitmap bmGray = new Bitmap(bmOrg.Width, bmOrg.Height,
PixelFormat.Format8bppIndexed);
// convert 1bpp to 8bpp, palette of bmGray is set to a grayscale one.
unsafe
{
for (y = 0; y < bmGray.Height; y++)
{
byte* pixelGray = (byte*)(void*)Scan0_gray + (y * strideGray);
byte* pixelOrg = (byte*)(void*)Scan0_org + (y * strideOrg);
for (x = 0; x < bmGray.Width; x++)
{
//ANDs between 128, 64, 32, 16, 8, 4, 2, 1 and the original image byte,
//to obtain the individual bits.
if ((1 << (7 - (x & 7)) & pixelOrg[x / 8]) != 0)
pixelGray[x] = 255;
else
pixelGray[x] = 0;
}
}
}
// smoothing algorithm. Idea is to calculate a mean value for a 2x2
// window, and set the four pixels to this mean value. In this way every
// pixel except those in the first row and the first column, will have it
// value changed twice.
unsafe
{
for (y = 0; y < bmGray.Height - 1; y++)
{
byte* pixel = (byte*)(void*)Scan0_gray + (y * strideGray);
for (x = 0; x < bmGray.Width - 1; x++)
{
mean = (pixel[x] + pixel[x + 1] + pixel[x + skip] + pixel[x + 1 +
skip]) / 4;
pixel[x] = pixel[x + 1] = pixel[x + skip] = pixel[x + 1 + skip] =
(byte)mean;
}
}
}
It works as intended, OK, but I'm not happy with the performance. On an old
Athlon 1800XP bitbucket the algorithm's running time on a 6000x4000 image
is about 8 seconds.
Any ideas how to tweak this mother?
Thanks in advance,