5

I Tried To Check If Part Of Image Existing In Another Image

Explanation:


full image:
http://imageshack.us/photo/my-images/526/part1g.png/

second part of image that i want to check if he existing in the full image:
http://imageshack.us/photo/my-images/706/part2p.png/

if the second part is Exist then the function return true
there is a function that can check if it exist?


(if it was only Single pixel then it was verey easy, but i want to check if Part Of Image Existing In Another Image)
there is a code that works , but it check if Single pixel exist in image:

    Dim bmp As Bitmap = PictureBox1.Image
    For x As Integer = 0 To bmp.Width - 1
        For y As Integer = 0 To bmp.Height - 1
            If bmp.GetPixel(x, y) = Color.FromArgb(48, 48, 48) Then
                msgbox("Pixel Exist In Image!!!")
            End If
        Next
    Next
roger janety
  • 61
  • 2
  • 8
  • someone?? I'm supposed to convert all image into array and then "instr" – roger janety Jun 05 '12 at 15:16
  • I wonder if steghide would do the job (or anything like it)? It is used to find if something is contained into an image. And it can add something into an image. Its command oriented so relatively easy to use. In this case, the second image is not hidden in the first one, but worth the try. I will try something with the images you gave us tonight. will keep you informed. I hope this will work. It should then save lots of work. – Minus Jun 07 '12 at 00:17
  • It did not work at all ( first images are not in a recognized format, second it can not compare 2 images, but create something from an image if there is something to extract ) – Minus Jun 07 '12 at 00:17
  • if you find something else that works i would love to hear about it,tnx about everything. – roger janety Jun 07 '12 at 10:52

2 Answers2

3

I wrote this extension to find an image within an image. It has a couple of limitations though: 1) The images must be saved without color-space (or the same ones anyways) and 2) It will not work with lossy-compressed images (ie. jpeg, for that you need averaging and tolerance implementation).

I have optimized the pixel matching routine. It's not fully debugged, but seem to work as expected. It ignores the alpha-channel (on purpose, extend as needed) and you need to try-catch on your caller (ie. out-of-memory exception).

Usage:

Dim p As Point = yourBitmap.Contains(bmpYouLookFor)
If p <> Nothing Then
'...
End If

The code: If you don't want to have it as an extension (which requires .net 3.5+) just remove the extension attribute and call it as an ordinary function with your source bitmap as an argument instead.

Copy and paste the following into a module (license: CC-attribution):

'*******************************************************************************
'*
'*      Epistemex
'*
'*      Bitmap extension: .Contains(bmp)
'*      KF
'*
'*      2012-09-26      Initial version
'*      2012-09-26      Minor optimization, exit for's impl.
'*
'*******************************************************************************

Imports System.Drawing
Imports System.Runtime.CompilerServices
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices

Module BitmapExtension

    <Extension()>
    Public Function Contains(src As Bitmap, ByRef bmp As Bitmap) As Point
        '
        '-- Some logic pre-checks
        '
        If src Is Nothing OrElse bmp Is Nothing Then Return Nothing

        If src.Width = bmp.Width AndAlso src.Height = bmp.Height Then
            If src.GetPixel(0, 0) = bmp.GetPixel(0, 0) Then
                Return New Point(0, 0)
            Else
                Return Nothing
            End If

        ElseIf src.Width < bmp.Width OrElse src.Height < bmp.Height Then
            Return Nothing

        End If
        '
        '-- Prepare optimizations
        '
        Dim sr As New Rectangle(0, 0, src.Width, src.Height)
        Dim br As New Rectangle(0, 0, bmp.Width, bmp.Height)

        Dim srcLock As BitmapData = src.LockBits(sr, Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb)
        Dim bmpLock As BitmapData = bmp.LockBits(br, Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb)

        Dim sStride As Integer = srcLock.Stride
        Dim bStride As Integer = bmpLock.Stride

        Dim srcSz As Integer = sStride * src.Height
        Dim bmpSz As Integer = bStride * bmp.Height

        Dim srcBuff(srcSz) As Byte
        Dim bmpBuff(bmpSz) As Byte

        Marshal.Copy(srcLock.Scan0, srcBuff, 0, srcSz)
        Marshal.Copy(bmpLock.Scan0, bmpBuff, 0, bmpSz)

        ' we don't need to lock the image anymore as we have a local copy
        bmp.UnlockBits(bmpLock)
        src.UnlockBits(srcLock)

        Dim x, y, x2, y2, sx, sy, bx, by, sw, sh, bw, bh As Integer
        Dim r, g, b As Byte

        Dim p As Point = Nothing

        bw = bmp.Width
        bh = bmp.Height

        sw = src.Width - bw      ' limit scan to only what we need. the extra corner
        sh = src.Height - bh     ' point we need is taken care of in the loop itself.

        bx = 0 : by = 0
        '
        '-- Scan source for bitmap
        '
        For y = 0 To sh
            sy = y * sStride
            For x = 0 To sw

                sx = sy + x * 3
                '
                '-- Find start point/pixel
                '
                r = srcBuff(sx + 2)
                g = srcBuff(sx + 1)
                b = srcBuff(sx)

                If r = bmpBuff(2) AndAlso g = bmpBuff(1) AndAlso b = bmpBuff(0) Then
                    p = New Point(x, y)
                    '
                    '-- We have a pixel match, check the region
                    '
                    For y2 = 0 To bh - 1
                        by = y2 * bStride
                        For x2 = 0 To bw - 1
                            bx = by + x2 * 3

                            sy = (y + y2) * sStride
                            sx = sy + (x + x2) * 3

                            r = srcBuff(sx + 2)
                            g = srcBuff(sx + 1)
                            b = srcBuff(sx)

                            If Not (r = bmpBuff(bx + 2) AndAlso
                                    g = bmpBuff(bx + 1) AndAlso
                                    b = bmpBuff(bx)) Then
                                '
                                '-- Not matching, continue checking
                                '
                                p = Nothing
                                sy = y * sStride
                                Exit For
                            End If

                        Next
                        If p = Nothing Then Exit For
                    Next
                End If 'end of region check

                If p <> Nothing Then Exit For
            Next
            If p <> Nothing Then Exit For
        Next

        bmpBuff = Nothing
        srcBuff = Nothing

        Return p

    End Function

End Module
0

You could just write a function to loop through every possible upper-left corner pixel of the second image, then copy the pixels out to another bitmap object, then compare the new bitmap object to your second image pixel for pixel.

So first you would loop through pixels at

  • x < mainImageWidth - subImageWidth
  • y < mainImageHeight - subImageHeight

If the pixel at (x, y) in the main image has the same colour value as the pixel at (0, 0) in the sub-image, copy out the area starting from (x, y) with the same dimensions as your sub-image from your main image to a new Bitmap object using a function like this one - http://msdn.microsoft.com/en-us/library/aa457087.aspx

Then just loop through the pixels in the new object and your sub-image, comparing colours at the same coordinates as you go. Break the loop if you encounter a difference. If you get to the end of this loop, you have a match and can return True, otherwise continue looping through the pixels of the main image until you hit a point where it's impossible for the sub-image to fit any more, then return False.

Seyren
  • 340
  • 1
  • 3
  • 15