Pumbaa Posted January 2, 2014 Share Posted January 2, 2014 Hi All. I'm trying to get pics difference in %. I tried to use ImageMagickObject.dll as it is fast enough & free under it's license. expandcollapse popup#include <WindowsConstants.au3> $DllExist = 1 Global $oIM = ObjCreate ("ImageMagickObject.MagickImage.1") If @error OR NOT IsObj ($oIM) Then If NOT FileExists ("ImageMagickObject.dll") Then MsgBox (16, "!", "No ImageMagickObject.dll - work impossible.") Exit EndIf RunWait (@ComSpec & " /c regsvr32 /s ImageMagickObject.dll", @ScriptDir , @SW_HIDE) $DllExist = 0 $oIM = ObjCreate ("ImageMagickObject.MagickImage.1") If @error OR NOT IsObj ($oIM) Then MsgBox (16, "!", "Error using ImageMagickObject.dll - work impossible.") Exit EndIf EndIf $Main = GUICreate ("GUI", 455, 290, 0, 0, $WS_DLGFRAME) $Quit = GUICtrlCreateButton ("Quit", 345, 167.5, 100) $Sec_old = -1 GUISetState (@SW_SHOW) While 1 $msg = GUIGetMsg() If $msg = $Quit Then If $DllExist = 1 Then RunWait (@ComSpec & " /c regsvr32 /u /s ImageMagickObject.dll", @ScriptDir , @SW_HIDE) EndIf Exit EndIf If $Sec_old <> @SEC Then $Sec_old = @SEC $oIM.Compare ("-metric", "MAE", "old.bmp", "new.bmp", "null:") EndIf WEnd As you see comparison is made every second, but I can not find the way to get the percentage of difference. $oIM.Compare returns empty string. When I push "Quit", I see in SciTE's log these strings: +>00:19:55 AU3Check ended.rc:0 >Running:(3.3.8.0) :Program FilesAutoIt3autoit3.exe "D:11.au3" 10.8064 (0.0423779) 10.8064 (0.0423779) 10.8064 (0.0423779) +>00:19:58 AutoIT3.exe ended.rc:0 +>00:19:59 AutoIt3Wrapper Finished >Exit code: 0 Time: 4.167 In center there are string with numbers - 1 string per 1 second of execution - which are somehow returned by ImageMagickObject & looks like what I need. These strings appear in log only when script execution is over - not earlier. I tried several cases with StderrRead, StdoutRead, ConsoleRead, DllCall, ObjEvent to get these strings while script execution. Tried them while running from SciTE & with compiled script. No result. May be I cook them in a wrong way. In attachment you can find code, dll, bmps I use. Grates to everyone who can offer solution, useful piece of code or helpful link. 1.zip Link to comment Share on other sites More sharing options...
Werty Posted January 5, 2014 Share Posted January 5, 2014 Try reading post #31 in JabberWockys imagemagickobject thread, maybe it's something. Link: Some guy's script + some other guy's script = my script! Link to comment Share on other sites More sharing options...
jaberwacky Posted January 5, 2014 Share Posted January 5, 2014 (edited) Did that work for you Werty? I always make the mistake of taking on bigger projects than I can handle which leads others to think I'm some kind of coding god. Edited January 5, 2014 by jaberwocky6669 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
UEZ Posted January 5, 2014 Share Posted January 5, 2014 (edited) Can you try this (GDI+ version only): AutoIt version 3.3.10.0 or higher needed! expandcollapse popup#include <Array.au3> #include <GDIPlus.au3> #include <MsgBoxConstants.au3> _GDIPlus_Startup() Global $hImage1, $hImage2 Global $sImages = FileOpenDialog("Select 2 images", "", "Image (*.bmp;*.jpg;*.png;*.gif)", $FD_MULTISELECT) If @error Then _Exit("Nothing selected") Global $aFiles = StringSplit($sImages, "|", 2) If (UBound($aFiles) < 3) Then _Exit("Select at least 2 images") $hImage1 = _GDIPlus_ImageLoadFromFile($aFiles[1]) If @error Then _Exit("Unable to load " & $aFiles[1]) $hImage2 = _GDIPlus_ImageLoadFromFile($aFiles[2]) If @error Then _Exit("Unable to load " & $aFiles[2]) If (_GDIPlus_ImageGetWidth($hImage1) <> _GDIPlus_ImageGetWidth($hImage2)) Then _Exit("Width of both images are different") If (_GDIPlus_ImageGetHeight($hImage1) <> _GDIPlus_ImageGetHeight($hImage2)) Then _Exit("Height of both images are different") Global $bFastCmp = True Global $aDiff = _GDIPlus_ImageCompare($hImage1, $hImage2, $bFastCmp) If $bFastCmp Then Exit MsgBox($MB_SYSTEMMODAL, "Compared", "Equal: " & $aDiff & " / " & @extended & " ms") Global $iChk = MsgBox(BitOR($MB_SYSTEMMODAL, $MB_YESNO), "Information", "Found " & Round((UBound($aDiff) - 1) / ($aDiff[0][1] * $aDiff[0][2]) * 100, 2) & " % differences in " & Round($aDiff[0][0], 2) & " ms." & _ @CRLF & @CRLF & _ "Display the array with information") If ($iChk = 6) Then _ArrayDisplay($aDiff, "Differences", Default, Default, Default, "Runtime / Coordinate (x,y)|Image1 Color|Image2 Color") Func _GDIPlus_ImageCompare($hImage1, $hImage2, $bFastCmp = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage1), $iH = _GDIPlus_ImageGetHeight($hImage1) If ($iW <> _GDIPlus_ImageGetWidth($hImage2)) Then Return SetError(1, 0, 0) If ($iH <> _GDIPlus_ImageGetHeight($hImage2)) Then Return SetError(2, 0, 0) Local $t = TimerInit() Local $tBitmapData1 = _GDIPlus_BitmapLockBits($hImage1, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local $tBitmapData2 = _GDIPlus_BitmapLockBits($hImage2, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local $pScan1 = DllStructGetData($tBitmapData1, "Scan0") Local $tPixel1 = DllStructCreate("uint[" & $iW * $iH & "];", $pScan1) Local $iStride = Abs(DllStructGetData($tBitmapData1, "Stride")) Local $pScan2 = DllStructGetData($tBitmapData2, "Scan0") Local $tPixel2 = DllStructCreate("uint[" & $iW * $iH & "];", $pScan2) If $bFastCmp Then $iResult = DllCall("msvcrt.dll", "int:cdecl", "memcmp", "ptr", $pScan1, "ptr", $pScan2, "uint", DllStructGetSize($tPixel1))[0] Else If ($iW * $iH + 1) * 3 > 16 * 1024^2 Then Return SetError(3, 0, 0) Local $iX, $iY, $iRowOffset, $iPixel1, $iPixel2, $c = 1, $aDiff[$iW * $iH + 1][3] For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 $iPixel1 = DllStructGetData($tPixel1, 1, $iRowOffset + $iX) ;get pixel color $iPixel2 = DllStructGetData($tPixel2, 1, $iRowOffset + $iX) ;get pixel color If $iPixel1 <> $iPixel2 Then $aDiff[$c][0] = $iX & ", " & $iY $aDiff[$c][1] = "0x" & Hex($iPixel1, 8) $aDiff[$c][2] = "0x" & Hex($iPixel2, 8) $c += 1 EndIf Next Next $aDiff[0][0] = TimerDiff($t) $aDiff[0][1] = $iW $aDiff[0][2] = $iH EndIf _GDIPlus_BitmapUnlockBits($hImage1, $tBitmapData1) _GDIPlus_BitmapUnlockBits($hImage2, $tBitmapData2) If $bFastCmp Then Return SetError(0, Int(TimerDiff($t)), $iResult = 0) ReDim $aDiff[$c][3] Return $aDiff EndFunc Func _Exit($sError = "") If $sError <> "" Then MsgBox($MB_ICONERROR, "ERROR", $sError) If ($hImage1 <> 0) Then _GDIPlus_ImageDispose($hImage1) If ($hImage2 <> 0) Then _GDIPlus_ImageDispose($hImage2) _GDIPlus_Shutdown() Exit EndFunc Br, UEZ Edited March 3, 2020 by UEZ jaberwacky 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Werty Posted January 5, 2014 Share Posted January 5, 2014 Did that work for you Werty? Huh? The post I linked to worked for you, I wrote it Or maybe I'm misunderstanding your question Some guy's script + some other guy's script = my script! Link to comment Share on other sites More sharing options...
jaberwacky Posted January 6, 2014 Share Posted January 6, 2014 I dunno, been a long time since I last thought about this stuff. I do remember the info option now. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Pumbaa Posted January 6, 2014 Author Share Posted January 6, 2014 Try reading post #31 in JabberWockys imagemagickobject thread, maybe it's something. Link: Tried this one before & now once again. Many of possible parameters for "-format" work, but "%[distortion]" returns empty string. By the way (quote from link) Using -: instead of info: appears to only output to the variable, not to the scite console Seems not to work with "compare" - I get "The requested action with this object has failed." error. Link to comment Share on other sites More sharing options...
Pumbaa Posted January 6, 2014 Author Share Posted January 6, 2014 UEZ:I tried GDI decision - very slow & too straight in comparison. My actual pictures are taken from webcam & are 640x480 pixels - it takes about 10 seconds to compare them, and due to picture quality even with real absence of changes images are reported to be different for about 90%. I also tried to use PixelGetColor, but result is approximately the same. Link to comment Share on other sites More sharing options...
UEZ Posted January 6, 2014 Share Posted January 6, 2014 (edited) The code detects real differences that means 0xFFFFFFFF is not equal to 0xFFFFFFFE whereas your eye will not detect the difference. It cannot skip "similar" looking pixels. Comparing 2 640x480 images on my notebook take approx. 1,4 seconds. For one time compare it is ok but too slow for repeated compares, e.g. images from web cams. Speed for such cases is a bottleneck for AutoIt... Br, UEZ Edited January 6, 2014 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Pumbaa Posted January 7, 2014 Author Share Posted January 7, 2014 "compare" sends output to stderr, not stdout. "%[distortion]" is for "compare". This goes to stdout. That's what I've got from ImageMagick forum. I already tried it but got nothing - may be did something wrong, cause never used these functions before. Can someone more familiar with them check them? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now