picture Comparer

Share your advanced PureBasic knowledge/code with the community.
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

picture Comparer

Post by dobro »

this procedure can be used to delete duplicate Pictures, present in the hard disk

[ALGO]
we take an image it is the color of a certain number of points at random on the image (there are more the better)

we take the image you look at the two coordinated even if the points have the same color

we established a tolerance level (even a picture may have been slightly retouched ..)

if there are less than the tier points are different, it is probably the same image

(code changes ... rate analysis of each component of a point is made that an average ansi)
(it can now compare a same image in different formats (png, bmp, jpg)
[/ ALGO]



;{- Enumerations / DataSections
;{ Windows
Enumeration
     #Window
EndEnumeration
;}
;{ Gadgets
Enumeration
     #titre
     #info
     #Button_image1
     #Button_image2
     #Button_compare
     #input
     #image1
     #image2
EndEnumeration

global path$= ""
usejpegimagedecoder ()
usepngimagedecoder ()
usetgaimagedecoder ()

Declare OpenWindow_Window()
Declare compare(im1,im2,po)
Declare taux(couleur)

;to predict the test on the color component of the point and not on the exact color .... (taux de rouge, vert,bleu)


;}
;{ Fonts
Enumeration
     #Font_titre
EndEnumeration
;}
Define.l Event, eventwindow , eventgadget , eventtype , eventmenu
;}
Procedure OpenWindow_Window()
     If openwindow ( #Window , 554, 111, 354, 191, "By Dobro" , #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_SizeGadget )
        
         textgadget ( #titre , 10, 10, 375, 35, "Comparateur d'image" , #PB_Text_Center )
         buttongadget ( #Button_image1 , 30, 90, 115, 35, "Load Picture 1" )
         buttongadget ( #Button_image2 , 30, 135, 115, 35, "Load Picture 2" )
         buttongadget ( #Button_compare , 230, 135, 115, 35, "compare !" )
         textgadget ( #info , 10, 60, 200, 35, "number of points to be compared" , #PB_Text_Center ) ; >3 !!
         stringgadget ( #input , 200, 60, 50, 35, "3" , #PB_String_Numeric )
         ; Gadget Fonts
         setgadgetfont ( #titre , loadfont ( #Font_titre , "Comic Sans MS" , 16, #PB_Font_Bold|#PB_Font_HighQuality ))
        
     EndIf
EndProcedure

OpenWindow_Window()

;{- Event loop
Repeat
    
     Event = waitwindowevent ()
     Select Event
         ; ///////////////////
         Case #PB_Event_Gadget
         eventgadget = eventgadget ()
         eventtype = eventtype ()
         select eventgadget
             case #titre
            
             case #Button_image1
             if path$= ""
                 path$= "c:\"
             endif
             file$= openfilerequester ( "Load Picture 1" ,path$, "*.*" ,0)
             if loadimage ( #image1 ,file$)<>0
                 Else
                 messagerequester ( "info" , "Picture not loaded" , #PB_MessageRequester_Ok )
             endif
            
            
             case #Button_image2
             if path$= ""
                 path$= "c:\"
             endif
             file$= openfilerequester ( "Load Picture 2" ,path$, "*.*" ,0)
             if loadimage ( #image2 ,file$) <>0
                 else
                 messagerequester ( "info" , "Picture not loaded" , #PB_MessageRequester_Ok )
             endif
            
             case #Button_compare
             po= val ( getgadgettext ( #input ))
            
             if compare( #image1 , #image2 ,po)= #true
                 messagerequester ( "info" , "This is certainly the same image" , #PB_MessageRequester_Ok )
                 Else
                 messagerequester ( "info" , "This is not the same image" , #PB_MessageRequester_Ok )
             endif
            
            
         Endselect
         ; ////////////////////////
         Case #PB_Event_CloseWindow
         eventwindow = eventwindow ()
         If eventwindow = #Window
             closewindow ( #Window )
             Break
         EndIf
     EndSelect
Forever

; **************************** Zone des procedures **********************************
procedure compare(im1,im2,po)
     ; By Dobro
     ; im1 = numero de l'image 1
     ; im2 = numero de l'image 2
     ; po = nombre de points de comparaison , plus il y en a plus c'est long, mais plus c'est bon LOL
     structure coordo
         x.l ; coordonné x du point
         y.l ; coordonné y du point
         couleur.l ; la couleur du point
     endstructure
     dim coordo.coordo(po) ; et met leur coordonnés dans la structure ainsi que leur couleur !
    
    
     if po<=3 :po=3:endif ; petite securité on verifie au moins 1 point
    
     if isimage ( #image1 )<>0
         Else
         messagerequester ( "Erreur" , "the images were not loaded" , #PB_MessageRequester_Ok )
         ProcedureReturn #false
     endif
     if isimage ( #image2 )<>0
         Else
         messagerequester ( "Erreur" , "the images were not loaded" , #PB_MessageRequester_Ok )
         ProcedureReturn #false
     endif
    
     x_im1= imagewidth ( #image1 )
     y_im1= imageheight ( #image1 )
     x_im2= imagewidth ( #image2 )
     y_im2= imageheight ( #image2 )
     if x_im1<=x_im2: x_de=x_im1:else: x_de=x_m2-1:endif ; on va recuperer la resolution la plus petite
     if y_im1<=y_im2:y_de=y_im1:else: y_de=y_m2-1:endif ; entre les 2 images
     if po> (x_de * y_de) : po=(x_de * y_de)/4:endif ; petite securité au cas ou po serai superieur au nombre de points de l'image
    
     ; ********* tire les points au dé ************
    
     startdrawing ( imageoutput ( #image1 ))
         for i=1 to po ; pour tout les points
             coordo(i)\x.l= random (x_de-1) ; on recup la coordonée x dans l'image 1
             coordo(i)\y.l= random (y_de-1) ; on recup la coordonée y dans l'image 1
             coordo(i)\couleur.l=taux( point (coordo(i)\x.l,coordo(i)\y.l) ) ; on recup la couleur dans l'image 1
         next i
     stopdrawing ()
     ; ****************************************
     ; on va comparer si les points sont pareil entre les 2 images
    
     startdrawing ( imageoutput ( #image2 ))
         for i=1 to po ; pour tout les points
             coul=taux( point (coordo(i)\x.l,coordo(i)\y.l) )
             if coul <> coordo(i)\couleur.l ; le point est different .. c'est pas le meme image
                 diff=diff+1
             endif
         next i
     stopdrawing ()
    
     if diff<(po/3) ; le seuil de difference est inferieur au tier des points (moins du tier des points sont different)
         ProcedureReturn #true ; c'est certainement la meme image ( tout depend du nombre de point testé )
         Else
         ProcedureReturn #false ; trop de difference ! c'est pas la meme image
     endif
endprocedure

procedure taux(couleur)
     taux_rouge= int (( red (couleur)/255)*100)
     taux_vert= int (( green (couleur)/255)*100)
     taux_bleu= int (( blue (couleur)/255)*100)
     total= int (taux_rouge+taux_vert+taux_bleu)/3
     ProcedureReturn total
endprocedure

; **********************************************************************************


;}



; EPB


these two images are considered identical!

Image
Image
Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
quasiperfect
Enthusiast
Enthusiast
Posts: 157
Joined: Tue Feb 13, 2007 6:16 pm
Location: Romania
Contact:

Re: picture Comparer

Post by quasiperfect »

thanks for sharing

with value 1 for points it crushes
[12:37:28] Waiting for executable to start...
[12:37:28] Executable type: Windows - x86 (32bit)
[12:37:28] Executable started.
[12:37:39] [ERROR] picture Comparer.pb (Line: 149)
[12:37:39] [ERROR] Array index out of bounds.


would be nice to detect also for resized or partial images

for resized i think your function will work you just have to make a condition to see witch image is bigger resize to smaller image then compare

for partial image i don't have any ideea
Registered user of PureBasic
WilliamL
Addict
Addict
Posts: 1252
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: picture Comparer

Post by WilliamL »

works fine here on my Mac! :)

How many points would give a good assurance of a match? 10? 30? 50%? 80%? A re-sized or re-touched picture isn't the same picture is it? I wouldn't want to throw out a larger version of the same pict because I came across the smaller version first.

A thumbnail of the loaded picture would be nice. Maybe the 'load' button could contain the loaded pict?

Hey, use the

Code: Select all

 brackets...
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Post Reply