Skip to content

Commit bc1ec0a

Browse files
committed
checkpoint for v0.24.0 Parrot Anafi Hotfix
1 parent d5f537e commit bc1ec0a

File tree

5 files changed

+85
-34
lines changed

5 files changed

+85
-34
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ android {
99
applicationId "com.openathena"
1010
minSdk 28
1111
targetSdk 34
12-
versionCode 46
13-
versionName "0.23.0"
12+
versionCode 48
13+
versionName "0.24.0"
1414

1515
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1616
signingConfig signingConfigs.debug

app/src/main/java/com/openathena/MainActivity.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,13 @@ public void calculateImage(View view, boolean shouldISendCoT)
755755
if (exifFocalLength == null) exifFocalLength = "-1.0";
756756
attribs += "FocalLength : " + roundDouble(MetadataExtractor.rationalToFloat(exifFocalLength)) + "mm" + "\n";
757757
attribs += MetadataExtractor.getTagString(ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM, exif);
758-
attribs += MetadataExtractor.getTagString(ExifInterface.TAG_DIGITAL_ZOOM_RATIO, exif);
758+
attribs += "DigitalZoomRatio : " + MetadataExtractor.getDigitalZoomRatio(exif) + "\n";
759759
attribs += MetadataExtractor.getTagString(ExifInterface.TAG_IMAGE_WIDTH, exif);
760760
attribs += MetadataExtractor.getTagString(ExifInterface.TAG_IMAGE_LENGTH, exif);
761761
// yikes
762762
if (IS_EXTENDED_COT_MODE_ACTIVE) {
763763
openAthenaCalculationInfo.put("focalLength", roundDouble(MetadataExtractor.rationalToFloat(exifFocalLength)));
764-
openAthenaCalculationInfo.put("digitalZoomRatio", zeroStringIfNull(exif.getAttribute(ExifInterface.TAG_DIGITAL_ZOOM_RATIO)));
764+
openAthenaCalculationInfo.put("digitalZoomRatio", zeroStringIfNull(Float.toString(MetadataExtractor.getDigitalZoomRatio(exif))));
765765
openAthenaCalculationInfo.put("imageWidth", zeroStringIfNull(exif.getAttribute(ExifInterface.TAG_IMAGE_WIDTH)));
766766
openAthenaCalculationInfo.put("imageLength", zeroStringIfNull(exif.getAttribute(ExifInterface.TAG_IMAGE_LENGTH)));
767767
}

app/src/main/java/com/openathena/MetadataExtractor.java

Lines changed: 79 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,83 @@ public static double[] getIntrinsicMatrixFromExif(OpenAthenaExifInterface exif)
805805
}
806806
}
807807

808+
public static float getDigitalZoomRatio(OpenAthenaExifInterface exif) throws Exception {
809+
float digitalZoomRatio = 1.0f;
810+
811+
String make = exif.getAttribute(ExifInterface.TAG_MAKE);
812+
if (make == null) make = "";
813+
String model = exif.getAttribute(ExifInterface.TAG_MODEL);
814+
if (model == null) model = "";
815+
816+
JSONObject drone = getMatchingDrone(exif);
817+
818+
try {
819+
double[] pixelDimensions = new double[4];
820+
if (drone != null) {
821+
pixelDimensions[0] = (double) rationalToFloat(drone.getString("ccdWidthMMPerPixel"));
822+
pixelDimensions[1] = (double) rationalToFloat(drone.getString("ccdHeightMMPerPixel"));
823+
pixelDimensions[2] = (double) drone.getInt("widthPixels");
824+
pixelDimensions[3] = (double) drone.getInt("heightPixels");
825+
} else {
826+
// placeholder values which will never be used
827+
pixelDimensions[0] = -1.0d;
828+
pixelDimensions[1] = -1.0d;
829+
pixelDimensions[2] = -1.0d;
830+
pixelDimensions[3] = -1.0d;
831+
}
832+
String digitalZoomRational = exif.getAttribute(ExifInterface.TAG_DIGITAL_ZOOM_RATIO);
833+
if (digitalZoomRational != null && !digitalZoomRational.equals("")) {
834+
digitalZoomRatio = rationalToFloat(exif.getAttribute(ExifInterface.TAG_DIGITAL_ZOOM_RATIO));
835+
if (digitalZoomRatio < 1.0f) {
836+
digitalZoomRatio = 1.0f;
837+
}
838+
}
839+
840+
if (make.equalsIgnoreCase("PARROT")) {
841+
if (model.equalsIgnoreCase("ANAFI") || model.equalsIgnoreCase("ANAFIUSA") || model.equalsIgnoreCase("ANAFIUA")) {
842+
Log.d(TAG, "isThermal: " + isThermal(exif));
843+
if (!isThermal(exif)) {
844+
Log.d(TAG, "getDigitalZoomRatio special case for parrot triggered");
845+
if (drone == null) {
846+
throw new Exception("Could not find necessary data for Parrot Anafi");
847+
}
848+
double imageWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, -1);
849+
if (imageWidth <= 0.0d) {
850+
throw new Exception("Could not determine width of image");
851+
}
852+
// Parrot ANAFI and ANAFI USA do not report digital zoom correctly in EXIF DigitalZoomRatio tag
853+
// as a workaround, we will look at the pixel width of the image
854+
// and assume it is cropped if it is less than the full sensor size.
855+
// ALTHOUGH: If a Parrot image has been scaled down by external software this value will be completely wrong
856+
digitalZoomRatio = 5344.0f / (float) imageWidth;
857+
}
858+
}
859+
}
860+
if (digitalZoomRatio != 1.0f) {
861+
Log.d(TAG, "digitalZoomRatio is: " + digitalZoomRatio);
862+
// Some thermal cameras perform undocumented integer upscaling on digitally zoomed thermal images
863+
// (which seems to be atypical for images with digital zoom)
864+
// to compensate, we ignore the digitalZoomRatio when calculating
865+
// the number of pixels for width and height
866+
//
867+
// Known behavior for Autel Evo III 640T, (TODO) might affect other make/models and/or color cameras as well!
868+
if (isThermal(exif) && make.equalsIgnoreCase("AUTEL ROBOTICS")) {
869+
Log.d(TAG, "edge case detected: image had undocumented pixel upscaling. Ignoring digitalZoomRatio");
870+
digitalZoomRatio = 1.0f;
871+
}
872+
}
873+
} catch (JSONException jse) {
874+
if (make.equalsIgnoreCase("PARROT")) {
875+
if (model.equalsIgnoreCase("ANAFI") || model.equalsIgnoreCase("ANAFIUSA") || model.equalsIgnoreCase("ANAFIUA")) {
876+
if (!isThermal(exif)) {
877+
throw new Exception("Could not find necessary data for Parrot Anafi");
878+
}
879+
}
880+
}
881+
}
882+
return digitalZoomRatio;
883+
}
884+
808885
protected static double[] getIntrinsicMatrixFromKnownCCD(OpenAthenaExifInterface exif, double[] pixelDimensions) throws Exception {
809886
JSONObject drone = getMatchingDrone(exif);
810887

@@ -843,27 +920,7 @@ protected static double[] getIntrinsicMatrixFromKnownCCD(OpenAthenaExifInterface
843920
double ccdWidthPixels = pixelDimensions[2];
844921
double ccdHeightPixels = pixelDimensions[3];
845922

846-
String digitalZoomRational = exif.getAttribute(ExifInterface.TAG_DIGITAL_ZOOM_RATIO);
847-
float digitalZoomRatio = 1.0f;
848-
if (digitalZoomRational != null && !digitalZoomRational.equals("")) {
849-
digitalZoomRatio = rationalToFloat(exif.getAttribute(ExifInterface.TAG_DIGITAL_ZOOM_RATIO));
850-
if (digitalZoomRatio < 1.0f) {
851-
digitalZoomRatio = 1.0f;
852-
}
853-
}
854-
if (digitalZoomRatio != 1.0f) {
855-
Log.d(TAG, "digitalZoomRatio is: " + digitalZoomRatio);
856-
// Some thermal cameras perform undocumented integer upscaling on digitally zoomed thermal images
857-
// (which seems to be atypical for images with digital zoom)
858-
// to compensate, we ignore the digitalZoomRatio when calculating
859-
// the number of pixels for width and height
860-
//
861-
// Known behavior for Autel Evo III 640T, (TODO) might affect other make/models and/or color cameras as well!
862-
if (isThermal(exif) && exif.getAttribute(ExifInterface.TAG_MAKE).equalsIgnoreCase("AUTEL ROBOTICS")) {
863-
Log.d(TAG, "edge case detected: image had undocumented pixel upscaling. Ignoring digitalZoomRatio");
864-
digitalZoomRatio = 1.0f;
865-
}
866-
}
923+
float digitalZoomRatio = getDigitalZoomRatio(exif);
867924

868925
double imageWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, -1);
869926
double imageHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, -1); // Image Height
@@ -904,14 +961,7 @@ protected static double[] getIntrinsicMatrixFromExif35mm(OpenAthenaExifInterface
904961
throw new Exception(parent.getString(R.string.error_metadata_extractor_focal_length_could_not_be_determined));
905962
}
906963

907-
String digitalZoomRational = exif.getAttribute(ExifInterface.TAG_DIGITAL_ZOOM_RATIO);
908-
float digitalZoomRatio = 1.0f;
909-
if (digitalZoomRational != null && !digitalZoomRational.equals("")) {
910-
digitalZoomRatio = rationalToFloat(exif.getAttribute(ExifInterface.TAG_DIGITAL_ZOOM_RATIO));
911-
if (digitalZoomRatio < 1.0f) {
912-
digitalZoomRatio = 1.0f;
913-
}
914-
}
964+
float digitalZoomRatio = getDigitalZoomRatio(exif);
915965

916966
double imageWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
917967
double imageHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0); // Image Height

metadata/en-US/changelogs/48.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hotfix with significant accuracy improvement for zoomed images from the Parrot Anafi and Anafi USA.

0 commit comments

Comments
 (0)