-
Notifications
You must be signed in to change notification settings - Fork 59
Integrating CV Ontologies with the DataStore format #844
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
base: master
Are you sure you want to change the base?
Changes from 3 commits
9f4e022
66e7f38
19f127b
76e1666
05f883f
db8a5d9
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 |
|---|---|---|
|
|
@@ -43,6 +43,7 @@ | |
| PARENT_TID_INDEX, | ||
| CHILD_TID_INDEX, | ||
| MEMBER_TID_INDEX, | ||
| PAYLOAD_INDEX, | ||
| ) | ||
|
|
||
| __all__ = [ | ||
|
|
@@ -72,8 +73,15 @@ | |
| make sure it available across the ontology system: | ||
| 1. Create a new top level class that inherits from `Entry` or `MultiEntry` | ||
| 2. Add the new class to `SinglePackEntries` or `MultiPackEntries` | ||
| 3. Register a new method in `DataStore`: `add_<new_entry>_raw()` | ||
| 4. Insert a new conditional branch in `EntryConverter.save_entry_object()` | ||
| 3. Insert a new conditional branch in `EntryConverter.save_entry_object()` | ||
| 4. Decide two main attributes which will qualify as your `attribute_data` | ||
| parameters. These parameters will be passes in your branch of | ||
| `EntryConverter.save_entry_object()`. If there are no such parameters, | ||
| you can pass None | ||
| 5. add `getter` and `setter` functions to update `attribute_data` parameters | ||
| if you have any | ||
| 6. If additional attributes are required, make the class a `dataclass` and set | ||
| `dataclass` attributes. | ||
| """ | ||
|
|
||
|
|
||
|
|
@@ -879,7 +887,9 @@ def image(self): | |
| "Cannot get image because image annotation is not " | ||
| "attached to any data pack." | ||
| ) | ||
| return self.pack.get_image_array(self._image_payload_idx) | ||
| return self.pack.get_payload_data_at( | ||
| Modality.Image, self._image_payload_idx | ||
| ) | ||
|
|
||
| @property | ||
| def max_x(self): | ||
|
|
@@ -1052,12 +1062,35 @@ def __init__(self, pack: PackType, image_payload_idx: int = 0): | |
| else: | ||
| self._image_payload_idx = image_payload_idx | ||
|
|
||
| @property | ||
| def image_payload_idx(self): | ||
| r"""Getter function of ``image_payload_idx``. The function will first try to | ||
| retrieve the image_payload_idx index from ``DataStore`` in ``self.pack``. If | ||
| this attempt fails, it will directly return the value in ``_image_payload_idx``. | ||
| """ | ||
| try: | ||
| self._image_payload_idx = self.pack.get_entry_raw(self.tid)[ | ||
| PAYLOAD_INDEX | ||
| ] | ||
| except KeyError: | ||
| pass | ||
| return self._image_payload_idx | ||
|
|
||
| @image_payload_idx.setter | ||
| def image_payload_idx(self, val: int): | ||
| r"""Setter function of ``image_payload_idx``. The update will also be populated | ||
| into ``DataStore`` in ``self.pack``. | ||
| """ | ||
| self._image_payload_idx = val | ||
| self.pack.get_entry_raw(self.tid)[PAYLOAD_INDEX] = val | ||
|
|
||
| def compute_iou(self, other) -> int: | ||
| intersection = np.sum(np.logical_and(self.image, other.image)) | ||
| union = np.sum(np.logical_or(self.image, other.image)) | ||
| return intersection / union | ||
|
|
||
|
|
||
| @dataclass | ||
| class Box(Region): | ||
| """ | ||
| A box class with a center position and a box configuration. | ||
|
|
@@ -1078,13 +1111,18 @@ class Box(Region): | |
| width: the width of the box, the unit is one image array entry. | ||
| """ | ||
|
|
||
| _cy: int | ||
Pushkar-Bhuse marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| _cx: int | ||
| _height: int | ||
| _width: int | ||
|
|
||
| def __init__( | ||
| self, | ||
| pack: PackType, | ||
| cy: int, | ||
| cx: int, | ||
| height: int, | ||
| width: int, | ||
| cy: int = 0, | ||
| cx: int = 0, | ||
| height: int = 1, | ||
| width: int = 1, | ||
Pushkar-Bhuse marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| image_payload_idx: int = 0, | ||
| ): | ||
| # assume Box is associated with Grids | ||
|
|
@@ -1180,6 +1218,7 @@ def compute_iou(self, other): | |
| return intersection / union | ||
|
|
||
|
|
||
| @dataclass | ||
| class BoundingBox(Box): | ||
| """ | ||
| A bounding box class that associates with image payload and grids and | ||
|
|
@@ -1208,15 +1247,17 @@ class BoundingBox(Box): | |
|
|
||
| """ | ||
|
|
||
| _grid_id: int | ||
Pushkar-Bhuse marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def __init__( | ||
| self, | ||
| pack: PackType, | ||
| height: int, | ||
| width: int, | ||
| grid_height: int, | ||
| grid_width: int, | ||
| grid_cell_h_idx: int, | ||
| grid_cell_w_idx: int, | ||
| height: int = 1, | ||
|
||
| width: int = 1, | ||
| grid_height: int = 1, | ||
| grid_width: int = 1, | ||
| grid_cell_h_idx: int = 0, | ||
| grid_cell_w_idx: int = 0, | ||
Pushkar-Bhuse marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| image_payload_idx: int = 0, | ||
| ): | ||
| self.grids = Grids(pack, grid_height, grid_width, image_payload_idx) | ||
|
|
@@ -1228,6 +1269,8 @@ def __init__( | |
| image_payload_idx, | ||
| ) | ||
|
|
||
| self._grid_id = self.grids.tid | ||
|
|
||
|
|
||
Pushkar-Bhuse marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| class Payload(Entry): | ||
| """ | ||
|
|
||
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 think we shouldn't use too many special const, we should simply store the payload details as attributes.
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.
So Payload Index is the only main attribute for
ImageAnnotationtype entries (just like howAnnotationhasstartandendindices,payload_indexis stored in the first two indices of theDataStoreentry. That's why I felt that could be the only constant we could add forImageAnnotationThere 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.
Let's just try not to add additional consts here. DataStore has a system to add attributes and datastore can manage the attribute position. Can we simply consider
Payload_indexto be a regular attribute?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.
Yes. Every
Entryhas two main attributes which occupy the first and second position in the datastore (for Annotation it is begin and end index). Similar, forImageAnnotationand its subclasses, the two main attributes are payload_idx and None (Implying that it only has one main attribute, the extra None is just for consistency). That is the reason I stored the Payload index value inconstantsThere 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.
what is the
Nonehere?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.
Ok, so I think the reason I have the confusion is that: once
Payloadis in our system, then all other payload-dependent entries (specifically, Annotation, ImageAnnotation, AudioAnnotation) should havePayloadassociated with it too. Now we only modify it forImageAnnotationin this PR, it feels a bit inconsistent to me.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.
Okay I understand now. In that case, do you suggest we make the payload index a data class attribute? In this way we can have it in all three.
Also,
Nonehere has no special significance. TheDataStoreentry structure is that the first two elements are the two main attributes, followed bytid,entry typeand data class attributes (if any). So in the case ofImageAnnotation, there is only one main attribute, so just to keep the structure consistent we have the second attribute asNone. This is the method followed for other entries that have less than two main attributes as well (eg.Generics)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.
Payloadfield. I am not sure of whatdata class attributemeans yet, but we need to make all of the consistent, but with two considerations:i. maybe it will make this PR too large?
ii. we don't want to change any existing behavior, i.e., previously we don't have multiple payloads for each modality, thus all entries are retrieved without any payload index. To keep the same behavior, we should assume any data operation that does not use a
payload indexdefault to 0, i.e., get from the first payload or add to the first payload when payload index is not specified.two main attributes? I just wonder why it could beNone.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.
1(i) I feel that changing the structure for all entry types to include payload index would be out of the scope of this PR.
1(ii) I believe this behavior is already being displayed atleast in the
ImageAnnotationtype entries.2 So this is a structure that is followed by all
DataStoreentries. The first two elements of the list are the two most common attributes of that entry (eg.beginandendindex forAnnotation). This is then followed by the remaining attributes liketid,type_name, etc. The structure is such that we need strictly TWO elements of common attributes in the beginning. But in the case ofImageAnnotation, there is only one such element (payload_index). Thus, to keep the structure consistent, we keep the second element as None.Uh oh!
There was an error while loading. Please reload this page.
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.
Sure, as long as we can ensure the
payloadindex is handled consistently, and we should create issues to track this for the next step.Yeah this is more like a reminder.
We actually can have different internal list structures for different entry types, I hope we don't have to strictly need two elements for each item.