Puede usar un algoritmo de pintura estándar. Estos algoritmos reemplazan los píxeles marcados en una imagen con los valores de píxeles que rodean estos píxeles marcados. El desafío aquí es detectar la cuadrícula (mis pruebas parecen mostrar que no es una cuadrícula completamente regular). Entonces, se me ocurrió esta solución:
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 salida del programa es la siguiente:
Para detectar la red hice una solución rápida y sucia. Se puede mejorar mucho, pero muestra la idea inicial. El flujo general es:
- detectar la cuadrícula
- crear una máscara que describa qué píxeles están dañados por la cuadrícula
- pintar los píxeles corruptos.
Para la pintura, utilicé la operación de pintura OpenCV . Para detectar la cuadrícula, realicé la detección de bordes en dirección X e Y utilizando un filtro Sobel. Luego agrego todos los valores de borde en la dirección X e Y para encontrar picos, donde están las líneas de la cuadrícula. Luego, elijo los picos más altos como las coordenadas donde se estiman las líneas de la cuadrícula. No funciona perfectamente (por ejemplo, los bordes fuertes de la imagen se detectan falsamente como líneas de cuadrícula), pero muestra la idea. Se puede mejorar, por ejemplo, con la transformación de Hough para encontrar líneas, patear bordes muy fuertes, etc.
Alternativamente, si la cuadrícula es realmente la misma para todas las imágenes, entonces puede realizar la detección de la cuadrícula conjuntamente para todas las imágenes, lo que produciría una precisión mucho mejor (solo realice la técnica anterior, pero antes de elegir los picos, resuma los resultados de todas las imágenes). Con más detalle, calcularía eX para todas las imágenes y agregaría todas estas eX juntas en un solo vector. Este vector tendrá una estructura de pico mucho más clara y el umbral puede hacerse más fácilmente.