-
Notifications
You must be signed in to change notification settings - Fork 0
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
Introduces PTP tab and Job #2
base: main
Are you sure you want to change the base?
Changes from all commits
b3fcbb9
eddabfc
e384eba
d5f6b36
f327d51
38b4dea
324bbc3
f05d894
7d4ede1
a88ee9d
540e09c
6ec484d
46269e5
4afcd80
1b985d5
9e44308
99d09f1
5e14200
884bf3d
06c64bc
35b0aa2
13d6e00
46db849
eb8d211
35ab9cc
08bd68d
18bba64
dd6486c
a242820
dd6019b
a418c5d
4d61d77
aa0ae07
0012002
02f8ab9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
torch==2.1.* | ||
git+https://github.com/facebookresearch/segment-anything.git | ||
numpy==1.24.* | ||
Pillow==9.3.* | ||
sahi==0.11.18 | ||
shapely==2.0.6 | ||
pycocotools==2.0.8 | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
namespace Biigle\Modules\Ptp\Console\Commands; | ||
|
||
use Biigle\Modules\Ptp\PtpServiceProvider as ServiceProvider; | ||
use Illuminate\Console\Command; | ||
|
||
class Publish extends Command | ||
{ | ||
/** | ||
* The console command name. | ||
* | ||
* @var string | ||
*/ | ||
protected $name = 'ptp:publish'; | ||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'Publish or refresh the public assets of this package'; | ||
|
||
/** | ||
* Execute the command. | ||
* | ||
* @return void | ||
*/ | ||
public function handle() | ||
{ | ||
$this->call('vendor:publish', [ | ||
'--provider' => ServiceProvider::class, | ||
'--tag' => ['public'], | ||
'--force' => true, | ||
]); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
namespace Biigle\Modules\Ptp\Database\Factories; | ||
|
||
use Biigle\Label; | ||
use Biigle\Modules\Ptp\PtpExpectedArea; | ||
use Biigle\Volume; | ||
use Illuminate\Database\Eloquent\Factories\Factory; | ||
|
||
class PtpExpectedAreaFactory extends Factory | ||
{ | ||
/** | ||
* The name of the factory's corresponding model. | ||
* | ||
* @var string | ||
*/ | ||
protected $model = PtpExpectedArea::class; | ||
|
||
/** | ||
* Define the model's default state. | ||
* | ||
* @return array | ||
*/ | ||
public function definition() | ||
{ | ||
return [ | ||
'label_id' => Label::factory(), | ||
'volume_id' => Volume::factory(), | ||
'areas' => json_encode([]), | ||
]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
use Illuminate\Support\Facades\DB; | ||
|
||
return new class extends Migration | ||
{ | ||
/** | ||
* Run the migrations. | ||
*/ | ||
public function up(): void | ||
{ | ||
Schema::create('ptp_expected_areas', function (Blueprint $table) { | ||
$table->bigIncrements('id'); | ||
$table->integer('volume_id')->unsigned()->index(); | ||
$table->foreign('volume_id')->references('id')->on('volumes')->onDelete('cascade'); | ||
$table->integer('label_id')->unsigned()->index(); | ||
$table->foreign('label_id')->references('id')->on('labels')->onDelete('cascade'); | ||
$table->jsonb('areas'); | ||
}); | ||
} | ||
|
||
/** | ||
* Reverse the migrations. | ||
*/ | ||
public function down(): void | ||
{ | ||
Schema::dropIfExists('ptp_expected_areas'); | ||
} | ||
}; |
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,91 @@ | ||||||
<?php | ||||||
|
||||||
namespace Biigle\Modules\Ptp\Http\Controllers\Api; | ||||||
use Biigle\Http\Controllers\Api\Controller; | ||||||
use Biigle\Modules\Ptp\Jobs\PtpJob; | ||||||
use Biigle\Modules\Ptp\Jobs\UploadPtpExpectedAreaJob; | ||||||
use Biigle\Modules\Ptp\Jobs\UploadConvertedAnnotationsJob; | ||||||
use Biigle\Modules\Ptp\PtpExpectedArea; | ||||||
use Biigle\ImageAnnotation; | ||||||
use Biigle\Volume; | ||||||
use Biigle\Label; | ||||||
use Illuminate\Http\Request; | ||||||
use Illuminate\Support\Facades\Bus; | ||||||
|
||||||
/** | ||||||
* Controller used for creating a PTP Job Chain | ||||||
*/ | ||||||
class PtpController extends Controller | ||||||
{ | ||||||
/** | ||||||
* Generate Point to Polygon Job Chain. | ||||||
* This method generates, based on the request. The jobs generated are first for computing and uploading the expected areas of converted polygons. | ||||||
* Then, it generates a job for executing the conversion and then upload the new annotations to the DB | ||||||
* | ||||||
* @param $request | ||||||
* @return | ||||||
*/ | ||||||
public function generatePtpJob(Request $request) { | ||||||
$this->validate($request, ['label_id' => 'integer', 'volume_id' => 'integer']); | ||||||
$volume = Volume::findOrFail($request->volume_id); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have to validate that the volume is an image volume and (maybe) that is does not have tiled images here. Video volumes are not supported. @dlangenk Would the Python script work with a huge image mosaic? |
||||||
$this->authorize('edit-in', $volume); Label::findOrFail($request->label_id); | ||||||
$imageAnnotationArray = []; | ||||||
$labelId = $request->label_id; | ||||||
$pointShapeId = 1; //Find annotations with selected label in desired volume | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No hard-coded IDs please 😉
Suggested change
|
||||||
$annotations = ImageAnnotation::join('image_annotation_labels','image_annotations.id', '=', 'image_annotation_labels.annotation_id') | ||||||
->join('images','image_annotations.image_id', '=','images.id') | ||||||
->where('image_annotation_labels.label_id', $labelId) | ||||||
->where('images.volume_id', $volume->id) | ||||||
->where('image_annotations.shape_id', $pointShapeId) | ||||||
->select('image_annotations.id as id', 'images.id as image_id', 'image_annotations.points as points','image_annotations.shape_id as shape_id') | ||||||
->get(); | ||||||
foreach ($annotations as $annotation) { | ||||||
if (!isset($imageAnnotationArray[$annotation->image_id])) { | ||||||
$imageAnnotationArray[$annotation->image_id] = []; | ||||||
} | ||||||
$imageAnnotationArray[$annotation->image_id][] = [ | ||||||
'annotation_id' => $annotation->id, | ||||||
'points' => $annotation->points, | ||||||
'shape' => $annotation->shape_id, | ||||||
'image' => $annotation->image_id, | ||||||
'label' => $labelId, | ||||||
]; | ||||||
}; | ||||||
|
||||||
// INFO: should we batch per small number or annotations? for now, just grouping per | ||||||
// image IDs | ||||||
|
||||||
$jobArray = []; | ||||||
$expectedAreaCount = PtpExpectedArea::where('label_id', $labelId)->where('volume_id', $volume->id)->count('id'); | ||||||
|
||||||
if ($expectedAreaCount == 0){ | ||||||
$expectedAreaJobs = []; | ||||||
$outputDir = config('ptp.temp_dir').'/compute-area/'.$volume->id.'/'.$labelId; | ||||||
|
||||||
foreach ($imageAnnotationArray as $imageId => $imageAnnotationValues){ | ||||||
$outputFile = "$outputDir/".$labelId."_"."$imageId.json"; | ||||||
$job = new PtpJob($request->user(), $imageAnnotationValues, 'compute-area', $labelId, $outputFile); | ||||||
array_push($expectedAreaJobs, $job); | ||||||
} | ||||||
array_push($jobArray, Bus::batch($expectedAreaJobs)); | ||||||
$uploadJob = new UploadPtpExpectedAreaJob($outputFile, $volume->id, $labelId); | ||||||
array_push($jobArray, $uploadJob); | ||||||
} | ||||||
|
||||||
$ptpConversionJobs = []; | ||||||
$outputDir = config('ptp.temp_dir').'/ptp/'.$volume->id.'/'.$labelId; | ||||||
|
||||||
foreach ($imageAnnotationArray as $imageId => $imageAnnotationValues){ | ||||||
$outputFile = "$outputDir/".$labelId."_"."$imageId.json"; | ||||||
$job = new PtpJob($request->user(), $imageAnnotationValues, 'ptp', $labelId, $outputFile) ; | ||||||
array_push($ptpConversionJobs, $job); | ||||||
} | ||||||
$job = new UploadConvertedAnnotationsJob($outputDir, $request->user()); | ||||||
|
||||||
array_push($jobArray, Bus::batch($ptpConversionJobs), $job); | ||||||
|
||||||
Bus::chain($jobArray)->dispatch(); | ||||||
|
||||||
return ['submitted' => true]; | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The last three are not really required, right?