Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flat label list tab #194

Open
wants to merge 67 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
bc09ec8
Import annotationsTab.vue
lehecht Oct 18, 2024
028e453
Add image annotation controller method
lehecht Oct 29, 2024
4a61ad7
Add largo annotationsTab component
lehecht Oct 29, 2024
2f61053
Return shapes to view
lehecht Oct 29, 2024
ea27e63
WIP: Add annotation tab functions
lehecht Oct 29, 2024
6790d4c
Make annotation selectable
lehecht Oct 30, 2024
3cc64b8
Display selected image annotation
lehecht Oct 30, 2024
030064f
Add get method in videoAnnotation controller
lehecht Oct 30, 2024
0cee1a2
Display video and image annotations
lehecht Oct 30, 2024
7dadcf1
Revert "Return shapes to view"
lehecht Oct 30, 2024
f60bd5a
Fix flat label view
lehecht Oct 30, 2024
3d7d7c3
Enable label (de)selection
lehecht Nov 4, 2024
0ec4881
Apply smaller changes
lehecht Nov 4, 2024
727062f
Remove comments and unsued parameter
lehecht Nov 4, 2024
4a616f5
Stream volume's annotation label data
lehecht Nov 11, 2024
b86e455
Change controller names
lehecht Nov 11, 2024
858a050
WIP: Process annotation stream
lehecht Nov 11, 2024
1405f82
Rename annotationLabel to label
lehecht Nov 12, 2024
633cc99
Rename api methods
lehecht Nov 12, 2024
ecde488
Process annotation labels to reuse them later
lehecht Nov 12, 2024
397b671
Update object key
lehecht Nov 12, 2024
250011a
Change comments
lehecht Nov 12, 2024
6d8ab24
Simplify code
lehecht Nov 12, 2024
0f3d8c0
Fix lint error
lehecht Nov 12, 2024
4e5aa86
Move controller classes
lehecht Nov 13, 2024
0332b2f
Check selection status by using method
lehecht Nov 13, 2024
b6c91ab
Split methods
lehecht Nov 15, 2024
261f210
Add flat label tab for whole project
lehecht Nov 15, 2024
fe92f69
Add controller methods to get all labels used in project
lehecht Nov 15, 2024
39571eb
Improve memory usage in controller methods
lehecht Nov 20, 2024
0643194
Update response parsing
lehecht Nov 20, 2024
83579a1
Fix missing merge of image and video labels
lehecht Nov 20, 2024
b53e9bd
Remove log
lehecht Nov 20, 2024
3002ba7
Add tests for project's annotation labels
lehecht Nov 21, 2024
5ab8c18
Add tests for volume's annotation labels
lehecht Nov 21, 2024
b1b2538
Add php doc
lehecht Nov 21, 2024
fd52b3a
Simplify counting annotations
lehecht Nov 21, 2024
31acc63
WIP: Fix label count after relabeling
lehecht Nov 22, 2024
dbda54c
WIP: Fix label count after deleting annotations
lehecht Nov 25, 2024
d11d1a7
Disable flat label tab when relabeling
lehecht Nov 25, 2024
e215645
Fix label count after relabeling or deletion
lehecht Nov 25, 2024
3b85ba5
Revert unnecessary changes
lehecht Nov 27, 2024
2f3fce5
Revert changes
lehecht Nov 28, 2024
56c138a
Improve code consistency
lehecht Nov 28, 2024
65e5998
Fix not updating badge count
lehecht Nov 28, 2024
acc4443
Rename variables for better understanding
lehecht Nov 28, 2024
6196f05
Hide label selection message when loading
lehecht Nov 28, 2024
b39ac4e
Change comment
lehecht Nov 28, 2024
3bd68b1
Process annotation label only once
lehecht Nov 29, 2024
1631acd
Synchronize label selection in tabs
lehecht Dec 2, 2024
10957d4
Add label_tree_id to response
lehecht Dec 2, 2024
3ffa2f4
Update tests
lehecht Dec 2, 2024
5a3f2df
Add comments
lehecht Dec 2, 2024
1673447
Return only ids but not whole labels
lehecht Dec 3, 2024
2d6ef8f
Use labels from labeltrees
lehecht Dec 3, 2024
0f1c5b0
Rename methods
lehecht Dec 3, 2024
e5310a5
Save image and video annotations in projectLargoContainer
lehecht Dec 3, 2024
a8c1d79
Update tests
lehecht Dec 3, 2024
7218317
Commit npm run prod
lehecht Dec 3, 2024
0b97310
Fix wrong annotation badge count
lehecht Dec 3, 2024
5ee59c1
Remove label if no annotation exists in annotation tab
lehecht Dec 3, 2024
fb190a8
Add new label during relabeing
lehecht Dec 4, 2024
4d359aa
Fix lint error
lehecht Dec 4, 2024
98c171b
Remove unused import
lehecht Dec 4, 2024
3d24254
Smaller changes
lehecht Dec 4, 2024
093aafd
Update api doc
lehecht Dec 4, 2024
d2b0aac
Commit npm run prod
lehecht Dec 4, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace Biigle\Modules\Largo\Http\Controllers\Api\Projects;

use Biigle\Http\Controllers\Api\Controller;
use Biigle\ImageAnnotation;
use Generator;
use Biigle\Project;
use Biigle\ImageAnnotation;
use Illuminate\Http\Request;
use Biigle\Http\Controllers\Api\Controller;
use Symfony\Component\HttpFoundation\StreamedJsonResponse;

class FilterImageAnnotationsByLabelController extends Controller
{
Expand Down Expand Up @@ -49,4 +51,57 @@ public function index(Request $request, $pid, $lid)
->orderBy('image_annotations.id', 'desc')
->pluck('images.uuid', 'image_annotations.id');
}

/**
* Get all image annotations with uuids for a given project
*
* @api {get}
* @apiGroup Projects
* @apiName test
* @apiParam {Number} id The Project ID
* @apiPermission user
* @apiDescription Returns a stream containing the image uuids and ids of annotations, labels and label trees
*
* @apiSuccessExample {json} Success response:
* [{
* "uuid":"9198ea9c-ef97-4af7-8018-407d16eafb65",
* "annotation_id":41,
* "label_id":14,
* "label_tree_id":123
* }]
*
*
* @param int $id Project ID
* @return \Symfony\Component\HttpFoundation\StreamedJsonResponse
*/
public function getProjectsAnnotationLabels($id)
{
$project = Project::findOrFail($id);
$this->authorize('access', $project);

$annotations = $project->imageVolumes()
->join('images', 'volumes.id', '=', 'images.volume_id')
->join('image_annotations', 'images.id', '=', 'image_annotations.image_id')
->join('image_annotation_labels', 'image_annotations.id', '=', 'image_annotation_labels.annotation_id')
->join('labels', 'image_annotation_labels.label_id', '=', 'labels.id')
->select(
'images.uuid',
'image_annotations.id as annotation_id',
'image_annotation_labels.label_id',
'labels.label_tree_id'
);

$res = function () use ($annotations): Generator {
foreach ($annotations->lazy() as $a) {
yield [
'uuid' => $a->uuid,
'annotation_id' => $a->annotation_id,
'label_id' => $a->label_id,
'label_tree_id' => $a->label_tree_id
];
}
};

return new StreamedJsonResponse($res());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace Biigle\Modules\Largo\Http\Controllers\Api\Projects;

use Biigle\Http\Controllers\Api\Controller;
use Generator;
use Biigle\Project;
use Biigle\VideoAnnotation;
use Illuminate\Http\Request;
use Biigle\Http\Controllers\Api\Controller;
use Symfony\Component\HttpFoundation\StreamedJsonResponse;

class FilterVideoAnnotationsByLabelController extends Controller
{
Expand Down Expand Up @@ -49,4 +51,57 @@ public function index(Request $request, $pid, $lid)
->orderBy('video_annotations.id', 'desc')
->pluck('videos.uuid', 'video_annotations.id');
}

/**
* Get all video annotations with uuids for a given project
*
* @api {get}
* @apiGroup Projects
* @apiName test
* @apiParam {Number} id The Project ID
* @apiPermission user
* @apiDescription Returns a stream containing the video uuids and ids of annotations, labels and label trees
*
* @apiSuccessExample {json} Success response:
* [{
* "uuid":"9198ea9c-ef97-4af7-8018-407d16eafb65",
* "annotation_id":41,
* "label_id":14,
* "label_tree_id":123
* }]
*
*
* @param int $id Project ID
* @return \Symfony\Component\HttpFoundation\StreamedJsonResponse
*/
public function getProjectsAnnotationLabels($id)
{
$project = Project::findOrFail($id);
$this->authorize('access', $project);

$annotations = $project->videoVolumes()
->join('videos', 'volumes.id', '=', 'videos.volume_id')
->join('video_annotations', 'videos.id', '=', 'video_annotations.video_id')
->join('video_annotation_labels', 'video_annotations.id', '=', 'video_annotation_labels.annotation_id')
->join('labels', 'video_annotation_labels.label_id', '=', 'labels.id')
->select(
'videos.uuid',
'video_annotations.id as annotation_id',
'video_annotation_labels.label_id',
'labels.label_tree_id'
);

$res = function () use ($annotations): Generator {
foreach ($annotations->lazy() as $a) {
yield [
'uuid' => $a->uuid,
'annotation_id' => $a->annotation_id,
'label_id' => $a->label_id,
'label_tree_id' => $a->label_tree_id
];
}
};

return new StreamedJsonResponse($res());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace Biigle\Modules\Largo\Http\Controllers\Api\Volumes;

use Biigle\Http\Controllers\Api\Controller;
use Biigle\ImageAnnotation;
use Generator;
use Biigle\Volume;
use Biigle\ImageAnnotation;
use Illuminate\Http\Request;
use Biigle\Http\Controllers\Api\Controller;
use Symfony\Component\HttpFoundation\StreamedJsonResponse;

class FilterImageAnnotationsByLabelController extends Controller
{
Expand Down Expand Up @@ -58,4 +60,55 @@ public function index(Request $request, $vid, $lid)
->orderBy('image_annotations.id', 'desc')
->pluck('images.uuid', 'image_annotations.id');
}

/**
* Get all image annotations with uuids for a given volume
*
* @api {get}
* @apiGroup Volumes
* @apiName test
* @apiParam {Number} id The Volume ID
* @apiPermission user
* @apiDescription Returns a stream containing the image uuids and ids of annotations, labels and label trees
*
* @apiSuccessExample {json} Success response:
* [{
* "uuid":"9198ea9c-ef97-4af7-8018-407d16eafb65",
* "annotation_id":41,
* "label_id":14,
* "label_tree_id":123
* }]
*
* @param int $id Volume ID
* @return \Symfony\Component\HttpFoundation\StreamedJsonResponse
*/
public function getVolumeAnnotationLabels($id)
{
$volume = Volume::findOrFail($id);
$this->authorize('access', $volume);

$annotations = $volume->images()
->join('image_annotations', 'images.id', '=', 'image_annotations.image_id')
->join('image_annotation_labels', 'image_annotations.id', '=', 'image_annotation_labels.annotation_id')
->join('labels', 'image_annotation_labels.label_id', '=', 'labels.id')
->select(
'images.uuid',
'image_annotations.id as annotation_id',
'image_annotation_labels.label_id',
'labels.label_tree_id'
);

$res = function () use ($annotations): Generator {
foreach ($annotations->lazy() as $a) {
yield [
'uuid' => $a->uuid,
'annotation_id' => $a->annotation_id,
'label_id' => $a->label_id,
'label_tree_id' => $a->label_tree_id
];
}
};

return new StreamedJsonResponse($res());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace Biigle\Modules\Largo\Http\Controllers\Api\Volumes;

use Biigle\Http\Controllers\Api\Controller;
use Biigle\VideoAnnotation;
use Generator;
use Biigle\Volume;
use Biigle\VideoAnnotation;
use Illuminate\Http\Request;
use Biigle\Http\Controllers\Api\Controller;
use Symfony\Component\HttpFoundation\StreamedJsonResponse;

class FilterVideoAnnotationsByLabelController extends Controller
{
Expand Down Expand Up @@ -58,4 +60,56 @@ public function index(Request $request, $vid, $lid)
->orderBy('video_annotations.id', 'desc')
->pluck('videos.uuid', 'video_annotations.id');
}

/**
* Get all video annotations with uuids for a given volume
*
* @api {get}
* @apiGroup Volumes
* @apiName test
* @apiParam {Number} id The Volume ID
* @apiPermission user
* @apiDescription Returns a stream containing the video uuids and ids of annotations, labels and label trees
*
* @apiSuccessExample {json} Success response:
* [{
* "uuid":"9198ea9c-ef97-4af7-8018-407d16eafb65",
* "annotation_id":41,
* "label_id":14,
* "label_tree_id":123
* }]
*
*
* @param int $id Volume ID
* @return \Symfony\Component\HttpFoundation\StreamedJsonResponse
*/
public function getVolumeAnnotationLabels($id)
{
$volume = Volume::findOrFail($id);
$this->authorize('access', $volume);

$annotations = $volume->videos()
->join('video_annotations', 'videos.id', '=', 'video_annotations.video_id')
->join('video_annotation_labels', 'video_annotations.id', '=', 'video_annotation_labels.annotation_id')
->join('labels', 'video_annotation_labels.label_id', '=', 'labels.id')
->select(
'videos.uuid',
'video_annotations.id as annotation_id',
'video_annotation_labels.label_id',
'labels.label_tree_id'
);

$res = function () use ($annotations): Generator {
foreach ($annotations->lazy() as $a) {
yield [
'uuid' => $a->uuid,
'annotation_id' => $a->annotation_id,
'label_id' => $a->label_id,
'label_tree_id' => $a->label_tree_id
];
}
};

return new StreamedJsonResponse($res());
}
}
16 changes: 16 additions & 0 deletions src/Http/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@
'uses' => 'Projects\FilterVideoAnnotationsByLabelController@index',
]);

$router->get('projects/{id}/image-annotations', [
'uses' => 'Projects\FilterImageAnnotationsByLabelController@getProjectsAnnotationLabels',
]);

$router->get('projects/{id}/video-annotations', [
'uses' => 'Projects\FilterVideoAnnotationsByLabelController@getProjectsAnnotationLabels',
]);

$router->get('volumes/{id}/annotations/sort/outliers/{id2}', [
'uses' => 'Volumes\SortAnnotationsByOutliersController@index',
]);
Expand All @@ -76,4 +84,12 @@
$router->get('volumes/{id}/video-annotations/filter/label/{id2}', [
'uses' => 'Volumes\FilterVideoAnnotationsByLabelController@index',
]);

$router->get('volume/{id}/image-annotations', [
'uses' => 'Volumes\FilterImageAnnotationsByLabelController@getVolumeAnnotationLabels'
]);

$router->get('volume/{id}/video-annotations', [
'uses' => 'Volumes\FilterVideoAnnotationsByLabelController@getVolumeAnnotationLabels'
]);
});
2 changes: 1 addition & 1 deletion src/public/assets/scripts/main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"/assets/scripts/main.js": "/assets/scripts/main.js?id=ed8d9b904adadcdce546b7b39d73ef4c",
"/assets/scripts/main.js": "/assets/scripts/main.js?id=c9d6f3c26bf3c9e235d9da85fcf25260",
"/assets/styles/main.css": "/assets/styles/main.css?id=68a88f330c08af97df1d47c207ea8ccb"
}
8 changes: 8 additions & 0 deletions src/resources/assets/js/api/labels.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ export default Vue.resource('api/v1/labels{/id}', {}, {
method: 'GET',
url: 'api/v1/labels{/id}/video-annotations',
},
fetchImageVolumeAnnotations: {
method: 'GET',
url: 'api/v1/volume{/id}/image-annotations',
},
fetchVideoVolumeAnnotations: {
method: 'GET',
url: 'api/v1/volume{/id}/video-annotations',
}
});
8 changes: 8 additions & 0 deletions src/resources/assets/js/api/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@ export default Vue.resource('api/v1/projects{/id}/largo', {}, {
method: 'GET',
url: 'api/v1/projects{/id}/annotations/sort/similarity',
},
getAllProjectsImageAnnotationLabels: {
method: 'GET',
url: 'api/v1/projects{/id}/image-annotations'
},
getAllProjectsVideoAnnotationLabels: {
method: 'GET',
url: 'api/v1/projects{/id}/video-annotations'
}
});
Loading
Loading