{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":103103,"databundleVersionId":13042974,"sourceType":"competition"},{"sourceId":720608,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":548102,"modelId":560916}],"dockerImageVersionId":31236,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# AlphaDent Dental Segmentation with YOLOv11-Seg\n\n## 1. Introduction \n## 2. Dataset Overview\n## 3. Methodology and sample outputs","metadata":{}},{"cell_type":"markdown","source":"# 1. Introduction\n\nDental image segmentation plays a crucial role in automated diagnosis and clinical decision support systems.\nIn this notebook, a YOLOv11-Seg–based deep learning pipeline is implemented for the AlphaDent competition, focusing on accurate and efficient segmentation of dental structures from high-resolution images.\n\nThe proposed approach aims to balance segmentation accuracy, inference speed, and training stability, making it suitable for real-world clinical applications.","metadata":{}},{"cell_type":"markdown","source":"# 2. Dataset Overview\n\nThe dataset consists of high-resolution dental images annotated with pixel-level segmentation masks.\nBelow, a subset of the training images is visualized to illustrate image quality, diversity, and structural details.","metadata":{}},{"cell_type":"code","source":"import os\nimport random\nimport cv2\nimport matplotlib.pyplot as plt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:07:21.965706Z","iopub.execute_input":"2026-01-15T12:07:21.966459Z","iopub.status.idle":"2026-01-15T12:07:22.572653Z","shell.execute_reply.started":"2026-01-15T12:07:21.966429Z","shell.execute_reply":"2026-01-15T12:07:22.571946Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMAGE_DIR = \"/kaggle/input/alpha-dent/AlphaDent/images/train\"  # kendi path'ine göre güncelle\nIMG_SIZE = 64\nROWS, COLS = 5, 5\nNUM_IMAGES = ROWS * COLS\n\nimage_files = [\n    os.path.join(IMAGE_DIR, f)\n    for f in os.listdir(IMAGE_DIR)\n    if f.lower().endswith((\".jpg\", \".jpeg\", \".png\"))\n]\n\nselected_images = random.sample(image_files, NUM_IMAGES)\n\nfig, axes = plt.subplots(ROWS, COLS, figsize=(10, 10))\n\nfor ax, img_path in zip(axes.flatten(), selected_images):\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n    \n    ax.imshow(img)\n    ax.axis(\"off\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:07:22.573739Z","iopub.execute_input":"2026-01-15T12:07:22.573954Z","iopub.status.idle":"2026-01-15T12:07:27.743065Z","shell.execute_reply.started":"2026-01-15T12:07:22.573934Z","shell.execute_reply":"2026-01-15T12:07:27.742378Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMAGE_DIR = \"/kaggle/input/alpha-dent/AlphaDent/images/train\"\nLABEL_DIR = \"/kaggle/input/alpha-dent/AlphaDent/labels/train\"\n\nIMG_SIZE = 128\nROWS, COLS = 5, 5\nNUM_IMAGES = ROWS * COLS\nALPHA = 0.5 \n\nimage_files = [\n    f for f in os.listdir(IMAGE_DIR)\n    if f.lower().endswith((\".jpg\", \".jpeg\", \".png\"))\n]\n\nselected_images = random.sample(image_files, NUM_IMAGES)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:08:07.261601Z","iopub.execute_input":"2026-01-15T12:08:07.262336Z","iopub.status.idle":"2026-01-15T12:08:07.269631Z","shell.execute_reply.started":"2026-01-15T12:08:07.262306Z","shell.execute_reply":"2026-01-15T12:08:07.268930Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def yolo_seg_to_mask_and_classes(label_path, img_shape):\n    h, w = img_shape[:2]\n    mask = np.zeros((h, w, 3), dtype=np.uint8)\n    classes = set()\n\n    if not os.path.exists(label_path):\n        return mask, classes\n\n    with open(label_path, \"r\") as f:\n        lines = f.readlines()\n\n    for line in lines:\n        data = list(map(float, line.strip().split()))\n        class_id = int(data[0])\n        classes.add(class_id)\n\n        points = np.array(data[1:]).reshape(-1, 2)\n        points[:, 0] *= w\n        points[:, 1] *= h\n        points = points.astype(np.int32)\n\n        # random color per object\n        color = np.random.randint(0, 255, size=3).tolist()\n        cv2.fillPoly(mask, [points], color)\n\n    return mask, classes\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:08:07.652813Z","iopub.execute_input":"2026-01-15T12:08:07.653060Z","iopub.status.idle":"2026-01-15T12:08:07.658860Z","shell.execute_reply.started":"2026-01-15T12:08:07.653038Z","shell.execute_reply":"2026-01-15T12:08:07.658206Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:08:31.335986Z","iopub.execute_input":"2026-01-15T12:08:31.336342Z","iopub.status.idle":"2026-01-15T12:08:31.341892Z","shell.execute_reply.started":"2026-01-15T12:08:31.336308Z","shell.execute_reply":"2026-01-15T12:08:31.341201Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, axes = plt.subplots(ROWS, COLS, figsize=(12, 12))\n\nfor ax, img_name in zip(axes.flatten(), selected_images):\n    img_path = os.path.join(IMAGE_DIR, img_name)\n    label_path = os.path.join(LABEL_DIR, img_name.rsplit(\".\", 1)[0] + \".txt\")\n\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    overlay = img.copy()\n    mask, classes = yolo_seg_to_mask_and_classes(label_path, img.shape)\n\n    overlay = cv2.addWeighted(overlay, 1, mask, ALPHA, 0)\n    overlay = cv2.resize(overlay, (IMG_SIZE, IMG_SIZE))\n\n    # Class ID text\n    if classes:\n        class_text = \", \".join([f\"Class {c}\" for c in sorted(classes)])\n    else:\n        class_text = \"No Label\"\n\n    ax.imshow(overlay)\n    ax.set_title(class_text, fontsize=8)\n    ax.axis(\"off\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:08:34.324094Z","iopub.execute_input":"2026-01-15T12:08:34.324719Z","iopub.status.idle":"2026-01-15T12:08:42.263539Z","shell.execute_reply.started":"2026-01-15T12:08:34.324694Z","shell.execute_reply":"2026-01-15T12:08:42.262533Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from collections import Counter","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:08:48.017273Z","iopub.execute_input":"2026-01-15T12:08:48.017854Z","iopub.status.idle":"2026-01-15T12:08:48.021302Z","shell.execute_reply.started":"2026-01-15T12:08:48.017827Z","shell.execute_reply":"2026-01-15T12:08:48.020481Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"LABEL_DIR = \"/kaggle/input/alpha-dent/AlphaDent/labels/train\" \n\nclass_counter = Counter()\n\nlabel_files = [\n    f for f in os.listdir(LABEL_DIR)\n    if f.endswith(\".txt\")\n]\n\nfor label_file in label_files:\n    label_path = os.path.join(LABEL_DIR, label_file)\n\n    with open(label_path, \"r\") as f:\n        for line in f:\n            if line.strip() == \"\":\n                continue\n            class_id = int(line.split()[0])\n            class_counter[class_id] += 1\n\nclass_ids = sorted(class_counter.keys())\ncounts = [class_counter[c] for c in class_ids]\nlabels = [f\"Class {c}\" for c in class_ids]\n\nplt.figure(figsize=(10, 5))\nplt.bar(labels, counts)\nplt.xlabel(\"Class ID\")\nplt.ylabel(\"Number of Samples (Instances)\")\nplt.title(\"Class-wise Sample Distribution (Training Set)\")\nplt.xticks(rotation=45)\nplt.tight_layout()\nplt.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:08:48.609692Z","iopub.execute_input":"2026-01-15T12:08:48.610388Z","iopub.status.idle":"2026-01-15T12:09:06.752344Z","shell.execute_reply.started":"2026-01-15T12:08:48.610360Z","shell.execute_reply":"2026-01-15T12:09:06.751634Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class_counter","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:09:06.753634Z","iopub.execute_input":"2026-01-15T12:09:06.753921Z","iopub.status.idle":"2026-01-15T12:09:06.758612Z","shell.execute_reply.started":"2026-01-15T12:09:06.753899Z","shell.execute_reply":"2026-01-15T12:09:06.757987Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 3. Methodology and sample outputs\n\nYOLOv11x-Seg model was used for dental image segmentation. The dataset was organized in YOLO segmentation format, and the data.yaml file was configured with correct training and validation paths. The model was then trained end-to-end on the AlphaDent dataset, and sample outputs below illustrate accurate and consistent segmentation results.\n\n### Training","metadata":{}},{"cell_type":"code","source":"!pip install ultralytics","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:09:06.759273Z","iopub.execute_input":"2026-01-15T12:09:06.759444Z","iopub.status.idle":"2026-01-15T12:09:13.336325Z","shell.execute_reply.started":"2026-01-15T12:09:06.759428Z","shell.execute_reply":"2026-01-15T12:09:13.335643Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from ultralytics import YOLO\n\nmodel = YOLO(\"yolov8x-seg.pt\") \n\nresults = model.train(\n    data=\"/kaggle/input/alpha-dent/AlphaDent/yolo_seg_train.yaml\", #your yaml \n    epochs= 100,\n    imgsz= 640,\n    batch= 4,\n    project=\"/kaggle/working/\"\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Testing\n\nFirst, validation images were used for testing, and then a comparison was presented with the actual masks. Since the label file for the test images was not provided, only the results are included.","metadata":{}},{"cell_type":"code","source":"# Testing Validation İmages\nfrom ultralytics import YOLO\n\nmodel = YOLO(r'/kaggle/input/alphadent-teeth-marking-yolov11-seg-model/pytorch/default/1/best.pt')\n\nmodel.predict(r'/kaggle/input/alpha-dent/AlphaDent/images/valid', save=True, conf=0.3, imgsz=640, project= r'/kaggle/working' )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:09:13.338238Z","iopub.execute_input":"2026-01-15T12:09:13.338499Z","iopub.status.idle":"2026-01-15T12:10:13.809771Z","shell.execute_reply.started":"2026-01-15T12:09:13.338475Z","shell.execute_reply":"2026-01-15T12:10:13.809130Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"GT_IMAGE_DIR = \"/kaggle/input/alpha-dent/AlphaDent/images/valid\"\nGT_LABEL_DIR = \"/kaggle/input/alpha-dent/AlphaDent/labels/valid\"\nPRED_IMAGE_DIR = \"/kaggle/working/predict\"\n\nIMG_SIZE = 128\nGRID = 5\nNUM_IMAGES = GRID * GRID\nALPHA = 0.5","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:10:13.810807Z","iopub.execute_input":"2026-01-15T12:10:13.811224Z","iopub.status.idle":"2026-01-15T12:10:13.814948Z","shell.execute_reply.started":"2026-01-15T12:10:13.811196Z","shell.execute_reply":"2026-01-15T12:10:13.814383Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def yolo_seg_to_mask(label_path, img_shape):\n    h, w = img_shape[:2]\n    mask = np.zeros((h, w, 3), dtype=np.uint8)\n\n    if not os.path.exists(label_path):\n        return mask\n\n    with open(label_path, \"r\") as f:\n        for line in f:\n            data = list(map(float, line.strip().split()))\n            points = np.array(data[1:]).reshape(-1, 2)\n\n            points[:, 0] *= w\n            points[:, 1] *= h\n            points = points.astype(np.int32)\n\n            color = (0, 255, 0)\n            cv2.fillPoly(mask, [points], color)\n\n    return mask","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:10:13.815912Z","iopub.execute_input":"2026-01-15T12:10:13.816224Z","iopub.status.idle":"2026-01-15T12:10:13.835717Z","shell.execute_reply.started":"2026-01-15T12:10:13.816188Z","shell.execute_reply":"2026-01-15T12:10:13.835013Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred_images = sorted([\n    f for f in os.listdir(PRED_IMAGE_DIR)\n    if f.endswith((\".jpg\", \".png\"))\n])[:NUM_IMAGES]\n\nfig, axes = plt.subplots(GRID, GRID * 2, figsize=(20, 10))\nfor i, img_name in enumerate(pred_images):\n    # paths\n    gt_img_path = os.path.join(GT_IMAGE_DIR, img_name)\n    gt_lbl_path = os.path.join(GT_LABEL_DIR, img_name.rsplit(\".\", 1)[0] + \".txt\")\n    pred_img_path = os.path.join(PRED_IMAGE_DIR, img_name)\n\n    # read GT image\n    img = cv2.imread(gt_img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    # GT overlay\n    gt_mask = yolo_seg_to_mask(gt_lbl_path, img.shape)\n    gt_overlay = cv2.addWeighted(img, 1, gt_mask, ALPHA, 0)\n    gt_overlay = cv2.resize(gt_overlay, (IMG_SIZE, IMG_SIZE))\n\n    # Prediction image (already rendered)\n    pred_img = cv2.imread(pred_img_path)\n    pred_img = cv2.cvtColor(pred_img, cv2.COLOR_BGR2RGB)\n    pred_img = cv2.resize(pred_img, (IMG_SIZE, IMG_SIZE))\n\n    r = i // GRID\n    c = (i % GRID) * 2\n\n    axes[r, c].imshow(gt_overlay)\n    axes[r, c].set_title(\"GT\", fontsize=8)\n    axes[r, c].axis(\"off\")\n\n    axes[r, c + 1].imshow(pred_img)\n    axes[r, c + 1].set_title(\"YOLOv11x-Seg\", fontsize=8)\n    axes[r, c + 1].axis(\"off\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:10:13.836591Z","iopub.execute_input":"2026-01-15T12:10:13.836815Z","iopub.status.idle":"2026-01-15T12:10:26.095990Z","shell.execute_reply.started":"2026-01-15T12:10:13.836792Z","shell.execute_reply":"2026-01-15T12:10:26.094005Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Testing Test İmages\n\nTEST_IMG_DIR = \"/kaggle/input/alpha-dent/AlphaDent/images/test\"\nPROJECT_DIR = \"/kaggle/working\"\nPRED_DIR = os.path.join(PROJECT_DIR, \"predict\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:10:26.097088Z","iopub.execute_input":"2026-01-15T12:10:26.097522Z","iopub.status.idle":"2026-01-15T12:10:26.102421Z","shell.execute_reply.started":"2026-01-15T12:10:26.097469Z","shell.execute_reply":"2026-01-15T12:10:26.101756Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = YOLO(\n    \"/kaggle/input/alphadent-teeth-marking-yolov11-seg-model/pytorch/default/1/best.pt\"\n)\n\ntest_images = sorted([\n    os.path.join(TEST_IMG_DIR, f)\n    for f in os.listdir(TEST_IMG_DIR)\n    if f.endswith((\".jpg\", \".png\"))\n])[:NUM_IMAGES]\n\nmodel.predict(\n    test_images,\n    save=True,\n    conf=0.3,\n    imgsz=640,\n    project=PROJECT_DIR,\n    name=\"predict\"\n)\n\npred_images = sorted([\n    f for f in os.listdir(PRED_DIR)\n    if f.endswith((\".jpg\", \".png\"))\n])[:NUM_IMAGES]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:10:26.103489Z","iopub.execute_input":"2026-01-15T12:10:26.104079Z","iopub.status.idle":"2026-01-15T12:10:50.310057Z","shell.execute_reply.started":"2026-01-15T12:10:26.104030Z","shell.execute_reply":"2026-01-15T12:10:50.309532Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, axes = plt.subplots(GRID, GRID, figsize=(10, 10))\n\nfor i, img_name in enumerate(pred_images):\n    img_path = os.path.join(PRED_DIR, img_name)\n\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n\n    r = i // GRID\n    c = i % GRID\n\n    axes[r, c].imshow(img)\n    axes[r, c].axis(\"off\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-15T12:10:50.311980Z","iopub.execute_input":"2026-01-15T12:10:50.312373Z","iopub.status.idle":"2026-01-15T12:10:55.224125Z","shell.execute_reply.started":"2026-01-15T12:10:50.312347Z","shell.execute_reply":"2026-01-15T12:10:55.223405Z"}},"outputs":[],"execution_count":null}]}