{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\n# Use the kagglehub client library to attach Kaggle resources like competitions, datasets, and models to your session\n# Learn more about kagglehub: https://github.com/Kaggle/kagglehub/blob/main/README.md\n\nimport kagglehub\n# kagglehub.dataset_download('<owner>/<dataset-slug>')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:51.791183Z","iopub.execute_input":"2026-09-27T12:26:51.792727Z","iopub.status.idle":"2026-09-27T12:26:53.394594Z","shell.execute_reply.started":"2026-09-27T12:26:51.792683Z","shell.execute_reply":"2026-09-27T12:26:53.393481Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# All needed libraries\nimport cv2\nimport os\nimport matplotlib.pyplot as plt\nimport zipfile","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:53.39632Z","iopub.execute_input":"2026-09-27T12:26:53.396885Z","iopub.status.idle":"2026-09-27T12:26:53.989438Z","shell.execute_reply.started":"2026-09-27T12:26:53.396854Z","shell.execute_reply":"2026-09-27T12:26:53.988169Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"zip_path = \"/kaggle/input/competitions/data-science-bowl-2018/stage1_train.zip\"\nextract_path = \"/kaggle/working/data\"\n\nos.makedirs(extract_path, exist_ok=True)\n\nwith zipfile.ZipFile(zip_path, \"r\") as z:\n    z.extractall(extract_path)\n\nprint(\"Extraction complete\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:53.990838Z","iopub.execute_input":"2026-09-27T12:26:53.991193Z","iopub.status.idle":"2026-09-27T12:26:58.271537Z","shell.execute_reply.started":"2026-09-27T12:26:53.991165Z","shell.execute_reply":"2026-09-27T12:26:58.270043Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"folder_name = \"/d1b173875e2261f55014bd27bd7174b9ae1c769338c1b31b5d737e9e60175993/images\"\ntotal = 0\nfor f in os.listdir(extract_path + folder_name):\n    print(f)\n    total +=1\nprint(total)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:58.273755Z","iopub.execute_input":"2026-09-27T12:26:58.275116Z","iopub.status.idle":"2026-09-27T12:26:58.286425Z","shell.execute_reply.started":"2026-09-27T12:26:58.275007Z","shell.execute_reply":"2026-09-27T12:26:58.283522Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Sample Image Visualization\nimage_name = \"/d1b173875e2261f55014bd27bd7174b9ae1c769338c1b31b5d737e9e60175993.png\"\nimage_path = extract_path + folder_name + image_name\nprint(\"Path:\", image_path)\nprint(\"Exists:\", os.path.exists(image_path))\nimg = cv2.imread(image_path)\nif img is None:\n    print(\"Error: Could not load image.\")\nelse:\n    print(\"Image shape:\", img.shape)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    plt.imshow(img)\n    plt.axis(\"off\")\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:58.288521Z","iopub.execute_input":"2026-09-27T12:26:58.289083Z","iopub.status.idle":"2026-09-27T12:26:58.582689Z","shell.execute_reply.started":"2026-09-27T12:26:58.289029Z","shell.execute_reply":"2026-09-27T12:26:58.581434Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Sample mask Visualization\nfolder_name = \"/d1b173875e2261f55014bd27bd7174b9ae1c769338c1b31b5d737e9e60175993/masks\"\ntotal = 0\nfor f in os.listdir(extract_path + folder_name):\n    print(f)\n    total +=1\nprint(total)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:58.584007Z","iopub.execute_input":"2026-09-27T12:26:58.584347Z","iopub.status.idle":"2026-09-27T12:26:58.595565Z","shell.execute_reply.started":"2026-09-27T12:26:58.584318Z","shell.execute_reply":"2026-09-27T12:26:58.594465Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Sample Mask Visualization\nmask_name = \"/a203b9d4166b9312ef53b04cc480a4a2dd9ba5cc34c9ce67320bb9d9ed79e6bd.png\"\nimage_path = extract_path + folder_name + mask_name\nprint(\"Path:\", image_path)\nprint(\"Exists:\", os.path.exists(image_path))\nimg = cv2.imread(image_path)\nif img is None:\n    print(\"Error: Could not load image.\")\nelse:\n    print(\"Image shape:\", img.shape)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    plt.imshow(img)\n    plt.axis(\"off\")\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:58.596846Z","iopub.execute_input":"2026-09-27T12:26:58.597192Z","iopub.status.idle":"2026-09-27T12:26:58.670164Z","shell.execute_reply.started":"2026-09-27T12:26:58.597165Z","shell.execute_reply":"2026-09-27T12:26:58.669327Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Work till simple experience with the data.","metadata":{}},{"cell_type":"markdown","source":"# Now work on the project.","metadata":{}},{"cell_type":"markdown","source":"### Load one image and its masks\n\nThis is your first actual image-analysis task. You need to check whether the original image and its masks line up.","metadata":{}},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport glob\n\nsample_dirs = [\n    d for d in glob.glob(extract_path + \"/*\")\n    if os.path.isdir(d)\n]\n\nsample = sample_dirs[0]\n\nimage_path = glob.glob(sample + \"/images/*\")[0]\nmask_paths = glob.glob(sample + \"/masks/*\")\n\nimage = cv2.imread(image_path)\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\nprint(\"Image shape:\", image.shape)\nprint(\"Number of masks:\", len(mask_paths))\n\nmask = cv2.imread(mask_paths[0], cv2.IMREAD_GRAYSCALE)\n\nplt.figure(figsize=(12, 5))\n\nplt.subplot(1, 2, 1)\nplt.imshow(image)\nplt.title(\"Original microscopy image\")\nplt.axis(\"off\")\n\nplt.subplot(1, 2, 2)\nplt.imshow(mask, cmap=\"gray\")\nplt.title(\"One nucleus mask\")\nplt.axis(\"off\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:58.671342Z","iopub.execute_input":"2026-09-27T12:26:58.671695Z","iopub.status.idle":"2026-09-27T12:26:58.91399Z","shell.execute_reply.started":"2026-09-27T12:26:58.671654Z","shell.execute_reply":"2026-09-27T12:26:58.912973Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"What you should observe\n\n- The original image contains cells and their surrounding structures.\n\n- A mask represents one annotated nucleus, with foreground pixels marking that nucleus.\n\n- Different masks in the same sample represent different nuclei.\n\n- The image and mask should have matching height and width.","metadata":{}},{"cell_type":"markdown","source":"### Visualize all nuclei together\n\nFor your first U-Net, you'll use a binary mask: all nuclei are white, and everything else is black. Combine the separate instance masks to create it.","metadata":{}},{"cell_type":"code","source":"combined = np.zeros(\n    image.shape[:2],\n    dtype=np.uint8\n)\n\nfor path in mask_paths:\n    m = cv2.imread(path, cv2.IMREAD_GRAYSCALE)\n    combined[m > 0] = 1\n\nplt.figure(figsize=(15, 5))\n\nplt.subplot(1, 3, 1)\nplt.imshow(image)\nplt.title(\"Original\")\nplt.axis(\"off\")\n\nplt.subplot(1, 3, 2)\nplt.imshow(combined, cmap=\"gray\")\nplt.title(\"Combined binary mask\")\nplt.axis(\"off\")\n\nplt.subplot(1, 3, 3)\nplt.imshow(image)\nplt.imshow(combined, cmap=\"Reds\", alpha=0.4)\nplt.title(\"Mask overlay\")\nplt.axis(\"off\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:26:58.915205Z","iopub.execute_input":"2026-09-27T12:26:58.915478Z","iopub.status.idle":"2026-09-27T12:26:59.264622Z","shell.execute_reply.started":"2026-09-27T12:26:58.915454Z","shell.execute_reply":"2026-09-27T12:26:59.263519Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"The overlay is particularly important. It helps you detect misalignment, missing annotations and incorrect mask loading before you spend time training.","metadata":{}},{"cell_type":"markdown","source":"### Perform dataset-level EDA\n\nNow inspect more than one image. You want to know whether all images have the same dimensions and how many masks each sample contains.","metadata":{}},{"cell_type":"code","source":"records = []\nno_image = 0\nimg_contain = 0\nfor sample in sample_dirs:\n    image_files = glob.glob(sample + \"/images/*\")\n    masks = glob.glob(sample + \"/masks/*\")\n    \n    if not image_files:\n        no_image += 1\n        continue\n    img_contain += 1\n    img = cv2.imread(image_files[0])\n    h, w = img.shape[:2]\n\n    records.append({\n        \"sample\": os.path.basename(sample),\n        \"height\": h,\n        \"width\": w,\n        \"channels\": img.shape[2],\n        \"num_masks\": len(masks)\n    })\n\ndf = pd.DataFrame(records)\n\nprint(df.head())\nprint(df.shape)\nprint(\"\\nDataset summary:\")\nprint(df[[\"height\", \"width\", \"channels\", \"num_masks\"]].describe())\n\nprint(\"\\nUnique image dimensions:\")\nprint(df.groupby([\"height\", \"width\"]).size())\nprint(\"Total number folder who don't contain any images are\", no_image)\nprint(\"Total number of folder which contain images are\", img_contain)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:35:37.792977Z","iopub.execute_input":"2026-09-27T12:35:37.793471Z","iopub.status.idle":"2026-09-27T12:35:41.203852Z","shell.execute_reply.started":"2026-09-27T12:35:37.79344Z","shell.execute_reply":"2026-09-27T12:35:41.202633Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Then plot the number of nuclei masks per image:","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(9, 5))\nplt.hist(df[\"num_masks\"], bins=30)\nplt.xlabel(\"Number of nucleus masks\")\nplt.ylabel(\"Number of images\")\nplt.title(\"Distribution of nuclei per image\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:37:43.170879Z","iopub.execute_input":"2026-09-27T12:37:43.17126Z","iopub.status.idle":"2026-09-27T12:37:43.359855Z","shell.execute_reply.started":"2026-09-27T12:37:43.171215Z","shell.execute_reply":"2026-09-27T12:37:43.358986Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"It tells you how much variation exists in the number of annotated nuclei between samples.","metadata":{}},{"cell_type":"markdown","source":"### Check image quality and mask validity","metadata":{}},{"cell_type":"raw","source":"# Check missing or unreadable image files\nprint(\"Samples analyzed:\", len(df))\nprint(\"Missing dimensions:\",\n      df[[\"height\", \"width\"]].isnull().sum())\n\n# Check whether images and masks have matching dimensions\nmismatches = []\n\nfor sample in sample_dirs:\n    image_files = glob.glob(sample + \"/images/*\")\n    masks = glob.glob(sample + \"/masks/*\")\n\n    if not image_files:\n        continue\n\n    img = cv2.imread(image_files[0])\n    if img is None:\n        mismatches.append((sample, \"Unreadable image\"))\n        continue\n\n    for path in masks:\n        m = cv2.imread(path, cv2.IMREAD_GRAYSCALE)\n        if m is None or m.shape != img.shape[:2]:\n            mismatches.append((sample, path))\n\nprint(\"Dimension/read errors:\", len(mismatches))","metadata":{"execution":{"iopub.status.busy":"2026-09-27T12:16:29.710981Z","iopub.execute_input":"2026-09-27T12:16:29.711614Z","iopub.status.idle":"2026-09-27T12:16:52.98554Z","shell.execute_reply.started":"2026-09-27T12:16:29.711591Z","shell.execute_reply":"2026-09-27T12:16:52.984577Z"}}},{"cell_type":"code","source":"# All_Dirs = [\n#     d for d in glob.glob(extract_path + \"/*\")\n# ]\n# print(len(All_Dirs))\n# print(len(sample_dirs))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:28:38.524977Z","iopub.execute_input":"2026-09-27T12:28:38.526067Z","iopub.status.idle":"2026-09-27T12:28:38.535631Z","shell.execute_reply.started":"2026-09-27T12:28:38.526012Z","shell.execute_reply":"2026-09-27T12:28:38.534237Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Original samples:\", len(sample_dirs))\n\nmask_counts = [\n    len(glob.glob(d + \"/masks/*\"))\n    for d in sample_dirs\n]\n\nprint(\"Total individual masks:\", sum(mask_counts))\nprint(\"Minimum masks per image:\", min(mask_counts))\nprint(\"Maximum masks per image:\", max(mask_counts))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-27T12:44:06.589851Z","iopub.execute_input":"2026-09-27T12:44:06.590212Z","iopub.status.idle":"2026-09-27T12:44:06.688641Z","shell.execute_reply.started":"2026-09-27T12:44:06.590183Z","shell.execute_reply":"2026-09-27T12:44:06.687619Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}