Sie können einen Standard-Inpainting-Algorithmus verwenden. Diese Algorithmen ersetzen markierte Pixel in einem Bild durch die Pixelwerte, die diese markierten Pixel umgeben. Die Herausforderung besteht hier darin, das Gitter zu erkennen (meine Tests scheinen zu zeigen, dass es kein vollständig reguläres Gitter ist). Also habe ich mir diese Lösung ausgedacht:
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)
Die Programmausgabe lautet wie folgt:
![Geben Sie hier die Bildbeschreibung ein](https://i.stack.imgur.com/bPcd4.png)
![Geben Sie hier die Bildbeschreibung ein](https://i.stack.imgur.com/IxzvU.png)
Um das Gitter zu erkennen, habe ich eine schnelle und schmutzige Lösung gefunden. Es kann viel verbessert werden, aber es zeigt die ursprüngliche Idee. Der allgemeine Ablauf ist:
- Erkennen Sie das Gitter
- Erstellen Sie eine Maske, die beschreibt, welche Pixel durch das Raster beschädigt werden
- Malen Sie die beschädigten Pixel.
Zum Inpainting habe ich OpenCV Inpaint verwendet. Zur Erkennung des Gitters habe ich eine Kantenerkennung in X- und Y-Richtung mit einem Sobel-Filter durchgeführt. Dann addiere ich alle Kantenwerte in X- und Y-Richtung, um Spitzen zu finden, bei denen sich die Gitterlinien befinden. Dann wähle ich die höchsten Spitzen als Koordinaten, bei denen die Gitterlinien geschätzt werden. Es funktioniert nicht perfekt (z. B. werden starke Kanten im Bild fälschlicherweise als Gitterlinien erkannt), aber es zeigt die Idee. Es kann zB durch Hough-Transformation verbessert werden, um Linien zu finden, sehr starke Kanten herauszuschmeißen usw.
Wenn das Raster für alle Bilder wirklich gleich ist, können Sie alternativ die Rastererkennung für alle Bilder gemeinsam durchführen, was zu einer viel besseren Genauigkeit führen würde (führen Sie einfach die oben beschriebene Technik aus, aber fassen Sie die Ergebnisse aus zusammen, bevor Sie die Peaks auswählen alle Bilder). Im Detail würden Sie eX für alle Bilder berechnen und alle diese eX zu einem einzigen Vektor addieren. Dieser Vektor hat eine viel klarere Peakstruktur und die Schwellenwertbildung kann einfacher durchgeführt werden.