Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/lint-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ jobs:

- name: Install Exiftool
run: |
wget https://exiftool.org/Image-ExifTool-13.56.tar.gz
gzip -dc Image-ExifTool-13.56.tar.gz | tar -xf -
cd Image-ExifTool-13.56
wget https://exiftool.org/Image-ExifTool-13.59.tar.gz
gzip -dc Image-ExifTool-13.59.tar.gz | tar -xf -
cd Image-ExifTool-13.59
perl Makefile.PL
sudo make install
cd ..
Expand Down
168 changes: 168 additions & 0 deletions cfg/dji.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#------------------------------------------------------------------------------
# File: exiftool.cfg
#
# Description: This config file contains tag definitions needed to be able
# to write Pix4D and Sentera XMP-Camera tags
#
# Usage: exiftool -config exiftool.cfg -XMP-camera:TAG=VAL ...
#
# Requires: ExifTool version 7.00 or later
#
# References: 1) https://support.pix4d.com/hc/en-us/articles/360016450032-Specifications-of-xmpcamera-tags
#------------------------------------------------------------------------------
Comment on lines +1 to +12

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description should be updated to mention dji tags as well.

Is there a reason a new file was created rather than just updating the existing exiftool.cfg? Unless there were conflicts, you should be able to extend the existing file without affecting the other entries, making maintenance easier.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was hoping it would be as simple as adding the drone-dji section but we write CaptureUUID in XMP-Camera and DJI writes it in drone-dji. This was one of the main issues with processing corrected images in pix4d fields and likely ODM.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should be able to have both, as they are in different namespaces (XMP-Camera vs XMP-DJI), but maybe there is something I'm missing. If you've already tried it and it doesn't work then I'm good with the workaround. Otherwise I can try it on my end this afternoon as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try it to double check, I think I had some of the syntax wrong the first time I tried and this method worked.


%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
Camera => {
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::Camera',
},
},
'drone-dji' => {
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::DJI',
},
},
},
);

%Image::ExifTool::UserDefined::Camera = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-Camera', 2 => 'Camera' },
NAMESPACE => { 'Camera' => 'http://pix4d.com/camera/1.0/' },
WRITABLE => 'string',
Yaw => { Writable => 'real' },
Pitch => { Writable => 'real' },
Roll => { Writable => 'real' },
IMUSampleSize => { Writable => 'integer' },
IMUTimeOffset => { Writable => 'integer' },
LineReadoutTime => { Writable => 'integer' },
IMUFrequency => { Writable => 'real' },
PrincipalPoint => { },
ModelType => { },
PerspectiveFocalLength => { Writable => 'real' },
PerspectiveDistortion => { },
IMULinearVelocity => { },
GPSXYAccuracy => { Writable => 'real' },
GPSZAccuracy => { Writable => 'real' },
RigName => { },
RigCameraIndex => { Writable => 'integer' },
IMUAngularVelocity => {
Binary => 1,
ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
},
# added 2020/04/02 (ref 1)
FisheyeAffineMatrix => { },
FisheyeAffineSymmetric => { },
FisheyePolynomial => { },
RigRelatives => { },
PerspectiveFocalLengthUnits => { },
CentralWavelength => { List => 'Seq' },
WavelengthFWHM => { List => 'Seq' },
BlackCurrent => { List => 'Seq' },
BandSensitivity => { List => 'Seq' },
SunSensor => { List => 'Seq' },
SunSensorExposureTime => { Writable => 'real' },
SunSensorSensitivity => { List => 'Seq' },
InvalidPixel => { List => 'Seq' },
VignettingPolynomial => { List => 'Seq' },
VignettingCenter => { List => 'Seq' },
VignettingPolynomial2DName => { List => 'Seq' },
VignettingPolynomial2D => { List => 'Seq' },
ColorTransform => { List => 'Seq' },
IsNormalized => { Writable => 'real' },
Albedo => { List => 'Seq' },
ReflectArea => { List => 'Seq' },
CalibrationPicture => { Writable => 'integer' },
GyroRate => { Writable => 'real' },
IMUPitchAccuracy => { Writable => 'real' },
IMURollAccuracy => { Writable => 'real' },
IMUYawAccuracy => { Writable => 'real' },
NominalCameraDistance => { Writable => 'real' },
SunSensorYaw => { Writable => 'real' },
SunSensorPitch => { Writable => 'real' },
SunSensorRoll => { Writable => 'real' },
SunSensorRelativeRotation => { Writable => 'real', List => 'Seq' },
TransformAlpha => { List => 'Seq' },
TransformBeta => { List => 'Seq' },
TransformGamma => { List => 'Seq' },
SensorBitDepth => { Writable => 'integer' },
SensorTemperature => { Writable => 'real' },
# (ref https://community.pix4d.com/t/camera-sun-irradiance-and-sun-angle-in-red-text/3290)
IrradianceRelativeRotation => { },
Irradiance => { List => 'Seq' },
IrradianceExposureTime => { Writable => 'real' },
IrradianceGain => { Writable => 'real' },
BandName => { List => 'Seq' },
# Not official pix4d fields
);

%Image::ExifTool::UserDefined::DJI = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-drone-dji', 2 => 'drone-dji' },
NAMESPACE => { 'drone-dji' => 'http://www.dji.com/drone-dji/1.0/' },
WRITABLE => 'string',
# Original GPS/flight tags from built-in DJI::XMP
AbsoluteAltitude => { Writable => 'real' },
RelativeAltitude => { Writable => 'real' },
GimbalRollDegree => { Writable => 'real' },
GimbalYawDegree => { Writable => 'real' },
GimbalPitchDegree => { Writable => 'real' },
FlightRollDegree => { Writable => 'real' },
FlightYawDegree => { Writable => 'real' },
FlightPitchDegree => { Writable => 'real' },
GpsLatitude => { Writable => 'real' },
GpsLongtitude => { Writable => 'real' },
GpsLongitude => { Writable => 'real' },
FlightXSpeed => { Writable => 'real' },
FlightYSpeed => { Writable => 'real' },
FlightZSpeed => { Writable => 'real' },
CamReverse => { },
GimbalReverse => { },
SelfData => { },
CalibratedFocalLength => { Writable => 'real' },
CalibratedOpticalCenterX => { Writable => 'real' },
CalibratedOpticalCenterY => { Writable => 'real' },
RtkFlag => { },
RtkStdLon => { Writable => 'real' },
RtkStdLat => { Writable => 'real' },
RtkStdHgt => { Writable => 'real' },
DewarpData => { },
DewarpFlag => { },
Latitude => { Writable => 'real' },
Longitude => { Writable => 'real' },
# Multispectral / M3M tags
ImageSource => { },
GpsStatus => { },
AltitudeType => { },
RtkDiffAge => { Writable => 'real' },
NTRIPMountPoint => { },
NTRIPPort => { Writable => 'integer' },
NTRIPHost => { },
SurveryingMode => { Writable => 'integer' },
UTCAtExposure => { },
ShutterType => { },
CameraSerialNumber => { },
DroneModel => { },
DroneSerialNumber => { },
CaptureUUID => { },
RelativeOpticalCenterX => { Writable => 'real' },
RelativeOpticalCenterY => { Writable => 'real' },
DewarpHMatrix => { List => 'Seq' },
CalibratedHMatrix => { List => 'Seq' },
VignettingFlag => { },
VignettingData => { List => 'Seq' },
LSType => { },
LSstatus => { },
Packageidx => { },
Cfgcnt => { },
RawData => { },
BandFreq => { List => 'Seq' },
Irradiance => { List => 'Seq' },
SensorGain => { },
SensorGainAdjustment => { },
SensorIndex => { },
BlackLevel => { },
DroneID => { },
);

1; #end
2 changes: 1 addition & 1 deletion correct_images_dir.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ metadata_datas = copy_metadata('imageio') + copy_metadata('imgcorrect')
a = Analysis(['scripts\\correct_images.py'],
pathex=['.'],
binaries=[],
datas=[('exiftool/exiftool.exe', '.'), ('cfg/exiftool.cfg', 'cfg'), ('cfg/reg_config.ini', 'cfg')] + metadata_datas,
datas=[('exiftool/exiftool.exe', '.'), ('cfg/exiftool.cfg', 'cfg'), ('cfg/dji.cfg', 'cfg'), ('cfg/reg_config.ini', 'cfg')] + metadata_datas,
hiddenimports=['pkg_resources.py2_warn'],
hookspath=[],
runtime_hooks=[],
Expand Down
2 changes: 1 addition & 1 deletion correct_images_gui_onefile.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ metadata_datas = copy_metadata('imageio') + copy_metadata('imgcorrect')
a = Analysis(['scripts\\correct_images_gui.py'],
pathex=['.'],
binaries=[],
datas=[('exiftool/exiftool.exe', '.'), ('cfg/exiftool.cfg', 'cfg'), ('cfg/reg_config.ini', 'cfg'), ('sentera_radiometric_corrections_icon.ico', '.')] + metadata_datas,
datas=[('exiftool/exiftool.exe', '.'), ('cfg/exiftool.cfg', 'cfg'), ('cfg/dji.cfg', 'cfg'), ('cfg/reg_config.ini', 'cfg'), ('sentera_radiometric_corrections_icon.ico', '.')] + metadata_datas,
hiddenimports=['pkg_resources.py2_warn'],
hookspath=[],
runtime_hooks=[],
Expand Down
2 changes: 1 addition & 1 deletion correct_images_onefile.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ metadata_datas = copy_metadata('imageio') + copy_metadata('imgcorrect')
a = Analysis(['scripts\\correct_images.py'],
pathex=['.'],
binaries=[],
datas=[('exiftool/exiftool.exe', '.'), ('cfg/exiftool.cfg', 'cfg'), ('cfg/reg_config.ini', 'cfg')] + metadata_datas,
datas=[('exiftool/exiftool.exe', '.'), ('cfg/exiftool.cfg', 'cfg'), ('cfg/dji.cfg', 'cfg'), ('cfg/reg_config.ini', 'cfg')] + metadata_datas,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_corrections_*.spec also had the exiftool.cfg, but it doesn't look like they actually use it. If we decide to keep the dji.cfg/exiftool.cfg split, maybe we update those spec files to remove exiftool.cfg to make it clearer that it isn't used for those exes. Or since very few people use get_correction, we could just remove it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats a good catch, I will remove those from the get_corrections files

hiddenimports=['pkg_resources.py2_warn'],
hookspath=[],
runtime_hooks=[],
Expand Down
2 changes: 1 addition & 1 deletion get_corrections_dir.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ metadata_datas = copy_metadata('imageio') + copy_metadata('imgcorrect')
a = Analysis(['scripts\\get_corrections.py'],
pathex=['.'],
binaries=[],
datas=[('exiftool/exiftool.exe', '.'), ('cfg/exiftool.cfg', 'cfg'), ('cfg/reg_config.ini', 'cfg')] + metadata_datas,
datas=[('exiftool/exiftool.exe', '.'), ('cfg/reg_config.ini', 'cfg')] + metadata_datas,
hiddenimports=['pkg_resources.py2_warn'],
hookspath=[],
runtime_hooks=[],
Expand Down
2 changes: 1 addition & 1 deletion get_corrections_onefile.spec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ metadata_datas = copy_metadata('imageio') + copy_metadata('imgcorrect')
a = Analysis(['scripts\\get_corrections.py'],
pathex=['.'],
binaries=[],
datas=[('exiftool/exiftool.exe', '.'), ('cfg/exiftool.cfg', 'cfg'), ('cfg/reg_config.ini', 'cfg')] + metadata_datas,
datas=[('exiftool/exiftool.exe', '.'), ('cfg/reg_config.ini', 'cfg')] + metadata_datas,
hiddenimports=['pkg_resources.py2_warn'],
hookspath=[],
runtime_hooks=[],
Expand Down
12 changes: 9 additions & 3 deletions imgcorrect/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@

def copy_exif(image_df_row, exiftool_path):
"""Copy image metadata with necessary changes from original image to corrected image."""
parser = MetadataParser(image_df_row.image_path)

command = [
exiftool_path,
"-config",
"cfg/exiftool.cfg",
]
make = parser.make()
if make == "DJI":
command += ["-config", "cfg/dji.cfg"]
elif make == "Sentera":
command += ["-config", "cfg/exiftool.cfg"]
command += [
Comment on lines +18 to +23

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question as above on whether we need to distinguish the two modes.

"-overwrite_original",
"-TagsFromFile",
image_df_row.image_path,
Expand All @@ -25,7 +32,6 @@ def copy_exif(image_df_row, exiftool_path):
"-xmp-Camera:BlackCurrent=0",
]
if image_df_row.reduce_xmp:
parser = MetadataParser(image_df_row.image_path)
cent_arr, fwhm_arr = parser.wavelength_data()
band_arr = parser.bandnames()
i = int(image_df_row.XMP_index)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "imgcorrect"
version = "2.1.2"
version = "2.1.3"
description = "Library to perform various corrections on imagery from supported sensors"
authors = ["Samuel Williams <sam.williams@sentera.com>", "Joseph Franck <joseph.franck@sentera.com>"]

Expand Down
Loading