Vision inference


source

save_series_pred

def save_series_pred(
    series_obj, save_dir, val:str='1234'
):

Saves series prediction with updated DICOM UIDs.


source

load_system_resources

def load_system_resources(
    models_path, learner_fn, variables_fn
):

Load necessary resources like learner and variables.


source

load_model_resources

def load_model_resources(
    model_path, device:str='cpu'
):

Load a safe model artifact and its embedded standard inference config.

This is the Safetensors-only counterpart to load_system_resources.


source

predict_from_config

def predict_from_config(
    model, inference_config, input
):

Apply serialized item transforms, execute one input, and decode its output contract.


source

inference_from_config

def inference_from_config(
    model, inference_config, fn:(<class 'str'>, <class 'pathlib.Path'>)='',
    save_path:(<class 'str'>, <class 'pathlib.Path'>)=None, org_img:NoneType=None, input_img:NoneType=None,
    org_size:NoneType=None
):

Run model-only binary/multiclass segmentation and restore original image space.

from fastcore.test import test_eq, test_fail
from fastMONAI.utils import make_output_spec, standard_inference_config

class _BinaryInferenceModel(torch.nn.Module):
    def forward(self, x):
        return x[:, :1]

_binary_config = standard_inference_config(
    apply_reorder=False,
    target_spacing=None,
    item_tfms=[{
        'name': 'PadOrCrop', 'size': [6, 6, 6],
        'padding_mode': 0, 'mask_name': None,
    }],
    output_spec=make_output_spec('binary_segmentation', threshold=0.5),
)
_binary_input = torch.linspace(-1, 1, 4 ** 3).reshape(1, 4, 4, 4)
_binary_pred = predict_from_config(_BinaryInferenceModel(), _binary_config, _binary_input)
test_eq(tuple(_binary_pred.shape), (1, 6, 6, 6))
test_eq(_binary_pred.dtype, torch.int64)

_classification_config = standard_inference_config(
    apply_reorder=False,
    target_spacing=None,
    item_tfms=[],
    output_spec=make_output_spec('classification', classes=['negative', 'positive']),
)
class _ClassificationInferenceModel(torch.nn.Module):
    def forward(self, x):
        return torch.tensor([[-1.0, 2.0]], device=x.device)

test_eq(
    predict_from_config(
        _ClassificationInferenceModel(), _classification_config, torch.zeros(1, 4, 4, 4)
    ),
    'positive',
)
test_fail(
    lambda: inference_from_config(_BinaryInferenceModel(), _classification_config),
    contains='only supports',
)

_regression_config = standard_inference_config(
    apply_reorder=False,
    target_spacing=None,
    item_tfms=[],
    output_spec=make_output_spec('regression', output_shape=[1]),
)
class _RegressionInferenceModel(torch.nn.Module):
    def forward(self, x):
        return torch.tensor([[42.0]], device=x.device)

test_eq(
    predict_from_config(
        _RegressionInferenceModel(), _regression_config, torch.zeros(1, 4, 4, 4)
    ),
    torch.tensor([42.0]),
)
test_fail(
    lambda: predict_from_config(_BinaryInferenceModel(), _binary_config, torch.zeros(4, 4, 4)),
    contains='channel-first',
)

source

inference

def inference(
    learn_inf, apply_reorder, target_spacing, fn:(<class 'str'>, <class 'pathlib.Path'>)='',
    save_path:(<class 'str'>, <class 'pathlib.Path'>)=None, org_img:NoneType=None, input_img:NoneType=None,
    org_size:NoneType=None
):

Predict on new data using exported model.


source

compute_binary_tumor_volume

def compute_binary_tumor_volume(
    mask_data:Image
):

Compute the volume of the tumor in milliliters (ml).

Post-processing


source

refine_binary_pred_mask

def refine_binary_pred_mask(
    pred_mask, remove_size:(<class 'int'>, <class 'float'>), percentage:float=0.2, verbose:bool=False
)->Tensor:

Removes small objects from the predicted binary mask.

Args: pred_mask: The (already binary) predicted mask to clean up. remove_size: Absolute reference object size in voxels (required, > 0). Objects smaller than remove_size * percentage are removed. percentage: Fraction of remove_size used as the cutoff. Defaults to 0.2. verbose: If True, print the number of components. Defaults to False.

Returns: The processed mask with small objects removed.

from fastcore.test import test_eq, test_fail

# large 4x4x4 (64 vox) + small 2x2x2 (8 vox) disjoint cubes
_m = np.zeros((10, 10, 10), dtype=np.uint8)
_m[1:5, 1:5, 1:5] = 1
_m[7:9, 7:9, 7:9] = 1

# cutoff 64*0.2=12.8 removes the small cube, keeps the large
_out = refine_binary_pred_mask(_m, remove_size=64, percentage=0.2)
test_eq(float(_out.sum()), 64.)
test_eq(float(_out[7:9, 7:9, 7:9].sum()), 0.)

# cutoff 8*0.2=1.6 keeps both cubes
_out2 = refine_binary_pred_mask(_m, remove_size=8, percentage=0.2)
test_eq(float(_out2.sum()), 72.)

# empty mask returns zeros
_empty = np.zeros((4, 4, 4), dtype=np.uint8)
test_eq(float(refine_binary_pred_mask(_empty, remove_size=8).sum()), 0.)

# remove_size is required and must be positive
test_fail(lambda: refine_binary_pred_mask(_m))
test_fail(lambda: refine_binary_pred_mask(_m, remove_size=None))
test_fail(lambda: refine_binary_pred_mask(_m, remove_size=0))
Parameter `min_size` is deprecated since version 0.26.0 and will be removed in 2.0.0 (or later). To avoid this warning, please use the parameter `max_size` instead. For more details, see the documentation of `remove_small_objects`. Note that the new threshold removes objects smaller than **or equal to** its value, while the previous parameter only removed smaller ones.

source

keep_largest

def keep_largest(
    pred_mask:Tensor
)->Tensor:

Keep only the largest connected component in a binary mask.

Args: pred_mask: Binary prediction mask tensor.

Returns: Binary mask with only the largest connected component.