CoolFace
Apppublic

Awesomenous/CellSegmentation

sourceHugging Facebsd-3-clauseupdated 3y agoView on Hugging Face
1likes
app.py116 linesDownload Raw Back to root
1import numpy as np2import torch3from torch import nn4from torchvision.transforms.functional import center_crop5from torchvision.transforms import Resize6import gradio as gr7from PIL import Image8 9class CNNBlock(nn.Module):10    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=0):11        super(CNNBlock, self).__init__()12    13        self.seq_block = nn.Sequential(14            nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, bias=False),15            nn.BatchNorm2d(out_channels),16            nn.ReLU(inplace=True)17        )18    19    def forward(self, x):20        return self.seq_block(x)21 22class CNNBlocks(nn.Module):23    def __init__(self, n_conv, in_channels, out_channels, padding):24        super(CNNBlocks, self).__init__()25        26        self.layers = nn.ModuleList()27        for i in range(n_conv):28            self.layers.append(CNNBlock(in_channels, out_channels, padding=padding))29            in_channels = out_channels30        31    def forward(self, x):32        for layers in self.layers:33            x = layers(x)34        return x35 36class Encoder(nn.Module):37    def __init__(self, in_channels, out_channels, padding, downhill=4):38        super(Encoder, self).__init__()39        40        self.enc_layers = nn.ModuleList()41        for i in range(downhill):42            self.enc_layers += [CNNBlocks(n_conv=2, in_channels=in_channels, out_channels=out_channels, padding=padding), 43                                nn.MaxPool2d(2,2)]44            in_channels = out_channels45            out_channels *= 246        self.enc_layers.append(CNNBlocks(n_conv=2, in_channels=in_channels, out_channels=out_channels, padding=padding))47    48    def forward(self, x):49        route_connection = []50        for layer in self.enc_layers:51            x = layer(x)52            if isinstance(layer, CNNBlocks):53                route_connection.append(x)54        return x, route_connection55 56class Decoder(nn.Module):57    def __init__(self, in_channels, out_channels, exit_channels, padding, uphill=4):58        super(Decoder, self).__init__()59        60        self.exit_channels = exit_channels61        self.layers = nn.ModuleList()62        for i in range(uphill):63 64            self.layers += [nn.ConvTranspose2d(in_channels, out_channels, kernel_size=2, stride=2),65                            CNNBlocks(n_conv=2, in_channels=in_channels, out_channels=out_channels, padding=padding)]66            in_channels //= 267            out_channels //= 268        self.layers.append(nn.Conv2d(in_channels, exit_channels, kernel_size=1, padding=0))69 70    def forward(self, x, routes_connection):71        routes_connection.pop(-1)72        for layer in self.layers:73            if isinstance(layer, CNNBlocks):74                routes_connection[-1] = center_crop(routes_connection[-1], (x.shape[2], x.shape[3]))75                x = torch.cat([x, routes_connection.pop(-1)], dim=1)76                x = layer(x)77            else:78                x = layer(x)79        return x80 81class UNET(nn.Module):82    def __init__(self, in_channels, first_out_channels, exit_channels, downhill, padding=0):83        super(UNET, self).__init__()84        self.encoder = Encoder(in_channels, first_out_channels, padding=padding, downhill=downhill)85        self.decoder = Decoder(first_out_channels*(2**downhill), first_out_channels*(2**(downhill-1)),86                               exit_channels, padding=padding, uphill=downhill)87    def forward(self, x):88        enc_out, routes = self.encoder(x)89        out = self.decoder(enc_out, routes)90        return out91 92model = UNET(3, 64, 1, 4, 1)93model.load_state_dict(torch.load("epoch_27.pth", map_location=torch.device('cpu')))94 95def predict(input_image):96    transform1 = Resize(size=(256,256))97    numpy_in = np.array(input_image.convert("RGB"))98    img = transform1(torch.from_numpy(numpy_in).permute(2,0,1).unsqueeze(dim=0).type(torch.float32))99    model.eval()100    with torch.inference_mode():101        pred = model(img)102    transform2 = Resize(size=(numpy_in.shape[0], numpy_in.shape[1]))103    final_img = transform2(pred.squeeze(dim=0).sigmoid()).round().squeeze().numpy()104    return Image.fromarray((final_img * 255).astype(np.uint8))105 106interface = gr.Interface(107    fn=predict,108    inputs=gr.Image(type="pil", label="Upload Image"),109    outputs=gr.Image(type="pil", label="Segmentation Mask"),110    examples=["00ae65c1c6631ae6f2be1a449902976e6eb8483bf6b0740d00530220832c6d3e.png",111             "2f929b067a59f88530b6bfa6f6889bc3a38adf88d594895973d1c8b2549fd93d.png",112             "432f367a4c5b5674de2e2977744d10289a064e5704b21af6607b4975be47c580.png",113             "Picture2.png"]114)115 116interface.launch()