Schnecken ausschneiden leicht gemacht (Teil 1)

Jens Dobberthin

Von Jens Dobberthin
16.07.2018 | 20 Minuten Lesezeit

Beim letzten Coding da Vinci-Hackathon hat das SnailSnap-Team gezeigt wie ihr euch zur Schnecke macht. Im ersten Teil unserer Serie von Blogeinträgen zum Thema Programmieren zeigen wir euch, wie ihr die Schnecken automatisiert ausschneidet und dann kreativ weiterverwenden könnt.

Die Sammlung „Mollusca“ des Museums für Naturkunde Berlin ist ein richtiger Hingucker. Mit rund 5 Millionen Sammlungsstücken ist sie übrigens eine der umfangreichsten Kollektionen des Museums. Die schiere Fülle der Sammlung lässt sich aber nur erahnen, wenn wir etwas programmieren. Am Ende dieses Blog-Eintrags habt ihr alle Materialien für ein Video zusammen, welches euch die Schönheit der Sammlung vorführt.

Hier könnt Ihr schon einmal reinschauen:


Damit ihr die folgende Anleitung nachvollziehen könnt, benötigt ihr ein paar Linux-Kenntnisse. Falls ihr an einem Punkt nicht weiterkommt, fragt jemanden, der euch helfen kann.

Den Quellcode für das Werkzeug zum Ausschneiden der Schnecken findet ihr auf GitHub. Für diesen Blog nutzen wir eine angepasste Version, damit die Arbeit ein wenig leichter wird. Öffnet einen Terminal und gebt folgendes ein:

$ git clone https://github.com/jdobber/mollex
$ cd mollex
$ meson --buildtype=debug build
$ ninja -C build

Jetzt solltet ihr das Programm mollex im Verzeichnis build finden. Damit ihr es benutzen könnt, müssen wir jetzt die Bilddateien (Scans) mit den Schnecken herunterladen. Ihr könnt euch die Scans in einer Gallerie im Web anschauen. Glücklicherweise müsst ihr aber nicht alle einzeln herunterladen, denn dafür gibt es ein kleines Shell-Skript, welches die Arbeit übernimmt. Bevor ihr das Script startet, seid euch bewusst, dass ihr jetzt ein paar Gigabytes herunterladet (genauer gesagt 16 GB). Also sorgt für genügend Platz auf eurer Festplatte, bevor ihr folgendes ins Terminal eingebt:

$ ./crawl.sh

Als nächstes benötigt ihr noch die Metadaten zu den Scans. Die Metadaten geben z.B. an, welche Schnecke sich in welcher Bilddatei befindet. Die Metadaten holt ihr euch wie folgt:

$ wget http://gbif.naturkundemuseum-berlin.de/CDV2018/Mollusken/Metadaten/species_list.csv

Das mollex-Programm erwartet die Bilder im Verzeichnis images und legt die ausgeschnittenen Schnecken im Verzeichnis out ab. Also bereiten wir dafür alles vor:

$ ln -s data/gbif.naturkundemuseum-berlin.de/CDV2018/Mollusken/Arten images
$ mkdir out

Nun aber seid ihr bereit und könnt mit dem Ausschneiden der Schnecken beginnen:

$ ./src/mollex

Das kann eine Weile dauern, aber am Ende liegen die Schnecken brav ausgeschnitten im Verzeichnis out. Falls ihr nicht so lange warten wollt, so könnt ihr jederzeit abbrechen. Die folgenden Ausführungen könnt ihr auch mit einer kleinen Teilmenge der Schnecken durchführen.

Doch wie kommen wir zu unserem kleinem Video? Damit wir ein Gefühl dafür bekommen, wieviele es eigentlich sind, möchten wir sie ganz schnell hintereinander anzeigen. Auch soll es noch einen kleinen Zähler und einen Fortschrittsbalken als visuelles Feedback geben. Wir wollen schließlich wissen, wieviele Schnecken noch auf uns warten. Und für die Biologie-Fans unter uns, zeigen wir natürlich auch noch den wissenschaftlichen Namen an.

Für die Umsetzung nutzen wir Processing, eine freie Software, die gerne von Künstlern zum Programmieren eingesetzt wird.

Unser mollex-Programm hat die Datei meta_file.csv ins Verzeichnis out geschrieben. Diese Datei müssen wir einlesen, denn dann können wir die einzelnen Bilddateien den richtigen wissenschaftlichen Namen zuordnen. Vorher müssen wir aber noch alle ; in , umwandeln, damit Processing die Datei verarbeiten kann. Das geht so:

sed -i 's/;/,/g' out/meta_file.csv

Nun sind wir bereit für unseren Sketch in Processing. Startet Processing und kopiert folgenden Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
String path = "/home/jens/spielwiese/experimental/mollex/out/";
String metaFile = path + "meta_file.csv";

PImage img= null;
int counter = 0 ;
int width = 854;
int height = 480;
int x = width / 2;
int y = height / 2;

boolean rec = false;
boolean stopped = false;

Table table;
String imageName;
String sciName;
String[] strList;
String prefix = "http://coll.mfn-berlin.de/u/";

int maxCounts = 100;
int steps = 10;
int progressBarWidth = 0;

void setup() {

  table = loadTable(metaFile, "header");
  maxCounts = table.getRowCount() - 1;

  steps = width / maxCounts;

  println(table.getRowCount() + " total rows in table");
  size(854, 480);  
}  

void draw() {

  if (!stopped) {
    background(0);
    img = loadImage(path + table.getRow(counter).getString("Image"));

    imageMode(CENTER);
    image(img, x, y);    


    textSize(18);
    textAlign(CENTER, BOTTOM);
    text(table.getRow(counter).getString("Scientific Name"), x, height - 40);

    strList = split(table.getRow(counter).getString("Image"), "_");
    textSize(12);
    textAlign(CENTER, BOTTOM);
    text(prefix + strList[0] + "_" + strList[1] + "_" + strList[2], x, height - 20);


    textSize(12);
    textAlign(LEFT, TOP);
    text(table.getRow(counter).getString("Class") + " >> " +
      table.getRow(counter).getString("Family") + " >> " +
      table.getRow(counter).getString("Genus") + " >> " +
      table.getRow(counter).getString("Species"),
      20, 10);
    textAlign(RIGHT, TOP);
    text(maxCounts - counter, width - 40, 10);

    strokeWeight(4);
    fill(0, 154, 186);
    rect(0, height - 10, width - map(counter, 0, maxCounts, 0, width), height);

    fill(255);      

    if (rec) {
      saveFrame("output/mol_####.tif");
    }

    delay(500);

    counter += 1;
    if (counter > maxCounts)
    {
      counter = 0;
    }
  }
}

void keyPressed() {
  if (key == 'r' || key == 'R') {
    rec = !rec;
  }
  println(rec);
  if (key == 's' || key == 'S') {
    stopped = !stopped;
  }
}


In Zeile 1 müsst ihr noch den Pfad anpassen, so dass Processing eure ausgeschnittenen Schnecken finden kann. In Zeile 27 könnt ihr maxCounts auf 10 (oder einen anderen Wert) setzen, dann werden nur die ersten 10 Schnecken und nicht alle angezeigt.

Soweit alles klar? Dann könnt ihr auf den Play-Knopf drücken.

Mit der Taste s könnt ihr den Durchlauf stoppen bzw. fortsetzen. Mit r könnt ihr die einzelnen Bilder (Frames) mitschneiden und euch daraus ein Video erstellen. Die Frames landen im Verzeichnis out/frames.

Spielt ein wenig mit dem Code. Vielleicht habt ihr noch andere Ideen, was man mit Schnecken so alles machen kann. Dann schreibt uns. Wir sind gespannt.

Im nächsten Teil zeigen wir euch, wie ihr an die genauen Koordinaten der Schnecken in den Originalbildern kommt.


Creative Commons Lizenzvertrag
Dieser Blogeintrag ist lizenziert unter einer Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 4.0 International Lizenz.