adesso Blog

Prototyping ist essenziell für die Entwicklung von guten User-Interfaces. Oftmals ist aber der Schritt von einer Wireframe-Skizze zu einem UI-Prototyp sehr zeitaufwändig. In diesem Blog-Post möchte ich einen Ansatz vorstellen, mit dem man diesen Schritt mithilfe von Computer Vision und Machine Learning verkürzen kann.

Wofür überhaupt der Aufwand?

Die Entwicklung von guten User-Interfaces ist keine einfache Sache. Jeder, der schon einmal probiert hat, ein Element mithilfe von CSS zu zentrieren, weiß, wovon ich spreche. Es gibt sogar eine Website die nur für diesen Zweck existiert: howtocenterincss.com.

Ohne gründliche Planung verschwendet man bei der Erstellung von User-Interfaces also sehr viel Zeit. Daher ist es oft sinnvoll, sich vorher zu überlegen, wie das User-Interface aussehen soll, bevor man mit der Arbeit anfängt. Das hilft dabei, Probleme früh zu erkennen und auszubessern. Oft ist es aber so, dass viele Probleme erst ersichtlich werden, wenn man seine skizzierte Idee in tatsächlichen HTML- und CSS-Code umsetzt.

Das Ziel

Es wäre also präferabel, einen Click-Dummy seines User-Interfaces zu erstellen, um diese Probleme zu erkennen, bevor man noch mehr Arbeit hineinsteckt. In dem folgenden Bild sieht man eine skizzierte Idee eines User-Interfaces und einen Click-Dummy, der der Skizze entspricht.

Handgezeichnete Skizze und entsprechender fertiger UI-Prototyp

Handgezeichnete Skizze und entsprechender fertiger UI-Prototyp

Auf der linken Seite sieht man ein Foto einer handgezeichneten Wireframe-Skizze. Oben in der Skizze wurde eine Navigation-Bar gezeichnet, in der Mitte ein Grid von Bildern mit Paragraphen daneben und unten ein Pagination-Element. Auf der rechten Seite sieht man eine Website, die in etwa der Skizze entspricht. Diese Website wurde mithilfe von Komponenten des Bootstrap CSS-Frameworks erstellt.

UI-Prototypen mithilfe von fertigen Bootstrap-Komponenten zu erstellen verkürzt den Arbeitsaufwand zwar signifikant, aber wäre es nicht noch besser, den UI-Prototyp automatisch generieren zu lassen, anstatt diese Komponenten von Hand zusammenzubauen?

Das ist die Idee dieses Ansatzes: Oft verwendete und typische UI-Elemente aus einer handgezeichneten Skizze erkennen, diese automatisch als Bootstrap-Komponenten zusammenbauen und daraus eine HTML-Datei generieren.

Verwendete Technologien

Um diesen Schritt zu automatisieren wurden hauptsächlich diese drei Bibliotheken verwendet:

  1. OpenCV: Eine Library für Computer Vision Techniken, hauptsächlich gemacht für die digitale Bildverarbeitung und die Erkennung von Objekten in Bildern.
  2. fastai: Eine Library, die Machine Learning und vor allem Deep Learning einfach zugänglich machen soll.
  3. yattag: Eine Library zur Generierung von HTML-Code.

Aufbau der Pipeline

Pipeline

Aufbau der Programm-Pipeline visualisiert

Die Pipeline ist so aufgebaut, dass ein Foto einer Wireframe-Skizze eingeben wird. Aus diesem Foto werden die gezeichneten UI-Elemente mittels Computer Vision Techniken ausgeschnitten. Dafür werden verschiedene Verfahren und Funktion von OpenCV verwendet, um die gezeichneten Linien von dem Hintergrund zu separieren.

Die ausgeschnittenen UI-Elemente werden dann durch ein Convolutional Neural Network (CNN) klassifiziert. CNNs sind spezielle neuronale Netzwerke aus dem Machine-Learning-Bereich, welche besonders gut bei der Erkennung von Objekten in einem Bild sind. Sie basieren auf bestimmten Prinzipien und Erkenntnissen über den visuellen Kortex von Lebewesen. fastai bietet einfache Lösungen, um ein solches CNN zu trainieren und zu verwenden.

Aus den klassifizierten Elementen können mithilfe von yattag HTML-Elemente generiert werden, die entsprechend den UI-Elementen in der Skizze positioniert werden.

Extrahierung der UI-Elemente aus dem Foto

Der erste Schritt ist, die gezeichneten UI-Elemente aus dem Foto der Skizze zu extrahieren. Dafür müssen diese zuerst lokalisiert und anschließend ausgeschnitten werden.

Segmentierung des Bildes in Vorder- und Hintergrund

Mit Hilfe eines Ridge-Detection-Filter gefolgt von Otsu-Thresholding kann das Bild einer Wireframe-Skizze einfach in Vorder- und Hintergrund segmentiert werden. Das Bild wird dadurch in schwarz und weiß binarisiert. Das heißt, es existieren keine Graustufen mehr: Pixel können nur noch komplett schwarz oder komplett weiß sein. Dieser Schritt ist für den folgenden Schritt notwendig.

Segmentation

Segmentierung durch Ridge-Detection-Filter mit anschließendem Otsu-Thresholding

Lokalisierung der UI-Elemente

Die gezeichneten UI-Elemente können aus beliebig vielen separaten Strichen bestehen, daher ist die Lokalisierung dieser nicht trivial. Um den Prozess stark zu vereinfachen, kann ein UI-Element mit einem Rechteck in der Zeichnung umrandet werden. Dadurch ist immer eindeutig, welche Striche zu einem UI-Element gehören. Dieser Prozess ist dadurch auch komplett unabhängig davon, wie die UI-Elemente selbst aussehen. Das heißt, dass für diesen Prozess kein neuronales Netzwerk trainiert werden muss.

Diese Umrandungen können durch OpenCVs Konturenfindung ermittelt werden. Mit dem Parameter RETR_EXTERNAL werden nur die Konturen auf oberster Hierarchieebene in einem segmentierten Bild gefunden. Diese Konturen entsprechen nur den äußeren gezeichneten Umrandungen: Die UI-Elemente innerhalb der Umrandungen werden ignoriert.

Um sicherzustellen, dass nur die Umrandungen ermittelt werden, müssen Lücken in diesen Umrandungen geschlossen werden. Dafür kann eine morphologische Transformation (in diesem Fall Dilatation) auf das Bild angewandt werden.

Konturen

Die gefundenen Konturen sind in Grün markiert. In der oberen Reihe ist eine Lücke in der Umrandung, es werden fälschlicherweise Konturen innerhalb der Umrandung gefunden. In der unteren Reihe wurde die Dilatation angewandt, es wurde nur die gezeichnete Umrandung als Kontur gefunden.

Ausschneiden der UI-Elemente

Um die lokalisierten UI-Elemente zu klassifizieren, müssen diese aus dem Eingabebild ausgeschnitten werden. Da die Konturen kontinuierliche Kurven sind, müssen vorerst Bounding Boxes ermittelt werden, da man aus einem Pixelbild nur Rechtecke ausschneiden kann. Da Rastergrafiken keine Rotation aufweisen können, müssten eigentlich Axis Aligned Bounding Boxes (AABBs) berechnet werden.

Bounding Boxes

Aus den Konturen ermittelte Bounding Boxes: AABB (links), rotierte BB (rechts)

Wie man in der Abbildung links jedoch erkennen kann, ist eine AABB nicht immer optimal. Stattdessen kann man eine rotierte Bounding Box ermitteln, wie in der Abbildung rechts zu sehen. Von dieser kann der Winkel der Rotation berechnet und anschließend der Bildausschnitt in entgegengesetzter Richtung um diesen Winkel rotiert werden. Dadurch wird die rotierte BB wieder zu einer AABB, die man aus dem Bild ausschneiden kann.

Entfernung der Umrandung

Die gezeichneten Rechtecke um jedes UI-Element dienen nur der Lokalisierung der einzelnen Elemente. Nach der Lokalisierung werden die gezeichneten Umrandungen nicht mehr benötigt.

Umrandung Entfernung

Entfernung der Umrandung

Um diese Umrandungen zu entfernen, können die zuvor ermittelten Konturen mit Weiß gefüllt werden. Schrumpft man anschließend diese gefüllten Flächen durch Erosion, kann man diese Fläche als Maske auf das ursprüngliche Bild anwenden. Dadurch wird die gezeichnete Umrandung effektiv und ohne viel Aufwand aus dem Bild entfernt.

Klassifizieren der ausgeschnittenen UI-Elemente

Um den entsprechenden HTML-Code zu generieren, müssen die extrahierten Bildausschnitte klassifiziert werden. Dafür kann ein Convolutional Neural Network (CNN) trainiert werden.

Training Data

Beispiele für gesammelte Skizzen

Für das Training wurden individuell gezeichnete Skizzen abfotografiert, in denen 10 verschiedenen UI-Elemente (wie zum Beispiel Labels, Buttons, Images etc.) gezeichnet worden sind. Beispiele für solche Skizzen sind in der obigen Abbildung zu sehen.

Extracted

Beispiele für extrahierte Bildausschnitte aus den Skizzen

Aus den gesammelten Fotos wurden dann mit der zuvor beschriebenen Methode die einzelnen UI-Elemente extrahiert. Diese Bildausschnitte dienten als Trainingsdaten für das CNN.

Für das CNN wurde fastai verwendet. Dieses Library erlaubt es mit nur einigen Zeilen Code ein neuronales Netzwerk zu trainieren. Hier ist ein minimal working example, welches ein CNN am MNIST Datensatz (Sammlung von handgezeichneten Ziffern des Modified National Institute of Standards and Technology) trainiert:

from fastai.vision import *
path = untar_data(MNIST_PATH)
data = image_data_from_folder(path)
learn = cnn_learner(data, models.resnet18, metrics=accuracy)
learn.fit(1)

Wenn ihr mehr über fastai erfahren wollt, findet ihr hier den Einsteiger-Kurs und die Dokumentation.

GUI

Die Klassifizierung durch das trainierte Modell in einer GUI visualisiert

Das trainierte Modell kann nun die lokalisierten und ausgeschnittenen UI-Elemente klassifizieren. In der Abbildung ist das Ergebnis dieser zwei Schritte in einer GUI visualisiert.

Generierung des Prototyps

Anhand der Klassifizierung können dann entsprechende HTML-Tags generiert werden, welche anhand der Position und Größe der Bounding Box mittels CSS positioniert werden können. Die HTML-Tags können dann mit Platzhalter-Inhalten wie Lorem Ipsum Text oder zufälligen Bildern von unsplash.com versehen werden. Dabei kann beispielsweise die Breite und Höhe der ermittelten Bounding Box als Breite und Höhe des Bildes verwendet werden: https://source.unsplash.com/random/500x600.

Die Resultate der HTML-Generierung repräsentieren eine Annäherung and einen echten Prototyp, sie sind jedoch bei weitem nicht perfekt.

Fazit

Die hier präsentierte Methode konnte auf einem ca. fünf Jahre alten Laptop 99% Genauigkeit erreichen, bei einer Trainingsdauer von unter einer Stunde. Der Nachteil dieser Methode ist jedoch, dass die benötigten Umrandungen um jedes UI-Element nicht intuitiv für Wireframe-Skizzen sind.

Wer jedoch die nötigen Ressourcen hat, um ein großes Set an Trainingsdaten zu sammeln, könnte die Schritte der Extraktion mittels OpenCV umgehen und ein Object-Detection-Netzwerk trainieren. Dies benötigt jedoch nicht nur weitaus mehr Trainingsdaten, die Daten benötigen zusätzlich zu den Labels auch noch Positionsinformationen für jedes UI-Element im Bild. Darüber hinaus müssten die Eingabebilder in das Object-Detection-Netzwerk größer sein, damit genügend Details erhalten bleiben. Dadurch ist nicht nur die Beschaffung der Trainingsdaten, sondern auch der Trainingsaufwand für ein solches Netzwerk weitaus größer.

Weitere Ressourcen

Den kompletten Source Code für das Projekt findet ihr hier.

Wer sich noch etwas genauer mit diesem Thema beschäftigen möchte, kann sich diese Blog-Posts und wissenschaftlichen Artikel durchlesen:

Autor Vincent Mathis

Vincent Mathis ist Werkstudent in der Software-Entwicklung. Er arbeitet in Frankfurt im Insurance Bereich.

  • adesso.de
  • News
  • Blog
  • UI-Prototyping - Wie man aus Wireframe Skizzen Prototypen generieren kann

Diese Seite speichern. Diese Seite entfernen.

C71.898,22.5,97.219,25.136,96.279,52.11z"/>