ndsampler.isect_indexer module

class ndsampler.isect_indexer.FrameIntersectionIndex[source]

Bases: NiceRepr

Build spatial tree for each frame so we can quickly determine if a random negative is too close to a positive. For each frame/image we built a qtree.

Example

>>> from ndsampler.isect_indexer import *
>>> import kwcoco
>>> import ubelt as ub
>>> dset = kwcoco.CocoDataset.demo()
>>> dset._ensure_imgsize()
>>> dset.remove_annotations([ann for ann in dset.anns.values()
>>>                          if 'bbox' not in ann])
>>> # Build intersection index aroung coco dataset
>>> self = FrameIntersectionIndex.from_coco(dset)
>>> gid = 1
>>> box = kwimage.Boxes([0, 10, 100, 100], 'xywh')
>>> isect_aids, ious = self.ious(gid, box)
>>> print(ub.urepr(ious.tolist(), nl=0, precision=4))
[0.0507]
classmethod from_coco(dset, verbose=0)[source]
Parameters:

dset (kwcoco.CocoDataset) – positive annotation data

Returns:

FrameIntersectionIndex

classmethod demo(*args, **kwargs)[source]

Create a demo intersection index.

Parameters:
  • *args – see kwcoco.CocoDataset.demo

  • **kwargs – see kwcoco.CocoDataset.demo

Returns:

FrameIntersectionIndex

overlapping_aids(gid, box)[source]

Find all annotation-ids within an image that have some overlap with a bounding box.

Parameters:
  • gid (int) – an image id

  • box (kwimage.Boxes) – the specified region

Returns:

list of annotation ids

Return type:

List[int]

CommandLine

USE_RTREE=0 xdoctest -m ndsampler.isect_indexer FrameIntersectionIndex.overlapping_aids
USE_RTREE=1 xdoctest -m ndsampler.isect_indexer FrameIntersectionIndex.overlapping_aids

Example

>>> from ndsampler.isect_indexer import *  # NOQA
>>> self = FrameIntersectionIndex.demo('shapes128')
>>> for gid, qtree in self.qtrees.items():
>>>     box = kwimage.Boxes([0, 0, qtree.width, qtree.height], 'xywh')
>>>     print(self.overlapping_aids(gid, box))
ious(gid, box)[source]

Find overlaping annotations in a specific image and their intersection over union with a a query box.

Parameters:
  • gid (int) – an image id

  • box (kwimage.Boxes) – the specified region

Returns:

isect_aids: list of annotation ids ious: jaccard score for each returned annotation id

Return type:

Tuple[List[int], ndarray]

iooas(gid, box)[source]

Intersection over other’s area

Parameters:
  • gid (int) – an image id

  • box (kwimage.Boxes) – the specified region

Like iou, but non-symetric, returned number is a percentage of the other’s (groundtruth) area. This means we dont care how big the (negative) box is.

random_negatives(num, anchors=None, window_size=None, gids=None, thresh=0.0, exact=True, rng=None, patience=None)[source]

Finds random boxes that don’t have a large overlap with positive instances.

Parameters:
  • num (int) – number of negative boxes to generate (actual number of boxes returned may be less unless exact=True)

  • anchors (ndarray) – prior normalized aspect ratios for negative boxes. Mutually exclusive with window_size.

  • window_size (ndarray) – absolute (W, H) sizes to use for negative boxes. Mutually exclusive with anchors.

  • gids (List[int]) – image-ids to generate negatives for, if not specified generates for all images.

  • thresh (float) – overlap area threshold as a percentage of the negative box size. When thresh=0.0, that means negatives cannot overlap any positive, when threh=1.0, there are no constrains on negative placement.

  • exact (bool) – if True, ensure that we generate exactly num boxes

  • rng (RandomState) – random number generator

Example

>>> from ndsampler.isect_indexer import *
>>> import ndsampler
>>> import kwcoco
>>> dset = kwcoco.CocoDataset.demo('shapes8')
>>> self = FrameIntersectionIndex.from_coco(dset)
>>> anchors = np.array([[.35, .15], [.2, .2], [.1, .1]])
>>> #num = 25
>>> num = 5
>>> rng = kwarray.ensure_rng(None)
>>> neg_gids, neg_boxes = self.random_negatives(
>>>     num, anchors, gids=[1], rng=rng, thresh=0.01, exact=1)
>>> # xdoc: +REQUIRES(--show)
>>> gid = sorted(set(neg_gids))[0]
>>> boxes = neg_boxes.compress(neg_gids == gid)
>>> import kwplot
>>> kwplot.autompl()
>>> img = kwimage.imread(dset.imgs[gid]['file_name'])
>>> kwplot.imshow(img, doclf=True, fnum=1, colorspace='bgr')
>>> support = self._support(gid)
>>> kwplot.draw_boxes(support, color='blue')
>>> kwplot.draw_boxes(boxes, color='orange')
_images/fig_ndsampler_isect_indexer_FrameIntersectionIndex_random_negatives_002.jpeg

Example

>>> from ndsampler.isect_indexer import *
>>> import kwcoco
>>> dset = kwcoco.CocoDataset.demo('shapes8')
>>> self = FrameIntersectionIndex.from_coco(dset)
>>> #num = 25
>>> num = 5
>>> rng = kwarray.ensure_rng(None)
>>> window_size = (50, 50)
>>> neg_gids, neg_boxes = self.random_negatives(
>>>     num, window_size=window_size, gids=[1], rng=rng,
>>>     thresh=0.01, exact=1)
>>> # xdoc: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()
>>> gid = sorted(set(neg_gids))[0]
>>> boxes = neg_boxes.compress(neg_gids == gid)
>>> img = kwimage.imread(dset.imgs[gid]['file_name'])
>>> kwplot.imshow(img, doclf=True, fnum=1, colorspace='bgr')
>>> support = self._support(gid)
>>> support.draw(color='blue')
>>> boxes.draw(color='orange')
_images/fig_ndsampler_isect_indexer_FrameIntersectionIndex_random_negatives_003.jpeg