Skip to content

Commit

Permalink
Merge pull request #1840 from AdeelH/docs
Browse files Browse the repository at this point in the history
Misc. documentation improvements
  • Loading branch information
AdeelH authored Jul 21, 2023
2 parents bff97f3 + 6376d0c commit e229483
Show file tree
Hide file tree
Showing 22 changed files with 229 additions and 87 deletions.
4 changes: 4 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ def setup(app: 'Sphinx') -> None:
'https://pytorch.org/docs/stable/',
'https://pytorch.org/docs/stable/objects.inv',
),
'onnx': (
'https://onnx.ai/onnx/',
'https://onnx.ai/onnx/objects.inv',
),
}

#########################
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Optional
from typing import Any, Optional, Union
from pyproj import Transformer

import numpy as np
Expand Down Expand Up @@ -99,10 +99,16 @@ def _pixel_to_map(self, pixel_point):
return map_point

@classmethod
def from_dataset(cls,
dataset,
map_crs: Optional[str] = 'epsg:4326',
**kwargs) -> 'RasterioCRSTransformer':
def from_dataset(
cls, dataset: Any, map_crs: Optional[str] = 'epsg:4326', **kwargs
) -> Union[IdentityCRSTransformer, 'RasterioCRSTransformer']:
"""Build from rasterio dataset.
Args:
dataset (Any): Rasterio dataset.
map_crs (Optional[str]): Target map CRS. Defaults to 'epsg:4326'.
**kwargs: Extra args for :meth:`.__init__`.
"""
transform = dataset.transform
image_crs = None if dataset.crs is None else dataset.crs.wkt
map_crs = image_crs if map_crs is None else map_crs
Expand All @@ -118,7 +124,14 @@ def from_dataset(cls,
return cls(transform, image_crs, map_crs, **kwargs)

@classmethod
def from_uri(cls, uri: str, map_crs: Optional[str] = 'epsg:4326',
**kwargs) -> 'RasterioCRSTransformer':
def from_uri(cls, uri: str, map_crs: Optional[str] = 'epsg:4326', **kwargs
) -> Union[IdentityCRSTransformer, 'RasterioCRSTransformer']:
"""Build from raster URI.
Args:
uri (Any): Raster URI.
map_crs (Optional[str]): Target map CRS. Defaults to 'epsg:4326'.
**kwargs: Extra args for :meth:`.__init__`.
"""
with rio.open(uri) as ds:
return cls.from_dataset(ds, map_crs=map_crs, **kwargs)
14 changes: 8 additions & 6 deletions rastervision_core/rastervision/core/data/label/labels.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Defines the abstract Labels class."""

from typing import TYPE_CHECKING, Any, Iterable
from typing import TYPE_CHECKING, Any, Iterable, List
from abc import (ABC, abstractclassmethod, abstractmethod)

if TYPE_CHECKING:
from shapely.geometry import Polygon
from rastervision.core.box import Box


Expand All @@ -15,24 +16,25 @@ class Labels(ABC):
"""

@abstractmethod
def __add__(self, other):
def __add__(self, other: 'Labels'):
"""Add labels to these labels.
Returns a concatenation of this and the other labels.
"""
pass

@abstractmethod
def filter_by_aoi(self, aoi_polygons):
"""Returns a copy of these labels filtered by a given set of AOI polygons
def filter_by_aoi(self, aoi_polygons: List['Polygon']) -> 'Labels':
"""Return a copy of these labels filtered by given AOI polygons.
Args:
aoi_polygons - A list of AOI polygons to filter by, in pixel coordinates.
aoi_polygons: List of AOI polygons to filter by, in pixel
coordinates.
"""
pass

@abstractmethod
def __eq__(self, other):
def __eq__(self, other: 'Labels'):
pass

@abstractmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from rastervision.core.box import Box
from rastervision.core.data.label.labels import Labels
from rastervision.core.data.label.tfod_utils.np_box_list import BoxList
from rastervision.core.data.label.tfod_utils.np_box_list import NpBoxList
from rastervision.core.data.label.tfod_utils.np_box_list_ops import (
prune_non_overlapping_boxes, clip_to_window, concatenate,
non_max_suppression)
Expand Down Expand Up @@ -33,7 +33,7 @@ def __init__(self,
class_ids: int numpy array of size n with class ids
scores: float numpy array of size n
"""
self.boxlist = BoxList(npboxes)
self.boxlist = NpBoxList(npboxes)
# This field name actually needs to be 'classes' to be able to use
# certain utility functions in the TF Object Detection API.
self.boxlist.add_field('classes', class_ids)
Expand Down Expand Up @@ -103,7 +103,7 @@ def make_empty(cls) -> 'ObjectDetectionLabels':
return cls(npboxes, class_ids, scores)

@staticmethod
def from_boxlist(boxlist: BoxList):
def from_boxlist(boxlist: NpBoxList):
"""Make ObjectDetectionLabels from BoxList object."""
scores = (boxlist.get_field('scores')
if boxlist.has_field('scores') else None)
Expand Down Expand Up @@ -166,7 +166,7 @@ def __len__(self) -> int:
def __str__(self) -> str:
return str(self.boxlist.get())

def to_boxlist(self) -> BoxList:
def to_boxlist(self) -> NpBoxList:
return self.boxlist

def to_dict(self, round_boxes: bool = True) -> dict:
Expand Down Expand Up @@ -245,7 +245,7 @@ def get_overlapping(labels: 'ObjectDetectionLabels',
clip: If True, clip label boxes to the window.
"""
window_npbox = window.npbox_format()
window_boxlist = BoxList(np.expand_dims(window_npbox, axis=0))
window_boxlist = NpBoxList(np.expand_dims(window_npbox, axis=0))
boxlist = prune_non_overlapping_boxes(
labels.boxlist, window_boxlist, minoverlap=ioa_thresh)
if clip:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from rastervision.core.data.label.utils import discard_prediction_edges

if TYPE_CHECKING:
from shapely.geometry import Polygon
from rastervision.core.data import (ClassConfig, CRSTransformer,
VectorOutputConfig)

Expand Down Expand Up @@ -66,21 +67,34 @@ def get_label_arr(self, window: Box,
pass

def get_windows(self, **kwargs) -> List[Box]:
"""Generate sliding windows over the local extent. The keyword args
are passed to Box.get_windows() and can therefore be used to control
the specifications of the windows.
"""Generate sliding windows over the local extent.
The keyword args are passed to :meth:`.Box.get_windows` and can
therefore be used to control the specifications of the windows.
If the keyword args do not contain size, a list of length 1,
containing the full extent is returned.
Args:
**kwargs: Extra args for :meth:`.Box.get_windows`.
"""
size: Optional[int] = kwargs.pop('size', None)
if size is None:
return [self.extent]
return self.extent.get_windows(size, size, **kwargs)

def filter_by_aoi(self, aoi_polygons: list, null_class_id: int,
def filter_by_aoi(self, aoi_polygons: List['Polygon'], null_class_id: int,
**kwargs) -> 'SemanticSegmentationLabels':
"""Keep only the values that lie inside the AOI."""
"""Keep only the values that lie inside the AOI.
Args:
aoi_polygons (List[Polygon]): AOI polygons to filter by, in pixel
coordinates.
null_class_id (int): Class ID to assign to pixels falling outside
the AOI polygons.
**kwargs: Extra args for
:meth:`.SemanticSegmentationLabels.get_windows`.
"""
if not aoi_polygons:
return self
for window in self.get_windows(**kwargs):
Expand All @@ -95,7 +109,7 @@ def mask_fill(self, window: Box, mask: np.ndarray,
"""
pass

def _filter_window_by_aoi(self, window: Box, aoi_polygons: list,
def _filter_window_by_aoi(self, window: Box, aoi_polygons: List['Polygon'],
null_class_id: int) -> None:
window_geom = window.to_shapely()
label_arr = self[window]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import numpy as np


class BoxList(object):
class NpBoxList(object):
"""A list of bounding boxes as a [y_min, x_min, y_max, x_max] numpy array.
It is assumed that all bounding boxes within a given list correspond to a
Expand Down
Loading

0 comments on commit e229483

Please sign in to comment.