HEIC-Fotos annehmen und den Ausschnitt weiter fassen

iPhones fotografieren HEIC; ohne pillow-heif wies die Bildpruefung jedes
Foto ab. Dazu: ein erkannter Vogel ohne bestimmbare Art wird nicht mehr als
"kein Vogel" gemeldet, und der Ausschnitt fuer die Sammlung ist quadratisch.
This commit is contained in:
christian committed 2026-10-14 18:16:08 +00:00
1 parent dbec78aa7a
commit f572c20080
9 files changed
+285 -8

No files matched your search

+63
View File
@@ -579,3 +579,66 @@ class AbzeichenTests(AppTestBasis):
self.assertLessEqual(z["ist"], z["ziel"])
class VogelOhneArtTests(AppTestBasis):
"""🔴 „Vogel ja, Art nein" darf nicht als „kein Vogel" ankommen.
Am 14.10.2026 erkannte der Detektor auf einem Handyfoto mit 93 % einen
Vogel, konnte die Art aber nicht bestimmen (Gegenlicht, Silhouette). In
der App stand „Kein Vogel erkannt. Auf dem Foto war nichts zu finden" —
und Christian hat daraufhin zugeschnitten, gegen ein Problem, das nie der
Zuschnitt war. Eine falsche Auskunft ist teurer als gar keine.
"""
def setUp(self):
super().setUp()
self.kamera = make_camera(token="kamera-geheim", mobil=True)
def _wartendes_foto(self):
jetzt = timezone.now()
s = Sighting.objects.create(
camera=self.kamera, started_at=jetzt, ended_at=jetzt,
frames_total=1, wartet_auf_bestimmung=True,
)
return s
def melde(self, s, nutzlast):
return self.client.post(
f"/api/offen/{s.id}/",
{"data": json.dumps(nutzlast)},
HTTP_AUTHORIZATION="Bearer kamera-geheim",
)
def test_vogel_ohne_art_behaelt_seinen_vogelwert(self):
s = self._wartendes_foto()
resp = self.melde(s, {"species": None, "confidence": 0.0,
"mean_bird_score": 0.93})
self.assertEqual(resp.status_code, 200, resp.content)
daten = self.json(f"/api/app/sichtungen/{s.id}/")
self.assertFalse(daten["wartet"])
self.assertIsNone(daten["art"])
# Das ist der Unterschied, an dem die App ihren Text waehlt.
self.assertAlmostEqual(daten["vogelwert"], 0.93, places=3)
def test_wirklich_kein_vogel_bleibt_bei_null(self):
s = self._wartendes_foto()
self.melde(s, {"species": None, "confidence": 0.0, "mean_bird_score": 0.0})
daten = self.json(f"/api/app/sichtungen/{s.id}/")
self.assertIsNone(daten["art"])
self.assertEqual(daten["vogelwert"], 0.0)
def test_vogel_ohne_art_zaehlt_als_bild_mit_vogel(self):
"""``frames_with_bird`` hing an der ART statt am Vogel."""
s = self._wartendes_foto()
self.melde(s, {"species": None, "mean_bird_score": 0.93})
s.refresh_from_db()
self.assertEqual(s.frames_with_bird, 1)
def test_ohne_vogel_kein_bild_mit_vogel(self):
s = self._wartendes_foto()
self.melde(s, {"species": None, "mean_bird_score": 0.0})
s.refresh_from_db()
self.assertEqual(s.frames_with_bird, 0)