5

Before someone flames me for not checking the other posts, I have done that already. I have a specific question about one of the techniques that exist to convert an image to grayscale.

I have read through the other posts on SO and basically copied technique 3 (ColorMatrix) from the tutorial at this site. It works very, very, quickly.

The problem I'm having is that what I need is a pure BW image. (i.e.: if average(R,B,G) > 200 => white else black). I have implemented it the straightforward way, and it actually takes nearly 10x as long as the grayscale algorithm from the tutorial.

I am no expert with image processing, and was wondering if there is any way to modify the snippet from the tutorial to convert images to pure black and white. If not, any efficient way would do.

EDIT:

Here's the code I'm using for the black and white (no brain approach):

public Bitmap make_bw(Bitmap original) {

    Bitmap output = new Bitmap(original.Width, original.Height);

    for (int i = 0; i < original.Width; i++) {

        for (int j = 0; j < original.Height; j++) {

            Color c = original.GetPixel(i, j);

            int average = ((c.R + c.B + c.G) / 3);

            if (average < 200)
                output.SetPixel(i, j, Color.Black);

            else
                output.SetPixel(i, j, Color.White);

        }
    }

    return output;       

}
user472875
  • 2,965
  • 4
  • 32
  • 66
  • You don't really need a color matrix to convert to a 1-bit (pure black and white) image. Try the second solution and see if that's any faster. (If not, please post your code.) – Cody Gray Feb 15 '11 at 06:56
  • cal you paste some code that is performing badly? how can something add 10x more time if you add only one 'if' to it? – Daniel Mošmondor Feb 15 '11 at 06:56

3 Answers3

3

I'm using this simple code:

public Bitmap GrayScaleFilter(Bitmap image)
{
    Bitmap grayScale = new Bitmap(image.Width, image.Height);

    for (Int32 y = 0; y < grayScale.Height; y++)
        for (Int32 x = 0; x < grayScale.Width; x++)
        {
            Color c = image.GetPixel(x, y);

            Int32 gs = (Int32)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);

            grayScale.SetPixel(x, y, Color.FromArgb(gs, gs, gs));
        }
    return grayScale;
}
3

Read this, same problem: What would be a good TRUE black and white colormatrix?

Community
  • 1
  • 1
xanatos
  • 102,557
  • 10
  • 176
  • 249
2

This guy makes three tests, the fastests being the ColorMatrix as mentioned here. External link about image conversion

BUT one of the commenters claims that the reason the direct and unsafe pixel access method is slower is calls to .Width and .Height in the bitmaps and copying these values to local variables makes direct pixel access substantially faster.

I tested this and it seems that the unsafe method is approximately 2.5 times faster than using the ColorMatrix. But it is arguably also more involved and obviously it requires that unsafe code is allowed in the project which might not be desirable.

faester
  • 14,108
  • 3
  • 40
  • 54
  • 1
    Please don't just include links to external articles without adding any examples here. Now link is dead and there is no way of knowing how to implement that. – kv1dr Dec 01 '20 at 08:47