Generate extreme points from an image. These are used to generate initial segmentation for annotation models. An optional perturbation can be passed to simulate user clicks. Args: img: Image to generate extreme points from. Expected Shape is ``(spatial_dim1, [, spat
(
img: NdarrayOrTensor, rand_state: np.random.RandomState | None = None, background: int = 0, pert: float = 0.0
)
| 1578 | |
| 1579 | |
| 1580 | def get_extreme_points( |
| 1581 | img: NdarrayOrTensor, rand_state: np.random.RandomState | None = None, background: int = 0, pert: float = 0.0 |
| 1582 | ) -> list[tuple[int, ...]]: |
| 1583 | """ |
| 1584 | Generate extreme points from an image. These are used to generate initial segmentation |
| 1585 | for annotation models. An optional perturbation can be passed to simulate user clicks. |
| 1586 | |
| 1587 | Args: |
| 1588 | img: |
| 1589 | Image to generate extreme points from. Expected Shape is ``(spatial_dim1, [, spatial_dim2, ...])``. |
| 1590 | rand_state: `np.random.RandomState` object used to select random indices. |
| 1591 | background: Value to be consider as background, defaults to 0. |
| 1592 | pert: Random perturbation amount to add to the points, defaults to 0.0. |
| 1593 | |
| 1594 | Returns: |
| 1595 | A list of extreme points, its length is equal to 2 * spatial dimension of input image. |
| 1596 | The output format of the coordinates is: |
| 1597 | |
| 1598 | [1st_spatial_dim_min, 1st_spatial_dim_max, 2nd_spatial_dim_min, ..., Nth_spatial_dim_max] |
| 1599 | |
| 1600 | Raises: |
| 1601 | ValueError: When the input image does not have any foreground pixel. |
| 1602 | """ |
| 1603 | check_non_lazy_pending_ops(img, name="get_extreme_points") |
| 1604 | if rand_state is None: |
| 1605 | rand_state = np.random.random.__self__ # type: ignore |
| 1606 | indices = where(img != background) |
| 1607 | if np.size(indices[0]) == 0: |
| 1608 | raise ValueError("get_extreme_points: no foreground object in mask!") |
| 1609 | |
| 1610 | def _get_point(val, dim): |
| 1611 | """ |
| 1612 | Select one of the indices within slice containing val. |
| 1613 | |
| 1614 | Args: |
| 1615 | val : value for comparison |
| 1616 | dim : dimension in which to look for value |
| 1617 | """ |
| 1618 | idx = where(indices[dim] == val)[0] |
| 1619 | idx = idx.cpu() if isinstance(idx, torch.Tensor) else idx |
| 1620 | idx = rand_state.choice(idx) if rand_state is not None else idx |
| 1621 | pt = [] |
| 1622 | for j in range(img.ndim): |
| 1623 | # add +- pert to each dimension |
| 1624 | val = int(indices[j][idx] + 2.0 * pert * (rand_state.rand() if rand_state is not None else 0.5 - 0.5)) |
| 1625 | val = max(val, 0) |
| 1626 | val = min(val, img.shape[j] - 1) |
| 1627 | pt.append(val) |
| 1628 | return pt |
| 1629 | |
| 1630 | points = [] |
| 1631 | for i in range(img.ndim): |
| 1632 | points.append(tuple(_get_point(indices[i].min(), i))) |
| 1633 | points.append(tuple(_get_point(indices[i].max(), i))) |
| 1634 | |
| 1635 | return points |
| 1636 | |
| 1637 |
searching dependent graphs…