たくさん時間のずれた写真の時計合わせ

DP1M0538

先日ポタリングに行ったのですが,その時持っていったカメラの時計が初期化されてしまっていてオフセットが6年半以上ありました.
(予備バッテリーが死んでバッテリー充電中に情報が初期化されてしまう)

これを正確な撮影時間に変更します.いつもはexiv2で設定していたのですが,今回これではうまく行かなかったのでexiftimeコマンドで設定しました.

先ずカメラ内時計と実際の時計の差分を求めます.正確な時間を撮影(今回はNICTのJST Clockを撮影)した結果はこんな感じでした.

$ ls --full-time DP1M0608.JPG
-rw-r--r-- 1 mk mk 9043186 2012-01-02 10:27:01.000000000 +0900 DP1M0608.JPG

写真に写った時間 -> 2018-07-17 07:32:00

それぞれUNIX EPOCに変換して引き算をすると差分は206312699秒でした.

$ date +%s -d '2012-01-02 10:27:01'
1325467621
$ date +%s -d '2018-07-17 07:32:00'
1531780320
$ expr 1531780320 - 1325467621
206312699

いつも使っているexiv2コマンドにこの秒を指定して修正しようとしたら日付がおかしくなってしまいました.

$ cp -p ./DP1M0608.JPG /tmp/DP1M0608.JPG
$ exiv2 -a +206312699 /tmp/DP1M0608.JPG
$ exiftime /tmp/DP1M0608.JPG
exiftime: field count mismatch (DateTime)
exiftime: field count mismatch (DateTimeOriginal)
exiftime: field count mismatch (DateTimeDigitized)
exiftime: field count mismatch (ImageUniqueID)
/tmp/DP1M0608.JPG: no timestamps available
$ exif /tmp/DP1M0608.JPG|grep -i date
Date and Time       |25548:01:17 21:27:01
Date and Time       |2012:01:02 10:27:01
Date and Time (Origi|25548:01:17 21:27:01
Date and Time (Digit|25548:01:17 21:27:01

manを確認すると,秒だけの指定は駄目でちゃんと計算して指定しないといけないようです.そして日またぎ以上は指定できないような感じです.これまではせいぜい数秒から数分しかずれなかったので気づきませんでした…….

       -a time
              Time  adjustment  in  the  format  [-]HH[:MM[:SS]]. This option is only used with the 'adjust' action. Examples: 1 adds one
              hour, 1:01 adds one hour and one minute, -0:00:30 subtracts 30 seconds.
 

計算するのが面倒なので差分を秒で指定できるツールはないだろうかと探してみると,exiftags packageのexiftimeが使えそうです.

              If val is numeric, one of either y, m, w, d, H, M, or S must be used to specify which part of the date is to be adjusted.
 

実際に試してみます.

念の為ファイルを/tmpにコピーして先ずはこれで試します.

$ cp -p ./DP1M0608.JPG /tmp/DP1M0608.JPG
$ exiftime /tmp/DP1M0608.JPG
exiftime: field count mismatch (ImageUniqueID)
Image Created: 2012:01:02 10:27:01
Image Generated: 2012:01:02 10:27:01
Image Digitized: 2012:01:02 10:27:01

-vでオフセットを指定します.今回は+206312699S206312699秒進めます.

$ exiftime -v +206312699S /tmp/DP1M0608.JPG
exiftime: field count mismatch (ImageUniqueID)
Image Created: 2018:07:17 07:32:00
Image Generated: 2018:07:17 07:32:00
Image Digitized: 2018:07:17 07:32:00

大丈夫そうです.
-vだけでは実際は書き換わりません-wで実際にexifを書き換えます.

$ exiftime -v +206312699S -w /tmp/DP1M0608.JPG
exiftime: field count mismatch (ImageUniqueID)
adjust time created in /tmp/DP1M0608.JPG from
  2012:01:02 10:27:01 to 2018:07:17 07:32:00? (y/n [n]) y
Image Created: 2012:01:02 10:27:01 -> 2018:07:17 07:32:00
adjust time generated in /tmp/DP1M0608.JPG from
  2012:01:02 10:27:01 to 2018:07:17 07:32:00? (y/n [n]) y
Image Generated: 2012:01:02 10:27:01 -> 2018:07:17 07:32:00
adjust time digitized in /tmp/DP1M0608.JPG from
  2012:01:02 10:27:01 to 2018:07:17 07:32:00? (y/n [n]) y
Image Digitized: 2012:01:02 10:27:01 -> 2018:07:17 07:32:00
$ exiftime /tmp/DP1M0608.JPG
exiftime: field count mismatch (ImageUniqueID)
Image Created: 2018:07:17 07:32:00
Image Generated: 2018:07:17 07:32:00
Image Digitized: 2018:07:17 07:32:00

exiftoolコマンドでファイルのタイムスタンプも修正します.

$ exiftool "-FileModifyDate<DateTimeOriginal" /tmp/DP1M0608.JPG
Warning: Bad PrintIM size - /tmp/DP1M0608.JPG
    1 image files updated
$ ls --full-time /tmp/DP1M0608.JPG
-rw-r--r-- 1 mk mk 9043186 2018-07-17 07:32:00.000000000 +0900 /tmp/DP1M0608.JPG

OKそうです.

本番のファイルを一気に書き換えてみます.
確認メッセージが出ないようexiftime-fオプションを付けています.

$ exiftime -v +206312699S -w -f ./*.JPG
./DP1M0537.JPG:
exiftime: field count mismatch (ImageUniqueID)
Image Created: 2012:01:01 08:46:51 -> 2018:07:16 05:51:50
Image Generated: 2012:01:01 08:46:51 -> 2018:07:16 05:51:50
Image Digitized: 2012:01:01 08:46:51 -> 2018:07:16 05:51:50
 
./DP1M0538.JPG:
exiftime: field count mismatch (ImageUniqueID)
Image Created: 2012:01:01 08:55:16 -> 2018:07:16 06:00:15
Image Generated: 2012:01:01 08:55:16 -> 2018:07:16 06:00:15
Image Digitized: 2012:01:01 08:55:16 -> 2018:07:16 06:00:15
 
   :
$ exiftime -v +206312699S -w -f ./*.X3F
   :

更に,gpscorrelateでジオタグを埋め込みます.

$ gpscorrelate -g ./2018-07-16鹿屋ポタ.gpx -z +9 -n *.JPG
$ gpscorrelate -g ./2018-07-16鹿屋ポタ.gpx -z +9 *.JPG

最後にファイルのタイムスタンプを修正します.

$ exiftool "-FileModifyDate<DateTimeOriginal" ./*

うまく行ったようです :)

環境

$ dpkg-query -W exiv2 exiftags exif
exif    0.6.21-2
exiftags        1.01-6build1
exiv2   0.25-3.1ubuntu0.18.04.1
$ lsb_release -d
Description:    Ubuntu 18.04.1 LTS
$ uname -m
x86_64

画像ファイルのタイムスタンプをexifの時間に合わせる

画像ファイルをSNSなどにアップロードするときに回線が細かったりデータ転送料金が従量制だったりするときにリサイズしてアップロードしたりするのですが,サービスによってはファイルのタイムスタンプを参照して悲しいことになることも.
オリジナルのexifが残っている場合はそれを参照してファイルのタイムスタンプを修正することが可能です.
というメモ.

$ exiftool "-FileModifyDate<DateTimeOriginal" DP1M0???.resized.JPG
   10 image files updated

環境

$ dpkg-query -W libimage-exiftool-perl
libimage-exiftool-perl  10.96-1
$ lsb_release -d
Description:    Debian GNU/Linux unstable (sid)
$ uname -m
x86_64

関連

ExifTool で任意の geotag 埋め込み

DSC_0241

撮影した写真への位置情報の書き込みにいつもは GPSロガーで記録したGPSログを使い,gpscorrelateコマンドを利用しています.

以下のスライドは2008年のものですが現在もそのままの手順で埋め込んでいます.

建物内などに入ったときなどGPSログが取れないので埋め込みも出来ていませんでした.でも今回建物内で撮影したのが分かっている写真にその場所の位置情報を埋め込みたいと思いました.

gpscorrelateコマンドのマニュアルを見た感じそれらしいオプションは見当たりませんでした.ダミーのGPSログを書くとかもちょっと考えたのですが,exiv2コマンドで座標指定でいけるのではとmanを見ると行けそうです.

       exiv2 -M"set Exif.GPSInfo.GPSLatitude 4/1 15/1 33/1" \
              -M"set Exif.GPSInfo.GPSLatitudeRef N" image.jpg
              Sets  the  latitude to 4 degrees, 15 minutes and 33 seconds north. The Exif standard stipulates that the GPS‐
              Latitude tag consists of three Rational numbers for the degrees, minutes and seconds of the latitude and GPS‐
              LatitudeRef contains either 'N' or 'S' for north or south latitude respectively.

しかし座標の度分秒変換が必要でちょっとめんどうです.
ExifToolを見ると変換なしで行けそうなのでこれで試してみました.(-geotag optionでgpscorrelateと同じこともできそう)

       -geotag TRKFILE
            Geotag images from the specified GPS track log file.  Using the -geotag option is equivalent to writing a value
            to the "Geotag" tag.  After the -geotag option has been specified, the value of the "Geotime" tag is written to
            define a date/time for the position interpolation.  If "Geotime" is not specified, the value is copied from
            "DateTimeOriginal#" (the "#" is added to copy the unformatted value, avoiding potential conflicts with the -d
            option).  For example, the following two commands are equivalent:

                exiftool -geotag trk.log image.jpg
                exiftool -geotag trk.log "-Geotime<DateTimeOriginal#" image.jpg

            When the "Geotime" value is converted to UTC, the local system timezone is assumed unless the date/time value
            contains a timezone.  Writing "Geotime" causes the following tags to be written (provided they can be
            calculated from the track log, and they are supported by the destination metadata format):  GPSLatitude,
            GPSLatitudeRef, GPSLongitude, GPSLongitudeRef, GPSAltitude, GPSAltitudeRef, GPSDateStamp, GPSTimeStamp,
            GPSDateTime, GPSTrack, GPSTrackRef, GPSSpeed, GPSSpeedRef, GPSImgDirection, GPSImgDirectionRef, GPSPitch and
            GPSRoll.  By default, tags are created in EXIF, and updated in XMP only if they already exist.  However,
            "EXIF:Geotime" or "XMP:Geotime" may be specified to write only EXIF or XMP tags respectively.  Note that
            GPSPitch and GPSRoll are non-standard, and require user-defined tags in order to be written.

すでに埋め込み済みのジオタグを参考にして,

$ exiftool -v IMGP5011.JPG|grep GPS
  | 12) GPSInfo (SubDirectory) -->
  | + [GPS directory with 11 entries]
  | | 0)  GPSVersionID = 2 0 0 0
  | | Warning = Tag ID 0x0000 out of sequence in GPS
  | | 1)  GPSVersionID = 2 3 0 0
  | | 2)  GPSLatitudeRef = N
  | | 3)  GPSLatitude = 31 19 18.23 (31/1 19/1 1823/100)
  | | 4)  GPSLongitudeRef = E
  | | 5)  GPSLongitude = 130 53 57.6 (130/1 53/1 5760/100)
  | | 6)  GPSAltitudeRef = 0
  | | 7)  GPSAltitude = 7.8833 (78833/10000)
  | | 8)  GPSTimeStamp = 7 10 37 (7/1 10/1 37/1)
  | | 9)  GPSMapDatum = WGS-84
  | | 10) GPSDateStamp = 2018:01:13

こんな感じかな?

  • GPSLongitudeRef=E -> 東経, 西経
  • GPSLongitude=130.86455555555557 -> 経度
  • GPSLatitudeRef=N -> 北緯, 南緯
  • GPSLatitude=31.386555555555553 -> 緯度
  • GPSAltitude=41.47 -> 海抜標高

実際にExifToolで埋め込んでみました.

$ exiftool -GPSLongitudeRef=E -GPSLongitude=130.86455555555557 -GPSLatitudeRef=N -GPSLatitude=31.386555555555553 -GPSAltitude=41.47 IMGP5021.JPG

座標系がないとまずいかなと思いましたがJOSMやGpsPruneにこの写真を読み込んでみると想定していた座標にプロットされました :)

20180117_00:01:45-2690020180116_05:01:42-30322

exiftoolは既定値ではIMGP5021.JPG_originalのようにオリジナルファイルのバックアップが作成されるので  問題なかったらこれは消しておきましょう.

$ rm *_original