Vous pouvez utiliser un algorithme de peinture standard. Ces algorithmes remplacent les pixels marqués d'une image par les valeurs de pixels qui entourent ces pixels marqués. Le défi ici est de détecter la grille (mes tests semblent montrer que ce n'est pas une grille complètement régulière). J'ai donc trouvé cette solution:
from PIL import Image
import requests
from io import BytesIO
import cv2
url = "http://i.stack.imgur.com/Ahrnl.jpg"
response = requests.get(url)
img = Image.open(BytesIO(response.content))
plt.imshow(img)
A = np.array(img)
A2 = A.copy()
A_gray = cv2.cvtColor(A, cv2.COLOR_RGB2GRAY)
# Do some rough edge detection to find the grid
sX = cv2.Sobel(A_gray, cv2.CV_64F, 1, 0, ksize=3)
sY = cv2.Sobel(A_gray, cv2.CV_64F, 0, 1, ksize=3)
sX[sX<0] = 0
sY[sY<0] = 0
plt.subplot(221)
plt.imshow(sX)
plt.subplot(222)
plt.imshow(sY)
plt.subplot(223)
# the sum operation projects the edges to the X or Y-axis.
# The 0.2 damps the high peaks a little
eX = (sX**.2).sum(axis=0)
eX = np.roll(eX, -1) # correct for the 1-pixel offset due to Sobel filtering
plt.plot(eX)
plt.subplot(224)
eY = (sY**.2).sum(axis=1)
eY = np.roll(eY, -1)
plt.plot(eY)
mask = np.zeros(A2.shape[:2], dtype=np.uint8)
mask[eY>480,:] = 1
mask[:, eX>390] = 1
A2[mask.astype(bool),:] = 255
plt.figure()
plt.subplot(221)
plt.imshow(A)
plt.subplot(222)
plt.imshow((A2))
restored = cv2.inpaint(A, mask, 1, cv2.INPAINT_NS)
plt.subplot(223)
plt.imshow(restored)
La sortie du programme est la suivante:
Pour détecter la grille, j'ai fait une solution rapide et sale. Il peut être beaucoup amélioré, mais il montre l'idée initiale. Le flux général est le suivant:
- détecter la grille
- créer un masque qui décrit quels pixels sont corrompus par la grille
- inpaint les pixels corrompus.
Pour l'inpainting, j'ai utilisé l' opération Inpaint d' OpenCV . Pour détecter la grille, j'ai effectué une détection de bord dans les directions X et Y en utilisant un filtre Sobel. Ensuite, j'ajoute toutes les valeurs de bord dans la direction X et la direction Y pour trouver des pics, où se trouvent les lignes de la grille. Ensuite, je choisis les pics les plus élevés comme coordonnées où les lignes de la grille sont estimées. Cela ne fonctionne pas parfaitement (par exemple, les bords forts de l'image sont faussement détectés comme des lignes de grille), mais cela montre l'idée. Il peut être amélioré par exemple par une transformation de Hough pour trouver des lignes, éliminer les bords très forts, etc.
Alternativement, si la grille est vraiment la même pour toutes les images, vous pouvez effectuer la détection de grille conjointement pour toutes les images, ce qui donnerait une bien meilleure précision (faites simplement la technique ci-dessus, mais avant de choisir les pics, résumez les résultats à partir de toutes les photos). Plus en détail, vous devez calculer l'eX pour toutes les images et ajouter tous ces eX ensemble dans un seul vecteur. Ce vecteur aura une structure de pic beaucoup plus claire et le seuillage peut être fait plus facilement.