-
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?
Conversation
This commit introduces some of the basic logic in the PTP job, adding minimal functionality. Does not work still, but now it receives the image and annotations it needs to process and catches the path where the Image is.
Initialises PTP script, while still not working, this will be the starting point of the Python script that translates the points to polygons.
Initialises the new PTP controller that will launch the jobs and associates it to the API via a mock route (/test-ptp) to test the new features of PTP.
The PTP script now works and is able to run annotation conversions from point to polygons using SAM. Introduces also docstrings and type hints for the Python script
The Python Job can now be run via API using the controller, now loading the image path correctly.
Initialise the PTP sidebar. Before it used to simply replicate the MAIA tab. For now, it uses a placeholder index for executing, as the page will need to be developed similarly to the maia one.
This commit introduces the Point to Polygon View, along with its entry in the routes.php file.
This commit initialises the PTP tab that now correctly loads the point annotations, for now showing just the info about the annotation. The blade template correctly loads the vue templates/.
This commit introduces changes to the various templates. Now the template is able to show images, without the annotations, which will be introduced in a future commit, along with the fact that it will show one image per time and
This commit introduces now a system that loads images as well as their outlines on the label. Mockups of the buttons that will generate the PTP jobs are inserted. This commit also introduces the styling for the PTP module.
This commit makes it possible to spawn a PtpJob from the frontend via the `send-ptp-job` route, launching the Python scripts per label. The `ptp.py` is modified accordingly. Styling is also changed, to reflect this grouping and to allow the container to show the annotations well. A temporary directory system is introduced in the config.
This commit introduces the new job with the role of uploading the result of computing the expected area of the Point to Polygon conversion. This is done through a simple prediction on the image and taking the raw result/
This commit introduces several fixes and changes regarding the Point to Polygon pipeline. Essentially, there is now just one pipeline, triggered by the selected button, that first computes the expected area, then uploads it on the DB. The expected area is then use to apply the Point to Polygon conversion. In the next commits a Job that uploads the new annotations will be created, as well as a better system for the exchange of information between jobs.
This commit introduces the Job that uploads the new annotations found with the Python script to the DB, as well as fixing related scripts in order for it to work correctly.
This commit fixes some bugs that did not allow some of the strategies of the PTP conversion to work.
This commit introduces a fix on the Ptp process that updates the ImageAnnotationLabels table in order to have annotation information associated to them.
Removes useless components and API
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.
Thanks! Mostly high-level comments first:
GPU or CPU?
Do you think these jobs should run on a GPU or is the runtime also decent on a CPU? We have to consider the following options:
-
On the GPU the whole volume is processed in a single job (because we have only one GPU for these long jobs). This may have the advantage of having to cache all files only once. Also, we may not need a temporary storage for the expected areas. The Python script can just get an input JSON with all annotation coordinates and label IDs as well as a directory of images and do everything else internally. The result is a JSON with the converted polygon coordinates.
-
On the CPU we can parallelize things and compute each image in a single job. This needs the temporary storage for the expected area and the different types of jobs (first process images for expected area, then do conversion).
Your current implementation of the jobs targets 2. Maybe it will be faster and easier to implement to do this on a GPU?
Volume Tab
I'd like this iteration of the feature to be implemented as an actual tab in the volume overview instead of a completely new view. You can take the biigle/laserpoints tab as an example.
Selection of a subset of labels should be optional. Either we don't offer this option at all for now (i.e. the user can only click the button "start" and all point annotations are converted) or we allow a selection of multiple labels. This can use the existing component to select multiple labels from label trees. Example from the clone volumes view:
Tests
You have to write tests for the controller and job classes.
Garbage files
There are still some files from biigle/maia in the repo (Requests, Jobs). Also the console publish command is not needed (it was used in the past by modules but not any more).
Branch
There is already the dev-modules-ptp
branch of biigle/core with the module installed. However, the module is curently not loaded there. You should add an extra section to the composer.json to enable package discovery upon installation.
sahi==0.11.18 | ||
shapely==2.0.6 | ||
pycocotools==2.0.8 |
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?
$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 comment
The reason will be displayed to describe this comment to others. Learn more.
No hard-coded IDs please 😉
$pointShapeId = 1; //Find annotations with selected label in desired volume | |
$pointShapeId = Shape::pointId(); //Find annotations with selected label in desired volume |
$labels = Label::whereIn('label_tree_id', $labelTrees->pluck('id'))->get(); | ||
|
||
// ID of point shape | ||
$pointAnnotationId = 1; |
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.
$pointAnnotationId = 1; | |
$pointAnnotationId = Shape::pointId(); |
use Illuminate\Queue\SerializesModels; | ||
use Storage; | ||
|
||
class PtpJob extends BaseJob implements ShouldQueue |
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.
This class has several attributes that were copy/pasted but are not relevant for this job.
/** | ||
* User responsible for the Point to Polygon conversion. | ||
* | ||
* @var User | ||
*/ | ||
public User $user; | ||
|
||
/** | ||
* The queue to push this job to. | ||
* | ||
* @var string | ||
*/ | ||
public string $inputDir; | ||
|
||
|
||
public function __construct(string $inputDir, User $user) | ||
{ | ||
$this->inputDir = $inputDir; | ||
$this->user = $user; | ||
} |
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.
With new PHP syntax you can do:
/** | |
* User responsible for the Point to Polygon conversion. | |
* | |
* @var User | |
*/ | |
public User $user; | |
/** | |
* The queue to push this job to. | |
* | |
* @var string | |
*/ | |
public string $inputDir; | |
public function __construct(string $inputDir, User $user) | |
{ | |
$this->inputDir = $inputDir; | |
$this->user = $user; | |
} | |
/** | |
* @var $user User responsible for the Point to Polygon conversion. | |
* @var $inputDir ... | |
*/ | |
public function __construct(public string $inputDir, public User $user) | |
{ | |
// | |
} |
mask = mask * 255 | ||
mask = mask.astype(np.uint8) | ||
contours, hierarchy = cv2.findContours( | ||
mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE |
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.
We don't want to store coordinates for each pixel 😉
mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE | |
mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE |
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.
I haven't read the whole script but maybe you can boil it down to only those features that are actually used by this BIIGLE module.
@@ -1,3 +1,3 @@ | |||
@if (($user->can('edit-in', $volume) || $user->can('sudo')) && $volume->isImageVolume() && !$volume->hasTiledImages()) | |||
<sidebar-tab name="maia" icon="robot" title="Perform Machine Learning Assisted Image Annotation (MAIA)" href="{{route('volumes-maia', $volume->id)}}"></sidebar-tab> | |||
<sidebar-tab name="ptp" icon="circle" title="Perform Point to Polygon conversion" href="{{route('volumes-ptp-conversion', $volume->id)}}"></sidebar-tab> |
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.
I thought that maybe we could use the same "magic hat" icon than MagicSAM, as the feature is very similar. It's basically MagicSAM on a volume level. @dlangenk what do you think?
*/ | ||
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 comment
The 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?
//annotation with labels and that are points | ||
$annotations = ImageAnnotation::join('image_annotation_labels','image_annotations.id', '=', 'image_annotation_labels.annotation_id') | ||
->join('images','image_annotations.image_id','=','images.id') | ||
->join('labels', 'image_annotation_labels.label_id','=','labels.id') | ||
->where('images.volume_id', $volume->id) | ||
->whereIn('image_annotation_labels.label_id', $labels->pluck('id')) | ||
->where('image_annotations.shape_id', $pointAnnotationId) | ||
->select('images.uuid', 'image_annotations.id', 'image_annotation_labels.label_id', 'labels.name AS label_name')->get(); | ||
|
||
//largo URL patches to show | ||
$largoPatchesUrl = Storage::disk(config('largo.patch_storage_disk'))->url(':prefix/:id.'.config('largo.patch_format')); |
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.
These are not needed (any more).
This MR introduces the first point to polygon functionalities, in particular:
Introduces a Tab in the volume view for the conversion
Creates a tab that can be used to create a PTP Job.
Once you have a Volume with point annotations, you can run a Point to Polygon job on a label with at least a point annotation. This will in turn run:
To test this MR:
dev-modules-point-to-polygon
branch for the biigle root