Accélérer la recherche des contours d'une image (ASM ?)
Publié : jeu. 31/juil./2008 23:19
Voici le code que j'ai créé pour trouver les pixels qui bordent une région colorée. Ceci n'est qu'un exemple, mais j'ai besoin d'optimiser ce code car dans mon programme (environ 5000 lignes de code...) j'utilise une procédure similaire dans la boucle principale et ça me fait ramer un peu, surtout en mode débogueur. Je n'y connais rien en ASM, mais s'il est possible d'optimiser (déjà bien optimisée pourtant il me semble...) la partie entre les FOR/NEXT je suis prenneur !
Bon sinon ça peut toujours servir d'exemple pour ceux qui cherchent un code de ce genre.
Bon sinon ça peut toujours servir d'exemple pour ceux qui cherchent un code de ce genre.
Code : Tout sélectionner
Enumeration
#Img1
#Img2
#Win
#Button
EndEnumeration
;Pour inverser les conventions RGB et BGR
Macro ReverseRGB(COLOR)
(COLOR & $FF0000) >> 16 + (COLOR & $00FF00) + (COLOR & $0000FF) << 16
EndMacro
;Test si c'est un pixel de bordure
Macro BorderMap(BMP,X,Y)
X=0 Or X=BMP\bmWidth-1 Or Y=0 Or Y=BMP\bmHeight-1
EndMacro
CreateImage(#Img1,360,240,32)
CreateImage(#Img2,360,240,32)
StartDrawing(ImageOutput(#Img1))
Box(0,0,360,240,RGB(255,255,255))
Circle(100,100,40,RGB(255,0,0))
Circle(130,110,25,RGB(255,0,0))
Circle(220,120,35,RGB(255,0,0))
Box(140,100,60,30,RGB(255,0,0))
StopDrawing()
StartDrawing(ImageOutput(#Img2))
Box(0,0,360,240,RGB(255,255,255))
StopDrawing()
*Address1=AllocateMemory(36)
*Address2=AllocateMemory(36)
Color=RGB(255,0,0)
GetObject_(ImageID(#Img1),SizeOf(BITMAP),@Img1.BITMAP)
GetObject_(ImageID(#Img2),SizeOf(BITMAP),@Img2.BITMAP)
For i=0 To 8 : PokeL(*Address2+i*4,ReverseRGB(Color)) : Next i
;***************************************************************************************
;-Détection des contours
For Y=0 To Img1\bmHeight-1
For X=0 To Img1\bmWidth-1
;Si c'est un pixel de la bonne couleur
If PeekL(Img1\bmBits+X*4+Y*Img1\bmWidthBytes)=ReverseRGB(Color)
;Si c'est un pixel de bordure
;Alors c'est un pixel de contour
If BorderMap(Img1,X,Y)
PokeL(Img2\bmBits+X*4+Y*Img2\bmWidthBytes,0)
Else
;Si ce N'est PAS un pixel de bordure
;On teste les 9 pixels aux alentours
CopyMemory(Img1\bmBits+(X-1)*4+(Y-1)*Img1\bmWidthBytes,*Address1,12)
CopyMemory(Img1\bmBits+(X-1)*4+(Y)*Img1\bmWidthBytes,*Address1+12,12)
CopyMemory(Img1\bmBits+(X-1)*4+(Y+1)*Img1\bmWidthBytes,*Address1+24,12)
;Si la couleur des 9 pixels enregistrés n'est pas identique
;A la couleur de la région sélectionnée
;Alors c'est un pixel de bordure
If Not CompareMemory(*Address1,*Address2,36)
PokeL(Img2\bmBits+X*4+Y*Img2\bmWidthBytes,0)
EndIf
EndIf
EndIf
Next X
Next Y
;***************************************************************************************
OpenWindow(#Win,0,0,360,300,"Fenêtre",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateGadgetList(WindowID(#Win))
ButtonGadget(#Button,150,250,60,40,"Changer")
Contour=0
;-Boucle principale
Repeat
Event=WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
Event=EventGadget()
Select Event
Case #Button
Contour=1-Contour
EndSelect
EndSelect
StartDrawing(WindowOutput(#Win))
If Not Contour
DrawImage(ImageID(#Img1),0,0)
Else
DrawImage(ImageID(#Img2),0,0)
EndIf
StopDrawing()
ForEver