0

I have a function in C# which compare two images and finds the differences between them. The problem is that it is too slow. How can I optimize the code by using bytes instead of GetPixel() method?

The speed of this calculus is 0.34 seconds and I should do it in at least ten times less. Some colleague told me I can improve the speed by using bytes.

private void btnGo_Click(object sender, EventArgs e)
{
    this.Cursor = Cursors.WaitCursor;
    Application.DoEvents();

    // Load the images.
    Bitmap bm1 = (Bitmap)picImage1.Image;
    Bitmap bm2 = (Bitmap)picImage2.Image;

    // Make a difference image.
    int wid = Math.Min(bm1.Width, bm2.Width);
    int hgt = Math.Min(bm1.Height, bm2.Height);
    Bitmap bm3 = new Bitmap(wid, hgt);

    // Create the difference image.
    bool are_identical = true;
    Color eq_color = Color.White;
    Color ne_color = Color.Red;
    for (int x = 0; x < wid; x++)
    {
        for (int y = 0; y < hgt; y++)
        {
             if (bm1.GetPixel(x, y).Equals(bm2.GetPixel(x, y)))
                bm3.SetPixel(x, y, eq_color);
             else
             {
                bm3.SetPixel(x, y, ne_color);
                are_identical = false;
             }
        }
    }

    // Display the result.
    picResult.Image = bm3;

    this.Cursor = Cursors.Default;
    if ((bm1.Width != bm2.Width) || (bm1.Height != bm2.Height)) 
    are_identical = false;
    if (are_identical)
        lblResult.Text = "The images are identical";
    else
        lblResult.Text = "The images are different";
  }

By using bytes I should be able to have this computation in 0.04 seconds.

AlketCecaj
  • 117
  • 1
  • 11
  • Consider that essentially your question might be a duplicate of this one: https://stackoverflow.com/questions/7350679/convert-a-bitmap-into-a-byte-array - and this question also would have some relevance: https://stackoverflow.com/questions/24701703/c-sharp-faster-alternatives-to-setpixel-and-getpixel-for-bitmaps-for-windows-f – Caius Jard Sep 06 '19 at 12:04
  • Thank you for the link. I actually have seen it as well as the one here : https://stackoverflow.com/questions/29925561/faster-c-sharp-image-processing The problem is I don't know how to compare the bytes in order to find the differences in the two images. With pixels is easier but how can I do it with bytes ? – AlketCecaj Sep 06 '19 at 12:10
  • Check out this post: https://stackoverflow.com/questions/26224095/how-to-find-the-difference-between-two-images – skolldev Sep 06 '19 at 12:14
  • 1
    The second link goes into some detail on this, but essentially in a bitmap that is ARGB format, there's a byte for the Alpha, a byte for the Red, byte for Green and byte for Blue, per pixel.. So 4 bytes per pixel.. If you have one array of bytes that is eg `[0x7F, 0xFF, 0x00, 0x00]` its a sort of semi transparent red and another that is `[0x7F, 0x00, 0xFF, 0x00]` it's a sort of semi transparent green - so the images are different there.. But also consider if you have two images as byte arrays and then you build a third image that starts out also as a byte array, you don't even need.. – Caius Jard Sep 06 '19 at 12:15
  • 1
    ..to interpret the bytes as pixels; if any byte in each block of 4 differs, just write a 4bytes representation of NE_COLOR to the output byte array.. Youre not considering things as pixels, it's essentially a purely byte-by-byte difference with an output that plops out blocks of 4 bytes (and if you find a difference in the first bytes of a 4 byte input block, skip the next 3 bytes of the input block) – Caius Jard Sep 06 '19 at 12:19
  • I see! Well, thank you very much for your insight! I will try this approach. – AlketCecaj Sep 06 '19 at 12:21
  • 1
    Look up Lockbits ! – TaW Sep 06 '19 at 12:26
  • @CaiusJard Actually, "ARGB" refers to a single little-endian integer; the actual byte components inside it are _reversed_. This means that as byte array, the order for one ARGB pixel is [B, G, R, A]. Also, the first link you commented here has most answers focusing on just saving the image in an image format, not extracting the pixel data. Might've been better to link to one of the actual answers there. – Nyerguds Sep 17 '19 at 09:00

0 Answers0