Merge pull request #8 from roboflow/documentation-improvements
Refactor documentation for Supervision
This commit is contained in:
commit
ae84cdeb02
|
|
@ -0,0 +1,9 @@
|
|||
Utilities for drawing on images.
|
||||
|
||||
## Draw Line
|
||||
|
||||
:::supervision.draw.utils.draw_line
|
||||
|
||||
## Draw Rectangle
|
||||
|
||||
:::supervision.draw.utils.draw_rectangle
|
||||
|
|
@ -9,21 +9,22 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
## 👋 hello
|
||||
## 👋 Welcome
|
||||
|
||||
A set of easy-to-use utils that will come in handy in any Computer Vision project. **Supervision** is still in
|
||||
pre-release stage. 🚧 Keep your eyes open for potential bugs and be aware that at this stage our API is still fluid
|
||||
and may change.
|
||||
Supervision is a set of easy-to-use utilities that will come in handy in any computer vision project.
|
||||
|
||||
## 💻 install
|
||||
**Supervision** is still in
|
||||
pre-release stage 🚧 Keep your eyes open for potential bugs and be aware that at this stage our API is still fluid and may change.
|
||||
|
||||
Pip install the supervision package in a
|
||||
## 💻 How to Install
|
||||
|
||||
You can install `supervision` with pip in a
|
||||
[**3.10>=Python>=3.7**](https://www.python.org/) environment.
|
||||
|
||||
!!! example "Pip install method (recommended)"
|
||||
|
||||
```bash
|
||||
pip install subervision
|
||||
pip install supervision
|
||||
```
|
||||
|
||||
!!! example "Git clone method (for development)"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
Utilities to help you build computer vision projects in notebook environments.
|
||||
|
||||
:::supervision.notebook.utils.show_frame_in_notebook
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
Useful utilities for common computer vision tasks.
|
||||
|
||||
## Helper for Processing Model Detections
|
||||
|
||||
:::supervision.tools.detections.Detections
|
||||
|
||||
## Count Objects That Pass a Line
|
||||
|
||||
:::supervision.tools.line_counter.LineCounter
|
||||
|
|
@ -19,8 +19,12 @@ extra:
|
|||
link: https://twitter.com/roboflow
|
||||
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Video: video.md
|
||||
- Home 🏠: index.md
|
||||
- Video 📷: video.md
|
||||
- Notebook Helpers 📓: notebook.md
|
||||
- Draw 🎨: draw.md
|
||||
- Geometry 📐: geometry.md
|
||||
- Tools 🛠: tools.md
|
||||
|
||||
theme:
|
||||
name: 'material'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
certifi==2022.12.7
|
||||
charset-normalizer==3.0.1
|
||||
click==8.1.3
|
||||
colorama==0.4.6
|
||||
ghp-import==2.1.0
|
||||
griffe==0.25.4
|
||||
idna==3.4
|
||||
importlib-metadata==6.0.0
|
||||
Jinja2==3.1.2
|
||||
Markdown==3.3.7
|
||||
MarkupSafe==2.1.2
|
||||
mergedeep==1.3.4
|
||||
mkdocs==1.4.2
|
||||
mkdocs-autorefs==0.4.1
|
||||
mkdocs-material==9.0.9
|
||||
mkdocs-material-extensions==1.1.1
|
||||
mkdocstrings==0.20.0
|
||||
mkdocstrings-python==0.8.3
|
||||
packaging==23.0
|
||||
Pygments==2.14.0
|
||||
pymdown-extensions==9.9.2
|
||||
python-dateutil==2.8.2
|
||||
PyYAML==6.0
|
||||
pyyaml_env_tag==0.1
|
||||
regex==2022.10.31
|
||||
requests==2.28.2
|
||||
six==1.16.0
|
||||
urllib3==1.26.14
|
||||
watchdog==2.2.1
|
||||
zipp==3.12.0
|
||||
|
|
@ -11,12 +11,16 @@ def draw_line(
|
|||
"""
|
||||
Draws a line on a given scene.
|
||||
|
||||
:param scene: np.ndarray : The scene on which the line will be drawn
|
||||
:param start: Point : The starting point of the line
|
||||
:param end: Point : The end point of the line
|
||||
:param color: Color : The color of the line
|
||||
:param thickness: int : The thickness of the line
|
||||
:return: np.ndarray : The scene with the line drawn on it
|
||||
Attributes:
|
||||
|
||||
scene (np.ndarray): The scene on which the line will be drawn
|
||||
start (Point): The starting point of the line
|
||||
end (Point): The end point of the line
|
||||
color (Color): The color of the line
|
||||
thickness (int): The thickness of the line
|
||||
|
||||
Returns:
|
||||
np.ndarray: The scene with the line drawn on it
|
||||
"""
|
||||
cv2.line(
|
||||
scene,
|
||||
|
|
@ -34,11 +38,19 @@ def draw_rectangle(
|
|||
"""
|
||||
Draws a rectangle on an image.
|
||||
|
||||
:param scene: np.ndarray : The image on which to draw the rectangle.
|
||||
:param rect: Rect : The rectangle to draw.
|
||||
:param color: Color : The color of the rectangle.
|
||||
:param thickness: int : The thickness of the rectangle border.
|
||||
:return: np.ndarray : The image with the rectangle drawn on it.
|
||||
Attributes:
|
||||
scene (np.ndarray): The scene on which the rectangle will be drawn
|
||||
rect (Rect): The rectangle to be drawn
|
||||
color (Color): The color of the rectangle
|
||||
thickness (int): The thickness of the rectangle border
|
||||
|
||||
Returns:
|
||||
np.ndarray: The scene with the rectangle drawn on it
|
||||
|
||||
Example:
|
||||
```python
|
||||
>>> # TODO: Add example
|
||||
```
|
||||
"""
|
||||
cv2.rectangle(
|
||||
scene,
|
||||
|
|
@ -58,6 +70,20 @@ def draw_filled_rectangle(scene: np.ndarray, rect: Rect, color: Color) -> np.nda
|
|||
:param rect: Rect : The rectangle to be drawn.
|
||||
:param color: Color : The color of the rectangle.
|
||||
:return: np.ndarray : The updated scene with the filled rectangle drawn on it.
|
||||
|
||||
Attributes:
|
||||
scene (np.ndarray): The scene on which the rectangle will be drawn
|
||||
rect (Rect): The rectangle to be drawn
|
||||
color (Color): The color of the rectangle
|
||||
|
||||
Returns:
|
||||
np.ndarray: The scene with the rectangle drawn on it
|
||||
|
||||
Example:
|
||||
```python
|
||||
>>> # TODO: Add example
|
||||
```
|
||||
|
||||
"""
|
||||
cv2.rectangle(
|
||||
scene,
|
||||
|
|
|
|||
|
|
@ -11,9 +11,16 @@ def show_frame_in_notebook(
|
|||
"""
|
||||
Display a frame in Jupyter Notebook using Matplotlib
|
||||
|
||||
:param frame: np.ndarray : The frame to be displayed.
|
||||
:param size: Tuple[int, int] : The size of the plot. default:(10,10)
|
||||
:param cmap: str : the colormap to use for single channel images. default:gray
|
||||
Attributes:
|
||||
frame (np.ndarray): The frame to be displayed.
|
||||
size (Tuple[int, int]): The size of the plot. default:(10,10)
|
||||
cmap (str): the colormap to use for single channel images. default:gray
|
||||
|
||||
Examples:
|
||||
```python
|
||||
>>> from supervision.notebook import show_frame_in_notebook
|
||||
|
||||
```
|
||||
"""
|
||||
if frame.ndim == 2:
|
||||
plt.figure(figsize=size)
|
||||
|
|
|
|||
|
|
@ -17,10 +17,11 @@ class Detections:
|
|||
"""
|
||||
Data class containing information about the detections in a video frame.
|
||||
|
||||
:param xyxy: np.ndarray : An array of shape (n, 4) containing the bounding boxes coordinates in format [x1, y1, x2, y2]
|
||||
:param confidence: np.ndarray : An array of shape (n,) containing the confidence scores of the detections.
|
||||
:param class_id: np.ndarray : An array of shape (n,) containing the class ids of the detections.
|
||||
:param tracker_id: Optional[np.ndarray] : An array of shape (n,) containing the tracker ids of the detections.
|
||||
Attributes:
|
||||
xyxy (np.ndarray): An array of shape (n, 4) containing the bounding boxes coordinates in format [x1, y1, x2, y2]
|
||||
confidence (np.ndarray): An array of shape (n,) containing the confidence scores of the detections.
|
||||
class_id (np.ndarray): An array of shape (n,) containing the class ids of the detections.
|
||||
tracker_id (Optional[np.ndarray]): An array of shape (n,) containing the tracker ids of the detections.
|
||||
"""
|
||||
self.xyxy: np.ndarray = xyxy
|
||||
self.confidence: np.ndarray = confidence
|
||||
|
|
@ -69,11 +70,17 @@ class Detections:
|
|||
"""
|
||||
Creates a Detections instance from a YOLOv5 output tensor
|
||||
|
||||
:param yolov5_output: np.ndarray : The output tensor from YOLOv5
|
||||
:return: Detections : A Detections instance representing the detections in the frame
|
||||
Attributes:
|
||||
yolov5_output (np.ndarray): The output tensor from YOLOv5
|
||||
|
||||
Returns:
|
||||
|
||||
Example:
|
||||
detections = Detections.from_yolov5(yolov5_output)
|
||||
```python
|
||||
>>> from supervision.tools.detections import Detections
|
||||
|
||||
>>> detections = Detections.from_yolov5(yolov5_output)
|
||||
```
|
||||
"""
|
||||
xyxy = yolov5_output[:, :4]
|
||||
confidence = yolov5_output[:, 4]
|
||||
|
|
@ -82,11 +89,14 @@ class Detections:
|
|||
|
||||
def filter(self, mask: np.ndarray, inplace: bool = False) -> Optional[np.ndarray]:
|
||||
"""
|
||||
Filter the detections by applying a mask
|
||||
Filter the detections by applying a mask.
|
||||
|
||||
:param mask: np.ndarray : A mask of shape (n,) containing a boolean value for each detection indicating if it should be included in the filtered detections
|
||||
:param inplace: bool : If True, the original data will be modified and self will be returned.
|
||||
:return: Optional[np.ndarray] : A new instance of Detections with the filtered detections, if inplace is set to False. None otherwise.
|
||||
Attributes:
|
||||
mask (np.ndarray): A mask of shape (n,) containing a boolean value for each detection indicating if it should be included in the filtered detections
|
||||
inplace (bool): If True, the original data will be modified and self will be returned.
|
||||
|
||||
Returns:
|
||||
Optional[np.ndarray]: A new instance of Detections with the filtered detections, if inplace is set to False. None otherwise.
|
||||
"""
|
||||
if inplace:
|
||||
self.xyxy = self.xyxy[mask]
|
||||
|
|
@ -120,12 +130,14 @@ class BoxAnnotator:
|
|||
"""
|
||||
A class for drawing bounding boxes on an image using detections provided.
|
||||
|
||||
:param color: Union[Color, ColorPalette] : The color to draw the bounding box, can be a single color or a color palette
|
||||
:param thickness: int : The thickness of the bounding box lines, default is 2
|
||||
:param text_color: Color : The color of the text on the bounding box, default is white
|
||||
:param text_scale: float : The scale of the text on the bounding box, default is 0.5
|
||||
:param text_thickness: int : The thickness of the text on the bounding box, default is 1
|
||||
:param text_padding: int : The padding around the text on the bounding box, default is 5
|
||||
Attributes:
|
||||
color (Union[Color, ColorPalette]): The color to draw the bounding box, can be a single color or a color palette
|
||||
thickness (int): The thickness of the bounding box lines, default is 2
|
||||
text_color (Color): The color of the text on the bounding box, default is white
|
||||
text_scale (float): The scale of the text on the bounding box, default is 0.5
|
||||
text_thickness (int): The thickness of the text on the bounding box, default is 1
|
||||
text_padding (int): The padding around the text on the bounding box, default is 5
|
||||
|
||||
"""
|
||||
self.color: Union[Color, ColorPalette] = color
|
||||
self.thickness: int = thickness
|
||||
|
|
@ -143,10 +155,13 @@ class BoxAnnotator:
|
|||
"""
|
||||
Draws bounding boxes on the frame using the detections provided.
|
||||
|
||||
:param frame: np.ndarray : The image on which the bounding boxes will be drawn
|
||||
:param detections: Detections : The detections for which the bounding boxes will be drawn
|
||||
:param labels: Optional[List[str]] : An optional list of labels corresponding to each detection. If labels is provided, the confidence score of the detection will be replaced with the label.
|
||||
:return: np.ndarray : The image with the bounding boxes drawn on it
|
||||
Attributes:
|
||||
frame (np.ndarray): The image on which the bounding boxes will be drawn
|
||||
detections (Detections): The detections for which the bounding boxes will be drawn
|
||||
labels (Optional[List[str]]): An optional list of labels corresponding to each detection. If labels is provided, the confidence score of the detection will be replaced with the label.
|
||||
|
||||
Returns:
|
||||
np.ndarray: The image with the bounding boxes drawn on it
|
||||
"""
|
||||
font = cv2.FONT_HERSHEY_SIMPLEX
|
||||
for i, (xyxy, confidence, class_id, tracker_id) in enumerate(detections):
|
||||
|
|
|
|||
|
|
@ -9,12 +9,18 @@ from supervision.tools.detections import Detections
|
|||
|
||||
|
||||
class LineCounter:
|
||||
"""
|
||||
Count the number of objects that cross a line.
|
||||
"""
|
||||
|
||||
def __init__(self, start: Point, end: Point):
|
||||
"""
|
||||
Initialize a LineCounter object.
|
||||
|
||||
:param start: Point : The starting point of the line.
|
||||
:param end: Point : The ending point of the line.
|
||||
Attributes:
|
||||
start (Point): The starting point of the line.
|
||||
end (Point): The ending point of the line.
|
||||
|
||||
"""
|
||||
self.vector = Vector(start=start, end=end)
|
||||
self.tracker_state: Dict[str, bool] = {}
|
||||
|
|
@ -25,7 +31,9 @@ class LineCounter:
|
|||
"""
|
||||
Update the in_count and out_count for the detections that cross the line.
|
||||
|
||||
:param detections: Detections : The detections for which to update the counts.
|
||||
Attributes:
|
||||
detections (Detections): The detections for which to update the counts.
|
||||
|
||||
"""
|
||||
for xyxy, confidence, class_id, tracker_id in detections:
|
||||
# handle detections with no tracker_id
|
||||
|
|
@ -77,13 +85,15 @@ class LineCounterAnnotator:
|
|||
"""
|
||||
Initialize the LineCounterAnnotator object with default values.
|
||||
|
||||
:param thickness: float : The thickness of the line that will be drawn.
|
||||
:param color: Color : The color of the line that will be drawn.
|
||||
:param text_thickness: float : The thickness of the text that will be drawn.
|
||||
:param text_color: Color : The color of the text that will be drawn.
|
||||
:param text_scale: float : The scale of the text that will be drawn.
|
||||
:param text_offset: float : The offset of the text that will be drawn.
|
||||
:param text_padding: int : The padding of the text that will be drawn.
|
||||
Attributes:
|
||||
thickness (float): The thickness of the line that will be drawn.
|
||||
color (Color): The color of the line that will be drawn.
|
||||
text_thickness (float): The thickness of the text that will be drawn.
|
||||
text_color (Color): The color of the text that will be drawn.
|
||||
text_scale (float): The scale of the text that will be drawn.
|
||||
text_offset (float): The offset of the text that will be drawn.
|
||||
text_padding (int): The padding of the text that will be drawn.
|
||||
|
||||
"""
|
||||
self.thickness: float = thickness
|
||||
self.color: Color = color
|
||||
|
|
@ -97,9 +107,13 @@ class LineCounterAnnotator:
|
|||
"""
|
||||
Draws the line on the frame using the line_counter provided.
|
||||
|
||||
:param frame: np.ndarray : The image on which the line will be drawn
|
||||
:param line_counter: LineCounter : The line counter that will be used to draw the line
|
||||
:return: np.ndarray : The image with the line drawn on it
|
||||
Attributes:
|
||||
frame (np.ndarray): The image on which the line will be drawn.
|
||||
line_counter (LineCounter): The line counter that will be used to draw the line.
|
||||
|
||||
Returns:
|
||||
np.ndarray: The image with the line drawn on it.
|
||||
|
||||
"""
|
||||
cv2.line(
|
||||
frame,
|
||||
|
|
|
|||
|
|
@ -7,27 +7,25 @@ from supervision.draw.color import Color
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'color_hex, expected_result, exception',
|
||||
"color_hex, expected_result, exception",
|
||||
[
|
||||
('fff', Color.white(), DoesNotRaise()),
|
||||
('#fff', Color.white(), DoesNotRaise()),
|
||||
('ffffff', Color.white(), DoesNotRaise()),
|
||||
('#ffffff', Color.white(), DoesNotRaise()),
|
||||
('f00', Color.red(), DoesNotRaise()),
|
||||
('0f0', Color.green(), DoesNotRaise()),
|
||||
('00f', Color.blue(), DoesNotRaise()),
|
||||
('#808000', Color(r=128, g=128, b=0), DoesNotRaise()),
|
||||
('', None, pytest.raises(ValueError)),
|
||||
('00', None, pytest.raises(ValueError)),
|
||||
('0000', None, pytest.raises(ValueError)),
|
||||
('0000000', None, pytest.raises(ValueError)),
|
||||
('ffg', None, pytest.raises(ValueError)),
|
||||
]
|
||||
("fff", Color.white(), DoesNotRaise()),
|
||||
("#fff", Color.white(), DoesNotRaise()),
|
||||
("ffffff", Color.white(), DoesNotRaise()),
|
||||
("#ffffff", Color.white(), DoesNotRaise()),
|
||||
("f00", Color.red(), DoesNotRaise()),
|
||||
("0f0", Color.green(), DoesNotRaise()),
|
||||
("00f", Color.blue(), DoesNotRaise()),
|
||||
("#808000", Color(r=128, g=128, b=0), DoesNotRaise()),
|
||||
("", None, pytest.raises(ValueError)),
|
||||
("00", None, pytest.raises(ValueError)),
|
||||
("0000", None, pytest.raises(ValueError)),
|
||||
("0000000", None, pytest.raises(ValueError)),
|
||||
("ffg", None, pytest.raises(ValueError)),
|
||||
],
|
||||
)
|
||||
def test_color_from_hex(
|
||||
color_hex,
|
||||
expected_result: Optional[Color],
|
||||
exception: Exception
|
||||
color_hex, expected_result: Optional[Color], exception: Exception
|
||||
) -> None:
|
||||
with exception:
|
||||
result = Color.from_hex(color_hex=color_hex)
|
||||
|
|
|
|||
|
|
@ -4,37 +4,28 @@ from supervision.geometry.dataclasses import Vector, Point
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'vector, point, expected_result',
|
||||
"vector, point, expected_result",
|
||||
[
|
||||
(Vector(start=Point(x=0, y=0), end=Point(x=5, y=5)), Point(x=-1, y=1), False),
|
||||
(Vector(start=Point(x=0, y=0), end=Point(x=5, y=5)), Point(x=6, y=6), False),
|
||||
(Vector(start=Point(x=0, y=0), end=Point(x=5, y=5)), Point(x=3, y=6), False),
|
||||
|
||||
(Vector(start=Point(x=5, y=5), end=Point(x=0, y=0)), Point(x=-1, y=1), True),
|
||||
(Vector(start=Point(x=5, y=5), end=Point(x=0, y=0)), Point(x=6, y=6), False),
|
||||
(Vector(start=Point(x=5, y=5), end=Point(x=0, y=0)), Point(x=3, y=6), True),
|
||||
|
||||
(Vector(start=Point(x=0, y=0), end=Point(x=1, y=0)), Point(x=0, y=0), False),
|
||||
(Vector(start=Point(x=0, y=0), end=Point(x=1, y=0)), Point(x=0, y=-1), True),
|
||||
(Vector(start=Point(x=0, y=0), end=Point(x=1, y=0)), Point(x=0, y=1), False),
|
||||
|
||||
(Vector(start=Point(x=1, y=0), end=Point(x=0, y=0)), Point(x=0, y=0), False),
|
||||
(Vector(start=Point(x=1, y=0), end=Point(x=0, y=0)), Point(x=0, y=-1), False),
|
||||
(Vector(start=Point(x=1, y=0), end=Point(x=0, y=0)), Point(x=0, y=1), True),
|
||||
|
||||
(Vector(start=Point(x=1, y=1), end=Point(x=1, y=3)), Point(x=0, y=0), False),
|
||||
(Vector(start=Point(x=1, y=1), end=Point(x=1, y=3)), Point(x=1, y=4), False),
|
||||
(Vector(start=Point(x=1, y=1), end=Point(x=1, y=3)), Point(x=2, y=4), True),
|
||||
|
||||
(Vector(start=Point(x=1, y=3), end=Point(x=1, y=1)), Point(x=0, y=0), True),
|
||||
(Vector(start=Point(x=1, y=3), end=Point(x=1, y=1)), Point(x=1, y=4), False),
|
||||
(Vector(start=Point(x=1, y=3), end=Point(x=1, y=1)), Point(x=2, y=4), False),
|
||||
]
|
||||
],
|
||||
)
|
||||
def test_vector_is_in(
|
||||
vector: Vector,
|
||||
point: Point,
|
||||
expected_result: bool
|
||||
) -> None:
|
||||
def test_vector_is_in(vector: Vector, point: Point, expected_result: bool) -> None:
|
||||
result = vector.is_in(point=point)
|
||||
assert result == expected_result
|
||||
|
|
|
|||
Loading…
Reference in New Issue