idbehold
Новичок
- Сообщения
- 42
- Репутация
- 4
Добрый день.
Есть два изображения, одинакового разрешения.
Нужно их сравнить и получить разницу, с учетом допустимого отклонения цвета
Для расчета отклонения я использую формулу расстояния между точками.
Для получения информации о цвете пикселя использую GdipBitmapGetPixel
Все работает, я получаю нужный результат, но скрипт работает медленно.
На сравнение изображений размером 500х300 у меня уходит 5 секунд.
Как можно ускорить обработку? Именно обход по всем пикселям изображения - мне не нужно ничего рисовать на GUI и тд - просто сравнить и найти разницу.
Есть какой-то способ быстро обойти все пиксели на изображении?
Вот скрипт:
Во вложении архив с этим скриптом и исходные картинки
Есть два изображения, одинакового разрешения.
Нужно их сравнить и получить разницу, с учетом допустимого отклонения цвета
Для расчета отклонения я использую формулу расстояния между точками.
Для получения информации о цвете пикселя использую GdipBitmapGetPixel
Все работает, я получаю нужный результат, но скрипт работает медленно.
На сравнение изображений размером 500х300 у меня уходит 5 секунд.
Как можно ускорить обработку? Именно обход по всем пикселям изображения - мне не нужно ничего рисовать на GUI и тд - просто сравнить и найти разницу.
Есть какой-то способ быстро обойти все пиксели на изображении?
Вот скрипт:
Код:
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.14.5
#ce ----------------------------------------------------------------------------
#include <GDIPlus.au3>
#include <GUIConstants.au3>
_GDIPlus_Startup()
$hImageOne = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\test_image_1.png')
$hImageTwo = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\test_image_2.png')
Global $iImageWidth = _GDIPlus_ImageGetWidth($hImageOne)
Global $iImageHeight = _GDIPlus_ImageGetHeight($hImageOne)
If ($iImageWidth <> _GDIPlus_ImageGetWidth($hImageTwo) or $iImageHeight <> _GDIPlus_ImageGetHeight($hImageTwo)) Then
ConsoleWriteError('Images must have equal size' & @CRLF)
Exit;
EndIf
Global $g_hGUI = GUICreate("Debug GUI", $iImageWidth, $iImageHeight)
Global $g_hGraphic = _GDIPlus_GraphicsCreateFromHWND($g_hGUI)
GUISetState(@SW_SHOW)
_GDIPlus_GraphicsDrawImage($g_hGraphic, $hImageOne, 0, 0)
ImageDiff_GetPixel($hImageOne, $hImageTwo, 0.3)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
EndSwitch
WEnd
_GDIPlus_ImageDispose($hImageOne)
_GDIPlus_ImageDispose($hImageTwo)
_GDIPlus_Shutdown()
;----------------------------------------------------------
; ImageDiff
;----------------------------------------------------------
Func ImageDiff_GetPixel($hImgOne, $hImgTwo, $tolerance)
$dx = 441 * $tolerance
Local $countEqualsPixels = 0
Local $timer = TimerInit()
Local $tArgb = DllStructCreate("dword Argb")
Local $pArgb = DllStructGetPtr($tArgb)
Local $colorBinOne, $colorBinTwo
For $iY = 0 to $iImageHeight - 1
_GDIPlus_GraphicsDrawImage($g_hGraphic, $hImageOne, 0, 0)
For $iX = 0 to $iImageWidth - 1
; Get pixel RGB at x.y
DllCall($__g_hGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hImgOne, "int", $iX, "int", $iY, "ptr", $pArgb)
Local $colorOne = '0x' & Hex(DllStructGetData($tArgb, "Argb"), 8)
$iOneRed = BitAND(BitShift($colorOne, 16), 0xFF)
$iOneGreen = BitAND(BitShift($colorOne, 8), 0xFF)
$iOneBlue = BitAND($colorOne, 0xFF)
DllCall($__g_hGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hImgTwo, "int", $iX, "int", $iY, "ptr", $pArgb)
Local $colorTwo = '0x' & Hex(DllStructGetData($tArgb, "Argb"), 8)
$iTwoRed = BitAND(BitShift($colorTwo, 16), 0xFF)
$iTwoGreen = BitAND(BitShift($colorTwo, 8), 0xFF)
$iTwoBlue = BitAND($colorTwo, 0xFF)
$distance = Sqrt( ($iOneRed - $iTwoRed)^2 + ($iOneGreen - $iTwoGreen)^2 + ($iOneBlue - $iTwoBlue)^2 )
if $distance < $dx Then
$countEqualsPixels += 1
Else
; not equal logic
DllCall($__g_hGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hImgOne, "int", $iX, "int", $iY, "dword", 0xFF000000)
EndIf
Next
Next
$countPixels = $iImageWidth * $iImageHeight
ConsoleWrite('Diff time : ' & TimerDiff($timer) & @CRLF);
ConsoleWrite('percent : ' & (($countEqualsPixels / $countPixels ) * 100) & @CRLF);
ConsoleWrite('pixels : ' & $countEqualsPixels & '/' & $countPixels & @CRLF);
EndFunc
Во вложении архив с этим скриптом и исходные картинки