-
Notifications
You must be signed in to change notification settings - Fork 14
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
Added shift method #9
Added shift method #9
Conversation
Thanks for the PR @harshraj22 👍 I have one minor comment, that we can accept a tuple of ints as def shift(self, shift_amount):
horizontal_shift, vertical_shift = shift_amount
... Also, can you add test cases for the new method |
@@ -34,6 +34,28 @@ def to_voc(self, return_values: bool = False) -> Union[Tuple[int, int, int, int] | |||
return x_tl, y_tl, x_br, y_br | |||
return BoundingBox(x_tl, y_tl, x_br, y_br, image_size=self.image_size, strict=self.strict) | |||
|
|||
def shift(self, horizontal_threshold: float, vertical_threshold: float) -> "AlbumentationsBoundingBox": |
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.
Please, take this comment as for other methods as well.
(1) Since we convert to VOC, the type hints as well as the docstring needs to be changed, only integers are accepted since we use VOC type under the hood for shifting.
(2) We need to clearly desribe and explicitly write in the docstring that shifting is performed in pixel values not in normalized values.
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.
@devrimcavusoglu I did not understand what do you mean by "pixel values not in normalised values". Could you clarify a little more ?
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. I meant unnormalized values, like those shift values (horizontal_threshold
, vertical_threshold
) must be always in pixel values integers because VOC style is in pixel values (x,y coordinates). For example YOLO style is (x-center, y-center, width, height)
but these values are normalized (w.r.t image_size) values and not pixel coordinates.
Currently, in the implementation in this PR, regardless of the box style the box is first converted to VOC style, and addition is then applied. That's why, for example, we cannot give normalized shift values to YOLO style values (normalized). Alternatively, if we take the input shift values in that particular box style, then VOC style conversion must be omitted. Further, see the pseudo snippet below
yolo_values = [0.4046875, 0.840625, 0.503125, 0.24375]
yolo_bbox = BoundingBox.from_yolo(*yolo_values, image_size=(640,480))
# I want to shift my YOLO box
shifted_yolo_box = yolo_bbox.shift(0.07, 0.02)
Now, when I call .shift()
internally these steps happen; (1) yolo_values are converted to voc values, (2) my shift values are added to the associated values 0.07
, 0.02
respectively.
At step (2) yolo shift values 0.07, 0.02
are added to VOC values which are [98, 345, 420, 462]
which is not desired. There are two solutions that comes up,
Solution 1 (Current)
Accept shift values as unnormalized. Convert the box values to voc, add the shift values, and return.
Solution 2
Omit converting values to VOC, directly apply the shift values and then instantiate/construct the object and return.
Both solutions are fine, and actually I guided you towards solution 1 although currently when I consider the case again, solution 2 seems a better alternative. In this case, I kinda misguided you towards solution 1. Thus, I see currently two options,
- Keep solution 1 (current implementation), but fix the accept type (all should be int because of converting VOC) and also add an info to the docstring about shift values must be unnormalized.
- Switch to solution 2 (might be better).
@harshraj22 wdyt of these alternatives ?
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, I too would prefer solution 2. So if I understand correctly, it would be overwriting shift
method in each BoundingBox type.
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, I too would prefer solution 2. So if I understand correctly, it would be overwriting
shift
method in each BoundingBox type.
Your implementation so far will remain as is except the to_voc conversion at step 1 since we'd like to update the values associated with each style. In short, simply remove to_voc parts in your implementation and all is fine. Also, your return part changes directly as cls()
instead of cls.from_voc()
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.
Well, in your fork for YOLO box everything seems fine, with the code snippet below, I got the desired output:
>>> yolo_values = [0.4046875, 0.840625, 0.503125, 0.24375]
>>> yolo_bbox = YoloBoundingBox.from_array(yolo_values, image_size=(640, 480))
>>> shifted_yolo_bbox = yolo_bbox.shift((0.08, 0.03))
>>> print(yolo_bbox)
>>> print(shifted_yolo_bbox)
<[0.4047 0.8406 0.5031 0.2437] (322x117) | Image: (640x480)>
<[0.4847 0.8706 0.5031 0.2437] (322x117) | Image: (640x480)>
,and this
>>> oob_bbox = yolo_bbox.shift((0.08, 0.2))
>>> print(oob_bbox)
Traceback (most recent call last):
...
ValueError: Given bounding box values is out of bounds.
All in all, everything seems fine. Can you give minimal example to reproduce your case ? Could you be accidentally shifted the box out of bounds ? @harshraj22 and can you give platform info, what OS and version, python version, etc.
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.
That's strange ! macOS Monterey, python3.8.9
to reproduce, from the latest commit on my branch, run pytest
from the pytest directory.
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.
Hi @harshraj22, sorry for late reply. Well, I've checked it. The tests failing simply because the shift amount tries to shift the boxes out of bounds,
# Albumentations box
<[0.1531 0.7188 0.6562 0.9625] (322x117) | Image: (640x480)>
# the shift amount
(2, 2)
Albumentations, fiftyone and YOLO are bounding box styles with normalized values meaning that the bounding boxes that are not OOB needs to be in (0,1) range, clearly with the shift (2,2)
they are pushed towards OOB. My advise is that, define two distinct fixtures for normalized shift, and unnormalized shift and apply accordingly.
Also, test case for COCO is failing due to mismatch between actual
being list, and desired
being tuple, simply just match the types either make both lists or both tuples, make them consistent among all test cases so chose one type for all test cases.
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 shift( )
method takes Tuple[int, int]
as arg right ? We can't pass a tuple of values in (0, 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.
The
shift( )
method takesTuple[int, int]
as arg right ? We can't pass a tuple of values in (0, 1) ?
No, we've picked the second option (see Solution 2), and thus on shift()
method every box takes their associated values. That is, normalized box styles (Albumentations, Fiftyone, YOLO) will take floats between (0,1)
, and unnormalized box styles (COCO, VOC) will take integers.
@harshraj22 sorry for late review. Thanks for the effort, I think we are almost there. I have two major comments:
Additionaly, there are some conflicts due to the release 0.1.1, can you please solve the conflicts also. |
@@ -1,5 +1,7 @@ | |||
from typing import Tuple, Union | |||
|
|||
from cv2 import threshold |
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.
Unused import should be removed
pybboxes/types/coco_bounding_box.py
Outdated
@@ -3,6 +3,8 @@ | |||
from pybboxes.types.base import BaseBoundingBox | |||
from pybboxes.types.bbox import BoundingBox | |||
|
|||
# from pybboxes.functional import convert_bbox |
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.
Remove unused import.
@@ -34,6 +36,35 @@ def to_voc(self, return_values: bool = False) -> Union[Tuple[int, int, int, int] | |||
return x_tl, y_tl, x_br, y_br | |||
return BoundingBox(x_tl, y_tl, x_br, y_br, image_size=self.image_size, strict=self.strict) | |||
|
|||
def shift(self, threshold: Tuple[int, int]) -> "AlbumentationsBoundingBox": |
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.
Tuple[float,float]
for Albumentations style, update the docstring also.
Added shift method to box.BoundingBox
@devrimcavusoglu Made the required changes. Please review again :) |
Thanks for the effort appreciated 🚀 I'll run the tests now though I have a single minor comment/suggestion in one naming. Edit: Tests are failing due to formatting, please see code-style guide. |
AlbumentationsBoundingBox | ||
The new bounding box. | ||
""" | ||
horizontal_threshold, vertical_threshold = amount |
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.
Can we rename these also (take this comment into consideration for all box types please)
horizontal_threshold, vertical_threshold
-> horizontal_shift, vertical_shift
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.
Done :)
* Formatted code * Passes tests
Linked with issue #5
All bounding box types convert to a VocBoundingBox object. The shifting is done in the VOC coordinates, and a new object of same class is being returned. All other properties are kept as passed during the initialisation of the current object.