{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":6116,"databundleVersionId":46660},{"sourceType":"competition","sourceId":27923,"databundleVersionId":3495119}],"dockerImageVersionId":31286,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\n\nimport numpy as np\nimport pandas as pd\n\nimport cv2\nimport skimage\nimport albumentations as A\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom matplotlib.animation import FuncAnimation\nfrom IPython.display import HTML\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:29.845131Z","iopub.execute_input":"2026-04-16T13:23:29.846022Z","iopub.status.idle":"2026-04-16T13:23:29.851176Z","shell.execute_reply.started":"2026-04-16T13:23:29.845985Z","shell.execute_reply":"2026-04-16T13:23:29.850273Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install segmentation_models_pytorch monai py7zr\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:29.853870Z","iopub.execute_input":"2026-04-16T13:23:29.854135Z","iopub.status.idle":"2026-04-16T13:23:34.183578Z","shell.execute_reply.started":"2026-04-16T13:23:29.854110Z","shell.execute_reply":"2026-04-16T13:23:34.182322Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import segmentation_models_pytorch \nimport monai\n\nfrom monai.data import CacheDataset, DataLoader\nfrom monai.transforms import Compose\nfrom monai.transforms import *\n\nfrom monai.inferers import sliding_window_inference\n\nimport py7zr\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:34.185965Z","iopub.execute_input":"2026-04-16T13:23:34.186281Z","iopub.status.idle":"2026-04-16T13:23:34.193719Z","shell.execute_reply.started":"2026-04-16T13:23:34.186247Z","shell.execute_reply":"2026-04-16T13:23:34.192569Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\n\nImage\n(N, C, H, W)\n          │                                                                      \n          ▼                                                                      \n┌──────────┐                                          ┌──────────┐                   ┌──────────┐\n│          │─────────── skip connection ─────────────►│          │─── projection ───►│          │\n│          │                                          │          │                   │          │\n└──────────┘                                          └──────────┘                   └──────────┘\n          │ pool                                           ▲ upsample                          │\n          ▼                                                │                                   ▼\n  ┌──────────┐                                    ┌──────────┐                       (N, 1, H, W)\n  │          │───────── skip connection ─────────►│          │                       Mask\n  │          │                                    │          │      \n  └──────────┘                                    └──────────┘           \n          │ pool                                       ▲ upsample            \n          ▼                                            │                \n    ┌──────────┐                              ┌──────────┐         \n    │          │─────── skip connection ─────►│          │         \n    │          │                              │          │         \n    └──────────┘                              └──────────┘\n          │ pool                               ▲ upsample\n          ▼                                    │\n        ┌────────────────────────────────────────┐\n        │               bottleneck               │\n        │                                        │\n        └────────────────────────────────────────┘\n\n UNet ENCODER                                   DECODER               HEAD\n\n\"\"\"\n\nclass UNet(nn.Module):\n    \n    def __init__(self, in_channels=1, out_channels=1):\n        super().__init__()\n        \n        ## encoder\n        self.enco0 = self.conv(in_channels, 64)\n        self.enco1 = self.conv(64, 128)\n        self.enco2 = self.conv(128, 256)\n        \n        ## bottleneck\n        self.bottleneck = self.conv(256, 512)\n        \n        ## decoder\n        self.deco2 = self.conv(512 + 256, 256)\n        self.deco1 = self.conv(256 + 128, 128)\n        self.deco0 = self.conv(128 + 64, 64)\n        \n        ## head\n        self.head = nn.Conv2d(64, out_channels, 1)\n        self.sigmoid = nn.Sigmoid()\n        \n        ## pooling and upsampling\n        self.pool = nn.MaxPool2d(2)\n        self.up = nn.Upsample(scale_factor=2, \n                              mode='bilinear', \n                              align_corners=True)\n    \n    def conv(self, in_channels, out_channels):\n        return nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, 3, padding=1),\n            nn.ReLU(inplace=True),\n            \n            nn.Conv2d(out_channels, out_channels, 3, padding=1),\n            nn.ReLU(inplace=True)\n        )\n    \n    def forward(self, x):\n        \n        enco0 = self.enco0(x) ## (N, 64, H, W)  \n        enco1 = self.enco1(self.pool(enco0)) ## (N, 128, H/2, W/2)  \n        enco2 = self.enco2(self.pool(enco1)) ## (N, 256, H/4, W/4)  \n        \n        middle = self.bottleneck(self.pool(enco2)) ## (N, 512, H/8, W/8)  \n        \n        deco2 = self.deco2(torch.cat([self.up(middle), enco2], dim=1)) ## (N, 256, H/4, W/4)\n        deco1 = self.deco1(torch.cat([self.up(deco2), enco1], dim=1)) ## (N, 128, H/2, W/2)\n        deco0 = self.deco0(torch.cat([self.up(deco1), enco0], dim=1)) ## (N, 64, H, W)\n\n        mask = self.sigmoid(self.head(deco0)) ## (N, 1, H, W)  \n        \n        return mask\n\nx = torch.randn(1, 1, 256, 256)\nml = UNet()\n\nml(x).shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:34.195693Z","iopub.execute_input":"2026-04-16T13:23:34.196011Z","iopub.status.idle":"2026-04-16T13:23:35.383457Z","shell.execute_reply.started":"2026-04-16T13:23:34.195982Z","shell.execute_reply":"2026-04-16T13:23:35.382323Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"original_img = [\n    [1, 2], \n    [3, 4]\n]\n\ntransposed_image = [\n    [1, 0, 2], \n    [0, 0, 0], \n    [3, 0, 4]\n]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:35.385819Z","iopub.execute_input":"2026-04-16T13:23:35.386150Z","iopub.status.idle":"2026-04-16T13:23:35.392835Z","shell.execute_reply.started":"2026-04-16T13:23:35.386121Z","shell.execute_reply":"2026-04-16T13:23:35.391083Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = segmentation_models_pytorch.Unet(\n    encoder_name=\"resnet34\",\n    encoder_weights=\"imagenet\",\n    in_channels=3,\n    classes=1,\n)\n\nmodel.encoder\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:35.394054Z","iopub.execute_input":"2026-04-16T13:23:35.394474Z","iopub.status.idle":"2026-04-16T13:23:37.416633Z","shell.execute_reply.started":"2026-04-16T13:23:35.394431Z","shell.execute_reply":"2026-04-16T13:23:37.415451Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\n\n                  image\n                      │\n        ┌─────────────┼─────────────┬──────────────┐\n        ▼             ▼             ▼              ▼\n  ┌─────────┐  ┌─────────┐  ┌─────────┐   ┌──────────┐\n  │ conv1×1 │  │ conv3×3 │  │ conv5×5 │   │  maxpool │\n  │         │  │         │  │         │   │  conv1×1 │\n  │         │  │         │  │         │   │          │\n  └─────────┘  └─────────┘  └─────────┘   └──────────┘\n        │             │             │              │\n        └─────────────┼─────────────┴──────────────┘\n                      │\n                 concat \n\n\"\"\"\n\ndilation1 = [\n    ['w1', 'w2', 'w3'],\n    ['w4', 'w5', 'w6'], \n    ['w7', 'w8', 'w9']\n]\n\ndilation2 = [\n    ['w1', ' 0', 'w2', ' 0', 'w3'],\n    [' 0', ' 0', ' 0', ' 0', ' 0'],\n    ['w4', ' 0', 'w5', ' 0', 'w6'],\n    [' 0', ' 0', ' 0', ' 0', ' 0'],\n    ['w7', ' 0', 'w8', ' 0', 'w9']\n]\n\ndilation4 = [\n    ['w1', ' 0', ' 0', ' 0', 'w2', ' 0', ' 0', ' 0', 'w3'],\n    [' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0'],\n    [' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0'],\n    [' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0'],\n    ['w4', ' 0', ' 0', ' 0', 'w5', ' 0', ' 0', ' 0', 'w6'],\n    [' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0'],\n    [' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0'],\n    [' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0', ' 0'],\n    ['w7', ' 0', ' 0', ' 0', 'w8', ' 0', ' 0', ' 0', 'w9']\n]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:37.417720Z","iopub.execute_input":"2026-04-16T13:23:37.418025Z","iopub.status.idle":"2026-04-16T13:23:37.428059Z","shell.execute_reply.started":"2026-04-16T13:23:37.417994Z","shell.execute_reply":"2026-04-16T13:23:37.426797Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\n\nImage\n(N, C, H, W)\n          │\n          ▼\n┌──────────┐                                     ┌──────────┐                                         ┌──────────┐\n│ C0       │───── 1×1 (64→128) ──► + ──► 3×3 ──► │ P0       │─────► + ───────── projection ─────────► │          │\n│          │                       ▲             │          │       ▲                                 │          │\n└──────────┘                       │ upsample    └──────────┘       │ upsample                        └──────────┘\n          │ pool                   │                                │                                           │\n          ▼                        │                                │                                           ▼\n  ┌──────────┐                     │             ┌──────────┐       │                                 (N, 1, H, W)\n  │ C1       │─── 1×1 (128→128) ─► + ──► 3×3 ──► │ P1       │───────┤                                 Mask\n  │          │                     ▲             │          │       │     \n  └──────────┘                     │ upsample    └──────────┘       │     \n          │ pool                   │                                │         \n          ▼                        │                                │         \n    ┌──────────┐                   │             ┌──────────┐       │    \n    │ C2       │─ 1×1 (256→128) ─► + ──► 3×3 ──► │ P2       │───────┤   \n    │          │                   ▲             │          │       │   \n    └──────────┘                   │ upsample    └──────────┘       │   \n          │ pool                   │                                │\n          ▼                        │                                │\n    ┌──────────┐                   │             ┌──────────┐       │\n    │ C3       │─ 1×1 (512→128) ─► ┘──► 3×3 ───► │ P3       │───────┘\n    │          │                                 │          │      \n    └──────────┘                                 └──────────┘\n\n UNet ENCODER                                    PYRAMID             FUSION      HEAD\n\n\"\"\"\n\nclass FPN(nn.Module):\n    \n    def __init__(self, in_channels=1, fpn_channels=128):\n        super().__init__()\n        \n        ## bottom-up (encoder)\n        self.enco0 = self.conv(in_channels, 64)\n        self.enco1 = self.conv(64, 128)\n        self.enco2 = self.conv(128, 256)\n        self.enco3 = self.conv(256, 512)\n\n        self.pool = nn.MaxPool2d(2)\n        \n        ## lateral connections (1×1 conv)\n        self.lateral3 = nn.Conv2d(512, fpn_channels, 1)\n        self.lateral2 = nn.Conv2d(256, fpn_channels, 1)\n        self.lateral1 = nn.Conv2d(128, fpn_channels, 1)\n        self.lateral0 = nn.Conv2d(64,  fpn_channels, 1)\n        \n        ## smooth connections (3×3 conv)\n        self.smooth3 = nn.Conv2d(fpn_channels, fpn_channels, 3, padding=1)\n        self.smooth2 = nn.Conv2d(fpn_channels, fpn_channels, 3, padding=1)\n        self.smooth1 = nn.Conv2d(fpn_channels, fpn_channels, 3, padding=1)\n        self.smooth0 = nn.Conv2d(fpn_channels, fpn_channels, 3, padding=1)\n    \n    def conv(self, in_ch, out_ch):\n        return nn.Sequential(\n            nn.Conv2d(in_ch, out_ch, 3, padding=1),\n            nn.BatchNorm2d(out_ch),\n            nn.ReLU(inplace=True),\n            \n            nn.Conv2d(out_ch, out_ch, 3, padding=1),\n            nn.BatchNorm2d(out_ch),\n            nn.ReLU(inplace=True),\n        )\n    \n    def forward(self, x):\n        \n        c0 = self.enco0(x) ## (N, 64, H, W)\n        c1 = self.enco1(self.pool(c0)) ## (N, 128, H/2,  W/2)\n        c2 = self.enco2(self.pool(c1)) ## (N, 256, H/4,  W/4)\n        c3 = self.enco3(self.pool(c2)) ## (N, 512, H/8,  W/8)\n        \n        p3 = self.lateral3(c3) ## (N, fpn_channels, H/8, W/8)\n        p2 = self.lateral2(c2) + F.interpolate(p3, scale_factor=2) ## (N, fpn_channels, H/4, W/4)\n        p1 = self.lateral1(c1) + F.interpolate(p2, scale_factor=2) ## (N, fpn_channels, H/2, W/2)\n        p0 = self.lateral0(c0) + F.interpolate(p1, scale_factor=2) ## (N, fpn_channels, H, W)\n        \n        p3 = self.smooth3(p3)\n        p2 = self.smooth2(p2)\n        p1 = self.smooth1(p1)\n        p0 = self.smooth0(p0)\n        \n        return p0, p1, p2, p3\n\nclass FPNSegmentation(nn.Module):\n    \n    def __init__(self, in_channels=1, num_classes=1, fpn_channels=128):\n        super().__init__()\n        \n        self.fpn = FPN(in_channels, fpn_channels)\n        \n        self.head = nn.Sequential(\n            nn.Conv2d(fpn_channels, 64, 3, padding=1),\n            nn.BatchNorm2d(64),\n            nn.ReLU(inplace=True),\n            \n            nn.Conv2d(64, num_classes, 1),\n        )\n        \n        self.sigmoid = nn.Sigmoid()\n    \n    def forward(self, x):\n        \n        p0, p1, p2, p3 = self.fpn(x)\n        \n        p1_up = F.interpolate(p1, size=p0.shape[2:], mode='bilinear', align_corners=True)\n        p2_up = F.interpolate(p2, size=p0.shape[2:], mode='bilinear', align_corners=True)\n        p3_up = F.interpolate(p3, size=p0.shape[2:], mode='bilinear', align_corners=True)\n        \n        fused = p0 + p1_up + p2_up + p3_up  \n        mask = self.sigmoid(self.head(fused))  \n        \n        return mask\n\nml = FPNSegmentation()\n\nml(x).shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:37.430032Z","iopub.execute_input":"2026-04-16T13:23:37.430474Z","iopub.status.idle":"2026-04-16T13:23:38.418390Z","shell.execute_reply.started":"2026-04-16T13:23:37.430443Z","shell.execute_reply":"2026-04-16T13:23:38.417263Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"## https://www.kaggle.com/competitions/tgs-salt-identification-challenge/writeups/b-e-s-phalanx-1st-place-solution-with-code\n\nclass FeaturePyramidAttention(nn.Module):\n    \n    def __init__(self, input_dim, output_dim):\n        super(FeaturePyramidAttention, self).__init__()\n        \n        self.glob = nn.Sequential(\n            nn.AdaptiveAvgPool2d(1), \n            nn.Conv2d(input_dim, output_dim, kernel_size=1, bias=False)\n        )\n\n        self.down21 = nn.Sequential(\n            nn.Conv2d(input_dim, input_dim, kernel_size=5, stride=2, padding=2, bias=False), \n            nn.BatchNorm2d(input_dim), \n            nn.ELU(True)\n        )\n        self.down31 = nn.Sequential(\n            nn.Conv2d(input_dim, input_dim, kernel_size=3, stride=2, padding=1, bias=False), \n            nn.BatchNorm2d(input_dim), \n            nn.ELU(True)\n        )\n\n        self.down22 = nn.Sequential(\n            nn.Conv2d(input_dim, output_dim, kernel_size=5, padding=2, bias=False), \n            nn.BatchNorm2d(output_dim), \n            nn.ELU(True))\n        self.down32 = nn.Sequential(\n            nn.Conv2d(input_dim, output_dim, kernel_size=3, padding=1, bias=False), \n            nn.BatchNorm2d(output_dim), \n            nn.ELU(True)\n        )\n\n        self.conv = nn.Sequential(\n            nn.Conv2d(input_dim, output_dim, kernel_size=1, bias=False), \n            nn.BatchNorm2d(output_dim), \n            nn.ELU(True)\n        )\n\n    def forward(self, x):\n        \n        g = self.glob(x) \n        print (g[0][:4])\n        \n        g = F.interpolate(g, scale_factor=16, mode='bilinear', align_corners=True)\n        print (g[0][:4])\n        \n        d2 = self.down21(x)  \n        d3 = self.down31(d2)  \n\n        d2 = self.down22(d2)  \n        d3 = self.down32(d3)  \n\n        d3 = F.interpolate(d3, scale_factor=2, mode='bilinear', align_corners=True)\n        d2 = d2 + d3\n\n        d2 = F.interpolate(d2, scale_factor=2, mode='bilinear', align_corners=True)\n        x = self.conv(x)  \n        x = x * d2\n        \n        x = x + g\n\n        return x\n\nlr = FeaturePyramidAttention(512, 256) \nx = torch.randn(2, 512, 16, 16)\n\nlr(x).shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:38.419825Z","iopub.execute_input":"2026-04-16T13:23:38.420086Z","iopub.status.idle":"2026-04-16T13:23:38.625640Z","shell.execute_reply.started":"2026-04-16T13:23:38.420061Z","shell.execute_reply":"2026-04-16T13:23:38.624778Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class SpatialAttentionBlock(nn.Module):\n    \n    def __init__(self, channel):\n        super(SpatialAttentionBlock, self).__init__()\n        \n        self.squeeze = nn.Conv2d(channel, 1, kernel_size=1, bias=False)\n        self.sigmoid = nn.Sigmoid()\n\n    def forward(self, x):\n        \n        z = self.squeeze(x)\n        z = self.sigmoid(z)\n        \n        return x * z\n\nclass GlobalAttentionBlock(nn.Module):\n    \n    def __init__(self, input_dim, reduction=4):\n        super(GlobalAttentionBlock, self).__init__()\n        \n        self.glob = nn.AdaptiveAvgPool2d(1)\n        \n        self.conv1 = nn.Conv2d(input_dim, input_dim // reduction, kernel_size=1, stride=1)\n        self.relu = nn.ReLU(inplace=True)\n        \n        self.conv2 = nn.Conv2d(input_dim // reduction, input_dim, kernel_size=1, stride=1)\n        self.sigmoid = nn.Sigmoid()\n\n    def forward(self, x):\n        \n        z = self.glob(x)\n        z = self.relu(self.conv1(z))\n        z = self.sigmoid(self.conv2(z))\n        \n        return x * z\n\nclass Decoder(nn.Module):\n    \n    def __init__(self, up_in, x_in, output_dim):\n        super(Decoder, self).__init__()\n        \n        up_out = x_out = output_dim // 2\n\n        self.tr_conv = nn.ConvTranspose2d(up_in, up_out, 2, stride=2)\n        self.x_conv = nn.Conv2d(x_in, x_out, 1, bias=False)\n        \n        self.bn = nn.BatchNorm2d(output_dim)\n        self.relu = nn.ReLU(True)\n        \n        self.s_att = SpatialAttentionBlock(output_dim)\n        self.c_att = GlobalAttentionBlock(output_dim, 16)\n\n    def forward(self, up_p, x_p):\n        \n        up_p = self.tr_conv(up_p)\n        x_p = self.x_conv(x_p)\n\n        p = torch.cat([up_p, x_p], 1)\n        p = self.relu(self.bn(p))\n        \n        s = self.s_att(p)\n        c = self.c_att(p)\n        \n        return s + c\n\nup_p = torch.randn(2, 512, 16, 16)\nx_p = torch.randn(2, 256, 32, 32)\nlr = Decoder(512, 256, 512) \n\nlr(up_p, x_p).shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:38.627163Z","iopub.execute_input":"2026-04-16T13:23:38.627462Z","iopub.status.idle":"2026-04-16T13:23:38.707813Z","shell.execute_reply.started":"2026-04-16T13:23:38.627437Z","shell.execute_reply":"2026-04-16T13:23:38.706855Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"p = \"/kaggle/input/competitions/uw-madison-gi-tract-image-segmentation/\"\ncs = [\n    \"train/case123/case123_day20/scans/\", \n    \"train/case123/case123_day22/scans/\",     \n    \"train/case30/case30_day0/scans/\", \n    \"train/case30/case30_day1/scans/\" \n]\nslices = [\n    ['0065', '0067', '0069'], \n    ['0099', '0101', '0103'], \n    ['0128', '0130', '0132'], \n    ['0084', '0086', '0088']\n]\nsuffixes = [\n    \"266_266_1.50_1.50\", \n    \"266_266_1.50_1.50\", \n    \"266_266_1.50_1.50\", \n    \"266_266_1.50_1.50\" \n]\nimages = []\n\nfor c, sl, sx in zip(cs, slices, suffixes):\n    image = [\n        cv2.imread(f\"{p}{c}slice_{s}_{sx}.png\", cv2.IMREAD_UNCHANGED).astype(np.float32) for s in sl\n    ]\n    image = np.stack(image, axis=-1)\n    \n    maxi = np.max(image)\n    image /= maxi\n\n    images += [image]\n\nimages[0].shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:38.708776Z","iopub.execute_input":"2026-04-16T13:23:38.709030Z","iopub.status.idle":"2026-04-16T13:23:38.903884Z","shell.execute_reply.started":"2026-04-16T13:23:38.709004Z","shell.execute_reply":"2026-04-16T13:23:38.902944Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def image_visualization(images, channels):\n    \n    fig, axes = plt.subplots(1, 4, figsize=(20, 5))\n    \n    for i, image in enumerate(images):\n\n        if channels == \"slice\":\n            axes[i].imshow(image[:,:,0])\n        else:\n            axes[i].imshow(image)\n        axes[i].axis('off')\n    \n    plt.tight_layout()\n    plt.show()\n\nimage_visualization(images, \"slice\")\nimage_visualization(images, \"2.5d\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:39.270990Z","iopub.execute_input":"2026-04-16T13:23:39.271345Z","iopub.status.idle":"2026-04-16T13:23:40.639567Z","shell.execute_reply.started":"2026-04-16T13:23:39.271314Z","shell.execute_reply":"2026-04-16T13:23:40.638347Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"slices = [\n    ('000'+str(s))[-4:] for s in range(1, 144+1)\n]\n\nvolume = [\n    cv2.imread(f\"{p}{cs[0]}slice_{s}_{suffixes[0]}.png\", cv2.IMREAD_UNCHANGED).astype(np.float32) for s in slices\n]\nvolume = np.stack(volume, axis=0)\n\nvolume.shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:40.641639Z","iopub.execute_input":"2026-04-16T13:23:40.642709Z","iopub.status.idle":"2026-04-16T13:23:42.169990Z","shell.execute_reply.started":"2026-04-16T13:23:40.642673Z","shell.execute_reply":"2026-04-16T13:23:42.169117Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def update(i, image, volume):\n    image.set_array(volume[i])\n    return [image]\n\ndef volume_vizualization(volume):\n\n    volume = ((volume - volume.min()) / (volume.max() - volume.min())).astype(np.float32)\n    volume = volume[::4]\n    \n    fig = plt.figure(figsize=(8, 8))\n    \n    ax = fig.add_subplot(111)\n    ax.axis('off')\n    \n    image = ax.imshow(volume[0], cmap='gray', vmin=0, vmax=1)\n    animation = FuncAnimation(fig, update, fargs=(image, volume),\n                              frames=len(volume), interval=500)\n    \n    plt.close(fig)\n    \n    return HTML(animation.to_jshtml())\n\nvolume_vizualization(volume)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:42.171072Z","iopub.execute_input":"2026-04-16T13:23:42.171452Z","iopub.status.idle":"2026-04-16T13:23:42.179563Z","shell.execute_reply.started":"2026-04-16T13:23:42.171412Z","shell.execute_reply":"2026-04-16T13:23:42.178006Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = monai.networks.nets.UNet(\n    spatial_dims=3, in_channels=1, out_channels=3, \n    channels=(16, 32, 64, 128, 256), \n    strides=(2, 2, 2, 2)\n)\nmodel.eval()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:43.205381Z","iopub.execute_input":"2026-04-16T13:23:43.205763Z","iopub.status.idle":"2026-04-16T13:23:43.237545Z","shell.execute_reply.started":"2026-04-16T13:23:43.205730Z","shell.execute_reply":"2026-04-16T13:23:43.236688Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"volume = ((volume - volume.min()) / (volume.max() - volume.min())).astype(np.float32)\nvolume = torch.from_numpy(volume).float()\nvolume = volume.unsqueeze(0)  \n\nvolume.shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:43.239025Z","iopub.execute_input":"2026-04-16T13:23:43.239319Z","iopub.status.idle":"2026-04-16T13:23:43.288330Z","shell.execute_reply.started":"2026-04-16T13:23:43.239292Z","shell.execute_reply":"2026-04-16T13:23:43.287607Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ys = np.random.randint(0, 1, (1, 144, 266, 266))\n\nys.shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:43.289194Z","iopub.execute_input":"2026-04-16T13:23:43.289452Z","iopub.status.idle":"2026-04-16T13:23:43.319925Z","shell.execute_reply.started":"2026-04-16T13:23:43.289428Z","shell.execute_reply":"2026-04-16T13:23:43.318716Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"## training phase \n## cache ds demo \n\nexpensive = Compose([\n    RandSpatialCropd(\n        keys=[\"image\", \"label\"],  \n        roi_size=(96, 96, 96)  \n    ), \n    ToTensord(keys=[\"image\", \"label\"]) \n])\ndataset = CacheDataset(\n    data=[{\"image\": volume, \"label\": ys}],\n    transform=expensive,\n    cache_rate=1/3\n)\n\nloader = DataLoader(dataset)\nfor batch in loader:\n    print(\n        batch['image'].shape, \n        batch['label'].shape\n    )\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:43.321069Z","iopub.execute_input":"2026-04-16T13:23:43.321384Z","iopub.status.idle":"2026-04-16T13:23:43.346206Z","shell.execute_reply.started":"2026-04-16T13:23:43.321354Z","shell.execute_reply":"2026-04-16T13:23:43.345236Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"## inference phase \n## sliding ws demo \n\nvolume = volume.unsqueeze(0)  \n\nwith torch.no_grad():\n    esti = sliding_window_inference(\n        inputs=volume, roi_size=(96, 96, 96), sw_batch_size=2, \n        overlap=.25, mode=\"gaussian\", sigma_scale=0.125, \n        predictor=model \n    )\n\nesti.shape\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:44.117399Z","iopub.execute_input":"2026-04-16T13:23:44.118435Z","iopub.status.idle":"2026-04-16T13:23:46.879527Z","shell.execute_reply.started":"2026-04-16T13:23:44.118390Z","shell.execute_reply":"2026-04-16T13:23:46.878729Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"## https://www.kaggle.com/code/radustoicescu/count-the-sea-lions-in-the-first-image  \n\nwith py7zr.SevenZipFile('/kaggle/input/competitions/noaa-fisheries-steller-sea-lion-population-count/TrainSmall2.7z', \n                        mode='r', password='kaggle2017steller') as z:\n    z.extractall(path='/kaggle/working/')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:46.881071Z","iopub.execute_input":"2026-04-16T13:23:46.881464Z","iopub.status.idle":"2026-04-16T13:23:56.063211Z","shell.execute_reply.started":"2026-04-16T13:23:46.881434Z","shell.execute_reply":"2026-04-16T13:23:56.062269Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/working/Train/train.csv')\n\ndf.head()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:56.064728Z","iopub.execute_input":"2026-04-16T13:23:56.065066Z","iopub.status.idle":"2026-04-16T13:23:56.085625Z","shell.execute_reply.started":"2026-04-16T13:23:56.065026Z","shell.execute_reply":"2026-04-16T13:23:56.084743Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image1 = cv2.imread(\"/kaggle/working/TrainDotted/41.jpg\")\nimage1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)\n\nplt.figure(figsize=(12, 16))\nplt.imshow(image1)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:56.086802Z","iopub.execute_input":"2026-04-16T13:23:56.087059Z","iopub.status.idle":"2026-04-16T13:23:57.555394Z","shell.execute_reply.started":"2026-04-16T13:23:56.087034Z","shell.execute_reply":"2026-04-16T13:23:57.553475Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image2 = cv2.imread(\"/kaggle/working/Train/41.jpg\")\nimage2 = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB)\n\nplt.figure(figsize=(12, 16))\nplt.imshow(image2)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:57.558182Z","iopub.execute_input":"2026-04-16T13:23:57.558556Z","iopub.status.idle":"2026-04-16T13:23:59.224760Z","shell.execute_reply.started":"2026-04-16T13:23:57.558496Z","shell.execute_reply":"2026-04-16T13:23:59.223639Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image3 = cv2.absdiff(image1, image2)\n\nplt.figure(figsize=(12, 16))\nplt.imshow(image3)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:23:59.225862Z","iopub.execute_input":"2026-04-16T13:23:59.226190Z","iopub.status.idle":"2026-04-16T13:24:00.700715Z","shell.execute_reply.started":"2026-04-16T13:23:59.226135Z","shell.execute_reply":"2026-04-16T13:24:00.699329Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"mask1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)\nmask1[mask1 < 20] = 0\nmask1[mask1 > 0] = 255\n\nmask2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)\nmask2[mask2 < 20] = 0\nmask2[mask2 > 0] = 255\n\nimage3 = cv2.bitwise_or(image3, image3, mask=mask1) \nimage3 = cv2.bitwise_or(image3, image3, mask=mask2) \nimage3 = cv2.cvtColor(image3, cv2.COLOR_BGR2GRAY) \n\nplt.figure(figsize=(12, 16))\nplt.imshow(image3)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:24:00.702206Z","iopub.execute_input":"2026-04-16T13:24:00.702761Z","iopub.status.idle":"2026-04-16T13:24:04.618467Z","shell.execute_reply.started":"2026-04-16T13:24:00.702713Z","shell.execute_reply":"2026-04-16T13:24:04.617470Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print (np.unique(image3)) \nprint (image3.shape, \n       (image3 != 0).sum(), \n       (image3 == 0).sum())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:24:04.619874Z","iopub.execute_input":"2026-04-16T13:24:04.620241Z","iopub.status.idle":"2026-04-16T13:24:05.121285Z","shell.execute_reply.started":"2026-04-16T13:24:04.620200Z","shell.execute_reply":"2026-04-16T13:24:05.119624Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"blobs = skimage.feature.blob_log(\n    image3, \n    min_sigma=3, \n    max_sigma=4, \n    num_sigma=1, \n    threshold=.02)\n\nprint (len(blobs))\nblobs[:8]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:24:05.124098Z","iopub.execute_input":"2026-04-16T13:24:05.125503Z","iopub.status.idle":"2026-04-16T13:24:08.018015Z","shell.execute_reply.started":"2026-04-16T13:24:05.125459Z","shell.execute_reply":"2026-04-16T13:24:08.016982Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df[df['train_id'] == 41]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:24:08.019107Z","iopub.execute_input":"2026-04-16T13:24:08.019400Z","iopub.status.idle":"2026-04-16T13:24:08.030472Z","shell.execute_reply.started":"2026-04-16T13:24:08.019372Z","shell.execute_reply":"2026-04-16T13:24:08.029483Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, axes = plt.subplots(3, 5, figsize=(20, 12))\n\nfor i, ax in enumerate(axes.flat):\n    \n    y, x, sigma = blobs[i]\n    y, x = int(y), int(x)\n    \n    crop = image1[y-64:y+64, x-64:x+64]\n    \n    ax.imshow(crop)\n    ax.axis('off')\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T13:24:08.032408Z","iopub.execute_input":"2026-04-16T13:24:08.032818Z","iopub.status.idle":"2026-04-16T13:24:09.613646Z","shell.execute_reply.started":"2026-04-16T13:24:08.032788Z","shell.execute_reply":"2026-04-16T13:24:09.612222Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}