{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":117682,"databundleVersionId":15062069,"sourceType":"competition"},{"sourceId":14245247,"sourceType":"datasetVersion","datasetId":9088503},{"sourceId":288572598,"sourceType":"kernelVersion"},{"sourceId":290917305,"sourceType":"kernelVersion"},{"sourceId":655294,"sourceType":"modelInstanceVersion","modelInstanceId":495238,"modelId":510647},{"sourceId":660383,"sourceType":"modelInstanceVersion","modelInstanceId":499479,"modelId":510647},{"sourceId":665924,"sourceType":"modelInstanceVersion","modelInstanceId":504051,"modelId":510647},{"sourceId":672178,"sourceType":"modelInstanceVersion","modelInstanceId":495238,"modelId":510647},{"sourceId":673516,"sourceType":"modelInstanceVersion","modelInstanceId":499479,"modelId":510647},{"sourceId":674747,"sourceType":"modelInstanceVersion","modelInstanceId":503784,"modelId":510647},{"sourceId":681152,"sourceType":"modelInstanceVersion","modelInstanceId":516822,"modelId":510647},{"sourceId":732880,"sourceType":"modelInstanceVersion","modelInstanceId":516822,"modelId":510647}],"dockerImageVersionId":31193,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport sys\nimport site\nimport importlib\n\n# Paket yolu\nwhl_dir = \"/kaggle/input/vsdetection-packages-offline-installer-only/whls\"\n\n# Kurulum (Sessiz modda ve bağımlılıksız)\n!pip install --no-index --find-links={whl_dir} medicai keras-nightly tifffile imagecodecs --no-deps -q\n\n# Kernel'ı yenilemeden kütüphaneyi içeri almanın yolu\nimportlib.reload(site)\nprint(\"✅ Kütüphaneler yüklendi ve yol güncellendi.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-02T21:36:56.51454Z","iopub.execute_input":"2026-02-02T21:36:56.515062Z","iopub.status.idle":"2026-02-02T21:37:03.438298Z","shell.execute_reply.started":"2026-02-02T21:36:56.515036Z","shell.execute_reply":"2026-02-02T21:37:03.437582Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport gc\nimport zipfile\nimport numpy as np\nimport pandas as pd\nimport tifffile\nfrom scipy import ndimage\nfrom PIL import Image\n\n# 1. ORTAM AYARLARI\nos.environ[\"KERAS_BACKEND\"] = \"tensorflow\"\nos.environ[\"TF_CPP_MIN_LOG_LEVEL\"] = \"3\"\nos.environ[\"TF_ENABLE_ONEDNN_OPTS\"] = \"0\"\n\nimport keras\nfrom medicai.models import TransUNet\n\n# 2. MODEL YOLLARI\nMODEL_101_PATH = \"/kaggle/input/colab-a-162v4-gpu-transunet-seresnext101-x160/model.weights.h5\"\nMODEL_50_PATH = \"/kaggle/input/train-transunet-baseline-lb-0-537/fine_tuning_epoch_20.weights.h5\"\n\n# 3. ROBUST VERİ OKUMA\ndef read_tiff_fixed(filepath):\n    try:\n        return tifffile.imread(filepath)\n    except Exception:\n        img = Image.open(filepath)\n        frames = [np.array(img.seek(i) or img) for i in range(img.n_frames)]\n        return np.stack(frames, axis=0)\n\n# 4. SENİN GÜNCEL \"DALLANMA DOSTU\" POST-PROCESS'İN (V4)\ndef improved_postprocess_v4(probs):\n    non_zero_probs = probs[probs > 0.01]\n    \n    # Otomatik eşikleme mantığın\n    threshold = np.percentile(non_zero_probs, 68) if len(non_zero_probs) > 1000 else 0.45\n    threshold = max(0.32, min(0.58, threshold)) \n    \n    T_low = 0.12 \n    T_high = threshold\n    \n    strong = probs >= T_high\n    weak = probs >= T_low\n    \n    structure = ndimage.generate_binary_structure(3, 3) \n    \n    # Binary Propagation ile dalları toplama\n    result = ndimage.binary_propagation(strong, mask=weak, structure=structure)\n    \n    from skimage.morphology import remove_small_objects\n    result = remove_small_objects(result.astype(bool), min_size=70)\n    \n    return result.astype(np.uint8)\n\n# 5. ENSEMBLE TAHMİN FONKSİYONU (Gaussian Ağırlıklı)\ndef predict_volume_v4(image_id, test_dir, m101, m50):\n    vol = read_tiff_fixed(f\"{test_dir}/{image_id}.tif\").astype(np.float32)\n    \n    vmin, vmax = np.percentile(vol, (0.5, 99.5))\n    vol = np.clip((vol - vmin) / (vmax - vmin + 1e-6), 0, 1)\n    \n    D, H, W = vol.shape\n    output = np.zeros((D, H, W), dtype=np.float32)\n    count = np.zeros((D, H, W), dtype=np.float32)\n    \n    patch_size, stride = 160, 80 \n    \n    ax = np.linspace(-(patch_size-1)/2., (patch_size-1)/2., patch_size)\n    xx, yy, zz = np.meshgrid(ax, ax, ax, indexing='ij')\n    weight = np.exp(-(xx**2 + yy**2 + zz**2) / (2 * (patch_size/6)**2))\n\n    print(f\"  🔍 {image_id} işleniyor (V4 Dallanma Analizi)...\")\n    for d in range(0, D - patch_size + 1, stride):\n        for h in range(0, H - patch_size + 1, stride):\n            for w in range(0, W - patch_size + 1, stride):\n                patch = vol[d:d+patch_size, h:h+patch_size, w:w+patch_size]\n                patch_input = np.expand_dims(patch, axis=(0, -1))\n                \n                # Tahmin: S101 (%60) + S50 (%40)\n                p101 = m101.predict(patch_input, verbose=0)[0, ..., 1:3].sum(axis=-1)\n                p50 = m50.predict(patch_input, verbose=0)[0, ..., 1:3].sum(axis=-1)\n                \n                combined = (p101 * 0.60 + p50 * 0.40)\n                \n                output[d:d+patch_size, h:h+patch_size, w:w+patch_size] += combined * weight\n                count[d:d+patch_size, h:h+patch_size, w:w+patch_size] += weight\n                \n    return output / (count + 1e-8)\n\n# 6. ANA YÜRÜTME\nprint(\"🚀 Modeller Yükleniyor...\")\nm50 = TransUNet(input_shape=(160, 160, 160, 1), encoder_name='seresnext50', classifier_activation='softmax', num_classes=3)\nm50.load_weights(MODEL_50_PATH)\n\nm101 = TransUNet(input_shape=(160, 160, 160, 1), encoder_name='seresnext101', classifier_activation='softmax', num_classes=3)\nm101.load_weights(MODEL_101_PATH)\n\ntest_df = pd.read_csv(\"/kaggle/input/vesuvius-challenge-surface-detection/test.csv\")\ntest_dir = \"/kaggle/input/vesuvius-challenge-surface-detection/test_images\"\n\nwith zipfile.ZipFile(\"submission.zip\", \"w\", compression=zipfile.ZIP_DEFLATED) as z:\n    for image_id in test_df[\"id\"]:\n        probs = predict_volume_v4(image_id, test_dir, m101, m50)\n        mask = improved_postprocess_v4(probs)\n        \n        out_name = f\"{image_id}.tif\"\n        tifffile.imwrite(out_name, mask)\n        z.write(out_name)\n        os.remove(out_name)\n        print(f\"✅ {image_id} tamamlandı. V4 Dallanmalar korundu.\")\n        gc.collect()\n\nprint(\"\\n🏆 Senin V4 modelin başarıyla tamamlandı!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-02T21:37:14.593771Z","iopub.execute_input":"2026-02-02T21:37:14.594069Z","iopub.status.idle":"2026-02-02T21:39:26.125839Z","shell.execute_reply.started":"2026-02-02T21:37:14.594036Z","shell.execute_reply":"2026-02-02T21:39:26.125214Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport tifffile\nimport zipfile\nfrom PIL import Image\nimport os\n\ndef get_mask_from_zip(zip_path, file_name):\n    \"\"\"Zip dosyasından maskeyi okur.\"\"\"\n    with zipfile.ZipFile(zip_path, 'r') as z:\n        with z.open(file_name) as f:\n            return tifffile.imread(f)\n\ndef read_raw_slice(path, slice_idx):\n    \"\"\"Ham görüntünün tek bir kesitini bellek dostu şekilde okur.\"\"\"\n    try:\n        with tifffile.TiffFile(path) as tif:\n            return tif.pages[slice_idx].asarray()\n    except:\n        with Image.open(path) as img:\n            img.seek(slice_idx)\n            return np.array(img)\n\n# --- AYARLAR ---\nimg_id = \"1407735\" # Analiz edilecek görsel ID'si\nzip_path = \"submission.zip\"\nraw_path = f\"/kaggle/input/vesuvius-challenge-surface-detection/test_images/{img_id}.tif\"\n\n# Kontrol: submission.zip var mı?\nif not os.path.exists(zip_path):\n    print(f\"Hata: '{zip_path}' bulunamadı. Lütfen önce tahmin kodunu çalıştırın.\")\nelse:\n    print(f\"🔬 {img_id} için güncel lif analizi başlatılıyor...\")\n\n    # 1. VERİLERİ ÇEK\n    mask_vol = get_mask_from_zip(zip_path, f\"{img_id}.tif\")\n    total_slices = mask_vol.shape[0]\n\n    # Analiz için 4 farklı derinlik seçelim (Daha geniş bir bakış açısı için)\n    # İlk ve son 20 kesiti gürültüden dolayı atlayıp aradan seçiyoruz\n    depths = np.linspace(20, total_slices - 20, 4, dtype=int) \n    \n    fig, axes = plt.subplots(len(depths), 3, figsize=(22, 22), facecolor='#0a0a0a')\n\n    for i, d in enumerate(depths):\n        # Ham kesiti oku ve görsel için normalize et\n        raw_slice = read_raw_slice(raw_path, d).astype(np.float32)\n        # Daha iyi kontrast için %1-99 percentil normalizasyon\n        vmin, vmax = np.percentile(raw_slice, (1, 99))\n        raw_slice_norm = np.clip((raw_slice - vmin) / (vmax - vmin + 1e-8), 0, 1)\n        \n        # Maske kesiti\n        mask_slice = mask_vol[d]\n        \n        # --- Sütun 1: Ham Parşömen ---\n        axes[i, 0].imshow(raw_slice_norm, cmap='gray')\n        axes[i, 0].set_title(f\"Derinlik {d}: Ham Veri\", color='white', fontsize=12)\n        axes[i, 0].axis('off')\n        \n        # --- Sütun 2: Modelin Yakaladığı Lifler (Maske) ---\n        axes[i, 1].imshow(mask_slice, cmap='hot') # 'hot' cmap lifleri daha belirgin gösterir\n        axes[i, 1].set_title(f\"Derinlik {d}: Tahmin Edilen Lif\", color='orange', fontsize=12)\n        axes[i, 1].axis('off')\n        \n        # --- Sütun 3: Overlay (Dolgunluk ve Kesintisizlik Kontrolü) ---\n        axes[i, 2].imshow(raw_slice_norm, cmap='gray')\n        # Sadece maske olan yerleri parlak yeşil yapalım\n        green_overlay = np.zeros((*mask_slice.shape, 4))\n        # Yeşil maskenin opaklığını artırarak dolgunluğu daha net görelim\n        green_overlay[mask_slice > 0] = [0, 1, 0, 0.6] # Parlak Yeşil, %60 Opaklık\n        \n        axes[i, 2].imshow(green_overlay)\n        axes[i, 2].set_title(f\"Derinlik {d}: Lif Dolgunluğu ve Uyum\", color='lime', fontsize=12)\n        axes[i, 2].axis('off')\n\n    plt.suptitle(f\"ID: {img_id} - GÜNCELLENMİŞ Lif Dolgunluğu ve Kesintisizlik Analizi\\n(Üstteki görüntüler daha az bulanık ve daha net olmalı)\", \n                 fontsize=24, color='white', y=1.02)\n    plt.tight_layout()\n    plt.show()\n\nprint(\"\\n🚀 Analiz görseli başarıyla oluşturuldu!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-02T21:39:33.103879Z","iopub.execute_input":"2026-02-02T21:39:33.104895Z","iopub.status.idle":"2026-02-02T21:39:35.412787Z","shell.execute_reply.started":"2026-02-02T21:39:33.104869Z","shell.execute_reply":"2026-02-02T21:39:35.41169Z"}},"outputs":[],"execution_count":null}]}