Freitag, 15. Mai 2015

Urlaubsfotos reparieren – mit exiftool und R

Wir waren im Urlaub – eine Woche Toskana. Schön :-)

Und natürlich hatte ich ein paar Kameras dabei. Konkret meine Nikon D7000 und die Fuji X20. Beide habe ich ordentlich zum Einsatz gebracht und einen riesen Haufen Bilder gemacht. Am 2. Tag, mitten in Volterra habe ich bemerkt, dass die Uhrzeit in der X20 nicht korrekt eingestellt war. Ist ja kein Problem, einfach schnell korrigiert und schon konnte es weiter gehen...

Am Abend habe ich dann alle Bilder auf das Laptop geladen und gesichtet/aussortiert. Und da fiel mir was seltsames auf: ab einem bestimmten Punkt gingen plötzlich Bilder durcheinander. Soll heißen, sie kamen nicht in der korrekten Reihenfolge und ich sah für eine Weile immer abwechselnd welche von innen und außen einer Kirche. Was ist da los? Na klar – die waren kurz vor bzw. nach der Zeitkorrektur aufgenommen worden und da Digikam die Fotos nach Aufnahme-Datum- und -Zeit sortiert, waren einige halt ineinander verschachtelt worden. Grumpf!

Natürlich ist das nicht wirklich schlimm, aber geärgert hat mich das schon. Andererseits: wie schwer kann es sein, die Datumsangabe zu korrigieren? Zuerst hatte ich ein wenig in den Menüs von Digikam herum gestochert, aber nicht wirklich eine gute Lösung gefunden. Also Kommandozeile zum Rettungseinsatz! Da gibt es nun ein sehr nützliches und extrem mächtiges Werkzeug namens exiftool. Das kann die Metadaten diverser Bild und anderer Medienformate lesen und schreiben. Damit sollte das doch gehen. Und in der Tat kann man sehr leicht viel über ein Bild in Erfahrung bringen:
>exiftool D7K_6266.JPG
ExifTool Version Number         : 9.74
File Name                       : D7K_6266.JPG
Directory                       : .
File Size                       : 11 MB
File Modification Date/Time     : 2015:05:04
                                  11:49:56+02:00
File Access Date/Time           : 2015:05:15
                                  21:07:14+02:00
File Inode Change Date/Time     : 2015:05:04
                                  21:26:46+02:00
File Permissions                : rw-------
File Type                       : JPEG
MIME Type                       : image/jpeg
Exif Byte Order                 : Big-endian
Processing Software             : digiKam-4.4.0
Make                            : NIKON CORPORATION
Camera Model Name               : NIKON D7000
[...]
OK - das ist schon mal gut – damit sollte sich das doch hinkriegen lassen. Nur stellt sich nun die Frage, welche Bilder eigentlich betroffen sind, schließlich will ich ja nur die modifizieren, die vor der Zeitjustierung auf der X20 aufgenommen wurden. Die richtige Kamera zu erwischen ist leicht: die Bilder meiner D7000 haben Filenamen im Stil D7K_6432.JPG und die X20 erzeugt Files nach dem Schema DSCF4535.JPG.
Aber wie finde ich nun die Stelle, an der ich die Zeit umgestellt habe? Und um wieviel muss ich korrigieren?

EXIF Daten systematisch analysieren

Als erstes habe ich also mal die Metadaten aller X20 Fotos in tab separierter Form ausgelesen. D.h. eigentlich interessierte mich nur der Aufnahme-Timestamp und so habe ich nur den und den Dateinamen angefordert:
    exiftool -T -filename -ExifIFD:DateTimeOriginal DSCF* \
        > ~/exif.tbl

Dieses File kann man nun super in meine Lieblings-Datenanalyse-Software R laden und weiter analysieren:
# read the data
dat <- read.delim('exif.tbl', header=FALSE, stringsAsFactors=FALSE)

# add some usefull column names
colnames(dat) <- c('filename','date')

# convert the date to proper datetime object
dat$date <- strptime(dat$date, "%Y:%m:%d %H:%M:%S")

# extract file numbers from filenames
dat$filenum <- as.integer(substr(dat$filename, 5, 8))

# sort by filenum, just in case
dat <- dat[order(dat$filenum), ]

Die Daten sollten nun schön in Form gebracht sein und man kann anfangen, sie anzuschauen:
> head(dat)
      filename                date filenum
1 DSCF4464.JPG 2015-05-02 18:19:52    4464
2 DSCF4465.JPG 2015-05-02 18:20:02    4465
3 DSCF4466.JPG 2015-05-02 18:20:10    4466
4 DSCF4467.JPG 2015-05-02 18:20:43    4467
[...]

OK - sieht gut aus. Erst mal ein Plot der Daten, das hilft fast immer:
with(dat, plot(filenum, date, col='royalblue'))
Wie man sehen kann, habe ich am Samstag Abend noch ein paar Fotos gemacht und dann ganz viele am Sonntag. Montags hatte ich nur die D7000 im Einsatz und daher keine Bilder der X20 usw. Wie schon gesagt hatte ich die Zeit am Sonntag korrigiert. Also fokussieren wir mal auf das Zeitinterval von 12:00 bis 17:00 an besagtem Sonntag:

with(
    dat[
        dat$date >= strptime(

                '2015-05-03 12:00',
                "%Y-%m-%d %H:%M"
            ) &
            dat$date <= strptime(
                '2015-05-03 17:00',
                "%Y-%m-%d %H:%M"
            ),
    ],
    plot(filenum, date, col='royalblue')
)
So sieht man schon mehr! Z.B. dass wir so gegen halb zwei in Volterra angekommen waren oder wann wir Pinkelpause gemacht haben. Aber zurück zum Thema: Nachdem die Datenpunkte in der Reihenfolge der Filenummern auf der x-Achse aufgetragen sind, sollte die Kurve monoton steigen. Aber so ca. bei Nummer 4530 oder so ist plötzlich ein Sprung um etwa 20 Minuten in die Vergangenheit zu erkennen. Das ist der Zeitpunkt an dem ich die Uhr gestellt hatte! D.h. alle Bilder vor diesem Sprung müssen um ca. 20 Minuten korrigiert werden. Aber wo genau geht es los? Auch da kann R helfen:
# find all rows for which timediff is negative
dat[which(diff(dat$date)<0), 'filenum']

[1] 4528
diff ermittelt jeweils die Differenz zwischen aufeinanderfolgenden Elementen eines Vektors. In unserem Fall in Sekunden. Und das Ergebnis des obigen Befehls sagt uns, dass an Position 4528 offenbar der Bruch lag d.h. das File danach lag vor 4528. Prüfen wir das mal kurz:
dat
        filename                date filenum
1   DSCF4464.JPG 2015-05-02 18:19:52    4464
2   DSCF4465.JPG 2015-05-02 18:20:02    4465

[...]
63  DSCF4526.JPG 2015-05-03 14:02:56    4526
64  DSCF4527.JPG 2015-05-03 14:03:02    4527
65  DSCF4528.JPG 2015-05-03 14:03:13    4528
66  DSCF4529.JPG 2015-05-03 13:43:29    4529
67  DSCF4530.JPG 2015-05-03 13:43:38    4530

[...]
Bingo! Also muss ich alle DSCF Files bis einschließlich DSCF4528.JPG um 20 Minuten zurückdatieren.


Und wie macht man das? Nun, zuerst habe ich mal alle fraglichen Files in einen Bastel-Ordner kopiert und dann das time shift feature von exiftool verwendet:
exiftool -AllDates-=0:20 *
Und das ist es dann auch schon. Alle *_orginal Files löschen, die exiftool sicherheitshalber angelegt hatte und dann die korrigierten Dateien in den ursprünglichen Ordner verschieben – fertig.

Keine Kommentare:

Kommentar veröffentlichen