Return the contour of binary input images that only compose of 0 and 1, with Laplacian kernel set as default for edge detection. Typical usage is to plot the edge of label or segmentation output. Args: kernel_type: the method applied to do edge detection, default is "Laplace".
| 587 | |
| 588 | |
| 589 | class LabelToContour(Transform): |
| 590 | """ |
| 591 | Return the contour of binary input images that only compose of 0 and 1, with Laplacian kernel |
| 592 | set as default for edge detection. Typical usage is to plot the edge of label or segmentation output. |
| 593 | |
| 594 | Args: |
| 595 | kernel_type: the method applied to do edge detection, default is "Laplace". |
| 596 | |
| 597 | Raises: |
| 598 | NotImplementedError: When ``kernel_type`` is not "Laplace". |
| 599 | |
| 600 | """ |
| 601 | |
| 602 | backend = [TransformBackends.TORCH] |
| 603 | |
| 604 | def __init__(self, kernel_type: str = "Laplace") -> None: |
| 605 | if kernel_type != "Laplace": |
| 606 | raise NotImplementedError('Currently only kernel_type="Laplace" is supported.') |
| 607 | self.kernel_type = kernel_type |
| 608 | |
| 609 | def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: |
| 610 | """ |
| 611 | Args: |
| 612 | img: torch tensor data to extract the contour, with shape: [channels, height, width[, depth]] |
| 613 | |
| 614 | Raises: |
| 615 | ValueError: When ``image`` ndim is not one of [3, 4]. |
| 616 | |
| 617 | Returns: |
| 618 | A torch tensor with the same shape as img, note: |
| 619 | 1. it's the binary classification result of whether a pixel is edge or not. |
| 620 | 2. in order to keep the original shape of mask image, we use padding as default. |
| 621 | 3. the edge detection is just approximate because it defects inherent to Laplace kernel, |
| 622 | ideally the edge should be thin enough, but now it has a thickness. |
| 623 | |
| 624 | """ |
| 625 | img = convert_to_tensor(img, track_meta=get_track_meta()) |
| 626 | img_: torch.Tensor = convert_to_tensor(img, track_meta=False) |
| 627 | spatial_dims = len(img_.shape) - 1 |
| 628 | img_ = img_.unsqueeze(0) # adds a batch dim |
| 629 | if spatial_dims == 2: |
| 630 | kernel = torch.tensor([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype=torch.float32) |
| 631 | elif spatial_dims == 3: |
| 632 | kernel = -1.0 * torch.ones(3, 3, 3, dtype=torch.float32) |
| 633 | kernel[1, 1, 1] = 26.0 |
| 634 | else: |
| 635 | raise ValueError(f"{self.__class__} can only handle 2D or 3D images.") |
| 636 | contour_img = apply_filter(img_, kernel) |
| 637 | contour_img.clamp_(min=0.0, max=1.0) |
| 638 | output, *_ = convert_to_dst_type(contour_img.squeeze(0), img) |
| 639 | return output |
| 640 | |
| 641 | |
| 642 | class Ensemble: |
no outgoing calls
searching dependent graphs…