{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":37333,"databundleVersionId":3949526,"sourceType":"competition"},{"sourceId":7791737,"sourceType":"datasetVersion","datasetId":4561028}],"dockerImageVersionId":30646,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!apt -y update && apt -y upgrade\n!apt -y install -d -o=dir::cache=/kaggle/working libvips libvips-dev libvips-tools\n!pip3 install --upgrade pip\n!pip3 download -d /kaggle/working pyvips\n!pip install pyvips\n!pip install pyradiomics\n!pip install pillow\n!dpkg -i --force-depends ./archives/*.deb >/dev/null 2>&1\n!pip install /kaggle/working/cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\n!pip install /kaggle/working/pyvips-2.2.2.tar.gz\n!pip install /kaggle/working/pycparser-2.21-py2.py3-none-any.whl","metadata":{"_uuid":"5dbbca4e-8a76-4f50-a89f-9b3a080da72b","_cell_guid":"68b32583-77c9-4dca-88b2-2a63034eda14","_kg_hide-input":false,"_kg_hide-output":false,"execution":{"iopub.status.busy":"2024-03-12T12:13:45.603377Z","iopub.execute_input":"2024-03-12T12:13:45.603729Z","iopub.status.idle":"2024-03-12T12:20:20.301476Z","shell.execute_reply.started":"2024-03-12T12:13:45.603699Z","shell.execute_reply":"2024-03-12T12:20:20.300244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pyvips\nimport os\nimport cv2\nimport sys\nfrom PIL import Image\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport zipfile\nfrom IPython.display import FileLink\nfrom pathlib import Path\nimport matplotlib.pyplot as plt\nimport tensorflow.keras.layers as l\nimport albumentations as A\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport SimpleITK as sitk\nfrom radiomics import featureextractor\nimport csv\nfrom radiomics import imageoperations\nfrom radiomics import featureextractor\n","metadata":{"_uuid":"b0f1850d-6943-46e9-b9a4-62bb8798ffd2","_cell_guid":"32d83000-de5f-48ac-8ce9-b77203d05498","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-03-12T12:21:51.183741Z","iopub.execute_input":"2024-03-12T12:21:51.184498Z","iopub.status.idle":"2024-03-12T12:21:51.19141Z","shell.execute_reply.started":"2024-03-12T12:21:51.184465Z","shell.execute_reply":"2024-03-12T12:21:51.190396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def parse_images(folder):\n    # get the full paths of the images\n    imgs = [os.path.join(folder, f) for f in os.listdir(folder)]\n\n    df = pd.DataFrame()\n    df['image_path'] = imgs\n    # remove extension, and have the id as first and last component, eg: 006388_0\n    df['image_id'] = df['image_path'].apply(lambda x: '_'.join(x.split('/')[-1].replace('.jpg', '').split('_')[:2]))\n    # remove extension, and have the instance_id as last component only, eg: 0, 1, ...\n    df['instance_id'] = df['image_path'].apply(lambda x: int(x.split('_')[-1].replace('.jpg', '')))\n\n    df = df.sort_values(['image_id', 'instance_id']).reset_index(drop=True)\n\n    return df\n\ndef merge_image_info(image_df, info_df):\n    return image_df.merge(info_df, on='image_id', how='left').reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-03-12T12:21:57.176318Z","iopub.execute_input":"2024-03-12T12:21:57.176701Z","iopub.status.idle":"2024-03-12T12:21:57.185281Z","shell.execute_reply.started":"2024-03-12T12:21:57.176673Z","shell.execute_reply":"2024-03-12T12:21:57.184211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv = pd.read_csv('/kaggle/input/mayo-clinic-strip-ai/train.csv')","metadata":{"execution":{"iopub.status.busy":"2024-03-12T12:21:58.894262Z","iopub.execute_input":"2024-03-12T12:21:58.894616Z","iopub.status.idle":"2024-03-12T12:21:58.911898Z","shell.execute_reply.started":"2024-03-12T12:21:58.894591Z","shell.execute_reply":"2024-03-12T12:21:58.910893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = merge_image_info(parse_images('/kaggle/input/6835-mayo-tiles-16/test'), train_csv)","metadata":{"execution":{"iopub.status.busy":"2024-03-12T12:22:02.637084Z","iopub.execute_input":"2024-03-12T12:22:02.63751Z","iopub.status.idle":"2024-03-12T12:22:03.045523Z","shell.execute_reply.started":"2024-03-12T12:22:02.637475Z","shell.execute_reply":"2024-03-12T12:22:03.044485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"label\"] = df[\"label\"].map({'CE': 0, 'LAA': 1})","metadata":{"execution":{"iopub.status.busy":"2024-03-12T12:22:13.165642Z","iopub.execute_input":"2024-03-12T12:22:13.166039Z","iopub.status.idle":"2024-03-12T12:22:13.186363Z","shell.execute_reply.started":"2024-03-12T12:22:13.16601Z","shell.execute_reply":"2024-03-12T12:22:13.185476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Initialize PyRadiomics feature extractor\nextractor = featureextractor.RadiomicsFeatureExtractor()\n# Define your lower and upper threshold values for yellow and brown\nlower_yellow = np.array([20, 100, 100])\nupper_yellow = np.array([30, 255, 255])\nlower_orange = np.array([5, 100, 100]) \nupper_orange = np.array([20, 255, 255])\nlower_brown = np.array([20, 50, 20]) \nupper_brown = np.array([40, 255, 200]) \n\n\n# Define the HSV color range for brown\nlower_brown = np.array([10, 50, 20])  \nupper_brown = np.array([40, 255, 255])  \n\n\nlower_blue = np.array([90, 50, 50])\nlower_purple = np.array([120, 50, 50])\nupper_purple = np.array([150, 255, 255])\nlower_dark_purple = np.array([100, 50, 50])  \nupper_dark_purple = np.array([120, 255, 255]) \n\nl_blu = np.array([0, 41, 38]) \nu_blu = np.array([36, 100, 100]) \nl_blu2 = np.array([0, 0, 0]) \nu_blu2 = np.array([36, 100, 10]) \nl_blu3 = np.array([300, 50, 50]) \nu_blu3 = np.array([320, 100, 100]) \nl_blu4 = np.array([240, 50, 50]) \nu_blu4 = np.array([180, 100, 100]) \nl_blu5 = np.array([67, 50, 50]) \nu_blu5 = np.array([340, 100, 255]) \n\n# Define lower and upper threshold values for white in HSV\nlower_white = np.array([0, 0, 200])\nupper_white = np.array([179, 30, 255])\n\n# Initialize list to store PyRadiomics data for all tiles of all images\npyradiomics_data = []\n\n\nfor i in range(len(df)):  \n    stained_image = cv2.imread(df[\"image_path\"][i])\n    label = df[\"label\"][i]\n    #stained_image = np.array(tile)\n    hsv_image = cv2.cvtColor(stained_image, cv2.COLOR_BGR2HSV)\n\n    # RBC\n    orange_mask = cv2.inRange(hsv_image, lower_orange, upper_orange)\n    yellow_mask = cv2.inRange(hsv_image, lower_yellow, upper_yellow)\n    brown_mask = cv2.inRange(hsv_image, lower_brown, upper_brown)\n    yellow_brown_mask = cv2.bitwise_or(yellow_mask, brown_mask)\n    yellow_brown_mask = cv2.bitwise_or(yellow_brown_mask, orange_mask)\n\n    ########\n    rbc_mask = yellow_brown_mask.copy()\n    rbc_mask[rbc_mask > 0] = 1\n\n    # WBC\n\n    #lower_dark_purple = np.array([100, 50, 50])  \n    #upper_dark_purple = np.array([120, 255, 255])  \n    dark_purple_mask = cv2.inRange(hsv_image, lower_dark_purple, upper_dark_purple)\n\n    blue_mask   = cv2.inRange(hsv_image, lower_blue, upper_purple)\n    purple_mask = cv2.inRange(hsv_image, lower_purple, upper_purple)\n    blue_purple_mask = cv2.bitwise_or(blue_mask, purple_mask)\n    purple_mask = cv2.bitwise_or(blue_purple_mask, dark_purple_mask)\n    #ADDED\n    pur_mask = cv2.inRange(hsv_image, l_blu5, u_blu5)\n    blue_purple_mask = cv2.bitwise_or(blue_purple_mask, pur_mask)\n    wbc_mask = blue_purple_mask.copy()\n    wbc_mask[wbc_mask > 0] = 1\n\n\n            # Fibrin/Platelets\n    white_mask = cv2.inRange(hsv_image, lower_white, upper_white)\n    fibrin_platelets_mask = cv2.bitwise_and(cv2.bitwise_not(yellow_brown_mask), cv2.bitwise_not(blue_purple_mask))\n    fibrin_platelets_mask = cv2.bitwise_and(fibrin_platelets_mask, cv2.bitwise_not(white_mask))\n    fibrin_platelets_mask[fibrin_platelets_mask > 0] = 1  # Ensure all non-zero values are set to 1\n\n\n    RBC = cv2.bitwise_and(stained_image, stained_image, mask = yellow_brown_mask)\n    WBC = cv2.bitwise_and(stained_image, stained_image, mask = blue_purple_mask)\n    FP  = cv2.bitwise_and(stained_image, stained_image, mask = fibrin_platelets_mask)\n\n    try:\n        # Read original image\n        original_image_sitk = sitk.GetImageFromArray(cv2.cvtColor(stained_image, cv2.COLOR_RGB2GRAY))\n\n        # Convert mask images to SimpleITK format\n        maskRBC_image_sitk = sitk.GetImageFromArray(rbc_mask)\n        maskWBC_image_sitk = sitk.GetImageFromArray(wbc_mask)\n        maskFP_image_sitk = sitk.GetImageFromArray(fibrin_platelets_mask)\n\n        # Extract features using PyRadiomics\n        featuresRBC = extractor.execute(original_image_sitk, maskRBC_image_sitk)\n        featuresWBC = extractor.execute(original_image_sitk, maskWBC_image_sitk)\n        featuresFP = extractor.execute(original_image_sitk, maskFP_image_sitk)\n\n        # Append data to list\n        pyradiomics_data.append({\n            'Image_ID': f\"{df['image_id'][i]}_{df['instance_id'][i]}\",\n            'Label': label,\n            **{f\"RBC_{k}\": v for k, v in featuresRBC.items()},\n            **{f\"WBC_{k}\": v for k, v in featuresWBC.items()},\n            **{f\"FP_{k}\": v for k, v in featuresFP.items()}\n        })\n    except Exception as e:\n        print(f\"{i})Error extracting features for tile {df['instance_id'][i]} of image {df['image_id'][i]}: {e}\")\n        continue\n\n# Convert list of dictionaries to DataFrame\npyradiomics_df = pd.DataFrame(pyradiomics_data)\npyradiomics_df.to_csv('/kaggle/working/pyrad.csv')\nprint(\"All PyRadiomics features saved successfully.\")","metadata":{},"execution_count":null,"outputs":[]}]}