I wrote perfectly working code that reads an image, and then does a kind of threshold on it by zone. If the zone has too much white then it turns all the zone into white, otherwise it turns into black.
The problem is that the code was originally from a C++ source with pointers and all instead of GetPixel()
etc. Speed was just instant, nothing more. Now that I rewrote "safely" (no pointers thingy), it take like 20 seconds per images, so instant versus 20 seconds = insane difference.
Could any of you help me improve that small code, even if you use back unsafe pointers code etc? I don't really care about that. The part I absolutely need is speed, and it has to be quick as possible because I will deal with huge images library. Instead of taking 30 minutes, it will literally takes days.
private Bitmap doti(Bitmap imag)
{
int threshold = 7;
int distance = 9;
int rows, cols, row, col, x, y, count;
int dhalf = (distance / 2) + 1;
int Sqdistance = SQ(distance);
rows = imag.Height;
cols = imag.Width;
Bitmap bitmap0 = (Bitmap)imag.Clone();
Bitmap bitmap = new Bitmap(cols, rows);
Bitmap outmap = new Bitmap(cols, rows);
//convert to grayscale of a single byte
for (row = 0; row < rows; row++)
for (col = 0; col < cols; col++)
{
Color pixel = bitmap0.GetPixel(col, row);
byte grayish = (byte)Math.Floor((decimal)(pixel.R + pixel.G + pixel.B) / 3);
bitmap.SetPixel(col, row, Color.FromArgb(grayish, grayish, grayish));
}
//check our threshold to set black or white by checking each pixels in a square defined by distance.
for (row = 0; row < rows; row++)
for (col = 0; col < cols; col++)
{
count = 0;
//could optimize here heavily maybe, by only checking inside a circle rather than square+dist.
for (x = Math.Max(col - dhalf, 0); x < Math.Min(col + dhalf, cols); x++)
for (y = Math.Max(row - dhalf, 0); y < Math.Min(row + dhalf, rows); y++)
{
//if inside the square and pixel color is not black count one more not black pixel
if ((Sqdistance > DISTANCE(col, row, x, y)) && ((bitmap.GetPixel(x, y).R) > 0)) //this second condition is killing a lot the speed to begin.
count++;
}
//if too much count of not black pixel, set it white.
if (count >= threshold)
outmap.SetPixel(col, row, Color.FromArgb(255, 255, 255));
else
outmap.SetPixel(col, row, Color.FromArgb(0, 0, 0));
}
return outmap;
}
SQ()
and DISTANCE()
:
private int SQ(int a) { return ((a) * (a)); }
private int DISTANCE(int a, int b, int c, int d) { return (SQ(a - c) + SQ(b - d)); }
for
loops intoforeach
loops \$\endgroup\$