efficient way to compare 2 images?
#61
(11-19-2022, 01:48 AM)SMcNeill Wrote:
(11-18-2022, 11:24 PM)SMcNeill Wrote: How fast are you needing your compares to be?  Somehow, it seems like everyone overlooked my working example here:  https://staging.qb64phoenix.com/showthre...1#pid10221

2000 full-screen compares of 720p HD images in 3 seconds.  That's 666 per second, or a comparison every 0.00something seconds.  

Since this isn't the type of routine which one needs to do repetitively, I'd think the little function I'd posted should be quick enough for most use cases.  Wink

If not, then you could probably save time with it considerably by writing a DECLARE LIBRARY routine and using memcmp directly, without having to copy the memory over into a set of temp strings to compare instead.  Wink

As I mentioned here, I went ahead and tried a memcmp demo:

Code: (Select All)
'int memcmp(const void *str1, const void *str2, size_t n)

Declare CustomType Library
    Function memcmp% (ByVal s1%&, Byval s2%&, Byval n As _Offset)
End Declare



Randomize Timer

Screen _NewImage(1280, 720, 32)

'let's make this an unique and pretty image!
For i = 1 To 100
    Line (Rnd * _Width, Rnd * _Height)-(Rnd * width, Rnd * _Height), &HFF000000 + Rnd * &HFFFFFF, BF
Next

image2 = _CopyImage(0) 'identical copies for testing
image3 = _CopyImage(0) 'identical copy...  BUT
_Dest image3
PSet (Rnd * _Width, Rnd * _Height), &HFF000000 + Rnd * &HFFFFFF 'We've just tweaked it so that there's no way in hell it's the same as the other two now!
_Dest 0 'image3 is EXACTLY one pixel different from the other two.  Can we detect that?
image4 = _CopyImage(0) 'an identical copy once again, because 0 will change once we print the resul


result1 = CompareImages(0, image2)
result2 = CompareImages(0, image3)
result3 = CompareImages(image2, image3)

Print "Current Screen and Image 1 Compare:  "; result1
Print "Current Screen and Image 2 Compare:  "; result2
Print "Image1 and Image 2 Compare        :  "; result3

Print
Print "Press <ANY KEY> for a speed test!"
Sleep

t# = Timer
Limit = 1000
For i = 1 To Limit
    result = CompareImages(image2, image3)
    result = CompareImages(image2, image4)
Next
Print
Print Using "####.####### seconds to do"; Timer - t#;
Print Limit * 2; "comparisons."


Function CompareImages (handle1 As Long, handle2 As Long)
    Static m(1) As _MEM
    'Dim s(1) As String
    m(0) = _MemImage(handle1): m(1) = _MemImage(handle2)
    If m(0).SIZE <> m(1).SIZE Then Exit Function 'not identical
    If m(0).ELEMENTSIZE <> m(1).ELEMENTSIZE Then Exit Function 'not identical
    's(0) = Space$(m(0).SIZE): s(1) = Space$(m(1).SIZE)
    '_MemGet m(0), m(0).OFFSET, s(0): _MemGet m(1), m(1).OFFSET, s(1)
    'If s(0) = s(1) Then CompareImages = -1
    If memcmp(m(0).OFFSET, m(1).OFFSET, m(0).SIZE) = 0 Then x = -1 Else x = 0
    CompareImages = x
End Function


[Image: image.png]

Holy smokes! Even better!
Reply
#62
Glad someone found and liked it.  I don't think anyone else paid much attention to me, with the code posted.  I was typing in invisible ink once again.  Big Grin
Reply
#63
(01-04-2023, 09:38 PM)SMcNeill Wrote: Glad someone found and liked it.  I don't think anyone else paid much attention to me, with the code posted.  I was typing in invisible ink once again.  Big Grin

Not at all! Just been a little busy with life, but I have been lurking and bookmarking your and others' interesting and useful contributions, for when I get more time to get back to some coding! I was in the middle of making a vector sprite editor for that spacewar game when things just got to be too much with the holidays, work, etc. I'll get back to it, but meanwhile keep up the good work!!
Reply




Users browsing this thread: 24 Guest(s)