Die auf aktuellen Computern speicherbare Datenmenge nimmt kontinuierlich zu, so ist beispielsweise die Forensik mit Mengen von Multimedia-Dateien konfrontiert, die sich von Hand nicht mehr bewältigen lassen. Wie dieser Artikel aber zeigt, lässt sich zumindest die Verarbeitung von Bilddateien mit wenigen Zeilen Python-Code automatisieren. Kurze Beispiele erklären die Erkennung von Hautpartien, Gesichtern und Text.
Python aufrüsten
Die Installation der erforderlichen Programmierbibliotheken und Programme erfolgt auf Debian-basierten Distributionen mittels Paketmanager:
aptitude install python-imagingpython-opencv tesseract-ocrtesseract-ocr-deu
Auf diesem Weg ist sichergestellt, dass das System die von den Python-Bindings geforderten Voraussetzungen erkennt und mit installiert. Aufgrund der verwendeten Bibliotheken kommt Python 2 für das Programm zum Einsatz (siehe Kasten "Versions-Wirrwarr").
Beim Paket »python-imaging«
handelt es sich um die Python Imaging Library (PIL, [1]), sie liest in der eingesetzten Version 1.1.17 eine Vielzahl von Bildformaten. Daneben bietet sie diverse Bildbearbeitungsoperationen sowie Zugriff auf die Farbwerte einzelner Pixel. Beides zusammen eignet sich gut, um die Hautanteile in einem Bild zu bestimmen.
Die Bibliothek »python-opencv«
(hier in der Version 2.1.0, [2]) ist eine ursprünglich von Intel veröffentlichte Bibliothek, die Algorithmen für maschinelles Sehen (Computer Vision) implementiert. Sie ist in C und C++ programmiert und steht unter der BSD-Lizenz.
Während für den Python-Interpreter in der Version 1 geschriebener Code auch auf Version 2 lauffähig war, ist dies beim Wechsel von Version 2 auf die im Dezember 2008 erschienene Version 3 nicht mehr ohne Weiteres möglich. Für einige der in diesem Artikel verwendeten Bibliotheken, zum Beispiel »python-openvc«
, stehen oft nur Distributionspakete für Python 2, genauer gesagt 2.6, zur Verfügung. Daher verwenden die gezeigten Codebeispiele Python-2-Syntax.
Um Texte in Bildern mit Hilfe von OCR (Optical Character Recognition) zu erkennen, verwendet dieser Artikel die Pakete »tesseract-ocr«
und »tesseract-ocr-deu«
in den Versionen 2.04 und 2.00. Dabei handelt es um das Kommandozeilen-Programm der ursprünglich von Hewlett-Packard entwickelten Software Tesseract. Mittlerweile verwaltet Google das Programm und entwickelt es weiter ([3], [4]). Der von Samuel Hofstaetter entwickelte Wrapper Python-Tesseract [5] wandelt zu verarbeitende Bilder in das einzige von Tesseract verstandene Format Tiff um, ruft das Programm auf und reicht dessen Ausgaben an den Python-Interpreter weiter.
Python-Tesseract liegt derzeit nicht als Debian-Paket vor. Zur Verwendung mit den Python-Skripten dieses Artikels genügt es, das auf der Projekthomepage verfügbare Skript »tesseract.py«
in deren Verzeichnis zu kopieren.
Hauptprogramm
Das Hauptprogramm »main.py«
ruft die einzelnen Unterfunktionen und damit die Erkennung der jeweils gesuchten Objekte auf. Zu Beginn importiert es die nötigen Funktionen, wie in Listing 1 zu sehen ist. Das Programm lässt sich dann wie in Zeile 11 beschrieben aufrufen. Je nach Aufruf kommt eine andere Unterfunktion zum Zuge (Zeilen 14 bis 22). Den eingegebenen Pfad nimmt in Zeile 24 die Funktion »os.walk()«
entgegen. Die »os«
-Bibliothek bietet viele Betriebssystemfunktionen, »walk«
durchsucht einen Verzeichnisbaum rekursiv und gibt ein Dreier-Tupel zurück. Aus diesem Tupel greift sich die folgende Zeile den Dateinamen heraus. Zeile 28 ruft die eigentliche Funktion auf.
01 #!/usr/bin/python
02 import os, sys
03
04 from faces import detectFaces
05 from skin import detectSkin
06 from ocr import extractText
07
08 def main():
09
10 if len(sys.argv) != 3:
11 print("Wrong number of arguments. Usage: python %s <faces|skin|text> <pPath>" % sys.argv[0])
12 sys.exit(-1)
13
14 if (sys.argv[1] == "faces"):
15 processFunc = detectFaces
16 elif (sys.argv[1] == "skin"):
17 processFunc = detectSkin
18 elif (sys.argv[1] == "text"):
19 processFunc = extractText
20 else:
21 print('Wrong parameter! Usage: python %s <faces|skin|text> <pPath>' % sys.argv[0])
22 sys.exit(-2)
23
24 for lRoot, lDirs, lFiles in os.walk(sys.argv[2]):
25 for lName in lFiles:
26 try:
27 pPath = lRoot + os.sep + lName
28 lResult = processFunc(pPath)
29 if lResult[0] == 0:
30 print("""Negative result for: %s
31 -------------------------------------------""" % pPath)
32 else:
33 print("""Positive result for: %s
34 -------------------------------------------""" % pPath)
35 except KeyboardInterrupt:
36 print("Cleaning up ...")
37 sys.exit(-1)
38 except IOError:
39 print("File \'"+ pPath + """\' is not supported or not a picture!
40 -------------------------------------------""")
41
42 if __name__ == "__main__":
43 main()
Ein Besonderheit von Python ist, dass eine Funktion mehrere Rückgabewerte besitzen kann. In diesem Fall ist das neben 0 oder 1(je nach Erfolg) zusätzlich der Pfad der Datei (Zeilen 29 bis 34). Die Catch-Blöcke fangen die verschiedenen möglichen Fehler ab: Es handelt sich entweder nicht um eine Bilddatei, die Datei wird nicht unterstützt oder das Programm wird mit [Strg]+[C] beendet. Die Zeilen 42 und 43 machen das Skript zu einem ausführbaren Programm.