È possibile utilizzare un algoritmo di pittura standard. Questi algoritmi sostituiscono i pixel contrassegnati in un'immagine con i valori dei pixel che circondano questi pixel contrassegnati. La sfida qui è quella di rilevare la griglia (i miei test sembrano dimostrare che non è una griglia completamente regolare). Quindi, ho trovato questa soluzione:
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)
L'output del programma è il seguente:
Per rilevare la griglia ho fatto una soluzione rapida e sporca. Può essere migliorato molto, ma mostra l'idea iniziale. Il flusso generale è:
- rilevare la griglia
- creare una maschera che descriva quali pixel sono danneggiati dalla griglia
- dipingere i pixel corrotti.
Per la pittura ho usato l' operazione di pittura di OpenCV . Per rilevare la griglia, ho eseguito il rilevamento dei bordi in direzione X e Y utilizzando un filtro Sobel. Quindi aggiungo tutti i valori dei bordi nella direzione X e Y per trovare i picchi, dove si trovano le linee della griglia. Quindi, scelgo i picchi più alti come coordinate in cui sono stimate le linee della griglia. Non funziona perfettamente (ad es. I bordi forti nell'immagine vengono rilevati erroneamente come linee della griglia), ma mostra l'idea. Può essere migliorato, ad esempio, dalla trasformazione di Hough per trovare linee, eliminare bordi molto forti ecc.
In alternativa, se la griglia è davvero la stessa per tutte le immagini, è possibile eseguire il rilevamento della griglia congiuntamente per tutte le immagini, il che produrrebbe una precisione molto migliore (basta fare la tecnica sopra, ma prima di scegliere i picchi, riassumere i risultati da tutte le foto). Più in dettaglio, calcoleresti eX per tutte le immagini e sommeresti tutti questi eX in un unico vettore. Questo vettore avrà una struttura di picco molto più chiara e la soglia può essere eseguita più facilmente.