Je n'ai pas mis le code de cette application car elle fait appel à des gadgets CustomGadget.
Et que ça n'est pas un code copier-collable rapidement.
J'ai fait quelques recherche et test pour arriver à terminer la partie nettoyage (la partie transformation est postée sur le forum dans les astuces

).
Et j'ai pu confirmer mes théories de l'algo de nettoyage avec des documents de recherche utilisés pour nettoyer des photos de télescope pour voir mieux les étoiles et les satellites (enlèvement du bruit du capteur de l'appareil).
Ici le code de nettoyage seul :
Principe :
on fait le calcul d'une moyenne de l'image qui servira pour la comparaison avec un seuil
A partir de là on détermine quels sont les pixels d'information utile ou non. Les pixels considérés comme utiles sont "sombres".
Le code a une préférence marquée pour les informations à fort contraste (les lignes et points, et non les zones unies).
On pourrais aussi voir ce que donnerais une atténuation progression en fonction de la distance au seuil.
Code : Tout sélectionner
UsePNGImageEncoder()
UsePNGImageDecoder()
UseJPEGImageDecoder()
;{ structure & procedure
Structure QuatreOctet
o1.a
o2.a
o3.a
o4.a
EndStructure
Structure couleur
StructureUnion
c.l
o.QuatreOctet
EndStructureUnion
EndStructure
Structure image
hdl.l
file.s
hdl_reduit.l
hdl_res.l
diviseur.l
rayon.l
seuil_diviseur.d
x_end.l
y_end.l
moy.d
sdt.d
Array lum.a(1, 1)
EndStructure
Procedure ImageToArrayLum(*image.image)
*image\hdl_reduit = CopyImage(*image\hdl, #PB_Any)
ResizeImage(*image\hdl_reduit, ImageWidth(*image\hdl) / *image\diviseur, ImageHeight(*image\hdl) / *image\diviseur)
If StartDrawing(ImageOutput(*image\hdl_reduit)) = 0
ProcedureReturn #False
EndIf
*image\x_end = OutputWidth() - 1
*image\y_end = OutputHeight() - 1
Dim *image\lum(*image\x_end, *image\y_end)
moyenne.l = 0
variance.d = 0
Define couleur.couleur
DisableDebugger
For y = 0 To *image\y_end
For x = 0 To *image\x_end
couleur\c = Point(x, y)
*image\lum(x, y) = (couleur\o\o1 + couleur\o\o2 + couleur\o\o3) / 3
moyenne + *image\lum(x, y)
Next
Next
*image\moy = moyenne / (*image\y_end + 1) / (*image\x_end + 1)
div.d = 1 / ((*image\y_end + 1) * (*image\x_end + 1) + 1)
; calcul de la variance
For y = 0 To *image\y_end
For x = 0 To *image\x_end
sous = *image\lum(x, y) - *image\moy
variance = variance + sous * sous * div
Next
Next
EnableDebugger
*image\sdt = Sqr(variance)
StopDrawing()
FreeImage(*image\hdl_reduit)
ProcedureReturn #True
EndProcedure
Procedure ImageMoyenneLocale(*image.image)
rayon_max = *image\rayon
;{ Précalcul des tranches de cercle
Dim x_largeur.l(rayon_max * 2 + 1)
For rayon = -rayon_max To rayon_max
x_largeur(rayon + rayon_max) = Sqr(rayon_max * rayon_max - rayon * rayon)
Debug x_largeur(rayon + rayon_max)
Next
;}
r_max = rayon_max - 1
r_min = -rayon_max + 1
image_w = *image\x_end + 1
image_h = *image\y_end + 1
xmax.l = *image\x_end
ymax.l = *image\y_end
Dim moy.a(1,1)
CopyArray(*image\lum(), moy())
DisableDebugger
For y = 0 To ymax
For x = 0 To xmax
n.l = 0 ; nb de point comptés dans la moyenne
moy.l = 0 ; init de la moyenne locale
For rayon = r_min To r_max
; x_largeur.l = Sqr(rayon_max * rayon_max - rayon * rayon)
x_largeur.l = x_largeur(rayon + rayon_max)
x_max.l = x + x_largeur
y_m = y + rayon
If y_m > -1 And y_m < image_h
For x_m = x - x_largeur To x_max
If x_m > -1 And x_m < image_w
n + 1
moy + moy(x_m, y_m)
EndIf
Next
EndIf
Next
moy(x, y) = moy / n
Next
Next
EnableDebugger
CopyArray(moy(), *image\lum())
EndProcedure
Procedure CalculImage(*image.image)
*image\hdl_res = CopyImage(*image\hdl, #PB_Any)
If StartDrawing(ImageOutput(*image\hdl_res)) = 0
ProcedureReturn #False
EndIf
x_end = OutputWidth() - 1
y_end = OutputHeight() - 1
seuil = *image\sdt / *image\seuil_diviseur
DisableDebugger
For y = 0 To y_end
y_rounded.l = Round(y / *image\diviseur, #PB_Round_Down)
For x = 0 To x_end
couleur.couleur\c = Point(x, y)
lum = (couleur\o\o1 + couleur\o\o2 + couleur\o\o3) / 3
x_rounded.l = Round(x / *image\diviseur, #PB_Round_Down)
If lum > *image\lum(x_rounded, y_rounded) - seuil
Plot(x, y, #White)
EndIf
Next
Next
EnableDebugger
StopDrawing()
ProcedureReturn *image\hdl_res
EndProcedure
;}
;{ test area
img.image\file = OpenFileRequester("Ouvrir une image", "", "Images|*.bmp;*.jpg;*.png", 0)
; Paramètre de nettoyage
img\diviseur = 10
img\rayon = 15
img\seuil_diviseur = 1.2
img\hdl = LoadImage(#PB_Any, img\file)
If IsImage(img\hdl) = 0 : End : EndIf
time = ElapsedMilliseconds()
ImageToArrayLum(img)
ImageMoyenneLocale(img)
CalculImage(img)
time = ElapsedMilliseconds() - time
MessageRequester("", "Tps total = " + time + " ms")
SaveImage(img\hdl_res, GetPathPart(img\file) + StringField(GetFilePart(img\file), 1, ".") + "_res_rapide.png", #PB_ImagePlugin_PNG)
;}