Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
19 changes: 0 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,6 @@ This module is already included in [`biigle/biigle`](https://github.com/biigle/b
2. Add `Biigle\Modules\Laserpoints\LaserpointsServiceProvider::class` to the `providers` array in `config/app.php`.
3. Run `php artisan vendor:publish --tag=public` to publish the public assets of this module.
4. Run `pip install -r vendor/biigle/laserpoints/requirements.txt` to install the Python requirements.
5. Configure a storage disk for the temporary laserpoints files `LASERPOINTS_DISK` variable to the name of this storage disk in the `.env` file. Example for a local disk:
```php
'laserpoints' => [
'driver' => 'local',
'root' => storage_path('framework/cache/laserpoints'),
],
```

## References

Reference publications that you should cite if you use the laser point detection for one of your studies.

- **BIIGLE 2.0**
[Langenkämper, D., Zurowietz, M., Schoening, T., & Nattkemper, T. W. (2017). Biigle 2.0-browsing and annotating large marine image collections.](https://doi.org/10.3389/fmars.2017.00083)
Frontiers in Marine Science, 4, 83. doi: `10.3389/fmars.2017.00083`

- **Laser Point Detection**
[Schoening, T., Kuhn, T., Bergmann, M., & Nattkemper, T. W. (2015). DELPHI—fast and adaptive computational laser point detection and visual footprint quantification for arbitrary underwater image collections.](https://doi.org/10.3389/fmars.2015.00020)
Frontiers in Marine Science, 2, 20. doi: `10.3389/fmars.2015.00020`

## Developing

Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
numpy==1.22.0
scipy==1.10.0
Pillow==10.3.0
numpy==2.1.*
scipy==1.13.*
opencv-contrib-python-headless==4.11.0.*
36 changes: 0 additions & 36 deletions src/Console/Commands/Config.php

This file was deleted.

37 changes: 0 additions & 37 deletions src/Console/Commands/Publish.php

This file was deleted.

174 changes: 136 additions & 38 deletions src/Http/Controllers/Api/LaserpointsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,96 +4,194 @@

use Biigle\Http\Controllers\Api\Controller;
use Biigle\Label;
use Biigle\Modules\Laserpoints\Http\Requests\ComputeImage;
use Biigle\Modules\Laserpoints\Http\Requests\ComputeVolume;
use Biigle\Modules\Laserpoints\Image;
use Biigle\Modules\Laserpoints\Jobs\ProcessImageDelphiJob;
use Biigle\Modules\Laserpoints\Jobs\ProcessImageAutomaticJob;
use Biigle\Modules\Laserpoints\Jobs\ProcessImageManualJob;
use Biigle\Modules\Laserpoints\Jobs\ProcessVolumeDelphiJob;
use Biigle\Modules\Laserpoints\Jobs\ProcessVolumeAutomaticJob;
use Biigle\Modules\Laserpoints\Jobs\ProcessVolumeManualJob;
use Biigle\Modules\Laserpoints\Volume;
use Biigle\Volume as BaseVolume;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

class LaserpointsController extends Controller
{
/**
* Compute distance between laser points for an image.
* Compute distance between laser points for an image with manual annotations.
*
* @api {post} images/:id/laserpoints/area Compute image area
* @api {post} images/:id/laserpoints/manual Compute image area with manual annotations
* @apiGroup Images
* @apiName ImagesComputeArea
* @apiName ImagesComputeAreaManual
* @apiPermission projectEditor
* @apiDescription This feature is not available for very large images.
*
* @apiParam {Number} id The image ID.
* @apiParam (Required arguments) {Number} label_id ID of the laser point label that was used.
* @apiParam (Required arguments) {Number} distance The distance between two laser points in cm.
*
* @param ComputeImage $request
* @param Request $request
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function computeImage(ComputeImage $request)
public function imageManual(Request $request, $id)
{
$image = Image::convert($request->image);
$image = Image::with('volume')->findOrFail($id);
$this->authorize('edit-in', $image->volume);
// TODO manual is possible for tiled images? how does the script get the dimensions? do we need a python script for this at all?
if ($image->tiled) {
throw ValidationException::withMessages([
'id' => 'Laser point detection is not available for very large images.',
]);
}
$request->validate([
'distance' => 'required|numeric|min:1',
'label_id' => 'required|integer|exists:labels,id',
]);

$label = Label::find($request->input('label_id'));

try {
$manual = $image->readyForManualDetection($label);
$image->readyForManualDetection($label);
} catch (Exception $e) {
throw ValidationException::withMessages([
'id' => 'Laser point detection can\'t be performed. '.$e->getMessage(),
]);
}

if ($manual) {
ProcessImageManualJob::dispatch($image, $request->input('distance'), $label->id)
->onQueue(config('laserpoints.process_manual_queue'));
} else {
try {
Volume::convert($image->volume)->readyForDelphiDetection($label);
} catch (Exception $e) {
throw ValidationException::withMessages([
'id' => 'Delphi laser point detection can\'t be performed. '.$e->getMessage(),
]);
}

ProcessImageDelphiJob::dispatch($image, $request->input('distance'), $label->id)
->onQueue(config('laserpoints.process_delphi_queue'));
ProcessImageManualJob::dispatch($image, $label, $request->input('distance'))
->onQueue(config('laserpoints.process_manual_queue'));
}

/**
* Compute distance between laser points for an image with automatic detection.
*
* @api {post} images/:id/laserpoints/automatic Compute image area with automatic detection
* @apiGroup Images
* @apiName ImagesComputeAreaAutomatic
* @apiPermission projectEditor
* @apiDescription This feature is not available for very large images.
*
* @apiParam {Number} id The image ID.
* @apiParam (Required arguments) {Number} distance The distance between two laser points in cm.
*
* @param Request $request
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function imageAutomatic(Request $request, $id)
{
$image = Image::with('volume')->findOrFail($id);
$this->authorize('edit-in', $image->volume);
if ($image->tiled) {
throw ValidationException::withMessages([
'id' => 'Laser point detection is not available for very large images.',
]);
}
$request->validate([
'distance' => 'required|numeric|min:1',
]);

ProcessImageAutomaticJob::dispatch($image, $request->input('distance'))
->onQueue(config('laserpoints.process_automatic_queue'));
}

/**
* Compute distance between laser points for a volume.
* Compute distance between laser points for a volume with manual annotations.
*
* @api {post} volumes/:id/laserpoints/area Compute image footprint for all images
* @api {post} volumes/:id/laserpoints/manual Compute image area with manual annotations
* @apiGroup Volumes
* @apiName VolumesComputeImageArea
* @apiName VolumesComputeAreaManual
* @apiPermission projectEditor
* @apiDescription This feature is not available for video volumes and volumes with very large images.
*
* @apiParam {Number} id The volume ID.
* @apiParam (Required arguments) {Number} label_id ID of the laser point label that was used.
* @apiParam (Required arguments) {Number} distance The distance between two laser points in cm.
*
* @param ComputeVolume $request
* @param Request $request
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function computeVolume(ComputeVolume $request)
public function volumeManual(Request $request, $id)
{
$volume = Volume::convert($request->volume);
// TODO use cache key to prevent users from submitting multiple jobs at the same
// time
$volume = Volume::findOrFail($id);
$this->authorize('edit-in', $volume);
if (!$volume->isImageVolume()) {
throw ValidationException::withMessages([
'id' => 'Laser point detection is only available for image volumes.',
]);
}
// TODO manual is possible for tiled images? how does the script get the dimensions? do we need a python script for this at all?
if ($volume->hasTiledImages()) {
throw ValidationException::withMessages([
'id' => 'Laser point detection is not available for volumes with very large images.',
]);
}
$request->validate([
'distance' => 'required|numeric|min:1',
'label_id' => 'required|integer|exists:labels,id',
]);

$label = Label::find($request->input('label_id'));

try {
$volume->readyForDelphiDetection($label);
$volume->readyForManualDetection($label);
} catch (Exception $e) {
throw ValidationException::withMessages([
'id' => 'Delphi laser point detection can\'t be performed. '.$e->getMessage(),
'id' => 'Laser point detection can\'t be performed. '.$e->getMessage(),
]);
}

ProcessVolumeDelphiJob::dispatch($volume, $request->input('distance'), $label->id)
->onQueue(config('laserpoints.process_delphi_queue'));
ProcessVolumeManualJob::dispatch($volume, $label, $request->input('distance'))
->onQueue(config('laserpoints.process_manual_queue'));
}

/**
* Compute distance between laser points for a volume with automatic detection.
*
* @api {post} volumes/:id/laserpoints/automatic Compute image area with automatic detection
* @apiGroup Volumes
* @apiName VolumesComputeAreaAutomatic
* @apiPermission projectEditor
* @apiDescription This feature is not available for video volumes and volumes with very large images.
*
* @apiParam {Number} id The image ID.
* @apiParam (Required arguments) {Number} distance The distance between two laser points in cm.
* @apiParam (Optional arguments) {boolean} disable_line_detection Set to true if the laser pointers can move relative to the camera (e.g. laser points could move even if the vehicle does not move).
*
* @param Request $request
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function volumeAutomatic(Request $request, $id)
{
// TODO use cache key to track which image job should delete cache data
// and to prevent users from submitting multiple jobs at the same time
$volume = Volume::findOrFail($id);
$this->authorize('edit-in', $volume);

if (!$volume->isImageVolume()) {
throw ValidationException::withMessages([
'id' => 'Laser point detection is only available for image volumes.',
]);
}

if ($volume->hasTiledImages()) {
throw ValidationException::withMessages([
'id' => 'Laser point detection is not available for volumes with very large images.',
]);
}

$request->validate([
'distance' => 'required|numeric|min:1',
'disable_line_detection' => 'boolean',
]);

ProcessVolumeAutomaticJob::dispatch($volume, $request->input('distance'), $request->input('disable_line_detection', false))
->onQueue(config('laserpoints.process_automatic_queue'));
}
}
56 changes: 0 additions & 56 deletions src/Http/Requests/ComputeImage.php

This file was deleted.

Loading