Computer Vision Case Study

Automatische Erkennung von Kleinbergbau

Tipp: Wechseln Sie zwischen allgemeinen Informationen und einer eher technischen Sicht auf dieses Projekt

Starting Point

Der handwerkliche und Kleinbergbau (Artisanal and small scale mining, ASM) ist für 10 % der weltweiten Goldproduktion mit einem geschätzten Marktwert von 14 Milliarden US-Dollar verantwortlich und beeinträchtigt das Leben von 10 bis 20 Millionen Bergleuten (und weiteren 80 Millionen Bergleuten für andere Rohstoffe) und ihrer Familien. ASM-Standorte befinden sich in mehr als 80 Entwicklungsländern und sind mit niedrigeren Umwelt- und Arbeitssicherheitsstandards verbunden. Zur Durchsetzung von Konzessionsrechten, der Arbeitsgesetzgebung oder zur Erforschung von Migrationsmustern ist es für Regierungsbehörden, NGOs und Forscher unerlässlich, rechtzeitig Daten über die Lage und Ausdehnung von ASM in ihrer jeweiligen Interessenregion zu erhalten. Da dazu riesige Gebiete überwacht werden müssen, sind Satellitenbilder die beste Technologie zur Kartierung von ASM. dida entwickelt zusammen mit dem MRE an der RWTH Aachen ASMSpotter, ein Computer Vision Tool zur automatischen Segmentierung von ASM-Standorten in Satellitenbildern.

Um das Ausmaß der ASM-Aktivitäten in einer bestimmten Region abzuschätzen, stützen sich Bergbauexperten derzeit auf manuelle Untersuchungen des Gebietes über Bing Maps und ähnliche Dienste. Bei diesem Ansatz gibt es viele Probleme. Dienste wie Bing Maps sind nicht unbedingt auf dem neuesten Stand, insbesondere in abgelegenen Regionen, in denen ASM durchgeführt wird. Auch da die Analyse der Daten manuell von einem Experten durchgeführt wird, ist es recht kostenintensiv und ineffizient, große Gebiete zu analysieren.

Challenges

Die größte Herausforderung bei der Entwicklung besteht darin, einen ausreichenden Satz von Ausbildungsdaten zu sammeln. Zu diesem Zweck hatten wir Zugang zu Planet Scope, einem hochauflösenden Satellitensystem, das von Planet Labs betrieben wird. Die Trainingsdaten bestehen aus weitgehend wolkenfreien Bildern des AOI. Abhängig vom AOI können wolkenfreie Bilder knapp sein, aber es gibt Methoden, mehrere Bilder im Laufe der Zeit zu kombinieren, um ein wolkenfreies Bild des AOI zu erhalten.

Unser Partner bei MRE kennzeichnete etwa 100 Planet Scope Bilder. Bei diesem Projekt war ein einziger Bergbauexperte für die Kennzeichnung zuständig. Für den Prototyp beschränkten wir die AOI auf den Nordosten von Surinam. Dieses Gebiet wurde ausgewählt, weil es repräsentativ für viele Regionen ist, in denen ASM-Standorte zu finden sind. Die Region liegt im Amazonas-Regenwald, und der hydraulische Bergbau ist die vorherrschende Methode für den Goldabbau. Planet Scope war die primäre Satellitenkonstellation, da sie eine der höchsten verfügbaren Auflösungen bietet (ca. 5m/px). Sentinel-2 wurde ebenfalls erfolgreich getestet, war jedoch nicht der primäre Fokus dieser Studie.

Solution

Wir trainieren ein tiefes neuronales Netzwerk mit einer U-Netz-Architektur. Das Modell ist als Python-Bibliothek verfügbar. ASMSpotter kann lokal ausgeführt werden, um vom Benutzer bereitgestellte Planet Scope Bilder zu analysieren. In einer zukünftigen Phase des Projekts kann ASMSpotter zu einem Cloud-Service entwickelt werden, der Satellitenbilder auf Anfrage analysiert oder so konfiguriert werden kann, dass er ein bestimmtes AOI kontinuierlich überwacht.

Verwendete Technologien: Python, PyTorch, Numpy, Matplotlib, Anfragen

Das Training des Deep Neural Network wurde auf einer Google Cloud Compute-Instanz mit Nvidia Tesla P100 durchgeführt. Die Beschriftung wurde mit LabelBox durchgeführt. Die Beschriftung erfolgte nicht auf dem Vollbild, sondern auf einer Graustufendarstellung des normalisierten Differenzwasserindex (NDWI). Planet Scope hat vier Kanäle (RGB+NIR). Der NDWI wird berechnet als

$$ NDWI = \frac{G - NIR}{G + NIR} $$

und es hebt Bereiche mit hohem Wassergehalt hervor. Das NDWI ist den Planet Scope Bildern als fünfter Kanal beigefügt. Der normalisierte Differenz-Vegetationsindex (NDVI) wird berechnet als

$$ NDVI = \frac{NIR - R}{NIR + R} $$

und hebt die Vegetation in den Bildern hervor. Er wird als sechster Kanal an die Eingabedaten angehängt.

Product

At first we need to import some standard libraries to handle and display the data.

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from PIL import Image

From the ASMSpotter package, we need to import the relevant functions. load_model, as the name suggests, loads the PyTorch model, while Preprocessor is a class that prepares the raw Planet Scope images for the analysis. In our case, we will run ASMSpotter on the GPU, which has only limited memory. Therefore, the image needs to be split into chunks and the predictions need to be stiched togeather. This is done by predict_full_image.

from ASMSpotter import load_model, predict_full_image
from ASMSpotter.preprocessor import Preprocessor

model = load_model()
preproc = Preprocessor()

Als Nächstes werden wir das Planet Scope Bild laden. Planet Scope Bilder können auf verschiedene Arten erhalten werden, z.B. durch Verwendung des Browsers mit einem GUI von Planet Labs oder durch Interaktion mit der API. Im Moment gehen wir davon aus, dass das Bild bereits heruntergeladen wurde. Planet Scope Bilder gibt es in verschiedenen Formen. Es gibt das analytische Produkt, das im Grunde genommen die Rohdaten sind und das für die Analyse verwendet wird. Zusätzlich bietet Planet Labs visuelle Produkte an, bei denen es sich um die gleichen Bilder handelt, die jedoch für die visuelle Darstellung vorbereitet sind. Wir haben beide heruntergeladen, damit wir ASMSpotters Vorhersage gut vorbereiten können. Möglicherweise können die Segmentierungsmasken auch in Kombination mit z.B. Karten dargestellt werden.

analytic_product_fname = "/home/dida/20181016_133712_1038_3B_AnalyticMS_SR.tif"
visual_product_fname = "/home/dida/20181016_133712_1038_3B_Visual.tif"

analytic_image = np.asarray(Image.open(analytic_product_fname))
visual_image = np.asarray(Image.open(visual_product_fname))

# Normalize visual representation for display
visual_image = visual_image - visual_image.min()
visual_image = visual_image / visual_image.max()

Zunächst muss das Analyseprodukt vorverarbeitet werden. Dies geschieht durch Aufruf des Preprocessor-Objektes auf dem analytischen Bild. Der Präprozessor hängt die NDWI und NDVI als zusätzliche Kanäle an das Bild an und normalisiert sie kanalweise. Das vorverarbeitete Bild in Kombination mit dem Modell kann an predict_full_image übergeben werden, der die Vorhersage im Falle von begrenztem Speicher übernimmt.

%%time
preprocessed_image = preproc(analytic_image)
segmentation_mask = predict_full_image(model, preprocessed_image)
CPU times: user 11.2 s, sys: 2.45 s, total: 13.7 s
Wall time: 12.1 s

And that is already it! segmentation_mask is a ndarray with the pixel-wise logits of the prediction. It can be converted to a segmentation mask by filtering for values > 0. The image covers roughly $360 \text{km}^2$ and it took $12 s$ to analyze.

With a few lines of code using matplotlib we can represent the segmentation mask in combination with the visual product.

current_cmap = matplotlib.cm.get_cmap("autumn")
current_cmap.set_bad(alpha=0.)

segmentation_mask[ segmentation_mask > 0 ] = 255.
segmentation_mask[ segmentation_mask <= 0 ] = np.nan

plt.figure(figsize=(20, 20))
plt.title("Detected ASM sites - highlighted in red", fontsize=20)
plt.imshow(visual_image)
plt.imshow(segmentation_mask, alpha=0.5, cmap=current_cmap)
plt.axis("off")
(-0.5, 8999.5, 4375.5, -0.5)

Zuerst müssen wir einige Standardbibliotheken importieren, um die Daten zu verarbeiten und anzuzeigen.

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from PIL import Image

Aus dem ASMSpotter-Paket müssen wir die entsprechenden Funktionen importieren. load_model, wie der Name schon sagt, lädt das PyTorch-Modell, während Preprocessor eine Klasse ist, die die rohen Planet Scope Bilder für die Analyse aufbereitet. In unserem Fall werden wir ASMSpotter auf der GPU laufen lassen, die nur über begrenzten Speicher verfügt. Daher muss das Bild in Stücke zerlegt und die Vorhersagen zusammengefügt werden. Dies geschieht durch predict_full_image.

from ASMSpotter import load_model, predict_full_image
from ASMSpotter.preprocessor import Preprocessor

model = load_model()
preproc = Preprocessor()

Als Nächstes werden wir das Planet Scope Bild laden. Planet Scope Bilder können auf verschiedene Arten erhalten werden, z.B. durch Verwendung des Browsers mit einem GUI von Planet Labs oder durch Interaktion mit der API. Im Moment gehen wir davon aus, dass das Bild bereits heruntergeladen wurde. Planet Scope Bilder gibt es in verschiedenen Formen. Es gibt das analytische Produkt, das im Grunde genommen die Rohdaten sind und das für die Analyse verwendet wird. Zusätzlich bietet Planet Labs visuelle Produkte an, bei denen es sich um die gleichen Bilder handelt, die jedoch für die visuelle Darstellung vorbereitet sind. Wir haben beide heruntergeladen, damit wir ASMSpotters Vorhersage gut vorbereiten können. Möglicherweise können die Segmentierungsmasken auch in Kombination mit z.B. Karten dargestellt werden.

analytic_product_fname = "/home/dida/20181016_133712_1038_3B_AnalyticMS_SR.tif"
visual_product_fname = "/home/dida/20181016_133712_1038_3B_Visual.tif"

analytic_image = np.asarray(Image.open(analytic_product_fname))
visual_image = np.asarray(Image.open(visual_product_fname))

# Normalize visual representation for display
visual_image = visual_image - visual_image.min()
visual_image = visual_image / visual_image.max()

Zunächst muss das Analyseprodukt vorverarbeitet werden. Dies geschieht durch Aufruf des Preprocessor-Objektes auf dem analytischen Bild. Der Präprozessor hängt die NDWI und NDVI als zusätzliche Kanäle an das Bild an und normalisiert sie kanalweise. Das vorverarbeitete Bild in Kombination mit dem Modell kann an predict_full_image übergeben werden, der die Vorhersage im Falle von begrenztem Speicher übernimmt.

%%time
preprocessed_image = preproc(analytic_image)
segmentation_mask = predict_full_image(model, preprocessed_image)
CPU times: user 11.2 s, sys: 2.45 s, total: 13.7 s
Wall time: 12.1 s

Und das ist schon alles! segmentation_mask ist ein ndarray mit den pixelweisen Logits der Vorhersage. Es kann in eine Segmentierungsmaske umgewandelt werden, indem auf Werte > 0 gefiltert wird. Das Bild umfasst etwa $360 \text{km}^2$ und die Analyse dauerte $12 s$.

Mit ein paar Zeilen Code unter Verwendung der matplotlib können wir die Segmentierungsmaske in Kombination mit dem visuellen Produkt darstellen.

current_cmap = matplotlib.cm.get_cmap("autumn")
current_cmap.set_bad(alpha=0.)

segmentation_mask[ segmentation_mask > 0 ] = 255.
segmentation_mask[ segmentation_mask <= 0 ] = np.nan

plt.figure(figsize=(20, 20))
plt.title("Detected ASM sites - highlighted in red", fontsize=20)
plt.imshow(visual_image)
plt.imshow(segmentation_mask, alpha=0.5, cmap=current_cmap)
plt.axis("off")
(-0.5, 8999.5, 4375.5, -0.5)

Case Studies in Computer Vision

Computer Vision

Überwachung von urbanen Veränderungen

Ein Algorithmus zur Bildsegmentierung unterstützt nachhaltige Stadtplanung.
Unsere Lösung
Computer Vision

Automatische Planung von Solaranlagen

Durch kreative Lösungen konnten wir die Planung von Solaranlagen automatisieren.
Unsere Lösung