Note that there are some explanatory texts on larger screens.

plurals
  1. PORecognizing image within image in C#
    text
    copied!<p>I'd like to find an image (<em>needle</em>) within an image (<em>haystack</em>).</p> <p>To keep things simple I take two screenshots of my desktop. One full size (<em>haystack</em>) and a tiny one (<em>needle</em>). I then loop through the haystack image and try to find the needle image.</p> <ol> <li>capture needle and haystack screenshot</li> <li>loop through haystack, looking out for haystack[i] == first pixel of needle</li> <li>[if 2. is true:] loop through the 2nd to last pixel of needle and compare it to haystack[i]</li> </ol> <p>Expected result: the needle image is found at the correct location.</p> <p>I already got it working for some coordinates/widths/heights (A).</p> <p>But sometimes bits seem to be "off" and therefore <strong>no match is found</strong> (B).</p> <p>What could I be doing wrong? Any suggestions are welcome. Thanks.</p> <hr> <pre><code>var needle_height = 25; var needle_width = 25; var haystack_height = 400; var haystack_width = 500; </code></pre> <hr> <p><strong>A. example input - match</strong></p> <pre><code>var needle = screenshot(5, 3, needle_width, needle_height); var haystack = screenshot(0, 0, haystack_width, haystack_height); var result = findmatch(haystack, needle); </code></pre> <p><strong>B. example input - NO match</strong></p> <pre><code>var needle = screenshot(5, 5, needle_width, needle_height); var haystack = screenshot(0, 0, haystack_width, haystack_height); var result = findmatch(haystack, needle); </code></pre> <hr> <p><strong>1. capture needle and haystack image</strong></p> <pre><code>private int[] screenshot(int x, int y, int width, int height) { Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); Graphics.FromImage(bmp).CopyFromScreen(x, y, 0, 0, bmp.Size); var bmd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); var ptr = bmd.Scan0; var bytes = bmd.Stride * bmp.Height / 4; var result = new int[bytes]; Marshal.Copy(ptr, result, 0, bytes); bmp.UnlockBits(bmd); return result; } </code></pre> <p><strong>2. try to find a match</strong></p> <pre><code>public Point findmatch(int[] haystack, int[] needle) { var firstpixel = needle[0]; for (int i = 0; i &lt; haystack.Length; i++) { if (haystack[i] == firstpixel) { var y = i / haystack_height; var x = i % haystack_width; var matched = checkmatch(haystack, needle, x, y); if (matched) return (new Point(x,y)); } } return new Point(); } </code></pre> <p><strong>3. verify full match</strong> </p> <pre><code>public bool checkmatch(int[] haystack, int[] needle, int startx, int starty) { for (int y = starty; y &lt; starty + needle_height; y++) { for (int x = startx; x &lt; startx + needle_width; x++) { int haystack_index = y * haystack_width + x; int needle_index = (y - starty) * needle_width + x - startx; if (haystack[haystack_index] != needle[needle_index]) return false; } } return true; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload