Petit programme sans grande prétention sur le traitement de l'image.
Depuis plusieurs mois, je fais du Java (stage éducation nationale).
Maintenant, je comprends mieux les ";{ ;}" dans Pb

A un moment donné, on a fait mumuse avec les filtres.
Le filtre est ici une petite matrice 3x3 que l'on va appliquer à chaque pixel de l'image.
On stocke le résultat dans une autre matrice "imageFiltrée".
Je suis retombé sur un truc que G-Rom avait utilisé, le filtre de Sobel.
Comme j'en aurai besoin quand je reviendrai sur "Perlin", j'ai fait quelques tests.
J'ai mis en forme avec PBSyntax de LSI (Merci M'sieur)!
Normalement ça fonctionne.
N'hésitez pas à trifouiller dans le filtre pour modifier le résultat.
Si vous avez des questions ou des remarques...
Code : Tout sélectionner
;**********************************************************
;Détection des contours avec le filtre de Sobel
;Auteur Huitbit
;Février 2012
;PureBasic 4.60 (Windows - x86)
;***********************************************************
#facteurDeNormalisation = 5.657 ; 5.657 = 4*Sqr(2) facteur de normalisation pour le filtre de Sobel
;dans l'expression :
;imageFiltree(x, y) = Sqr(imageFiltreX(x, y) * imageFiltreX(x, y) + imageFiltreY(x, y) * imageFiltreY(x, y))/ #facteurDeNormalisation
;les valeurs maximales pour les composantes X et Y sont 4*255
; => sans normalisation, la valeur finale maximale serait sqr(4²*255² + 4²*255²) = sqr(2*4²*255²) = 4*sqr(2)*255
; valeur supérieure à 255 et donc incorrecte
;On applique à un élément M(i,j) de la matrice M() le filtre choisi et on met le résultat dans c(i,j)
;On renvoie tout ça au programme principal
Procedure ConvolutionParMatrice3x3(i.i, j.i, Array filtre.i(2), Array M.i(2))
cij.i ; composante de matrice qui sera renvoyée au programme
For l = -1 To 1 ; lignes
For k = -1 To 1 ; colonnes
cij = cij + filtre(l + 1, k + 1) * M(i + l, j + k)
Next k
Next l
ProcedureReturn cij
EndProcedure
;-PROGRAMME PRINCIPAL
If OpenWindow(0, 100, 100, 800, 600, "PureBasic - Image")
;-chargement de l'image à filtrer
title$ = "Choisissez une image au format JPEG, PNG ou BMP"
image$ = OpenFileRequester(title$, "", "*.JPEG ; *.PNG ; *.BMP", 1, #PB_Requester_MultiSelection)
UseJPEGImageDecoder()
UsePNGImageDecoder()
If image$<> ""
LoadImage(0, image$)
height = ImageHeight(0)
width = ImageWidth(0)
ResizeWindow(0, 100, 100, width, height)
Dim imageTableau.i(width - 1, height - 1)
Dim imageFiltrex.i(width - 1, height - 1)
Dim imageFiltreY.i(width - 1, height - 1)
Dim imageFiltree.i(width - 1, height - 1)
;-Filtres de Sobel
;--selon X
Dim filtreX.i(2, 2)
filtreX(0, 0) = 1
filtreX(1, 0) = 2
filtreX(2, 0) = 1
filtreX(0, 1) = 0
filtreX(1, 1) = 0
filtreX(2, 1) = 0
filtreX(0, 2) = -1
filtreX(1, 2) = -2
filtreX(2, 2) = -1
;--selon Y
Dim filtreY.i(2, 2)
filtreY(0, 0) = 1
filtreY(1, 0) = 0
filtreY(2, 0) = -1
filtreY(0, 1) = 2
filtreY(1, 1) = 0
filtreY(2, 1) = -2
filtreY(0, 2) = 1
filtreY(1, 2) = 0
filtreY(2, 2) = -1
;- transformation n/b
StartDrawing(ImageOutput(0))
For i = 0 To width - 1
For j = 0 To height - 1
imageTableau(i, j) = (Red(Point(i, j)) + Green(Point(i, j)) + Blue(Point(i, j))) / 3
Next j
Next i
StopDrawing() ; This is absolutely needed when the drawing operations are finished !!! Never forget it !
;- application des filtres selon X et Y
For x = 1 To width - 2
For y = 1 To height - 2
imageFiltreX(x, y) = ConvolutionParMatrice3x3(x, y, filtreX(), imageTableau())
imageFiltreY(x, y) = ConvolutionParMatrice3x3(x, y, filtreY(), imageTableau())
;-Image finale normalisée
imageFiltree(x, y) = Sqr(imageFiltreX(x, y) * imageFiltreX(x, y) + imageFiltreY(x, y) * imageFiltreY(x, y)) / #facteurDeNormalisation
Next y
Next x
;-Création de l'image filtrée (en réalité le négatif pour une meilleure visibilité(choix arbitraire)
If CreateImage(1, width, height)
StartDrawing(ImageOutput(1))
For i = 0 To width - 1
For j = 0 To height - 1
niv = imageFiltree(i, j)
Box(i, j, 1, 1, RGB(255 - niv, 255 - niv, 255 - niv))
Next j
Next i
StopDrawing()
EndIf
Else
End
EndIf
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_Repaint
StartDrawing(WindowOutput(0))
DrawImage(ImageID(1), 0, 0)
StopDrawing()
EndIf
Until EventID = #PB_Event_CloseWindow ; If the user has pressed on the close button
EndIf
End ; All the opened windows are closed automatically by PureBasic