-
Notifications
You must be signed in to change notification settings - Fork 1
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
#16 - Add roi tool #28
Conversation
Codecov Report
@@ Coverage Diff @@
## main #28 +/- ##
=========================================
- Coverage 13.28% 9.38% -3.91%
=========================================
Files 4 4
Lines 143 373 +230
=========================================
+ Hits 19 35 +16
- Misses 124 338 +214
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
e136772
to
ab57a6e
Compare
9aec5cc
to
8a9013b
Compare
This PR closes issue #16 Features
ROIs:
- drawn_on_frame: 57000
line_color: '#2E91E5'
name: enclosure
path: M348.0491395793499,...
- drawn_on_frame: 38000
line_color: '#E15F99'
name: left_box
path: M484.23300516875133,...
What is missing
|
Note on the aboveTo really review this PR, you need to alias (at least some of) the videos in |
Manual testing looks good. I've just drawn some boxes. I can see the paths appear in the metadata.yaml 👍 I can also (re)load them on closing and restarting the server. How easy would it be (sorry!) to implement backspace deletion? Moving the RoIs around and resizing are both possible, but my naive attempts to delete (backspace and right-click) don't do anything, I have to notice the feint backspace icon on hover at the top. If this is not easy, please ignore. The dash "hovering toolbar" interface is adequate. And anyway the researchers will become accustomed to this because the plots also have that. |
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.
LGTM!
The only substantial thing is my backspace comment ☝️.
I actually thought of that as well. Unfortunately, I haven't found any plotly-native way of enabling shape deletion via clicking An idea would be to add a delete functionality to rows of the table, such that if you delete a row, the corresponding shape disappears. That would be possible, but would increase the complexity of the callback dance between |
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.
Looks good!
Mostly minor comments post-hoc. The only comment that I think would be more important is the one with suggestions on the layout. I think right now there is a lot of back an forth between different areas of the screen (visually and with the mouse). I added some suggestions to hopefully make it flow a bit more naturally.
@@ -3,3 +3,10 @@ metadata_fields_file_path: ./sample_project/metadata_fields.yaml | |||
metadata_key_field_str: File | |||
pose_estimation_model_str: DLC_resnet50_jwasp_femaleandmaleSep12shuffle1_1000000 | |||
pose_estimation_results_path: ./sample_project/pose_estimation_results | |||
roi_names: |
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.
minor consistency suggestions:
- shall we call these 'ROI_tags', to match the 'event_tags'?
- shall we always write ROI in caps?
Hardware_description: Reference 'nectar-open-close.pdf' on ceph (in \zoo\raw\LondonZoo\Experiment-protocols\Jewel-wasp_Ampulex-compressa\) | ||
or Google Drive (most up-to-date version if they are different - in Experiment Protocols\jewel-wasp_Ampulex-compressa\) | ||
ROIs: | ||
- drawn_on_frame: 57000 |
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.
When you dump a dictionary in a yaml file, by default the keys are sorted alphabetically. The order of the keys is preserved if you add the sort_keys=False
argument (so yaml.safe_dump(<dict>, <yaml_file>, sort_keys=False)
).
A small thing, but if the metadata files are to be read or checked by a human, I think it would be nice to show the keys in a more intuitive order (maybe name > drawn_on_frame > path > line_color). Also relevant for the visualisation in the metadata table.
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.
also we need to add the ROIs field to the metadata_fields.yaml (otherwise for me the tests fail)
|
||
VIDEO_TYPES = [".avi", ".mp4"] | ||
# TODO: other video extensions? have this in project config file instead? | ||
ROI_CMAP = px.colors.qualitative.Dark24 | ||
# TODO: make colomap this a project config parameter? |
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'm in favor of keeping the project config minimal (that's why I was doubting about adding the VIDEO_TYPES variable above).
One option may be to have sections within the config file, in which we can separate 'cosmetic' parameters from mandatory fields (not sure what would be the best way to do this though, maybe just with comments?).
In any case I think the ROIs colormap won't be something the user will want to change, so I would say for this there is no need to add it to the project config.
] | ||
video_paths.sort() | ||
video_names = [p.name for p in video_paths] | ||
video_paths_str = [p.absolute().as_posix() for p in video_paths] |
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.
thinking about refactoring: we may want to have this video paths extraction as a helper function, we use it both quite a bit
], | ||
Input("session-storage", "data"), | ||
) | ||
def update_roi_select_options( |
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 like the consistency in the function naming....taking notes for refactoring phase 🤓
) -> list: | ||
""" | ||
Set the color of the ROI names in the ROI table | ||
based on the color assigned to that ROI shape. |
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'm not sure if I am biased but I find this description very copilot-y! haha 😁
Shouldn't it just be 'Set the color of the ROIs in the table'?
roi_color_mapping : dict | ||
Dictionary with the following keys: | ||
- roi2color: dict mapping ROI names to colors | ||
- color2roi: dict mapping colors to ROI names |
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.
probably irrelevant but I don't understand why you need a color2roi
mapping... 🤔
|
||
# If triggered by the load ROIs button click | ||
# Load the ROIs from the metadata file | ||
# CAUTION! This will overwrite any ROIs is the roi-storage |
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.
typo: *in the roi-storage
State("roi-colors-storage", "data"), | ||
], | ||
) | ||
def update_roi_storage( |
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 like that this function has nice guiding comments
# Initialize the ROI status alert | ||
init_roi_status: dict = {"message": "No ROIs to save.", "color": "light"} | ||
|
||
# Instructions for the 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.
Some thoughts about the layout:
- It'd be nice if the layout was intuitive enough so that we can omit written instructions. If we see we do need them, one option to make them take less space could be to put them in a collapsable panel (just as we were thinking to show the code that generates plots).
- I find it more user friendly if all the inputs are on the same area. In this case, the selected video, the selected frame, and the ROI to label next. In that spirit I would suggest to move the 'Create new ROI for' just under the frame selector. Otherwise, I feel there is a lot of back and forth across the screen.
- similarly, I think the 'Save ROIs' button could be better placed under the table. After you define them, you review the table and then click save. I think it follows a bit more naturally the workflow. I'd keep the other buttons together with the 'Save ROIs' one, to have all the actions together.
In this PR I will tackle issue #16