Neti : Un nettoyeur de photo de texte

Vous avez développé un logiciel en PureBasic et vous souhaitez le faire connaitre ?
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Neti : Un nettoyeur de photo de texte

Message par graph100 »

Ce type de logiciel existe déjà sur les smartPhones, mais je me suis retrouvé avec des scans / photos de document écrit, et ils ne gèrent pas de manière pratique les photos déjà prisent.
Je me suis donc creusé la cervelle pour faire la même chose sur un pc, pour profiter de la puissance de calcul de nos machine (si un tel peut le faire pourquoi pas mon ordi ?! :lol: )

Bref, voila NETI (pour NETtoie Image) : Neti.zip

Ce que ça fait :
Prend un dossier d'image, nettoie les images selon 3 paramètres qui permettent d'obtenir le résultat désiré
si le cadre rouge est bougé, l'image finale sera un rectangle calculé à partir du cadre rouge.

Le même rectangle est appliqué pour tout le dossier, il est donc préférable de ne pas avoir bougé les documents et l'appareil (photo / scan..) entre chaque photo.
La détection des bords de l'image n'est pas encore faite.

Honnêtement le prog est pas fini, l'interface n'est pas vraiment au point, ça peut crasher si le cadre rouge sort des images, etc..
Mais j'en avais besoin pour bosser, donc je l'ai mis à ce point là.

EXEMPLE

Image originale :
Image

Image Nettoyée :
Image
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Neti : Un nettoyeur de photo de texte

Message par Backup »

je n'en aurai probablement pas l'utilisation , mais merci pour le partage :)

ps : je pense que tu n'as pas eu beaucoup de retour, car les gens sont en vacances
donc moins présent :)

par contre ton algo est t'il compliqué ?
je dis ça car je l'aurai bien inclue dans Barbouille :)
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Neti : Un nettoyeur de photo de texte

Message par graph100 »

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 :D ).
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)


;}


Dernière modification par graph100 le dim. 12/mai/2013 22:29, modifié 1 fois.
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Neti : Un nettoyeur de photo de texte

Message par Backup »

Merci pour le partage :)
Frenchy Pilou
Messages : 2194
Inscription : jeu. 27/janv./2005 19:07

Re: Neti : Un nettoyeur de photo de texte

Message par Frenchy Pilou »

Et les mots qui sont encore difficilement lisibles par le programme, on les envoie au système de re Captcha! ;)

http://www.youtube.com/watch?v=-Ht4qiDRZE8

(on peut mettre des sous-titres en français)
Est beau ce qui plaît sans concept :)
Speedy Galerie
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Neti : Un nettoyeur de photo de texte

Message par Ar-S »

Salut Graph.
Dans ton exemple tu passes de l'image marron à l'image traitée ? Ton programme zappe la déformation ou tu as utilisé une autre image ?
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Neti : Un nettoyeur de photo de texte

Message par graph100 »

Effectivement l'image d'entrée est l'image marron, et celle en sortie est présentée en dessous, je n'ai rien fait d'autre que de les mettre en plus petit sur le post.

Mon programme effectue la transformation d'un quadrangle vers un rectangle. Il faut utiliser le cadre rouge (normalement sur le tour de l'image au début) pour donner la forme du quadrangle.
Je ne me suis pas encore attaqué à la détection de la forme automatiquement.
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Répondre