diff --git a/src/Converter.php b/src/Converter.php index b42287a..4565205 100644 --- a/src/Converter.php +++ b/src/Converter.php @@ -2,11 +2,18 @@ namespace Biigle\Modules\MetadataIfdo; use Biigle\MediaType; +use Biigle\Services\MetadataParsing\Label; +use Biigle\Services\MetadataParsing\LabelAndUser; +use Biigle\Services\MetadataParsing\User; use Biigle\Services\MetadataParsing\VolumeMetadata; +use Biigle\Shape; +use Illuminate\Support\Arr; class Converter { private $acquisitionFormat = ''; + private $annotators = []; + private $labels = []; public function __construct($acquisitionFormat) { @@ -15,10 +22,13 @@ public function __construct($acquisitionFormat) public function convert($ifdo) { + $this->annotators = $this->extractIfdoAnnotators($ifdo->getImageSetHeader()['image-annotation-creators']); + $this->labels = $this->extractIfdoLabels($ifdo->getImageSetHeader()['image-annotation-labels']); + $data = new VolumeMetadata($this->mediaType()); foreach ($ifdo->getImageSetItems() as $name => $items) { - if ( ! is_array($items)) + if ( ! array_is_list($items)) { $items = [$items]; } @@ -39,12 +49,18 @@ public function convert($ifdo) if ( ! is_null($fileData = $data->getFile($name)) && ! is_null($takenAt)) { - $fileData->addFrame(...$params); + $fileData->addFrame(...Arr::except($params, ['name'])); } else { $class = $this->metadataClass(); $fileData = new $class(...$params); + + if (isset($item['image-annotations'])) + { + $this->addAnnotations($fileData, $item['image-annotations']); + } + $data->addFile($fileData); } @@ -62,6 +78,97 @@ protected function maybeCastToFloat(?string $value): ?float return (is_null($value) || $value === '') ? null : floatval($value); } + private function addAnnotations($fileData, $ifdoAnnotations) + { + foreach ($ifdoAnnotations as $ifdoAnnotation) + { + $fileData->addAnnotation($this->ifdoToBiigleAnnotation($ifdoAnnotation)); + } + } + + private function ifdoToBiigleAnnotation($ifdoAnnotation) + { + $class = $this->annotationClass(); + $params = [ + $this->ifdoShapeToBiigleShape($ifdoAnnotation['shape']), + $ifdoAnnotation['coordinates'], + $this->ifdoLabelsToBiigleLabelAndUsers($ifdoAnnotation['labels']), + ]; + + if (isset($ifdoAnnotation['frames'])) + { + $params[] = $ifdoAnnotation['frames']; + } + + $annotation = new $class(...$params); + + return $annotation; + } + + private function ifdoLabelsToBiigleLabelAndUsers($ifdoLabels) + { + return array_map([$this, 'ifdoLabelToBiigleLabelAndUser'], $ifdoLabels); + } + + private function ifdoLabelToBiigleLabelAndUser($ifdoLabel) + { + return new LabelAndUser( + $this->labelForId($ifdoLabel['label']), + $this->userForId($ifdoLabel['annotator']) + ); + } + + private function extractIfdoLabels($ifdoLabels) + { + $labels = []; + foreach ($ifdoLabels as $ifdoLabel) + { + $labels[$ifdoLabel['id']] = new Label($ifdoLabel['id'], $ifdoLabel['name']); + } + return $labels; + } + + private function extractIfdoAnnotators($ifdoAnnotators) + { + $annotators = []; + foreach ($ifdoAnnotators as $ifdoAnnotator) + { + $annotators[$ifdoAnnotator['id']] = new User($ifdoAnnotator['id'], $ifdoAnnotator['name']); + } + return $annotators; + } + + private function userForId($id) + { + return $this->annotators[$id]; + } + + private function labelForId($id) + { + return $this->labels[$id]; + } + + private function ifdoShapeToBiigleShape($shape) + { + switch ($shape) + { + case 'single-pixel': + return Shape::point(); + case 'polyline': + return Shape::line(); + case 'polygon': + return Shape::polygon(); + case 'circle': + return Shape::circle(); + case 'rectangle': + return Shape::rectangle(); + case 'ellipse': + return Shape::ellipse(); + case 'whole-frame': + return Shape::wholeFrame(); + } + } + private function mediaType() { switch ($this->acquisitionFormat) @@ -84,4 +191,14 @@ private function metadataClass() } } + private function annotationClass() + { + switch ($this->acquisitionFormat) + { + case 'photo': + return 'Biigle\Services\MetadataParsing\ImageAnnotation'; + case 'video': + return 'Biigle\Services\MetadataParsing\VideoAnnotation'; + } + } } diff --git a/src/MetadataIfdoServiceProvider.php b/src/MetadataIfdoServiceProvider.php index f4d1078..11c6074 100644 --- a/src/MetadataIfdoServiceProvider.php +++ b/src/MetadataIfdoServiceProvider.php @@ -18,7 +18,7 @@ public function boot(Modules $modules) $this->loadViewsFrom(__DIR__ . '/resources/views', 'metadata-ifdo'); ParserFactory::extend(IfdoParser::class, 'image'); - ParserFactory::extend(VideoIfdoParser::class, 'video'); + ParserFactory::extend(IfdoParser::class, 'video'); $modules->register('metadata-ifdo', [ 'viewMixins' => [ 'metadataParsers', diff --git a/src/VideoIfdoParser.php b/src/VideoIfdoParser.php deleted file mode 100644 index 3664497..0000000 --- a/src/VideoIfdoParser.php +++ /dev/null @@ -1,6 +0,0 @@ -assertEquals(2.1, $file->distanceToGround); $this->assertEquals(5.1, $file->area); $this->assertEquals(21, $file->yaw); + + $this->assertCount(7, $file->getAnnotations()); + $annotation = array_pop($file->annotations); + + $this->assertEquals(3, $annotation->shape->id); + $this->assertEquals('Hans Wurst', $annotation->labels[0]->user->name); + } + + public function testGetVideoMetadata() + { + $file = new File(__DIR__ . "/files/video-example-1.json"); + $parser = new IfdoParser($file); + $data = $parser->getMetadata(); + $this->assertEquals(MediaType::videoId(), $data->type->id); + $this->assertNull($data->name); + $this->assertNull($data->url); + $this->assertNull($data->handle); + $this->assertCount(1, $data->getFiles()); + $file = $data->getFiles()->last(); + $this->assertEquals('SO242_2_163-1_LowerHD.mp4', $file->name); + $this->assertEquals('2019-04-06 04:29:27.000000', $file->takenAt); + $this->assertEquals(-117.0214286, $file->lng); + $this->assertEquals(11.8582192, $file->lat); + $this->assertEquals(-4129.6, $file->gpsAltitude); + $this->assertEquals(2.1, $file->distanceToGround); + $this->assertEquals(5.1, $file->area); + $this->assertEquals(21, $file->yaw); + + // var_dump($file); } } diff --git a/tests/MetadataIfdoServiceProviderTest.php b/tests/MetadataIfdoServiceProviderTest.php index 1c8c390..6809b75 100644 --- a/tests/MetadataIfdoServiceProviderTest.php +++ b/tests/MetadataIfdoServiceProviderTest.php @@ -1,11 +1,11 @@ markTestIncomplete('implement metadata parser'); - $file = new File(__DIR__."/files/image-ifdo.json"); + $file = new File(__DIR__ . "/files/image-ifdo.json"); $parser = ParserFactory::getParserForFile($file, 'image'); $this->assertInstanceOf(ImageIfdoParser::class, $parser); } @@ -28,7 +28,7 @@ public function testGetVideoIfdo() { $this->markTestIncomplete('implement metadata parser'); - $file = new File(__DIR__."/files/video-ifdo.json"); + $file = new File(__DIR__ . "/files/video-ifdo.json"); $parser = ParserFactory::getParserForFile($file, 'video'); $this->assertInstanceOf(VideoIfdoParser::class, $parser); } diff --git a/tests/files/image-ifdo.json b/tests/files/image-ifdo.json index e1010a2..6abc626 100644 --- a/tests/files/image-ifdo.json +++ b/tests/files/image-ifdo.json @@ -83,6 +83,12 @@ "id": "4", "name": "Trash" } + ], + "image-annotation-creators": [ + { + "id": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "name": "Hans Wurst" + } ] }, "image-set-items": { @@ -94,138 +100,136 @@ "image-depth": 2248, "image-camera-yaw-degrees": 20 }, - "SO268-2_100-1_OFOS_SO_CAM-1_20190406_052726.JPG": [ - { - "image-datetime": "2019-04-06 05:27:26.000000", - "image-uuid": "884dcc58-3ade-4d47-af11-2701356206c0", - "image-hash-sha256": "cc877a4f71cbc24ce0859fe9449a862d5b65dd1ca8e741015626e15d4b292da9", - "image-handle": "https://example.com/884dcc58-3ade-4d47-af11-2701356206c0", - "image-altitude": -4129.6, - "image-latitude": 11.8582192, - "image-longitude": -117.0214286, - "image-area-square-meter": 5.1, - "image-meters-above-ground": 2.1, - "image-camera-yaw-degrees": 21, - "image-annotations": [ - { - "shape": "single-pixel", - "coordinates": [[ - 3632.34, - 1736.22 - ]], - "labels": [ - { - "label": "1", - "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", - "created-at": "2023-11-22T13:59:52.000000Z" - } - ] - }, - { - "shape": "single-pixel", - "coordinates": [[ - 2857.97, - 2182.47 - ]], - "labels": [ - { - "label": "2", - "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", - "created-at": "2023-11-22T13:59:53.000000Z" - } - ] - }, - { - "shape": "single-pixel", - "coordinates": [[ - 3645.47, - 2615.59 - ]], - "labels": [ - { - "label": "3", - "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", - "created-at": "2023-11-22T13:59:54.000000Z" - } - ] - }, - { - "shape": "rectangle", - "coordinates": [[ - 1251.9, - 1604.93, - 963.15, - 2031.5, - 1195.92, - 2189.07, - 1484.67, - 1762.5 - ]], - "labels": [ - { - "label": "4", - "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", - "created-at": "2023-11-22T13:59:59.000000Z" - } - ] - }, - { - "shape": "circle", - "coordinates": [[ - 2372.34, - 3160.28, - 220.11 - ]], - "labels": [ - { - "label": "1", - "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", - "created-at": "2023-11-22T14:00:02.000000Z" - } - ] - }, - { - "shape": "polyline", - "coordinates": [[ - 4268.91, - 3678.72, - 5207.34, - 3652.47, - 5443.59, - 2871.53 - ]], - "labels": [ - { - "label": "3", - "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", - "created-at": "2023-11-22T14:00:07.000000Z" - } - ] - }, - { - "shape": "polygon", - "coordinates": [[ - 4715.16, - 1552.47, - 5627.34, - 1703.41, - 5666.72, - 948.72, - 4918.59, - 699.34, - 4715.16, - 1552.47 - ]], - "labels": [ - { - "label": "4", - "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", - "created-at": "2023-11-22T14:00:14.000000Z" - } - ] - } - ] - } - ] + "SO268-2_100-1_OFOS_SO_CAM-1_20190406_052726.JPG": { + "image-datetime": "2019-04-06 05:27:26.000000", + "image-uuid": "884dcc58-3ade-4d47-af11-2701356206c0", + "image-hash-sha256": "cc877a4f71cbc24ce0859fe9449a862d5b65dd1ca8e741015626e15d4b292da9", + "image-handle": "https://example.com/884dcc58-3ade-4d47-af11-2701356206c0", + "image-altitude": -4129.6, + "image-latitude": 11.8582192, + "image-longitude": -117.0214286, + "image-area-square-meter": 5.1, + "image-meters-above-ground": 2.1, + "image-camera-yaw-degrees": 21, + "image-annotations": [ + { + "shape": "single-pixel", + "coordinates": [[ + 3632.34, + 1736.22 + ]], + "labels": [ + { + "label": "1", + "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "created-at": "2023-11-22T13:59:52.000000Z" + } + ] + }, + { + "shape": "single-pixel", + "coordinates": [[ + 2857.97, + 2182.47 + ]], + "labels": [ + { + "label": "2", + "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "created-at": "2023-11-22T13:59:53.000000Z" + } + ] + }, + { + "shape": "single-pixel", + "coordinates": [[ + 3645.47, + 2615.59 + ]], + "labels": [ + { + "label": "3", + "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "created-at": "2023-11-22T13:59:54.000000Z" + } + ] + }, + { + "shape": "rectangle", + "coordinates": [[ + 1251.9, + 1604.93, + 963.15, + 2031.5, + 1195.92, + 2189.07, + 1484.67, + 1762.5 + ]], + "labels": [ + { + "label": "4", + "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "created-at": "2023-11-22T13:59:59.000000Z" + } + ] + }, + { + "shape": "circle", + "coordinates": [[ + 2372.34, + 3160.28, + 220.11 + ]], + "labels": [ + { + "label": "1", + "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "created-at": "2023-11-22T14:00:02.000000Z" + } + ] + }, + { + "shape": "polyline", + "coordinates": [[ + 4268.91, + 3678.72, + 5207.34, + 3652.47, + 5443.59, + 2871.53 + ]], + "labels": [ + { + "label": "3", + "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "created-at": "2023-11-22T14:00:07.000000Z" + } + ] + }, + { + "shape": "polygon", + "coordinates": [[ + 4715.16, + 1552.47, + 5627.34, + 1703.41, + 5666.72, + 948.72, + 4918.59, + 699.34, + 4715.16, + 1552.47 + ]], + "labels": [ + { + "label": "4", + "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "created-at": "2023-11-22T14:00:14.000000Z" + } + ] + } + ] + } } } diff --git a/tests/files/video-example-1.json b/tests/files/video-example-1.json new file mode 100644 index 0000000..7855365 --- /dev/null +++ b/tests/files/video-example-1.json @@ -0,0 +1,1447 @@ +{ + "image-set-header": + { + "image-abstract": "Image Abstract", + "image-acquisition": "video", + "image-altitude-meters": -4094.5, + "image-annotation-creators": + [ + { + "id": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "name": "Timm Schoening" + } + ], + "image-annotation-labels": + [ + { + "id": "some-uuid", + "name": "Animal" + } + ], + "image-area-square-meter": 5, + "image-context": + { + "name": "Text Context", + "uri": "https://example.com" + }, + "image-coordinate-reference-system": "EPSG:4326", + "image-coordinate-uncertainty-meters": 4.74, + "image-copyright": "(c) GEOMAR Helmholtz Centre for Ocean Research Kiel. Contact: presse@geomar.de", + "image-datetime": "2019-04-06 04:29:27.000000", + "image-event": + { + "name": "SO268-1_21-1_OFOS", + "uri": "https://portal.geomar.de/metadata/event/show/1603320?leg=348623" + }, + "image-latitude": 11.8581802, + "image-license": + { + "name": "CC-BY", + "uri": "https://creativecommons.org/licenses/by/4.0/legalcode" + }, + "image-longitude": -117.0214864, + "image-meters-above-ground": 2, + "image-pi": + { + "name": "Timm Schoening", + "uri": "https://orcid.org/0000-0002-0035-3282" + }, + "image-platform": + { + "name": "SO_PFM-01_OFOS", + "uri": "https://dm.pages.geomar.de/equipment/equipment/SO/PFM/SO_PFM-1_OFOS_Isitec/" + }, + "image-project": + { + "name": "Test Project", + "uri": "https://doi.org/example" + }, + "image-sensor": + { + "name": "SO_CAM-1_Photo_OFOS", + "uri": "https://dm.pages.geomar.de/equipment/equipment/SO/CAM/SO_CAM-1_Photo_OFOS/" + }, + "image-set-data-handle": "20.500.12085/d7546c4b-307f-4d42-8554-33236c577450@data", + "image-set-handle": "https://hdl.handle.net/someHandle", + "image-set-ifdo-version": "v2.1.0", + "image-set-metadata-handle": "20.500.12085/d7546c4b-307f-4d42-8554-33236c577450@metadata", + "image-set-name": "SO268 SO268-2_100-1_OFOS SO_CAM-1_Photo_OFOS", + "image-set-uuid": "d7546c4b-307f-4d42-8554-33236c577450" + }, + "image-set-items": + { + "SO242_2_163-1_LowerHD.mp4": + [ + { + "image-altitude": -4129.6, + "image-annotations": + [ + { + "coordinates": + [ + [ + 681.7, + 521.44, + 99.17 + ], + [ + 681, + 521, + 99 + ], + [ + 684, + 516, + 97 + ], + [ + 681, + 511, + 97 + ], + [ + 684, + 506, + 97 + ], + [ + 686, + 501, + 95 + ], + [ + 690, + 496, + 97 + ], + [ + 692, + 491, + 99 + ], + [ + 694, + 485, + 97 + ], + [ + 697, + 480, + 99 + ], + [ + 698, + 474, + 99 + ], + [ + 699, + 469, + 99 + ], + [ + 697, + 464, + 97 + ], + [ + 693, + 459, + 99 + ], + [ + 688, + 455, + 99 + ], + [ + 683, + 452, + 97 + ], + [ + 677, + 450, + 97 + ], + [ + 672, + 447, + 97 + ], + [ + 666, + 444, + 99 + ], + [ + 660, + 440, + 95 + ], + [ + 655, + 436, + 97 + ], + [ + 650, + 431, + 99 + ], + [ + 646, + 427, + 97 + ], + [ + 642, + 423, + 97 + ], + [ + 638, + 419, + 97 + ], + [ + 634, + 415, + 97 + ], + [ + 631, + 410, + 97 + ], + [ + 629, + 405, + 97 + ], + [ + 634, + 403, + 97 + ], + [ + 639, + 405, + 97 + ], + [ + 643, + 410, + 95 + ], + [ + 645, + 415, + 97 + ], + [ + 649, + 420, + 97 + ], + [ + 653, + 425, + 97 + ], + [ + 656, + 431, + 97 + ], + [ + 657, + 436, + 97 + ], + [ + 657, + 442, + 95 + ], + [ + 656, + 447, + 95 + ], + [ + 653.5, + 452.5, + 93.5 + ], + [ + 649, + 456, + 95 + ], + [ + 644.5, + 458.5, + 91.5 + ], + [ + 639.5, + 459.5, + 93.5 + ], + [ + 634.5, + 455.5, + 89.5 + ], + [ + 630.5, + 451.5, + 89.5 + ], + [ + 628.5, + 446.5, + 89.5 + ], + [ + 628.5, + 440.5, + 89.5 + ], + [ + 629, + 435, + 88 + ], + [ + 631, + 430, + 88 + ], + [ + 633, + 425, + 86 + ], + [ + 636, + 420, + 86 + ], + [ + 639.5, + 415.5, + 84.5 + ], + [ + 641.5, + 410.5, + 84.5 + ], + [ + 644, + 406, + 86 + ], + [ + 638.5, + 404.5, + 89.5 + ], + [ + 632.5, + 405.5, + 91.5 + ], + [ + 626.5, + 405.5, + 91.5 + ], + [ + 621.5, + 406.5, + 93.5 + ], + [ + 615.5, + 406.5, + 93.5 + ], + [ + 610.5, + 409.5, + 93.5 + ], + [ + 607.5, + 414.5, + 93.5 + ], + [ + 603.5, + 418.5, + 91.5 + ], + [ + 601.5, + 423.5, + 91.5 + ], + [ + 600.5, + 428.5, + 93.5 + ], + [ + 599.5, + 433.5, + 93.5 + ], + [ + 598.5, + 438.5, + 93.5 + ], + [ + 598.5, + 444.5, + 93.5 + ], + [ + 593.5, + 443.5, + 93.5 + ], + [ + 589.5, + 439.5, + 93.5 + ], + [ + 585.5, + 435.5, + 93.5 + ], + [ + 580.5, + 431.5, + 93.5 + ], + [ + 577.5, + 425.5, + 93.5 + ], + [ + 573.5, + 420.5, + 93.5 + ], + [ + 571.5, + 415.5, + 93.5 + ], + [ + 569.5, + 410.5, + 93.5 + ], + [ + 568.5, + 405.5, + 93.5 + ], + [ + 569.5, + 400.5, + 93.5 + ], + [ + 574.5, + 397.5, + 91.5 + ], + [ + 576, + 403, + 95 + ], + [ + 577.5, + 408.5, + 93.5 + ], + [ + 575, + 413, + 95 + ], + [ + 571, + 418, + 95 + ], + [ + 567, + 422, + 95 + ], + [ + 561, + 424, + 95 + ], + [ + 555, + 424, + 95 + ], + [ + 549, + 424, + 95 + ], + [ + 543, + 424, + 97 + ], + [ + 539, + 420, + 97 + ], + [ + 538, + 415, + 97 + ], + [ + 540, + 410, + 97 + ], + [ + 538, + 405, + 99 + ], + [ + 533, + 404, + 97 + ], + [ + 528, + 401, + 97 + ], + [ + 525, + 396, + 97 + ], + [ + 521, + 390, + 97 + ], + [ + 518, + 385, + 97 + ], + [ + 515, + 380, + 97 + ], + [ + 516, + 375, + 97 + ], + [ + 511, + 374, + 97 + ], + [ + 506, + 375, + 97 + ], + [ + 501, + 376, + 97 + ], + [ + 495, + 375, + 97 + ], + [ + 489, + 375, + 95 + ], + [ + 483, + 375, + 97 + ], + [ + 478, + 376, + 97 + ], + [ + 473, + 377, + 95 + ], + [ + 478, + 375, + 95 + ], + [ + 481, + 370, + 95 + ], + [ + 479.5, + 364.5, + 93.5 + ], + [ + 475, + 361, + 95 + ], + [ + 472.5, + 355.5, + 93.5 + ], + [ + 468.5, + 350.5, + 93.5 + ], + [ + 466.5, + 345.5, + 93.5 + ], + [ + 461.5, + 342.5, + 93.5 + ], + [ + 456.5, + 340.5, + 93.5 + ], + [ + 451.5, + 339.5, + 93.5 + ], + [ + 446.5, + 340.5, + 93.5 + ], + [ + 441.5, + 339.5, + 93.5 + ], + [ + 436, + 340, + 95 + ], + [ + 430, + 341, + 95 + ], + [ + 425, + 345, + 95 + ], + [ + 420.5, + 349.5, + 93.5 + ], + [ + 416.5, + 354.5, + 93.5 + ], + [ + 413.5, + 360.5, + 91.5 + ], + [ + 413.5, + 367.5, + 91.5 + ], + [ + 413.5, + 373.5, + 91.5 + ], + [ + 414.5, + 378.5, + 89.5 + ], + [ + 417.5, + 384.5, + 89.5 + ], + [ + 421.5, + 390.5, + 89.5 + ], + [ + 421.5, + 396.5, + 89.5 + ], + [ + 416.5, + 400.5, + 89.5 + ], + [ + 411.5, + 402.5, + 89.5 + ], + [ + 409.5, + 396.5, + 89.5 + ], + [ + 411, + 390, + 88 + ], + [ + 412, + 384, + 88 + ], + [ + 411, + 378, + 88 + ], + [ + 412, + 369, + 86 + ], + [ + 410.5, + 361.5, + 84.5 + ], + [ + 411.5, + 354.5, + 84.5 + ], + [ + 409, + 346, + 86 + ], + [ + 408, + 340, + 86 + ], + [ + 408, + 328, + 86 + ], + [ + 406, + 320, + 86 + ], + [ + 404, + 314, + 86 + ], + [ + 404, + 306, + 86 + ], + [ + 402.5, + 296.5, + 84.5 + ], + [ + 401.5, + 288.5, + 84.5 + ], + [ + 399, + 279, + 83 + ], + [ + 399, + 271, + 83 + ], + [ + 398, + 261, + 83 + ], + [ + 395, + 251, + 83 + ], + [ + 393, + 244, + 83 + ], + [ + 391, + 233, + 83 + ], + [ + 388, + 224, + 83 + ], + [ + 385, + 214, + 83 + ], + [ + 382, + 206, + 83 + ], + [ + 379.5, + 197.5, + 84.5 + ], + [ + 375.5, + 188.5, + 84.5 + ], + [ + 372.5, + 181.5, + 84.5 + ], + [ + 370, + 174, + 86 + ], + [ + 366, + 166, + 86 + ], + [ + 362, + 158, + 86 + ], + [ + 358, + 149, + 86 + ], + [ + 355, + 141, + 86 + ], + [ + 351, + 133, + 86 + ], + [ + 347, + 125, + 86 + ], + [ + 343, + 118, + 86 + ], + [ + 339, + 110, + 86 + ], + [ + 335, + 104, + 86 + ], + [ + 330.5, + 96.5, + 84.5 + ], + [ + 327.5, + 91.5, + 84.5 + ], + [ + 323.5, + 86.5, + 84.5 + ], + [ + 318.5, + 82.5, + 84.5 + ], + [ + 315.5, + 77.5, + 84.5 + ], + [ + 311, + 74, + 86 + ], + [ + 306, + 69, + 86 + ], + [ + 299, + 64, + 86 + ], + [ + 294, + 61, + 86 + ], + [ + 286.5, + 57.5, + 84.5 + ], + [ + 279.5, + 54.5, + 84.5 + ], + [ + 270.5, + 51.5, + 84.5 + ], + [ + 263.5, + 50.5, + 84.5 + ], + [ + 254.5, + 50.5, + 84.5 + ], + [ + 246.5, + 51.5, + 84.5 + ], + [ + 239.5, + 54.5, + 84.5 + ], + [ + 229.5, + 55.5, + 84.5 + ], + [ + 221.5, + 59.5, + 84.5 + ], + [ + 217, + 62, + 86 + ], + [ + 208, + 67, + 86 + ], + [ + 201, + 74, + 88 + ], + [ + 196, + 79, + 88 + ], + [ + 188, + 89, + 88 + ], + [ + 185, + 94, + 88 + ], + [ + 180, + 99, + 88 + ], + [ + 176, + 105, + 88 + ], + [ + 170.5, + 111.5, + 89.5 + ], + [ + 166.5, + 116.5, + 89.5 + ], + [ + 161.5, + 123.5, + 89.5 + ], + [ + 156.5, + 129.5, + 89.5 + ], + [ + 153.5, + 136.5, + 89.5 + ], + [ + 148.5, + 143.5, + 89.5 + ], + [ + 143.5, + 150.5, + 89.5 + ], + [ + 138.5, + 157.5, + 89.5 + ], + [ + 133.5, + 163.5, + 89.5 + ], + [ + 130.5, + 171.5, + 89.5 + ], + [ + 123.5, + 178.5, + 89.5 + ], + [ + 118.5, + 187.5, + 89.5 + ], + [ + 114.5, + 193.5, + 89.5 + ], + [ + 110.5, + 202.5, + 91.5 + ], + [ + 104.5, + 210.5, + 91.5 + ], + [ + 100.5, + 219.5, + 91.5 + ], + [ + 95.5, + 228.5, + 91.5 + ], + [ + 89.5, + 237.5, + 89.5 + ], + [ + 85, + 246, + 88 + ], + [ + 80, + 255, + 86 + ], + [ + 74.5, + 264.5, + 84.5 + ], + [ + 67.5, + 273.5, + 84.5 + ], + [ + 61, + 284, + 83 + ], + [ + 56, + 294, + 83 + ], + [ + 48, + 304, + 83 + ], + [ + 40, + 314, + 83 + ], + [ + 28, + 324, + 83 + ], + [ + 16, + 329, + 83 + ] + ], + "frames": + [ + 0.402947, + 0.48, + 1, + 1.32, + 1.64, + 1.84, + 2.04, + 2.24, + 2.4, + 2.6, + 2.8, + 3.04, + 3.36, + 3.64, + 3.84, + 4.04, + 4.16, + 4.28, + 4.4, + 4.52, + 4.64, + 4.76, + 4.88, + 5, + 5.12, + 5.28, + 5.44, + 5.68, + 6.08, + 6.36, + 6.64, + 6.84, + 7.04, + 7.24, + 7.48, + 7.64, + 7.88, + 8.08, + 8.32, + 8.52, + 8.72, + 9, + 9.24, + 9.52, + 9.72, + 9.92, + 10.12, + 10.32, + 10.48, + 10.72, + 10.92, + 11.16, + 11.36, + 12.44, + 12.76, + 13.04, + 13.28, + 13.52, + 13.88, + 14.36, + 14.8, + 15.08, + 15.36, + 15.6, + 15.92, + 16.32, + 16.88, + 17.16, + 17.4, + 17.6, + 17.8, + 18, + 18.16, + 18.36, + 18.56, + 18.8, + 19.44, + 19.8, + 20.04, + 20.28, + 20.56, + 20.8, + 21, + 21.2, + 21.4, + 21.76, + 22.24, + 22.6, + 23.12, + 24.2, + 24.64, + 25, + 25.28, + 25.52, + 25.72, + 26.04, + 26.4, + 28.12, + 28.36, + 28.6, + 28.8, + 29.04, + 29.32, + 29.64, + 30.08, + 31.24, + 31.64, + 32.48, + 32.84, + 33.32, + 33.64, + 34.04, + 34.68, + 35.48, + 35.8, + 36, + 36.2, + 36.4, + 36.6, + 36.8, + 37, + 37.24, + 37.52, + 37.84, + 38.08, + 38.32, + 38.48, + 38.68, + 38.88, + 39, + 39.16, + 39.48, + 39.6, + 39.68, + 39.76, + 39.84, + 39.92, + 39.96, + 40.04, + 40.08, + 40.16, + 40.2, + 40.24, + 40.28, + 40.32, + 40.36, + 40.4, + 40.44, + 40.48, + 40.52, + 40.56, + 40.6, + 40.64, + 40.68, + 40.72, + 40.76, + 40.8, + 40.84, + 40.88, + 40.92, + 40.96, + 41, + 41.04, + 41.08, + 41.12, + 41.16, + 41.2, + 41.24, + 41.28, + 41.32, + 41.36, + 41.4, + 41.44, + 41.48, + 41.52, + 41.6, + 41.64, + 41.72, + 41.8, + 41.88, + 41.96, + 42.04, + 42.12, + 42.2, + 42.28, + 42.36, + 42.4, + 42.48, + 42.56, + 42.6, + 42.68, + 42.72, + 42.76, + 42.8, + 42.84, + 42.88, + 42.92, + 42.96, + 43, + 43.04, + 43.08, + 43.12, + 43.16, + 43.2, + 43.24, + 43.28, + 43.32, + 43.36, + 43.4, + 43.44, + 43.48, + 43.52, + 43.56, + 43.6, + 43.64, + 43.68, + 43.72, + 43.76, + 43.8, + 43.84, + 43.88, + 43.92 + ], + "labels": + [ + { + "annotator": "4b6f42ff-6198-4b52-aa1c-fde5aa50265b", + "created-at": "2023-11-22T14:02:18.000000Z", + "label": "some-uuid" + } + ], + "shape": "circle" + } + ], + "image-area-square-meter": 5.1, + "image-camera-yaw-degrees": 21, + "image-datetime": "2019-04-06 04:29:27.000000", + "image-latitude": 11.8582192, + "image-longitude": -117.0214286, + "image-meters-above-ground": 2.1 + }, + { + "image-altitude": -4129.6, + "image-area-square-meter": 5.1, + "image-camera-yaw-degrees": 21, + "image-datetime": "2019-04-06 04:30:27.000000", + "image-latitude": 11.8582192, + "image-longitude": -117.0214286, + "image-meters-above-ground": 2.1 + } + ] + } +}