CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    Sep 2004
    Posts
    57

    I have function that finds a smaller image within a big image, but I'm stuck

    Here's my function that takes two bitmaps as parameters. The first bitmap is a larger image, and the second image is a smaller image. The function then searches through the larger image to see if the smaller image is a part of it. It works with a 5x5 and 4x4 bitmap. The 5x5 bitmap is all black, except the left and top edge(1px width) is white. The 4x4 image is all black. When I start to do more complex images, such as a 50x50 image that is a piece of my desktop and a 40x40 piece that is a smaller piece of that piece, it fails.

    I will attach 4 small bmp files that work with the function.

    Code:
    public bool Compare(Bitmap bmp1, Bitmap bmp2)
            {
                bool mismatch = false;
    
                BitmapData bmData_1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height),
                    ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                int stride_1 = bmData_1.Stride;
                System.IntPtr Scan0_1 = bmData_1.Scan0;
    
                BitmapData bmData_2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height),
                   ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                int stride_2 = bmData_2.Stride;
                System.IntPtr Scan0_2 = bmData_2.Scan0;
    
    
                unsafe
                {
                    byte* p_1 = (byte*)(void*)Scan0_1;
                    byte* p_2 = (byte*)(void*)Scan0_2;
                    byte* tempP_1 = p_1;
                    byte* tempP_2 = p_2;
                    int nOffset_1 = stride_1 - bmp1.Width * 3;
                    int nOffset_2 = stride_2 - bmp2.Width * 3;
                    int nWidth_1 = bmp1.Width * 3;
                    int nWidth_2 = bmp2.Width * 3;
    
                    for (int y = 0; y < bmp1.Height - bmp2.Height + 1; y++)
                    {
                        for (int x = 0; x < nWidth_1 - nWidth_2 + 3; x++)
                        {
                            tempP_1 = p_1;
                            for (int i = 0; i < bmp2.Height; i++)
                            {
                                for (int j = 0; j < nWidth_2; j++)
                                {
                                    // If there is a mismatch, the go to the next pixel
                                    // in the bigger image
                                    mismatch = false;
                                    if (tempP_1[j] != tempP_2[0])
                                    {
                                        mismatch = true;
                                        break;
                                    }
                                    if (i == bmp2.Height - 1 && j == nWidth_2 - 1)
                                    { // We are finished
                                        txtX.Text = x.ToString();
                                        txtY.Text = y.ToString();
                                        return true;
                                    }
                                    // Move over to the next column
                                    ++tempP_2;
                                }
                                // If there is a mismatch, the go to the next pixel
                                // in the bigger image
                                if (mismatch)
                                {
                                    // The temp pointer for the smaller image
                                    // can be reset because the search is starting
                                    // over with the next pixel in the larger image
                                    tempP_2 = p_2;
                                    break;
                                }
                                // Increase the temp pointer for the larger image to
                                // go to the next row but the same column.
                                tempP_1 += (nWidth_1 - x) + nOffset_1;
                                // Go to the next row for the temp pointer for the
                                // smaller image
                                tempP_2 += nOffset_2;
                            }
                            ++p_1; // Move over 1 column
                        }
                        p_1 += nWidth_2 + nOffset_1; // Move down one row
                    }
                }
    
                bmp1.UnlockBits(bmData_1);
                bmp2.UnlockBits(bmData_2);
    
                return false;
            }
    Am I going about this the totally wrong way? Pretending that this worked correctly...is there a faster or more efficient way to do this? I eventually want to be able to search the whole screen(could be up to 1600x1200 if needed) for an image maybe at MAX 100x100(if that) in under a second(Is that possible? If not, what's the most positive estimate?)

    Any help or comments is very welcome.

    Thanks!
    Jon
    Attached Images Attached Images     

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured