{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":94147,"databundleVersionId":11390004,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Histopathology Dataset Preprocess\n\nThis notebook has been prepared as part of the [Global AI Hackathon'25 by Elucidata](https://www.kaggle.com/competitions/el-hackathon-2025/overview).\n\n## Overview\n\nThe primary objective of this challenge is to develop AI models that can accurately predict the spatial distribution of biological cell types in a tissue slice using routine H&E slides. This will enable deeper insights into tissue biology, bridging the gap between traditional histology and advanced spatial transcriptomics.\n\n---\n\n## <span style=\"color:#2ecc71\">Advanced H&E Image Preprocessing</span>\n\nWe designed a multi-stage pipeline that  \n1) standardizes image format,  \n2) isolates tissue regions,  \n3) enhances contrast,  \n4) removes background whitespaces  \nall tailored for H&E-stained whole-slide images.\n\n\n\n","metadata":{}},{"cell_type":"markdown","source":"### 1. `check_image(img)`\n- Ensures `uint8` type & scales `[0–1]` floats → `[0–255]`  \n- Guarantees downstream OpenCV compatibility  \n\n### 2. `whitespace_filtering(img, filter_strength, preserve_tissue)`\n- **Brightness & Saturation Masks**: Adaptive thresholds (`light`, `moderate`, `aggressive`)  \n- **Hematoxylin & Eosin Masks**: HSV-based purple/pink extraction  \n- **Tissue Preservation**: Optional weak-tissue recovery via texture fusion & morphological dilation  \n- **Output**: Filtered RGB + binary tissue mask  \n\n### 3. `histopathology_tissue_mask(img)`\n- Combines Otsu thresholding, dot-removal, contour filtering (area > 500 px)  \n- Morphological closing (kernel 120×120) + opening (5×5)  \n- Robust mask for downstream model  \n\n### 4. `process_histopathology_image(img)`\n1. Generate tissue mask → isolate regions  \n2. Apply CLAHE on L channel (clipLimit=2.5) → boost local contrast ([PMC5498226])  \n3. Fine-tune white filtering (`light` mode)  \n\n**✨ Key Benefits**  \n- Improves **signal-to-noise** by focusing on diagnostically relevant areas  \n- Adapts to slide variability via parameterized filter strengths  \n- Enhances micro-architectural details crucial for tumor grading  \n","metadata":{}},{"cell_type":"markdown","source":"\n---\n\nThis notebook was used for testing purposes and was prepared by [Sems Kurtoglu](https://www.kaggle.com/shemskurtoglu).  ","metadata":{}},{"cell_type":"code","source":"import h5py\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.linear_model import  RANSACRegressor\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\n\nimport matplotlib.pyplot as plt\nimport cv2","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:27.534937Z","iopub.execute_input":"2025-05-19T09:44:27.535206Z","iopub.status.idle":"2025-05-19T09:44:36.561583Z","shell.execute_reply.started":"2025-05-19T09:44:27.535177Z","shell.execute_reply":"2025-05-19T09:44:36.560760Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"try:\n    from tqdm.notebook import tqdm as tqdm_notebook\nexcept ImportError:\n    from tqdm import tqdm as tqdm_notebook\n    import warnings\n    warnings.warn(\"tqdm.notebook bulunamadı, standart tqdm kullanılıyor. Görsel sorunlar yaşanabilir.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:36.562378Z","iopub.execute_input":"2025-05-19T09:44:36.562772Z","iopub.status.idle":"2025-05-19T09:44:36.717231Z","shell.execute_reply.started":"2025-05-19T09:44:36.562752Z","shell.execute_reply":"2025-05-19T09:44:36.716538Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class HistologyDataLoader:\n    def __init__(self, h5_file_path=\"/kaggle/input/el-hackathon-2025/elucidata_ai_challenge_data.h5\", save_logic=True):\n        self.h5_file_path = h5_file_path\n        self.train_slide_ids = []\n        self.train_spot_tables = {}\n        self.train_images = {}\n        self.test_slide_ids = []\n        self.test_spot_tables = {}\n        self.test_images = {}\n        save_file = save_logic\n\n    def load_train_spot_data(self):\n        \"\"\"\n        Load training spot data from the H5 file and store each slide as a DataFrame.\n        \"\"\"\n        with h5py.File(self.h5_file_path, \"r\") as f:\n            train_spots = f[\"spots/Train\"]\n            for slide_name in train_spots.keys():\n                spot_array = np.array(train_spots[slide_name])\n                df = pd.DataFrame(spot_array, columns=[\"x\", \"y\"] + [f\"C{i}\" for i in range(1, 36)])\n                self.train_spot_tables[slide_name] = df\n                self.train_slide_ids.append(slide_name)\n        print(\"Training spot data loaded successfully.\", self.train_slide_ids)\n        \n    def load_train_images(self):\n        \"\"\"\n        Load training HE images from the H5 file.\n        Adjust the key if your H5 file uses a different naming convention.\n        \"\"\"\n        with h5py.File(self.h5_file_path, \"r\") as f:\n            # Adjust key if necessary (e.g., f[\"images/Train\"] if needed)\n            train_imgs = f[\"images/Train\"]\n            for slide_name in train_imgs.keys():\n                image_array = np.array(train_imgs[slide_name])\n                self.train_images[slide_name] = image_array\n        print(\"Training images loaded successfully.\",self.train_slide_ids)\n\n    def load_test_spot_data(self, slide_id=\"S_7\"):\n        \"\"\"\n        Load test spot data for a given slide.\n        \"\"\"\n        with h5py.File(self.h5_file_path, \"r\") as f:\n            test_spots = f[\"spots/Test\"]\n            if slide_id not in test_spots:\n                print(\"ATTENTION:\", test_spots.keys())\n                raise ValueError(f\"Slide {slide_id} not found in test spot data.\")\n            spot_array = np.array(test_spots[slide_id])\n            test_df = pd.DataFrame(spot_array, columns=[\"x\", \"y\"])\n            self.test_slide_ids.append(slide_id)\n            self.test_spot_tables[slide_id] = test_df\n        print(f\"Test spot data for slide {slide_id} loaded successfully.\")\n        return test_df\n\n    def load_test_images(self, slide_id=\"S_7\"):\n        \"\"\"\n        Load test HE image for a given slide.\n        \"\"\"\n        with h5py.File(self.h5_file_path, \"r\") as f:\n            test_imgs = f[\"images/Test\"]\n            if slide_id not in test_imgs:\n                raise ValueError(f\"Slide {slide_id} not found in test images.\")\n            image_array = np.array(test_imgs[slide_id])\n            self.test_images[slide_id] = image_array\n        print(f\"Test image for slide {slide_id} loaded successfully.\")\n        return image_array\n\n    def load_train_data(self):\n        self.load_train_spot_data()\n        self.load_train_images()\n\n    def load_test_data(self):\n        self.load_test_spot_data()\n        self.load_test_images()\n\n    def visualize(self, image, image2=None, coor=None, coor2=None, title=\"Sample\", \n               title2=None, figsize=(6,6), comparison=False):\n        \"\"\"\n        Bir ya da iki görüntüyü görselleştirir ve isteğe bağlı olarak koordinat noktalarını gösterir.\n        \n        Parametreler:\n            image: Görselleştirilecek ana görüntü\n            image2: Karşılaştırma için ikinci görüntü (isteğe bağlı)\n            coor: İlk görüntü üzerinde işaretlenecek koordinatlar {\"x\": x_coords, \"y\": y_coords}\n            coor2: İkinci görüntü üzerinde işaretlenecek koordinatlar {\"x\": x_coords, \"y\": y_coords}\n            title: İlk görüntünün başlığı (varsayılan: \"Sample\")\n            title2: İkinci görüntünün başlığı (isteğe bağlı)\n            figsize: Görüntüleme boyutu (varsayılan: (6,6))\n            comparison: Karşılaştırma modunu etkinleştirme (varsayılan: False)\n        \"\"\"\n        \n        if comparison and image2 is not None:\n            # İki görüntüyü yan yana göster\n            fig, axs = plt.subplots(1, 2, figsize=figsize)\n            \n            # İlk görüntü\n            axs[0].imshow(image, aspect=\"auto\")\n            if coor is not None:\n                x, y = coor[\"x\"], coor[\"y\"]\n                axs[0].scatter(x, y, color=\"red\", s=1, alpha=0.4)\n            axs[0].set_title(title)\n            axs[0].axis('off')\n            \n            # İkinci görüntü\n            axs[1].imshow(image2, aspect=\"auto\")\n            if coor2 is not None:\n                x, y = coor2[\"x\"], coor2[\"y\"]\n                axs[1].scatter(x, y, color=\"red\", s=1, alpha=0.4)\n            axs[1].set_title(title2 if title2 is not None else f\"{title} (2)\")\n            axs[1].axis('off')\n            \n            plt.tight_layout()\n            plt.show()\n        else:\n            # Tek görüntü göster\n            plt.figure(figsize=figsize)\n            plt.imshow(image, aspect=\"auto\")\n            \n            if coor is not None:\n                x, y = coor[\"x\"], coor[\"y\"]\n                plt.scatter(x, y, color=\"red\", s=1, alpha=0.4)\n                \n            plt.axis('off')\n            plt.title(title)\n            plt.show()\n\n\n    def get_visualize(self, id=\"1\", spot=True):\n        sample = \"S_\" + id\n        \n        if sample in self.train_slide_ids:\n            image = np.array(self.train_images[sample])\n            spots = self.train_spot_tables[sample]\n        elif sample in self.test_slide_ids:\n            image = np.array(self.test_images[sample])\n            spots = self.test_spot_tables[sample]\n        else:\n            print(\"Not found\", sample)\n\n        if spot:\n            self.visualize(image, coor=spots, title=sample)\n        else:\n            self.visualize(image, title=sample)\n        \n\n\n#create dataset\nhistodata = HistologyDataLoader()\nhistodata.load_train_data()\nhistodata.load_test_data()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:36.719262Z","iopub.execute_input":"2025-05-19T09:44:36.719769Z","iopub.status.idle":"2025-05-19T09:44:39.196768Z","shell.execute_reply.started":"2025-05-19T09:44:36.719745Z","shell.execute_reply":"2025-05-19T09:44:39.195898Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nhistodata.get_visualize(spot=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:39.197709Z","iopub.execute_input":"2025-05-19T09:44:39.198009Z","iopub.status.idle":"2025-05-19T09:44:40.398262Z","shell.execute_reply.started":"2025-05-19T09:44:39.197984Z","shell.execute_reply":"2025-05-19T09:44:40.397420Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img_S1 = histodata.train_images['S_1']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:40.399091Z","iopub.execute_input":"2025-05-19T09:44:40.399415Z","iopub.status.idle":"2025-05-19T09:44:40.403614Z","shell.execute_reply.started":"2025-05-19T09:44:40.399392Z","shell.execute_reply":"2025-05-19T09:44:40.402746Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def check_image(img):\n    \"\"\"\n    Görüntüyü belirtilen hedefe dönüştürür (varsayılan RGB)\n    \n    Parametreler:\n        img: Giriş görüntüsü\n        target_format: Hedef format ('RGB' veya 'BGR')\n    \n    Dönüş:\n        İşlenmiş görüntü\n    \"\"\"\n    # Veri tipini doğru şekilde dönüştür\n    if img.dtype != np.uint8:\n        if img.max() <= 1.0:  # [0,1] aralığında normalize edilmiş görüntü\n            img = (img * 255).astype(np.uint8)\n        else:  # Görüntü zaten uygun aralıkta\n            img = img.astype(np.uint8)\n    \n    return img\n\n\n\ndef histopathology_tissue_mask(img):\n    \"\"\"\n    Histopatolojik görüntüdeki doku alanını maskeleyip kenarlıktaki nokta desenini çıkaran gelişmiş fonksiyon.\n    \n    Parametre:\n        img: İşlenecek görüntü (RGB veya BGR formatında)\n        \n    Dönüş:\n        final_mask: Doku alanını belirten ikili maske\n    \"\"\"\n    #1\n    img_rgb = check_image(img)\n    \n    # 2. Çoklu doku tespiti\n    # Gri tonlamalı görüntü oluştur ve gürültü azalt\n    gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)\n    blurred = cv2.GaussianBlur(gray, (5, 5), 0)\n    \n    # Doku tespiti için farklı yöntemler uygula\n    # a. Kenarlık noktalarını tespit et\n    _, dots_mask = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY)\n    \n    # b. HSV renk uzayında mor doku tespiti - daha geniş renk aralığı\n    hsv = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2HSV)\n    lower_purple = np.array([100, 15, 20])  # Genişletilmiş renk aralığı\n    upper_purple = np.array([180, 255, 255])\n    purple_mask = cv2.inRange(hsv, lower_purple, upper_purple)\n    \n    # c. Otsu thresholding ile arka plan/doku ayrımı\n    _, otsu_mask = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)\n    \n    # 3. Maske işlemleri\n    # Tüm doku tespitlerini birleştir\n    combined_tissue_mask = cv2.bitwise_or(purple_mask, otsu_mask)\n    \n    # Kenarlık noktalarını genişlet\n    kernel_small = np.ones((5, 5), np.uint8)\n    dilated_dots = cv2.dilate(dots_mask, kernel_small, iterations=2)\n    \n    # Doku maskesinden nokta desenini çıkar\n    tissue_mask = cv2.bitwise_and(combined_tissue_mask, cv2.bitwise_not(dilated_dots))\n    \n    # 4. Maske iyileştirme\n    # Boşlukları doldur\n    kernel_large = np.ones((40, 40), np.uint8)\n    filled_mask = cv2.morphologyEx(tissue_mask, cv2.MORPH_CLOSE, kernel_large, iterations=2)\n    \n    # Gürültüyü temizle\n    filled_mask = cv2.morphologyEx(filled_mask, cv2.MORPH_OPEN, kernel_small, iterations=1)\n    \n    # 5. Büyük doku alanlarını seç\n    contours, _ = cv2.findContours(filled_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n    final_mask = np.zeros_like(filled_mask)\n    \n    for contour in contours:\n        # Daha küçük alanlar için daha düşük eşik değeri\n        if cv2.contourArea(contour) > 5000:  \n            cv2.drawContours(final_mask, [contour], -1, 255, -1)\n    \n    # 6. Son dokunuşlar\n    # İçteki küçük boşlukları doldur\n    kernel_medium = np.ones((20, 20), np.uint8)\n    final_mask = cv2.morphologyEx(final_mask, cv2.MORPH_CLOSE, kernel_medium, iterations=2)\n    \n    # Kenarları yumuşat\n    final_mask = cv2.morphologyEx(final_mask, cv2.MORPH_DILATE, kernel_small, iterations=1)\n    final_mask = cv2.medianBlur(final_mask, 5)  # Kenarları düzgünleştir\n    \n    return final_mask\n\n\ndef process_histopathology_image(img):\n    img_rgb = check_image(img)\n\n    \n    # 1. Doku maskesini oluştur\n    mask = histopathology_tissue_mask(img)\n    \n    # 2. Maskeyi görüntüye uygula (sadece doku bölgesini al)\n    masked_img = cv2.bitwise_and(img_rgb, img_rgb, mask=mask)\n    \n    # 3. CLAHE uygula\n    # LAB renk uzayına dönüştür\n    lab = cv2.cvtColor(masked_img, cv2.COLOR_RGB2LAB)\n    l, a, b = cv2.split(lab)\n    \n    # L kanalının tipini kontrol et\n    if l.dtype != np.uint8:\n        l = l.astype(np.uint8)\n    \n    # CLAHE uygula\n    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(4, 4))\n    cl = clahe.apply(l)\n    \n    # Kanalları birleştir\n    enhanced_lab = cv2.merge((cl, a, b))\n    result = cv2.cvtColor(enhanced_lab, cv2.COLOR_LAB2RGB)\n    \n    return result\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:40.404576Z","iopub.execute_input":"2025-05-19T09:44:40.404824Z","iopub.status.idle":"2025-05-19T09:44:40.427508Z","shell.execute_reply.started":"2025-05-19T09:44:40.404800Z","shell.execute_reply":"2025-05-19T09:44:40.426652Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def improved_whitespace_filtering(img, filter_strength='moderate', preserve_tissue=True):\n    \"\"\"\n    H&E boyalı histopatoloji görüntülerinde beyaz alanları daha hassas filtreleyen gelişmiş fonksiyon\n    \n    Parametreler:\n        img: İşlenecek görüntü\n        filter_strength: Filtreleme şiddeti ('light', 'moderate', 'aggressive')\n        preserve_tissue: Doku yapısını koruma modunu etkinleştir\n        \n    Dönüş:\n        filtered_img: Filtrelenmiş görüntü\n        mask: Doku maskesi\n    \"\"\"\n    # Görüntüyü kontrol et\n    img_rgb = check_image(img)\n    \n    # Parlaklık ve HSV kanallarını hesapla\n    gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)\n    hsv = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2HSV)\n    \n    # Filtreleme şiddetine göre parametreleri ayarla\n    if filter_strength == 'light':\n        brightness_threshold = 220\n        sensitivity = 0.6\n    elif filter_strength == 'moderate':\n        brightness_threshold = 210\n        sensitivity = 0.8\n    else:  # aggressive\n        brightness_threshold = 200\n        sensitivity = 1.0\n    \n    # 1. Parlaklık bazlı temel beyaz alan maskesi\n    _, brightness_mask = cv2.threshold(gray, brightness_threshold, 255, cv2.THRESH_BINARY_INV)\n    \n    # 2. Doygunluk kanalı kullanarak doku tespiti (düşük doygunluk = beyaz alanlar)\n    s_channel = hsv[:,:,1]\n    _, saturation_mask = cv2.threshold(s_channel, 30 * sensitivity, 255, cv2.THRESH_BINARY)\n    \n    # 3. H&E boyalı dokularda mor bölgeleri koru\n    lower_purple = np.array([120, 20, 20])\n    upper_purple = np.array([170, 255, 255])\n    purple_mask = cv2.inRange(hsv, lower_purple, upper_purple)\n    \n    # 4. Eosin boyalı bölgeleri (pembe) koru\n    lower_pink = np.array([150, 20, 100])\n    upper_pink = np.array([180, 150, 255])\n    pink_mask = cv2.inRange(hsv, lower_pink, upper_pink)\n    \n    # Tüm doku maskelerini birleştir\n    tissue_mask = cv2.bitwise_or(cv2.bitwise_or(brightness_mask, saturation_mask), \n                                 cv2.bitwise_or(purple_mask, pink_mask))\n    \n    # Doku koruma seçeneği etkinse\n    if preserve_tissue:\n        # Zayıf dokuları da koru (daha düşük eşikle tekrar tespit et)\n        _, weak_tissue_mask = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)\n        \n        # Renk bilgisini kullanarak zayıf dokuları filtrele\n        texture_enhanced = cv2.addWeighted(gray, 0.5, hsv[:,:,1], 0.5, 0)\n        _, texture_mask = cv2.threshold(texture_enhanced, 30, 255, cv2.THRESH_BINARY)\n        \n        # İnce doku yapılarını koru\n        kernel = np.ones((3,3), np.uint8)\n        tissue_mask = cv2.morphologyEx(tissue_mask, cv2.MORPH_DILATE, kernel)\n        tissue_mask = cv2.bitwise_or(tissue_mask, cv2.bitwise_and(weak_tissue_mask, texture_mask))\n    \n    # Son maske işlemleri\n    kernel = np.ones((3,3), np.uint8)\n    tissue_mask = cv2.morphologyEx(tissue_mask, cv2.MORPH_CLOSE, kernel, iterations=1)\n    \n    # Maskeyi orijinal görüntüye uygula\n    filtered_img = cv2.bitwise_and(img_rgb, img_rgb, mask=tissue_mask)\n    \n    return filtered_img, tissue_mask","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:40.428512Z","iopub.execute_input":"2025-05-19T09:44:40.428796Z","iopub.status.idle":"2025-05-19T09:44:40.451673Z","shell.execute_reply.started":"2025-05-19T09:44:40.428768Z","shell.execute_reply":"2025-05-19T09:44:40.450808Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ndef histopathology_tissue_mask(img):\n    img_rgb = check_image(img)\n    gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)\n    blurred = cv2.GaussianBlur(gray, (5, 5), 0)\n    \n    # Kenarlık noktalarını tespit et\n    _, dots_mask = cv2.threshold(gray, 215, 255, cv2.THRESH_BINARY)\n    \n    # HSV renk uzayına dönüştür\n    hsv = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2HSV)\n    \n    # Hematoksilin boyalı bölgeler (mor-mavi)\n    lower_purple = np.array([90, 30, 20])\n    upper_purple = np.array([170, 255, 255])\n    purple_mask = cv2.inRange(hsv, lower_purple, upper_purple)\n    \n    # Eosin boyalı bölgeler (pembe-kırmızı)\n    lower_pink = np.array([150, 20, 100])\n    upper_pink = np.array([180, 150, 255])\n    pink_mask = cv2.inRange(hsv, lower_pink, upper_pink)\n    \n    # Otsu eşikleme\n    _, otsu_mask = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)\n\n    \n    # Tüm doku maskelerini birleştir\n    combined_tissue_mask = cv2.bitwise_or(purple_mask, pink_mask)\n    \n    # Devam eden işlemler...\n    kernel_small = np.ones((5, 5), np.uint8)\n    dilated_dots = cv2.dilate(dots_mask, kernel_small, iterations=2)\n    tissue_mask = cv2.bitwise_and(combined_tissue_mask, cv2.bitwise_not(dilated_dots))\n    \n    # Boşlukları doldur - daha küçük kernel boyutu\n    kernel_large = np.ones((120, 120), np.uint8)  # 180 yerine daha küçük\n    filled_mask = cv2.morphologyEx(tissue_mask, cv2.MORPH_CLOSE, kernel_large, iterations=1)\n    \n    # Gürültüyü temizle\n    filled_mask = cv2.morphologyEx(filled_mask, cv2.MORPH_OPEN, kernel_small, iterations=1)\n    \n    # Doku alanlarını seç - eşik değerini düşürdük\n    contours, _ = cv2.findContours(filled_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n    final_mask = np.zeros_like(filled_mask)\n    \n    for contour in contours:\n        if cv2.contourArea(contour) > 500:  # Daha fazla doku yakalamak için 800 yerine 500\n            cv2.drawContours(final_mask, [contour], -1, 255, -1)\n    \n    return final_mask\n\n    \n\ndef process_histopathology_image(img):\n    \"\"\"\n    Histopatoloji görüntüsünü işleyip beyaz alanları kaldırarak dokuları vurgular\n    \"\"\"\n    img_rgb = check_image(img)\n    \n    # Doku maskesini oluştur\n    mask = histopathology_tissue_mask(img_rgb)\n    \n    # Maskeyi görüntüye uygula\n    masked_img = cv2.bitwise_and(img_rgb, img_rgb, mask=mask)\n    \n    # CLAHE uygula (mevcut kodunuz)\n    lab = cv2.cvtColor(masked_img, cv2.COLOR_RGB2LAB)\n    l, a, b = cv2.split(lab)\n    \n    if l.dtype != np.uint8:\n        l = l.astype(np.uint8)\n    \n    clahe = cv2.createCLAHE(clipLimit=2.5, tileGridSize=(8, 8))\n    cl = clahe.apply(l)\n    \n    enhanced_lab = cv2.merge((cl, a, b))\n    result = cv2.cvtColor(enhanced_lab, cv2.COLOR_LAB2RGB)\n\n    # Gelişmiş beyaz alan filtreleme\n    #result, whitespace_mask = advanced_whitespace_filtering(result)\n    result, _ = improved_whitespace_filtering(result, filter_strength='light')\n    \n    return result\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:40.453931Z","iopub.execute_input":"2025-05-19T09:44:40.454183Z","iopub.status.idle":"2025-05-19T09:44:40.475352Z","shell.execute_reply.started":"2025-05-19T09:44:40.454163Z","shell.execute_reply":"2025-05-19T09:44:40.474641Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image = histodata.train_images['S_1']\nhistodata.visualize(image, image2=process_histopathology_image(image),\n                    comparison=True, figsize=(12,6))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:40.476274Z","iopub.execute_input":"2025-05-19T09:44:40.476575Z","iopub.status.idle":"2025-05-19T09:44:42.516213Z","shell.execute_reply.started":"2025-05-19T09:44:40.476556Z","shell.execute_reply":"2025-05-19T09:44:42.514722Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image = histodata.train_images['S_2']\nhistodata.visualize(image, image2=process_histopathology_image(image),\n                    comparison=True, figsize=(12,6))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:42.517186Z","iopub.execute_input":"2025-05-19T09:44:42.517520Z","iopub.status.idle":"2025-05-19T09:44:44.236079Z","shell.execute_reply.started":"2025-05-19T09:44:42.517492Z","shell.execute_reply":"2025-05-19T09:44:44.235209Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image = histodata.train_images['S_3']\nhistodata.visualize(image, image2=process_histopathology_image(image),\n                    comparison=True, figsize=(12,6))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:44.237119Z","iopub.execute_input":"2025-05-19T09:44:44.237420Z","iopub.status.idle":"2025-05-19T09:44:45.821666Z","shell.execute_reply.started":"2025-05-19T09:44:44.237398Z","shell.execute_reply":"2025-05-19T09:44:45.820841Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image = histodata.train_images['S_4']\nhistodata.visualize(image, image2=process_histopathology_image(image),\n                    comparison=True, figsize=(12,6))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:45.822385Z","iopub.execute_input":"2025-05-19T09:44:45.822656Z","iopub.status.idle":"2025-05-19T09:44:47.416892Z","shell.execute_reply.started":"2025-05-19T09:44:45.822637Z","shell.execute_reply":"2025-05-19T09:44:47.415784Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image = histodata.train_images['S_5']\nhistodata.visualize(image, image2=process_histopathology_image(image),\n                    comparison=True, figsize=(12,6))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:47.417911Z","iopub.execute_input":"2025-05-19T09:44:47.418212Z","iopub.status.idle":"2025-05-19T09:44:49.019508Z","shell.execute_reply.started":"2025-05-19T09:44:47.418190Z","shell.execute_reply":"2025-05-19T09:44:49.018628Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image = histodata.train_images['S_6']\nhistodata.visualize(image, image2=process_histopathology_image(image),\n                    comparison=True, figsize=(12,6))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-19T09:44:49.020300Z","iopub.execute_input":"2025-05-19T09:44:49.020615Z","iopub.status.idle":"2025-05-19T09:44:50.554559Z","shell.execute_reply.started":"2025-05-19T09:44:49.020595Z","shell.execute_reply":"2025-05-19T09:44:50.553571Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"This notebook was used for testing purposes and was prepared by [Sems Kurtoglu](https://www.kaggle.com/shemskurtoglu)","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}