Embedded Vision Baukasten

Die Evolution der klassischen Machine Vision zur Embedded Vision entwickelt sich rasant weiter. Die kompakten Systeme, bei denen der Kostenfaktor eine wesentliche Rolle spielt, verbrauchen weniger Energie bei derzeit steigender Leistungsfähigkeit. Dennoch kann die Entwicklung eines Embedded Vision Geräts sehr zeit- und kostenintensiv sein. Die Einschränkungen dieser hochspezialisierten Geräte bei Schnittstellen, Performance, Speicherplatz, Anzeige- und Eingabemöglichkeiten erschweren das Hardware-Handling und die Softwareentwicklung im Vergleich zu einer Desktop Workstation mit Standardkomponenten doch sehr. Und gerade bei Eigenentwicklungen (Hardware-Plattform, Firmware und Software) verliert man u.U. sehr viel Zeit bis erste Ergebnisse vorliegen.

Doch gerade für die Vorentwicklungsphase gibt es mittlerweile eine Reihe geeigneter Embedded Standard-Komponenten, die erste Tests out-of-the-box ermöglichen. In Kombination mit geeigneten Softwarelösungen lassen sich damit sehr schnell erste Ergebnisse der späteren Vision Anwendung ableiten.

Unser TechTipp zeigt in wenigen einfachen Schritten, wie Sie mit einer uEye Kamera und einem Raspberry Pi 3 eine einfache Embedded Vision Anwendung realisieren können.

Schritt 1: Hardware vorbereiten

Installieren Sie einen Raspberry Pi 3 mit dem Raspbian OS und aktualisieren das System auf den neusten Softwarestand.

pi@raspberrypi:~ $ sudo apt-get update && apt-get upgrade

Anleitungen zur Einrichtung eines Raspberry Pi finden Sie im Internet. Theoretisch können Sie jedes andere ARMv7 kompatible Embedded Board (z.B. Odroid XU4) für die Demo verwenden. Der Raspberry Pi3 besitzt aber mit seiner Quadcore CPU genügend Leistung für einfache Bildverarbeitungstests und das Raspbian OS bringt schon viele, der benötigte Komponenten vorinstalliert mit. Alles weiter lässt sich bequem über die Paketquellen nachinstallieren.

Schließen Sie eine USB uEye Kamera an einem USB Port des Raspberry Pi an.

pi@raspberrypi:~ $ sudo pip install pyueye

Damit wird das uEye Python Interface für die Verwendung mit Python 2.7 im System installiert. Notwendige Modul-Abhängigkeiten werden durch PIP direkt mit installiert. Um die korrekte Installation zu prüfen, starten Sie den Python-Interpreter und importieren das uEye Modul.

pi@raspberrypi:~ $ python
Python 2.7.9 (default, Sep 17 2016, 20:26:04)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyueye import ueye
>>>

Wenn keine Fehlermeldung angezeigt wird, war die Installation erfolgreich.

Schritt 3: OpenCV installieren

Die OpenCV Entwicklungsbibliothekn lassen sich sehr einfach aus den Raspbian Paketquellen installieren. Es handelt sich dabei zwar um eine ältere Version (2.4.9.1), die aber für unsere Demo vollkommen ausreicht. Die Python-Anbindung für die OpenCV Bibliotheken finden Sie für Python 2.7 ebenfalls in den Paketquellen. Für die Verwendung mit Python 3 müssen Sie diese aus den Code-Quellen für die Embedded Plattform selbst kompilieren. Einfache Anleitungen dafür finden Sie aber auch im Netz.

pi@raspberrypi:~ $ sudo apt-get install libopencv-dev python-opencv

Auch diese Installation können Sie im Python-Interpreter mit dem Import des OpenCV Moduls „cv2“ prüfen.

Schritt 4: PyuEye Beispiel-Anwendung downloaden und testen

Als Ausgangspunkt für Ihre eigenen Bildverarbeitungsanwendungen mit uEye und dem Python Interface laden Sie sich das Sourcecode-Beispiel, das auf der TechTipp-Webseite verlinkt ist und entpacken es in einem beliebigen Verzeichnis auf Ihrem Raspberry Pi.

Das Sourcecode-Beispiel ist komplett in Python erstellt. Daher müssen Sie es nicht für die Systemarchitektur (ARMv7 A) des Raspberry Pi cross-kompilieren. Durch den Python Interpreter können Sie es direkt ausführen. Damit ist es plattformunabhängig. Das heißt, Sie können dieses Sourcecode-Beispiel auch auf einem Windows oder Linux Desktop System ausführen, sofern die benötigten Voraussetzungen (uEye Treiber, PyuEye Interface, Python 2.7) auf diesen Systemen installiert sind. 

Das PyuEye Sourcecode Beispiel ist in vier Python-Dateien aufgeteilt, die Klassen und Funktionalitäten zu unterschiedlichen Teilen des Beispielprogramms bereitstellen:

1) pyueye_example_camera.py

Stellt die Klasse „Camera“ mit häufig benötigten Funktionen zum Umgang mit der Kamera zur Verfügung.

2) pyueye_example_gui.py

Mit den Klassen “PyuEyeQtView” und “PyuEyeQtApp“ können Sie ein einfaches Qt Widget-Programm und damit den Rahmen für eine GUI-Anwendung erstellen. Dieses Modul basiert auf Qt4 und nutzt dementsprechend die Python Qt4 Bindings (PyQt4). Qt4 ist auf in Raspbian Jessie bereits integriert. Die Python Bindungs können Sie über die Paketquellen installieren:

pi@raspberrypi:~ $ sudo apt-get install python-qt4 python-qt4-doc

3) pyueye_example_utils.py

Dieses Modul bringt wichtige Convenience-Funktionen und Klassen mit, die im Umgang mit einer Kamera-Anwendung sehr hilfreich sind. Von Exception-Handling über den Umgang mit Kameradaten und Bildspeichern ist einiges dabei.

4) pyueye_example_main.py

Das Main-Modul legt ein einfaches Qt-Anwendungsgerüst an, öffnet und initialisiert die angeschlossene Kamera und stellt Ihnen bereits eine Image-Processing Callback-Funktion zur Verfügung, in der eine einfache Bildverarbeitung mit OpenCV realisiert ist. Wenn Sie die Demo ausführen, wird Ihnen das Livebild der angeschlossenen Kamera und Ergebnisse der Bildverarbeitung angezeigt.

pi@raspberrypi:~/example $ python pyueye_example_main.py

OpenCV Bildverarbeitung

Unsere einfache Bildverarbeitung mit OpenCV sucht nach Kreisen im Bild und markiert sie.

Dafür genügen wenige Code-Zeilen im Main-Modul, da OpenCV für diese Aufgabe eine vollständige Implementierung mit der Funktion cv2.HoughCircles beinhaltet, die wir hierfür nutzen. Um mit OpenCV arbeiten zu können, wurde „cv2“ und „numpy“ importiert:

from pyueye_example_camera import Camera
from pyueye_example_utils import FrameThread
from pyueye_example_gui import PyuEyeQtApp, PyuEyeQtView
from PyQt4 import QtGui

from pyueye import ueye

import cv2
import numpy as np
def process_image(self, image_data):

    # reshape the image data as 1dimensional array
    image = image_data.as_1d_image()    
    # make a gray image
    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    #image = cv2.medianBlur(image,5)
    # find circles in the image
    circles = cv2.HoughCircles(image, cv2.cv.CV_HOUGH_GRADIENT, 1.2, 100)
    # make a color image again to mark the circles in green
    image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
    
    if circles is not None:
	   # convert the (x, y) coordinates and radius of the circles to integers
	   circles = np.round(circles[0, :]).astype("int") 
	   # loop over the (x, y) coordinates and radius of the circles
	   for (x, y, r) in circles:
		  # draw the circle in the output image, then draw a rectangle
		  # corresponding to the center of the circle
		  cv2.circle(image, (x, y), r, (0, 255, 0), 6)
    
    # show the image with Qt
    return QtGui.QImage(image.data,
                        image_data.mem_info.width,
                        image_data.mem_info.height,
                        QtGui.QImage.Format_RGB888)

Python-typisch können Sie die modifizierte Applikation direkt ausführen. Ohne viel Aufwand können Sie Anwendung auch weiter modifizieren und andere Verarbeitungsaufgaben mit OpenCV testen.