Fotografische Erschließung
Für die fotografische Erschließung wird eine Sony A6000 verwendet. Zusätzlich wird ein Sony 50F18-Objektiv verwendet. Das Objektiv hat eine feste Brennweite von 50 mm und eine maximale Blende von F1,8.
Fotografie
Der Fotostand
Der Fotostand ist so aufgebaut, dass eine Pappe, entweder weiß oder schwarz, den Hintergrund bildet. Dabei ist die Pappe so gelegt, dass statt der Ecke am Übergang von Auflagefläche des Tischs zur Wand eine Falte gelegt ist. Durch diese Rundung ist die Ecke nicht auf den Fotos sichtbar. Der Hintergrund wird an die Objektfarbe angepasst: helle oder weiße Objekte werden vor der schwarzen Pappe und farbige Objekte vor der weißen Pappe fotografiert.
Die Beleuchtung erfolgt mit einem Scheinwerfer (Samtian 600 LED CRI 5600K) mit maximaler Leuchtkraft von 2200 Lumen. Das Objekt wird von der rechten Seite bestrahlt und auf der linken Seite steht eine weiße Pappe, um Licht gestreut zurückzuwerfen. Durch den Aufbau kommt es zu Lichtreflexen auf dem Objekt, die im Foto durch eine Überbelichtung sichtbar werden. Das Nutzen eines Polarisationsfilters verhindert diese Reflexe nicht, weshalb sie in Kauf genommen werden müssen. Von dem Zerstreuen der Lichtreflexe wurde abgesehen, weil scharfe Reflexe eine geringere Fläche verfälschen, als diffuse. Die verfälschten Flächen werden dadurch kompensiert, dass vom Objekt mehrere Aufnahmen gemacht werden.
Von jedem Objekt werden zehn Fotos angefertigt: eine mit Graukarte für den objektspezifischen Weißabgleich, acht vom Objekt in Frontalansicht in verschiedenen Winkeln und eine von der Standfläche des Objekts. Jede Frontal-Aufnahme ist um ca. 45° bezogen auf die vorherige Aufnahme gedreht. Dadurch wird jeder Punkt durchschnittlich viermal abgebildet und nur maximal einmal ist die Lichtreflexion im Punkt. Dieses Vorgehen ist ohnehin zur vollständigen Erfassung des Etiketts und des Fußes bei einem Objekt mit Holzfuß notwendig.
Die Drehung erfolgt mit einem von der Werkstatt des Betriebsbereichs der Fakultät für Chemie und Physik bereitgestellten Drehtellers. Dieser wird mit einem Schrittmotor betrieben und von einem Arduino nano gesteuert.
Die Kamera ist auf einem Stativ in einem sinnvollen Abstand zum Objekt aufgebaut und mit einem USB-Kabel an den Aufnahme-Laptop angeschlossen.
Der Drehteller
Um eine einheitliche Drehung der Objekte zu ermöglichen, wurde ein Drehteller gebaut. Die Steuerung erfolgt über ein Arduino Nano, das mit 3 Knöpfen, einer Schrittmotorsteuerung (MAKERFACTORY Schrittmotor-Treiber-Modul MF-6402411, ULN2003), mit einem Schrittmotor (28BYJ-48) und einem 16x2-LCD-Display verbunden ist.
Die 3 Knöpfe sind zum Auslösen der Vorwärts- (Drehung um +45°) und Rückwärts- (Drehung um -45°)bewegung sowie zum "Nullen" der aktuellen Position programmiert. Das Display zeigt dabei den aktuellen Winkel bezogen auf die Nullposition an. Der Schrittmotor benötigt wenige mA Strom, weshalb die Steuerung mit einer Powerbank betrieben wird.
Der Motor ist in einer Konstruktion des Betriebsbereichs der Fakultät für Chemie und Physik eingebaut. Er ist auf eine Kunststoff-Platte geschraubt, auf der einen Axialkugellager liegt. Oben auf dem Kugellager ist eine weitere Kunststoffplatte aufgelegt, die mit der Drehachse des Motors verbunden ist. Durch das Kugellager mit ca. 12 cm Durchmesser ist ein Kippeln der Objekte während der Drehung ausgeschlossen.
Auf dem Drehteller ist eine weiße (bzw. schwarze) Pappe mit einem doppelt so großen Durchmesser, wie der Drehteller geklebt. Dadurch ist das Kugellager und der eigentliche Drehteller auf den Fotos nicht sichtbar.
Die Programmierung des Arduinos nutzt die TinyStepper-Bibliothek. Für jeden Schritt des Motors wird eine Zeit von 15 ms gewartet, sodass die Drehung erfolgen kann, bevor der nächste Schritt folgt. Der Quelltext ist im Folgenden gegeben:
include
include
include
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
// Define Arduino Pin Outputs to to the ULN2003 Darlington Array to drive a 28BYJ-48 Stepper Motor
define IN1 11
define IN2 10
define IN3 9
define IN4 8
define HALFSTEPS 4096 // Number of half-steps for a full rotation
// Initialize the TinyStepper Class
TinyStepper stepper(HALFSTEPS, IN1, IN2, IN3, IN4);
const int nullPin = 4;
const int plusPin = 2;
const int minusPin = 3;
int Schritt = 0;
int i;
int Winkel[] = {0, 45, 90, 135, 180, 225, 270, 315};
void setup()
{
// initialize the pushbutton pin as an input:
pinMode(nullPin, INPUT);
pinMode(plusPin, INPUT);
pinMode(minusPin, INPUT);
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Position");
lcd.setCursor(0,1);
lcd.print("Winkel: ");
}
void loop()
{
if (digitalRead(nullPin) == HIGH) {
Schritt = 0;
stepper.Disable();
showWinkel();
while (digitalRead(nullPin) == HIGH) { // Warte, bis der Kopf losgelassen wurde
delay(50);
}
} else if (digitalRead(minusPin) == HIGH) {
Schritt -= 1;
stepper.Move(-45, 15);
if (Schritt < 0) {
Schritt = 7;
}
showWinkel();
while (digitalRead(minusPin) == HIGH) { // Warte, bis der Kopf losgelassen wurde
delay(50);
}
} else if (digitalRead(plusPin) == HIGH) {
Schritt += 1;
stepper.Move(45, 15);
if (Schritt > 7) {
Schritt = 0;
}
showWinkel();
while (digitalRead(plusPin) == HIGH) { // Warte, bis der Kopf losgelassen wurde
delay(50);
}
}
delay(100);
}
void showWinkel() {
lcd.setCursor(9,1);
lcd.print(" ");
lcd.setCursor(9,1);
lcd.print(Winkel[Schritt]);
lcd.print(" deg");
}
Die Kameraeinstellungen
Die Kamera wird als Tethering-Gerät von der Software Darktable angesteuert. Durch das Fehlen der Live-Ansicht im Tethering-Modus der Kamera müssen aber alle Einstellungen an der Kamera selbst durchgeführt werden. Die Aufnahme eines Fotos kann dann vom Laptop aus initialisiert werden.
Als Standard-Einstellungen wird ISO100 mit einer Blende F11 verwendet. Die Kamera verfügt über einen Zebra-Modus, bei dem alle über- bzw. unterbelichteten Bereiche mit einem sich bewegenden Schwarz-Weiß-Muster markiert werden. Die Belichtungszeit wird so gewählt, dass dieses Muster nicht innerhalb des zu fotografierenden Objekts auftritt (abgesehen von der Lichtreflexion). Das Objekt wird möglichst zentral im Bild, möglichst flächenfüllend aufgestellt. Der Fokus wird am Objektiv eingestellt.
Die Fotos werden im RAW-Format direkt über den Tethering-Modus an den Laptop und Darktable übertragen. Im Darktable erfolgt anschließend die weitere Bearbeitung der Fotos.
Fotoaufnahmeablauf
-
Der Fotostand wird aufgebaut und das erste Objekt (zuvor mit einem weichen Tuch gereinigt) positioniert.
-
Vor das Objekt wird die Farbkalibrierungskarte (datacolor Spyder ColorCheckr 24) gestellt und fotografiert. Das erfolgt jeden Tag als erstes Foto.
-
Die Farbkalibrierungskarte wird auf die Weißabgleichseite gedreht und hinter das Objekt gestellt. Neben dem Objekt wird eine Karte mit einem Maßstab gelegt. Mit diesem Aufbau wird ein weiteres Foto aufgenommen.
-
Die Farbkalibrierungskarte und der Maßstab werden entfernt und das Objekt frontal fotografiert (ggf. Zebra und Fokus prüfen).
-
Das Objekt wird um 45°gedreht und das nächste Foto aufgenommen. Dieser Schritt wird siebenmal wiederholt.
-
Das Objekt wird hingelegt und die Standfläche fotografiert.
Anschließend wird das nächste (gereinigte) Objekt positioniert und mit Schritt 3 fortgefahren.
Fotonachbearbeitung
Die Bildbearbeitung und der Export erfolgen im Programm Darktable mit der Version 3.8 oder höher. Es dürfen nur geradzahlige Versionen verwendet werden (ungeradzahlige Versionen sind Entwicklungsversionen!).
Begründung der Softwarewahl
Bedauerlicherweise gibt es immer noch einige Wissenschaftler, die Software nach dem Motto "Was nichts kostet, ist nichts wert" auswählen. Mit diesem Motto ist Open-Source-Software ausgeschlossen. Diese Ansicht ist heute überholt, weshalb hier eine Begründung für die Entscheidung, Darktable als Open-Source-Software für das Projekt zu verwenden, gegeben werden soll.
Open-Source-Software wird in der Regel von Freiwilligen in ihrer Freizeit programmiert. Mit der Software wird kein Geld verdient (mit dem Support hingegen schon), sie steht aber jedem zur Nutzung und Veränderung frei zur Verfügung.
Open-Source-Software ist am Interesse des freiwilligen Programmierers orientiert. Die Programmierung erfolgt zwanglos, daher kann es sein, dass Open-Source-Software weniger Funktionen als kommerzielle Produkte bietet. Eine Vielzahl von Open-Source-Software bietet heute aber deutlich mehr Funktionen als kommerzielle Äquivalente (unter anderem Python vs. Matlab). Die Programmierer arbeiten freiwillig und haben daher eine höhere intrinsische Motivation am Projekt, als es oftmals in Firmen der Fall ist. Allerdings ist die Benutzerfreundlichkeit oft gegenüber kommerzieller Software etwas geringer (es gibt auch Gegenbeispiele: z. B. KDE Plasma vs. Windows). Viele Open-Source-Softwareprojekte bieten einen umfassenden Einblick in die Vorgänge des Programms, was sie teilweise unübersichtlich wirken lässt.
Kommerzielle Software ist hingegen am Benutzer orientiert und versucht Arbeitsabläufe angenehm zu gestalten und weniger wichtige Einstellungen, um die sich "der Nutzer nicht kümmern braucht" zu "verstecken".
Im Sinne des wissenschaftlichen Arbeitens sollten möglichst alle Schritte offengelegt und nachvollziehbar dokumentiert werden. Das ist mit Open-Source-Software wegen des größeren Einblicks in die Programme einfacher. Die etwas geringer Benutzerfreundlichkeit wird damit in Kauf genommen. Der wichtigste Punkt, ob alle benötigten Funktionen der kommerziellen Software auch in der Open-Source-Software vorhanden sind, muss jedoch zuvor geprüft werden. Darktable unterstützt alle Funktionen, die im Projekt benötigt werden.
Bildbearbeitung und -kontrolle
Die Bildbearbeitung erfolgt in Darktable Version 3.8 oder höher.
Einstellungen in Darktable
-
szenenbezogene Bearbeitung
-
benutze LittleCMS 2
-
chromatische Adaption: modern
-
in der Dunkelkammer -> Softproof-Profil (unter dem Bild rechts) -> alles auf Adobe RGB (kompatibel) setzen
Bearbeitungsablauf
-
Farbkalibrierungs-Foto:
-
Eingabefarbprofil -> Eingabeprofil und Arbeitsprofil auf "lineares ProFoto RGB" setzen, Gamut beschneiden aus:
Dieser Farbraum ist sehr groß und es werden weniger Farben bei der Bearbeitung abgeschnitten.
-
Objektivkorrektur -> einschalten: Objektivdaten wurden von der Kamera mitgeliefert.
-
Ausgabefarbprofil -> Ausgabevorsatz: Wahrnehmung; Exportprofil: Adobe RGB (kompatibel)
-
Farbkalibrierung -> Weißabgleich mit Pipette (benötigt grauen Hintergrund, muss nicht das Mittelgrau sein), Anpassung sollte auf CAT16 stehen!
-
Farbkalibrierung -> negativen RGB-Anteil abschneiden -> ausgeschlossen
-
Farbkalibrierung -> Kalibrierung mit Color Checker -> "Datacolor SpyderCheckr24 post-2018" wählen -> Farben einpassen -> Profil berechnen lassen und annehmen
-
Belichtung -> von Farbkalibrierung vorgeschlagene Werte eingeben.
-
Anzeige von Farb-Über- und -Unterschreitung einschalten und im Belichtungsmodul so lange korrigieren, bis in der Farbtafel keine Fehler mehr auftauchen.
-
Farbkalibrierung -> "Ergebnis Delta E prüfen" -> sollte unter 4,3 im Durchschnitt liegen und "gut" oder "akzeptabel" anzeigen, sonst weitere Anpassungen des Profils und der Belichtung durchführen, sofern eine Verbesserung erreicht wird.
-
Vorlaufstapel zusammenfassen
-
im Leuchttisch: aus Farbkalibrierungsfoto alle Anpassungen (s. o.) selektiv kopieren und bei allen Fotos anwenden
-
im Weißabgleich-Objektfoto: Farbkalibrierung -> Pipette auf Mittelgrau setzen -> Verlaufsstapel zusammenfassen
-
im Leuchttisch: Weißabgleich selektiv kopieren und auf alle Fotos des Objekts anwenden.
-
Kontrolle aller Bilder, ob eine Farb-Über- oder Unterschreitung im Objekt vorkommt, ggf. vorsichtig korrigieren
-
mit Schritt im 3 (Weißabgleich-Objekt-Foto) mit nächstem Objekt weitermachen
Export der Bilder
Die Bilder werden als 16-bit Tif im Adobe RGB (kompatibel)-Farbraum exportiert (DFG-Standard, Masterbild). Für die Verwendung in der Anzeigesoftware werden alle Bilder zusätzlich als JPG mit dem Adobe RGB (kompatibel) Farbraum und dem sRGB-Farbraum exportiert.
Nachbearbeitung der Metadaten der Bilder und Erstellung von Thumbnails
Die Anzeigesoftware ist webbasiert. Es werden noch Thumbnails (300x300 Pixel Maximalgröße) und Bilder in HD-Aufösung (1080p) erzeugt, um die Datenübertragung und damit die Ladezeit der Anzeige gering zu halten.
Die Exif- und XMP-Metadaten der Bilder werden mit einem Python-Skript vervollständigt. Dazu kommt das Modul pyexiv2 zum Einsatz. Es werden die Daten des Dublin-Core eingefügt (unter anderem der Titel des Objekts) und die Fotografen sowie die Bergakademie namentlich als Urheber genannt. Schließlich wird die Lizenz in die Metadaten geschrieben.
Außerdem werden den Bildern ein Wasserzeichen mit dem Siegen der TU Bergakademie Freiberg in der rechten oberen Ecke, wo bei keinem Bild ein Objekt verdeckt wird, eingefügt. Schließlich werden Thumbnails mit maximal 300x300 Pixel und in HD-Auflösung durch das Skript erstellt. Die Metadaten der Bilder werden auf die Thumbnails übertragen.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 2 11:08:16 2024
@author: marcus
"""
import pyexiv2
import mimetypes
import datetime
import os
from PIL import Image
import re
import sqlite3
import json
src = "/run/media/marcus/Extreme SSD/fullsize/"
thumbnailDir = "/run/media/marcus/Extreme SSD/thumbnails"
imageNumber = re.compile(r"TUBAF_CW_(\d+)_([\w\d]+)\.\w+")
connection = sqlite3.connect("Winklersammlung.sqlite3")
connection.row_factory = sqlite3.Row
cursor = connection.cursor()
watermark = Image.open("TUBAF.png").convert('RGBA')
watermark.thumbnail((750,750))
try:
pyexiv2.xmp.register_namespace("http://creativecommons.org/ns/", 'cc')
except:
pass
def interpretField(data):
if type(data) == type(1):
return data
if type(data) == type("Ich bin ein String!"):
ret = ""
try:
ret = json.loads(data.replace("'", '"'))
return ret
except:
return data
return None
ls = os.listdir(src + "/sRGB")
sRGBs = [ x for x in ls if os.path.isfile(src + "/sRGB/" + x) and x.endswith(".jpg")]
sRGBs.sort()
for sRGB in sRGBs:
print("Processing ", sRGB)
# find Number
m = imageNumber.match(sRGB)
title = ""
number = sRGB[:-4]
cursor.execute("SELECT ResourceID, resourceType, resourceDescription FROM Resources WHERE resourceLink LIKE '%"+sRGB[:-4]+".tif'")
objResource = cursor.fetchone()
res = "00"
if objResource:
res = str(interpretField(objResource['ResourceID']))
if not m:
print("Cannot find ID!")
if objResource:
title = interpretField(objResource['resourceType'])[1]
description = interpretField(objResource['resourceDescription'])
else:
number = int(m.group(1))
zusatz = str(m.group(2))
cursor.execute("SELECT objectTitle, description FROM Objects WHERE objectID=" + str(number))
objObject = cursor.fetchone()
title = objObject['objectTitle'] + " -- "
try:
int(zusatz)
title += "frontal - " + zusatz + "°"
except:
title += zusatz
description = interpretField(objObject['description'])
metadata_1 = pyexiv2.ImageMetadata(src + "/sRGB/" + sRGB)
metadata_1.read()
metadata_1.modified = True
image = Image.open(src + "/sRGB/" + sRGB).convert('RGBA')
image.alpha_composite(watermark, (3274, 0))
image = image.convert('RGB')
image.save(src + "/sRGB/" + sRGB)
tn300 = image.copy()
tn300.thumbnail((300,300))
tn300.save(thumbnailDir + "/300/" + sRGB)
metadata_2 = pyexiv2.metadata.ImageMetadata(thumbnailDir + "/300/" + sRGB)
metadata_2.read()
tnHD = image.copy()
tnHD.thumbnail((1920, 1080))
tnHD.save(thumbnailDir + "/HD/" + sRGB)
metadata_3 = pyexiv2.metadata.ImageMetadata(thumbnailDir + "/HD/" + sRGB)
metadata_3.read()
metadata_1['Xmp.cc.license'] = pyexiv2.XmpTag('Xmp.cc.license', 'https://creativecommons.org/publicdomain/zero/1.0/')
metadata_1['Xmp.cc.attributionName'] = pyexiv2.XmpTag('Xmp.cc.attributionName', 'TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger')
metadata_1['Xmp.dc.title'] = pyexiv2.XmpTag('Xmp.dc.title', title)
metadata_1['Xmp.dc.creator'] = pyexiv2.XmpTag('Xmp.dc.creator', ['Marcus Herbig', 'Georg Franze', 'Andrea Brünner', 'Carlos Soliz', 'Michel Krüger'])
metadata_1['Xmp.dc.publisher'] = pyexiv2.XmpTag('Xmp.dc.publisher', ['TU Bergakademie Freiberg'])
metadata_1['Xmp.dc.subject'] = pyexiv2.XmpTag('Xmp.dc.subject', ['Clemens-Winkler-Sammlung'])
metadata_1['Xmp.dc.language'] = pyexiv2.XmpTag('Xmp.dc.language', ['de_DE'])
metadata_1['Xmp.dc.format'] = pyexiv2.XmpTag('Xmp.dc.format', mimetypes.guess_type(src + "/sRGB/" + sRGB)[0])
metadata_1['Xmp.dc.identifier'] = pyexiv2.XmpTag('Xmp.dc.identifier', sRGB[:-4])
metadata_1['Xmp.dc.description'] = pyexiv2.XmpTag('Xmp.dc.description', description)
metadata_1['Xmp.dc.rights'] = pyexiv2.XmpTag('Xmp.dc.rights', "CC0 - TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger")
metadata_1['Xmp.dc.source'] = pyexiv2.XmpTag('Xmp.dc.source', "TU Bergakademie Freiberg - Institut für Anorganische Chemie, DFG-Projektnummer 465474202")
metadata_1['Xmp.xmp.CreatorTool'] = pyexiv2.XmpTag('Xmp.xmp.CreatorTool', 'darktable, imagemagick, python, pyexiv2')
metadata_1['Xmp.xmp.MetadataDate'] = pyexiv2.XmpTag('Xmp.xmp.MetadataDate', datetime.datetime.now())
metadata_1['Xmp.xmpRights.Marked'] = pyexiv2.XmpTag('Xmp.xmpRights.Marked', True)
metadata_1['Xmp.xmpRights.Owner'] = pyexiv2.XmpTag('Xmp.xmpRights.Owner', ['TU Bergakademie Freiberg', 'Marcus Herbig', 'Georg Franze', 'Andrea Brünner', 'Carlos Soliz', 'Michel Krüger'])
usageTerms = """
No Copyright
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law.
You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. See Other Information below.
Other Information
In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights.
Unless expressly stated otherwise, the person who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law.
When using or citing the work, you should not imply endorsement by the author or the affirmer.
"""
metadata_1['Xmp.xmpRights.UsageTerms'] = pyexiv2.XmpTag('Xmp.xmpRights.UsageTerms', usageTerms)
metadata_1['Xmp.xmpMM.DocumentID'] = pyexiv2.XmpTag('Xmp.xmpMM.DocumentID', "TUBAF_CW_res_" + res)
metadata_1['Exif.Image.Copyright'] = pyexiv2.ExifTag('Exif.Image.Copyright', "CC0 - TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger")
metadata_1['Exif.Image.ImageDescription'] = pyexiv2.ExifTag('Exif.Image.ImageDescription', description)
metadata_1.write()
metadata_1.copy(metadata_2, xmp=True, exif=True)
metadata_2.write()
metadata_1.copy(metadata_3, xmp=True, exif=True)
metadata_3.write()
ls = os.listdir(src + "/AdobeRGB")
adobeRGBs = [ x for x in ls if os.path.isfile(src + "/AdobeRGB/" + x) and x.endswith(".jpg")]
adobeRGBs.sort()
for adobeRGB in adobeRGBs:
print("Processing ", adobeRGB)
# find Number
m = imageNumber.match(adobeRGB)
title = ""
number = adobeRGB[:-4]
cursor.execute("SELECT ResourceID, resourceType, resourceDescription FROM Resources WHERE resourceLink LIKE '%"+adobeRGB[:-4]+".tif'")
objResource = cursor.fetchone()
res = "00"
if objResource:
res = str(interpretField(objResource['ResourceID']))
if not m:
print("Cannot find ID!")
if objResource:
title = interpretField(objResource['resourceType'])[1]
description = interpretField(objResource['resourceDescription'])
else:
number = int(m.group(1))
zusatz = str(m.group(2))
cursor.execute("SELECT objectTitle, description FROM Objects WHERE objectID=" + str(number))
objObject = cursor.fetchone()
title = objObject['objectTitle'] + " -- "
try:
int(zusatz)
title += "frontal - " + zusatz + "°"
except:
title += zusatz
description = interpretField(objObject['description'])
if not title:
title = "unbenannt"
if not description:
description = "keine Beschreibung"
metadata_1 = pyexiv2.ImageMetadata(src + "/AdobeRGB/" + adobeRGB)
metadata_1.read()
metadata_1.modified = True
image = Image.open(src + "/AdobeRGB/" + adobeRGB).convert('RGBA')
image.alpha_composite(watermark, (3274, 0))
image = image.convert('RGB')
image.save(src + "/AdobeRGB/" + adobeRGB)
metadata_1['Xmp.cc.license'] = pyexiv2.XmpTag('Xmp.cc.license', 'https://creativecommons.org/publicdomain/zero/1.0/')
metadata_1['Xmp.cc.attributionName'] = pyexiv2.XmpTag('Xmp.cc.attributionName', 'TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger')
metadata_1['Xmp.dc.title'] = pyexiv2.XmpTag('Xmp.dc.title', title)
metadata_1['Xmp.dc.creator'] = pyexiv2.XmpTag('Xmp.dc.creator', ['Marcus Herbig', 'Georg Franze', 'Andrea Brünner', 'Carlos Soliz', 'Michel Krüger'])
metadata_1['Xmp.dc.publisher'] = pyexiv2.XmpTag('Xmp.dc.publisher', ['TU Bergakademie Freiberg'])
metadata_1['Xmp.dc.subject'] = pyexiv2.XmpTag('Xmp.dc.subject', ['Clemens-Winkler-Sammlung'])
metadata_1['Xmp.dc.language'] = pyexiv2.XmpTag('Xmp.dc.language', ['de_DE'])
metadata_1['Xmp.dc.format'] = pyexiv2.XmpTag('Xmp.dc.format', mimetypes.guess_type(src + "/AdobeRGB/" + adobeRGB)[0])
metadata_1['Xmp.dc.identifier'] = pyexiv2.XmpTag('Xmp.dc.identifier', adobeRGB[:-4])
metadata_1['Xmp.dc.description'] = pyexiv2.XmpTag('Xmp.dc.description', description)
metadata_1['Xmp.dc.rights'] = pyexiv2.XmpTag('Xmp.dc.rights', "CC0 - TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger")
metadata_1['Xmp.dc.source'] = pyexiv2.XmpTag('Xmp.dc.source', "TU Bergakademie Freiberg - Institut für Anorganische Chemie, DFG-Projektnummer 465474202")
metadata_1['Xmp.xmp.CreatorTool'] = pyexiv2.XmpTag('Xmp.xmp.CreatorTool', 'darktable, imagemagick, python, pyexiv2')
metadata_1['Xmp.xmp.MetadataDate'] = pyexiv2.XmpTag('Xmp.xmp.MetadataDate', datetime.datetime.now())
metadata_1['Xmp.xmpRights.Marked'] = pyexiv2.XmpTag('Xmp.xmpRights.Marked', True)
metadata_1['Xmp.xmpRights.Owner'] = pyexiv2.XmpTag('Xmp.xmpRights.Owner', ['TU Bergakademie Freiberg', 'Marcus Herbig', 'Georg Franze', 'Andrea Brünner', 'Carlos Soliz', 'Michel Krüger'])
usageTerms = """
No Copyright
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law.
You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. See Other Information below.
Other Information
In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights.
Unless expressly stated otherwise, the person who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law.
When using or citing the work, you should not imply endorsement by the author or the affirmer.
"""
metadata_1['Xmp.xmpRights.UsageTerms'] = pyexiv2.XmpTag('Xmp.xmpRights.UsageTerms', usageTerms)
metadata_1['Xmp.xmpMM.DocumentID'] = pyexiv2.XmpTag('Xmp.xmpMM.DocumentID', "TUBAF_CW_res_" + res)
metadata_1['Exif.Image.Copyright'] = pyexiv2.ExifTag('Exif.Image.Copyright', "CC0 - TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger")
metadata_1['Exif.Image.ImageDescription'] = pyexiv2.ExifTag('Exif.Image.ImageDescription', description)
metadata_1.write()
ls = os.listdir(src + "/tif")
tifs = [ x for x in ls if os.path.isfile(src + "/tif/" + x) and x.endswith(".tif")]
tifs.sort()
tifs.reverse()
for tif in tifs:
print("Processing ", tif)
# find Number
m = imageNumber.match(tif)
title = ""
number = tif[:-4]
cursor.execute("SELECT ResourceID, resourceType, resourceDescription FROM Resources WHERE resourceLink LIKE '%"+tif[:-4]+".tif'")
objResource = cursor.fetchone()
res = "00"
if objResource:
res = str(interpretField(objResource['ResourceID']))
if not m:
print("Cannot find ID!")
if objResource:
title = interpretField(objResource['resourceType'])[1]
description = interpretField(objResource['resourceDescription'])
else:
number = int(m.group(1))
zusatz = str(m.group(2))
cursor.execute("SELECT objectTitle, description FROM Objects WHERE objectID=" + str(number))
objObject = cursor.fetchone()
title = objObject['objectTitle'] + " -- "
try:
int(zusatz)
title += "frontal - " + zusatz + "°"
except:
title += zusatz
description = interpretField(objObject['description'])
if not title:
title = "unbenannt"
if not description:
description = "keine Beschreibung"
metadata_1 = pyexiv2.ImageMetadata(src + "tif/" + tif)
metadata_1.read()
metadata_1.modified = True
os.system("composite -gravity NorthEast TUBAF.png \"" + src + "tif/" + tif + "\" \"" + src + "tif/" + tif + "\"")
metadata_1['Xmp.cc.license'] = pyexiv2.XmpTag('Xmp.cc.license', 'https://creativecommons.org/publicdomain/zero/1.0/')
metadata_1['Xmp.cc.attributionName'] = pyexiv2.XmpTag('Xmp.cc.attributionName', 'TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger')
metadata_1['Xmp.dc.title'] = pyexiv2.XmpTag('Xmp.dc.title', title)
metadata_1['Xmp.dc.creator'] = pyexiv2.XmpTag('Xmp.dc.creator', ['Marcus Herbig', 'Georg Franze', 'Andrea Brünner', 'Carlos Soliz', 'Michel Krüger'])
metadata_1['Xmp.dc.publisher'] = pyexiv2.XmpTag('Xmp.dc.publisher', ['TU Bergakademie Freiberg'])
metadata_1['Xmp.dc.subject'] = pyexiv2.XmpTag('Xmp.dc.subject', ['Clemens-Winkler-Sammlung'])
metadata_1['Xmp.dc.language'] = pyexiv2.XmpTag('Xmp.dc.language', ['de_DE'])
metadata_1['Xmp.dc.format'] = pyexiv2.XmpTag('Xmp.dc.format', mimetypes.guess_type(src + "/tif/" + tif)[0])
metadata_1['Xmp.dc.identifier'] = pyexiv2.XmpTag('Xmp.dc.identifier', tif[:-4])
metadata_1['Xmp.dc.description'] = pyexiv2.XmpTag('Xmp.dc.description', description)
metadata_1['Xmp.dc.rights'] = pyexiv2.XmpTag('Xmp.dc.rights', "CC0 - TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger")
metadata_1['Xmp.dc.source'] = pyexiv2.XmpTag('Xmp.dc.source', "TU Bergakademie Freiberg - Institut für Anorganische Chemie, DFG-Projektnummer 465474202")
metadata_1['Xmp.xmp.CreatorTool'] = pyexiv2.XmpTag('Xmp.xmp.CreatorTool', 'darktable, imagemagick, python, pyexiv2')
metadata_1['Xmp.xmp.MetadataDate'] = pyexiv2.XmpTag('Xmp.xmp.MetadataDate', datetime.datetime.now())
metadata_1['Xmp.xmpRights.Marked'] = pyexiv2.XmpTag('Xmp.xmpRights.Marked', True)
metadata_1['Xmp.xmpRights.Owner'] = pyexiv2.XmpTag('Xmp.xmpRights.Owner', ['TU Bergakademie Freiberg', 'Marcus Herbig', 'Georg Franze', 'Andrea Brünner', 'Carlos Soliz', 'Michel Krüger'])
usageTerms = """
No Copyright
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law.
You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. See Other Information below.
Other Information
In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights.
Unless expressly stated otherwise, the person who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law.
When using or citing the work, you should not imply endorsement by the author or the affirmer.
"""
metadata_1['Xmp.xmpRights.UsageTerms'] = pyexiv2.XmpTag('Xmp.xmpRights.UsageTerms', usageTerms)
metadata_1['Xmp.xmpMM.DocumentID'] = pyexiv2.XmpTag('Xmp.xmpMM.DocumentID', "TUBAF_CW_res_" + res)
metadata_1['Exif.Image.Copyright'] = pyexiv2.ExifTag('Exif.Image.Copyright', "CC0 - TU Bergakademie Freiberg: Marcus Herbig, Georg Franze, Andrea Brünner, Carlos Soliz, Michel Krüger")
metadata_1['Exif.Image.ImageDescription'] = pyexiv2.ExifTag('Exif.Image.ImageDescription', description)
metadata_1.write()
Lizenzierung der Bilder
Die Bilder werden unter der CC0-Lizenz veröffentlicht. Diese Lizenz erlaubt jegliche Weiterverwendung der Bilder. Die Nennung des Urhebers durch den Nachnutzer ist nicht erforderlich, darf aber gemacht werden. Diese Lizenz wurde gewählt, um einerseits die Bilder einer möglichst breiten Öffentlichkeit zur Verfügung zu stellen und außerdem um Urheberrechtsprobleme zu vermeiden. Es liegt eine Erklärung aller Fotografen vor, die das Einverständnis mit dieser Lizenzierung beinhaltet.