Vb.Net Проверьте, существует ли изображение в другом изображении
Я пытался проверить, существует ли часть изображения в другом изображении
Объяснение:
полное изображение:
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
2 ответа
Я написал это расширение, чтобы найти изображение в изображении. Однако он имеет несколько ограничений: 1) изображения должны быть сохранены без цветового пространства (или в любом случае одинаковых) и 2) он не будет работать с изображениями со сжатием с потерями (т. Е. Jpeg, для этого необходимо усреднение и допуск реализация).
Я оптимизировал процедуру сопоставления пикселей. Это не полностью отлажено, но, кажется, работает как ожидалось. Он игнорирует альфа-канал (намеренно расширяет по мере необходимости), и вам нужно попытаться поймать вызывающего (т.е. исключение нехватки памяти).
Использование:
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
Вы можете просто написать функцию, чтобы пройти через все возможные пиксели верхнего левого угла второго изображения, затем скопировать пиксели в другой растровый объект, а затем сравнить новый растровый объект со вторым пикселем изображения для пикселя.
Итак, сначала вы бы перебрать пиксели в
- x
- y
- y
Если пиксель в точке (x, y) на основном изображении имеет то же значение цвета, что и пиксель в точке (0, 0) на подизображении, скопируйте область, начинающуюся с (x, y), с теми же размерами, что и у вашего изображения. субизображение из вашего основного изображения в новый растровый объект с помощью функции, подобной этой - http://msdn.microsoft.com/en-us/library/aa457087.aspx
Затем просто прокрутите пиксели в новом объекте и вашем подизображении, сравнивая цвета по тем же координатам, что и вы. Разорвать петлю, если вы столкнулись с разницей. Если вы дойдете до конца этого цикла, у вас будет совпадение и вы сможете вернуть значение True, в противном случае продолжайте циклически проходить по пикселям основного изображения до тех пор, пока не достигнете точки, в которой подизображение больше не сможет поместиться, а затем верните значение False.,