Source code for acia.segm.processor.cpn

"""Module for Contour Proposal Networks"""

import celldetection as cd
import numpy as np
import torch
from tqdm.auto import tqdm

from acia.attribute import attribute_segmentation
from acia.base import Contour, Overlay


[docs] class CPNSegmenter: """Contour Proposal Networks segmenter: https://github.com/FZJ-INM1-BDA/celldetection"""
[docs] def __init__(self, nms_thresh=0.4): # Load pretrained model self.device = "cuda" if torch.cuda.is_available() else "cpu" self.model = cd.fetch_model( "ginoro_CpnResNeXt101UNet-fbe875f1a3e5ce2c", check_hash=True ).to(self.device) self.model.nms_thresh = nms_thresh self.model.eval()
def __call__(self, image_sequence): contours = [] max_frame = 0 for frame_id, img in enumerate( tqdm(image_sequence, desc="Perform segmentation...") ): # Load input img = img.raw print(img.dtype, img.shape, (img.min(), img.max())) if len(img.shape) == 3: # we have HxWxC # strip of last channel to make it grayscale img = img[..., 0] # convert to rgb img = np.stack((img,) * 3, axis=-1) # Run model with torch.no_grad(): x = cd.to_tensor( img, transpose=True, device=self.device, dtype=torch.float32 ) x = x / x.max() # ensure 0..1 range x = x[ None ] # add batch dimension: Tensor[3, h, w] -> Tensor[1, 3, h, w] y = self.model(x) frame_ov = y["contours"][0] torch_frame_ov = frame_ov.cpu().numpy() for cont in torch_frame_ov: contours.append(Contour(cont, -1, frame_id, 0)) max_frame = frame_id overlay = Overlay(contours, frames=list(range(max_frame + 1))) attribute_segmentation(overlay, self) return overlay