Sign in to follow this  
Followers 0
Pumbaa

ImageMagickObject - compare - how to get pics difference in %?

10 posts in this topic

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.

#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) :D: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

Share this post


Link to post
Share on other sites



Try reading post #31 in JabberWockys imagemagickobject thread, maybe it's something.

Link:

Share this post


Link to post
Share on other sites

#3 ·  Posted (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.  :P

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Can you try this (GDI+ version only):

AutoIt version 3.3.10.0 or higher needed!

 

#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)
(@error) ? _Exit("Nothing selected") : ""
Global $aFiles = StringSplit($sImages, "|", 2)
(UBound($aFiles) < 3) ? _Exit("Select at least 2 images") : ""
$hImage1 = _GDIPlus_ImageLoadFromFile($aFiles[1])
(@error) ? _Exit("Unable to load " & $aFiles[1]) : ""
$hImage2 = _GDIPlus_ImageLoadFromFile($aFiles[2])
(@error) ? _Exit("Unable to load " & $aFiles[2]) : ""
(_GDIPlus_ImageGetWidth($hImage1) <> _GDIPlus_ImageGetWidth($hImage2)) ? _Exit("Width of both images are different") : ""
(_GDIPlus_ImageGetHeight($hImage1) <> _GDIPlus_ImageGetHeight($hImage2)) ? _Exit("Height of both images are different") : ""

Global $aDiff = _GDIPlus_ImageCompare($hImage1, $hImage2)
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?")
($iChk = 6) ? _ArrayDisplay($aDiff, "Differences", Default, Default, Default, "Coordinate (x,y)|Image1 Color|Image2 Color") : ""

Func _GDIPlus_ImageCompare($hImage1, $hImage2)
    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 $tBitmapData1 = _GDIPlus_BitmapLockBits($hImage1, 0, 0, $iW, $iH, BitOR($GDIP_ILMWRITE, $GDIP_ILMREAD), $GDIP_PXF32ARGB)
    Local $tBitmapData2 = _GDIPlus_BitmapLockBits($hImage2, 0, 0, $iW, $iH, BitOR($GDIP_ILMWRITE, $GDIP_ILMREAD), $GDIP_PXF32ARGB)

    Local $iScan1 = DllStructGetData($tBitmapData1, "Scan0")
    Local $tPixel1 = DllStructCreate("int[" & $iW * $iH & "];", $iScan1)

    Local $iScan2 = DllStructGetData($tBitmapData2, "Scan0")
    Local $tPixel2 = DllStructCreate("int[" & $iW * $iH & "];", $iScan2)

    Local $iX, $iY, $iRowOffset, $iPixel1, $iPixel2, $aDiff[$iW * $iH + 1][3], $c = 1, $e, $t = TimerInit()
    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)
                $aDiff[$c][2] = "0x" & Hex($iPixel2)
                $c += 1
            EndIf
        Next
    Next
    $aDiff[0][0] = TimerDiff($t)
    $aDiff[0][1] = $iW
    $aDiff[0][2] = $iH
    _GDIPlus_BitmapUnlockBits($hImage1, $tBitmapData1)
    _GDIPlus_BitmapUnlockBits($hImage2, $tBitmapData2)
    ReDim $aDiff[$c][3]
    Return $aDiff
EndFunc


Func _Exit($sError = "")
    If $sError <> "" Then MsgBox($MB_ICONERROR, "ERROR", $sError)
    ($hImage1 <> 0) ? _GDIPlus_ImageDispose($hImage1) : ""
    ($hImage2 <> 0) ? _GDIPlus_ImageDispose($hImage2) : ""
    _GDIPlus_Shutdown()
    Exit
EndFunc

Br,

UEZ

Edited by UEZ
1 person likes this

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Did that work for you Werty?

 

Huh? The post I linked to worked for you, I wrote it :D

Or maybe I'm misunderstanding your question :)

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

#9 ·  Posted (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 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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

 

"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?

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0