Comment éliminer les zones grisâtres d'un scan.
Un programme de quelques lignes en Python permet de supprimer les
zônes grises du scan, au bord des pages, notamment si le scan
concerne une page double.
 |

|
 |
Voici l'original |
voici le masque de bruit
|
et voici l'image corrigée |
#Python 2.5.2
# -*- encoding: utf-8 -*-
import numpy
import os
import os.path
import Image
import ImageOps
import sys
Première étape:Identifier la zone
grise
Appliquer une dilatation (voir morphologie) 3 fois de suite ; les
zones blanches sont agrandies et il ne reste que le gris.
Explications et procédures sur :http://francoislouislaillier.developpez.com/Python/Tutoriel/InitiationNumpy/Tuto1/
# -*- ces procédures sont empuntées au
tutoriel numpy -*-
def OuvrirImg(path):
Img = Image.open( path)
Img1 = ImageOps.grayscale(Img)
largeur,hauteur = Img1.size
imdata=Img1.getdata()
tab=numpy.array(imdata)
matrix = numpy.reshape(tab,(hauteur,largeur))
return matrix
def Bord(data):
data=numpy.array(data)
x=data.shape[1]+2
y=data.shape[0]+2
new=[x*[0]]*y #création du tableau
new=numpy.array(new)
h=1
for i in range(1,y-1):
for j in range(1,x-1):
new[i][j]=data[i-1][j-1] #remplissage du tableau
return new
def Dilatation(img,dest):
Dilate=[0]*(img.shape[1]-2)*(img.shape[0]-2)
h=0
for i in range(1,img.shape[0]-1):
for j in
range(1,img.shape[1]-1):
Dilate[h]=max([img[i-1][j-1],img[i][j-1],img[i+1][j-1],img[i-1][j],img[i][j],img[i+1][j],img[i-1][j+1],img[i][j+1],img[i+1][j+1]])
#Mise de la
valeur max du voisinage 3x3 au point(x,y)
h+=1
Dilate=numpy.array(Dilate)
Dilate=numpy.reshape(Dilate,(img.shape[0]-2,img.shape[1]-2))
RebuildImg(Dilate,dest)
def RebuildImg(data,path): #data de l'image à reconstruire, plus
chemin de sortie.
Copie =
Image.new("L",(data.shape[1],data.shape[0]))
Copie.putdata(list(data.flat))
Copie.save(path)
Deuxième étape: combiner le masque
obtenu dans la première étape avec l'original
def
elimine_bruit(original,masque,destination):
Comparaison=[0]*(original.shape[1])*(original.shape[0])
h=0
for i in range(0,original.shape[0]):
for j in
range(0,original.shape[1]):
if masque[i][j]<250: #le pixel est dans la zone bruitée
if original[i][j]>masque[i][j]: #le pixel original est plus
clair que le niveau du bruit, on le recopie
Comparaison[h]=original[i][j]
else: #le pixel original est plus sombre ou égal au niveau
du bruit en ce point, on soustrait le niveau de bruit
Comparaison[h]=255-masque[i][j]+original[i][j]
else: #le pixel n'est pas dans la zone bruitée, on recopie
l'original
Comparaison[h]=original[i][j]
h+=1
Comparaison=numpy.array(Comparaison)
Comparaison=numpy.reshape(Comparaison,(original.shape[0],original.shape[1]))
RebuildImg(Comparaison,destination)
return
Soit pour enchaîner le tout:
if __name__ == "__main__":
source_gris=OuvrirImg( u"chemin de l'image originale")
#* une fois*
fichier_temp=os.tempnam()+".bmp" #crée un fichier temporaire pour
le masque
provisoire=Bord(source_gris)
final=Dilatation(provisoire,fichier_temp)
provisoire_gris=OuvrirImg(fichier_temp)
provisoire=Bord(provisoire_gris)
os.remove(fichier_temp) #le fichier temporaire est inutile
#* deux fois*
fichier_temp=os.tempnam()+".bmp"
final=Dilatation(provisoire,fichier_temp)
provisoire_gris=OuvrirImg(fichier_temp)
provisoire=Bord(provisoire_gris)
os.remove(fichier_temp)
#* trois fois*
fichier_temp=os.tempnam()+".bmp"
final=Dilatation(provisoire,fichier_temp)
bruit_gris=OuvrirImg(fichier_temp)
os.remove(fichier_temp)
#* fin de la construction du masque
elimine_bruit(source_gris,bruit_gris,u'chemin de sauvegarde
résultat')