【问题标题】:Vb.Net Check If Image Existing In Another ImageVb.Net检查图像是否存在于另一个图像中
【发布时间】:2012-06-09 14:52:11
【问题描述】:

我试图检查图像的一部分是否存在于另一个图像中

解释:


全图:
http://imageshack.us/photo/my-images/526/part1g.png/

第二部分我想检查他是否存在于完整图像中
http://imageshack.us/photo/my-images/706/part2p.png/

如果第二部分是 Exist 则函数返回 true
有一个函数可以检查它是否存在?


(如果它只是单个像素,那么这很容易,但我想检查图像的一部分是否存在于另一个图像中)
有一个有效的代码,但它检查图像中是否存在单个像素

    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

【问题讨论】:

  • 某人??我应该将所有图像转换为数组,然后“instr”
  • 我想知道 steghide 是否能胜任这项工作(或类似的工作)?它用于查找图像中是否包含某些内容。它可以在图像中添加一些东西。它的命令导向所以相对容易使用。在这种情况下,第二张图片并没有隐藏在第一张图片中,但值得一试。我会用你今晚给我们的图像尝试一些东西。会及时通知您。我希望这会奏效。它应该可以节省大量工作。
  • 它根本不起作用(第一个图像不是可识别的格式,第二个它无法比较 2 个图像,但如果有要提取的东西,则从图像中创建一些东西)
  • 如果你找到其他有用的东西,我很想听听,关于一切。

标签: vb.net bitmap pixel


【解决方案1】:

我编写此扩展程序是为了在图像中查找图像。但是它有一些限制:1)图像必须在没有色彩空间的情况下保存(或无论如何都相同)和 2)它不适用于有损压缩图像(即 jpeg,因为你需要平均和容差实施)。

我已经优化了像素匹配例程。它没有完全调试,但似乎按预期工作。它会忽略 alpha 通道(故意,根据需要扩展),您需要尝试捕获调用者(即内存不足异常)。

用法:

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

代码:如果您不想将其作为扩展名(需要 .net 3.5+),只需删除扩展名属性并将其作为普通函数调用,并将源位图作为参数。

将以下内容复制并粘贴到模块中(许可证: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

【讨论】:

  • 把它当作一个普通的函数使用,它就像魅力一样!在我的机器上它也出奇的快:)
【解决方案2】:

您可以编写一个函数来遍历第二个图像的每个可能的左上角像素,然后将像素复制到另一个位图对象,然后将新的位图对象与您的第二个图像像素逐个像素地进行比较。

所以首先你会遍历像素

  • x
  • y

如果主图(x,y)处的像素与子图(0,0)处的像素颜色值相同,则复制出从(x,y)开始的区域,颜色相同尺寸作为从主图像到新位图对象的子图像,使用这样的功能 - http://msdn.microsoft.com/en-us/library/aa457087.aspx

然后只需循环遍历新对象和子图像中的像素,在相同坐标处比较颜色。如果遇到差异,请打破循环。如果你到达这个循环的结尾,你有一个匹配并且可以返回 True,否则继续循环遍历主图像的像素,直到你到达一个子图像不可能再适合的点,然后返回 False .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 2015-04-14
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多