Close

Ungänzen von Schweißnähten automatisch auswerten mit Python

In diesem Artikel soll es darum gehen, wie man mit wenigen Zeilen Python-Code Röntgenbilder von Schweißnähten auswerten kann. Dazu wird während der Verarbeitung der Kontrast angepasst, die Farben des Bildes invertiert und die möglichen Ungänzen farblich hervorgehoben. Es wurde maßgeblich die skimage Bibliothek verwendet. Diese stellt klassische Algorithmen und Filter der Bildverarbeitung zur Verfügung.

Voraussetzungen

Für die Programmierung wurde ein Jupyter Notebook mit Python 3.7 verwendet. Besonders nützlich ist die Entkoppelung vom Host-System bzw. die Verwendung von Docker-Containern. Dies ist aber nicht zwingend notwendig. Um später ggf. tiefere Analysen mit Machine Learning durchzuführen, ist hier ein TensorFlow Docker Image verwendet worden. Wer Docker nicht verwenden will oder einfach nur den Python-Code sehen möchte, kann die nächsten Abschnitte einfach überspringen.

Einrichten des Docker Images

Wenn Docker installiert ist, kann wie folgt das Jupyter Notebook initialisiert werden. Dazu muss zunächst das TensorFlow Image heruntergeladen (docker pull) und danach gestartet (docker run) werden. Dann kann bequem über den Browser programmiert werden, da der localhost Port 8888 auf die Web IDE des Containers geleitet wird (-p 8888:8888).  Die Option –name tf gibt dem Container den Namen tf (als Abkürzung für TensorFlow), um ihn später besser aufrufen zu können. Damit der erstellte Code auch gespeichert werden kann, muss ebenso ein Ordner “tf” erstellt werden (mkdir), der im Docker Container als Volume (mit der Option -v <path>)  gemountet wird. Dieser kann auch beliebig heißen, muss allerdings dann in den Pfaden entsprechend angepasst werden.

Die folgenden Befehle müssen dazu ausgeführt werden:

cd <my-path>
mkdir tf
docker pull tensorflow/tensorflow:latest-py3-jupyter
docker run -p 8888:8888 --name tf -v <path-to-my-tf-folder>/tf:/tf/Entwicklung tensorflow/tensorflow:latest-py3-jupyter

Nun wird ein Jupyter Notebook Server auf dem lokalen Rechner gehostet. Folgt man den Anweisungen in der Konsole, kann man dann auf den korrespondierenden Pfad http://127.0.0.1:8888/?token=<token>im Browser gehen und im Ordner ‘Entwicklung ein Notebook erstellen. Dazu oben rechts auf den Button ‘New‘ und dann ‘Notebook: Python 3‘ klicken.

Danach sollte man zeitnah speichern per ‘File‘ – ‘Save And Checkpoint‘ , wo durch eine Datei ‘Untitled.ipynberstellt wird, die nun auch auf dem Host-System liegt und dadurch gesichert ist.

Einrichten der Python Umgebung

Nun müssen die erforderlichen Python Pakete installiert werden. Dazu sollte entweder im Docker Container oder mit Virtual Environments (falls Docker nicht verwendet wurde) gearbeitet werden. Mit dem Befehl (docker exec) kann im Container auf die Konsole zugegriffen werden und die Pakete per pip installiert werden. Hier wird hauptsächlich das Paket scikit-image oder skimage für die Verarbeitung und matplotlib zur Darstellung verwendet werden. Zusätzlich werden noch numpy zur Hilfe verwendet. Zur Installation müssen die folgenden Befehle ausgeführt werden.

docker exec -it tf /bin/bash 
#Console of container
pip install matplotlib numpy scipy scikit-image

Das Python Skript

Als erstes müssen die verschiedenen Pakete importiert werden. Wir erstellen einen neuen Abschnitt im Notebook oder unserem Skript und fügen die folgenden Zeilen ein:

import numpy as np
import matplotlib.pyplot as plt
import base64
from skimage import feature, io, filters, util, exposure, restoration
from matplotlib.colors import ListedColormap

Danach wird eine Funktion erstellt, die die Farben für die Markierung der Ungänzen und Schweißnahtfehler anpasst. Es sollen nämlich verschiedene Bild-Schichten übereinander gelegt werden. Daher müssen die nicht markierten Stellen der Ebene transparent sein.

def createTransparentMap(cmap):
# Get the colormap colors
my_cmap = cmap(np.arange(cmap.N))
# Set alpha
my_cmap[:,-1] = np.linspace(0, 1, cmap.N)
# Create new colormap
return ListedColormap(my_cmap)

Danach wird eine Funktion definiert, die Bilder base64 encoded einlesen kann. Hierzu wird zunächst auf die Formatierung des Bild Strings geprüft und danach eine Pixel-Matrix ausgegeben. Es könnte ebenso eine Datei geladen werden mithilfe der io.imread-Methode von skimage. Allerdings müsste diese dann auch gemountet werden. Hier wurde im Hinblick auf die Verwendung innerhalb eines möglichen Webservice die base64 Variante gewählt, da diese oft als Standard für RESTful-Interfaces genutzt wird.

def decode(base64_string):
# check format
if isinstance(base64_string, bytes):
base64_string = base64_string.decode("utf-8")
# decode
imgdata = base64.b64decode(base64_string)
img = io.imread(imgdata, as_gray=True, plugin='imageio')
# pixel matrix
return img

Um fortzufahren, werden danach im Skript einige Konstanten definiert. Ein Sigma-Wert der für die Kantenerkennung mit einem Canny-Filter genutzt wird. Zwei angepasste Farbpaletten für die Markierung der Ungänzen und ein Censure-Detektor, um Features im Bild zu erkennen. Die Schweißnahtfehler werden dann als Feature des Bildes automatisch erkannt und markiert.

sigma = 0.6
redMap = createTransparentMap(plt.cm.cool)
blueMap = createTransparentMap(plt.cm.GnBu)
detector = feature.CENSURE()

Im Anschluss kann die eigentlich Analysefunktion für die Markierung erstellt werden. Dazu wird das Bild zunächst in eine Pixel-Matrix überführt mit Hilfe der zuvor erstellten decode-Methode. Danach wird eine Sigmoid-Funktion angewendet, um den Kontrast des Bildes zu anzupassen. In der Bildverarbeitung wird die Sigmoid-Funktion neben der ReLU sehr häufig als Standard verwendet. Die angepasste Matrix dient dem Censure-Detektor als Input.

def process_image(baseImage):

  im = decode(baseImage)
  # Correction of image (contrast, noise etc)
  sigmoid_im = exposure.adjust_sigmoid(im)

#Feature detection
  detector.detect(sigmoid_im)

Im Anschluss werden in den Variablen edges1 und edges2 die Ergebnisse der Kantenerkennung gespeichert. Dazu wird ein Canny-Algorithmus (mit dem zuvor definierten Sigma) und ein Sobel-Filter verwendet. Allerdings werden diese nicht auf die Sigmoid-adaptierte Matrix angewendet, da diese bei dem Testbild ein zu großes Rauschen verursacht.

  # Compute the Canny filter for two values of sigma
  edges1 = feature.canny(im, sigma=sigma)
  edges2 = filters.sobel(im)

Nachdem nun die Features und Kanten des Bildes erkannt wurden, können diese mit matplotlib dargestellt werden. Dazu wird eine 1-achsige Grafik erstellt und mit den ax.imshow-Aufrufen die Bildebenen gezeichnet. In der untersten Ebene werden die Farben der Sigmoid-Matrix invertiert (util.invert) und danach die Kanten (Canny und Sobel) mit den zuvor angepassten Farben gezeichnet. Im Anschluss werden die erkannten Features des Censure-Detektors mit einem Scatter-Plot eingezeichnet und die Grafik final mit plt.show präsentiert.

  # display edges
  fig, (ax) = plt.subplots(nrows=1, ncols=1, figsize=(32, 12), sharex=True, sharey=True)

  #draw pixels
ax.imshow(util.invert(sigmoid_im), cmap=plt.cm.gray)
  ax.imshow(edges1, cmap=redMap)
  ax.imshow(edges2, cmap=redMap)

  # display censure features
  ax.scatter(detector.keypoints[:, 1], detector.keypoints[:, 0], 2 ** detector.scales, facecolors='none', edgecolors='r')
  ax.axis('off')
plt.show()

Verwendet man nun die Funktion process_image mit einem Beispiel-Bild kann dies wie folgt aussehen. Dazu wurde eine JPEG-Datei mithilfe dieses Tools (im binary-Format) encodiert. Sie stellt ein typisches digitales RT-Bild einer Schweißnaht dar. 

sampleImage = '...' 
processImage(sampleImage)

Fazit

Dieses kurze Skript zeigt, wie eine Bild einer Schweißnaht mit einfachen Funktion der skimage Bibliothek angepasst werden kann. Die Parameter und Filter-Funktionen wurden hier so gewählt, dass sie Fehler und Ungänzen auf dem Testbild erkennen können. Für den Einsatz in der Praxis empfiehlt es sich jedoch diese Parameter nicht starr vorzugeben sondern adaptiv zu wählen. Nächste Schritte zur Einbettung des Algorithmus in einen Cloud-Service könnten zum Beispiel AWS Lambda oder ein eigenes React Frontend sein. Außerdem kann die Umgebung mit TensorFlow verwendet werden, um weitere Algorithmen z.B. mit Machine Learning anzuwenden. Um erste Schritte in der Bildverarbeitung zu machen, bietet skimage allerdings noch genügend Filter und Optionen.

Haben Sie Fragen oder Anmerkungen? Kontaktieren Sie uns gerne.

Related Posts