{"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":"gpu","dataSources":[{"sourceId":107469,"databundleVersionId":13058354,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install -q ultralytics\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom tqdm import tqdm\n\n# المسارات\nimages_dir = \"/kaggle/input/multi-class-object-detection-challenge/Starter_Dataset/train/images\"\nlabels_dir = \"/kaggle/input/multi-class-object-detection-challenge/Starter_Dataset/train/labels\"\naug_images_dir = \"/path/to/save/augmented/images\"\naug_labels_dir = \"/path/to/save/augmented/labels\"\n\nos.makedirs(aug_images_dir, exist_ok=True)\nos.makedirs(aug_labels_dir, exist_ok=True)\n\n# عدد النسخ لكل صورة\nn_augmentations = 4\n\n# حجم الصورة الثابت\nIMAGE_SIZE = 640  # أو أي حجم تستخدمه في تدريبك\n\n# تعريف الـ augmentations\ntransform = A.Compose([\n    A.RandomBrightnessContrast(p=0.5),\n    A.HueSaturationValue(hue_shift_limit=10, sat_shift_limit=30, val_shift_limit=10, p=0.7),\n    A.HorizontalFlip(p=0.5),\n    A.Rotate(limit=20, p=0.5),\n    A.Resize(IMAGE_SIZE, IMAGE_SIZE),\n], bbox_params=A.BboxParams(format='yolo', label_fields=['class_labels']))\n\n# التحويل والتخزين\nfor filename in tqdm(os.listdir(images_dir)):\n    if filename.endswith((\".jpg\", \".png\", \".jpeg\")):\n        image_path = os.path.join(images_dir, filename)\n        label_path = os.path.join(labels_dir, os.path.splitext(filename)[0] + \".txt\")\n\n        # اقرأ الصورة\n        image = cv2.imread(image_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        height, width, _ = image.shape\n\n        # اقرأ الـ labels\n        bboxes = []\n        class_labels = []\n        if os.path.exists(label_path):\n            with open(label_path, 'r') as f:\n                for line in f.readlines():\n                    class_id, x_center, y_center, w, h = map(float, line.strip().split())\n                    bboxes.append([x_center, y_center, w, h])\n                    class_labels.append(int(class_id))\n\n        for i in range(n_augmentations):\n            try:\n                augmented = transform(image=image, bboxes=bboxes, class_labels=class_labels)\n                aug_img = cv2.cvtColor(augmented['image'], cv2.COLOR_RGB2BGR)\n\n                new_img_name = f\"{os.path.splitext(filename)[0]}_aug{i}.jpg\"\n                new_label_name = f\"{os.path.splitext(filename)[0]}_aug{i}.txt\"\n\n                cv2.imwrite(os.path.join(aug_images_dir, new_img_name), aug_img)\n\n                with open(os.path.join(aug_labels_dir, new_label_name), 'w') as f:\n                    for bbox, cls in zip(augmented['bboxes'], augmented['class_labels']):\n                        x, y, w, h = bbox\n                        f.write(f\"{cls} {x:.6f} {y:.6f} {w:.6f} {h:.6f}\\n\")\n            except Exception as e:\n                print(f\"Error augmenting {filename}: {e}\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import yaml\n\n# Set paths\nbase_path = \"/kaggle/input/multi-class-object-detection-challenge\"\nyaml_path = \"/kaggle/working/yolo_params.yaml\"\n\n\n# Build YAML dictionary\ndata_yaml = {\n    \"train\": f\"{base_path}/Starter_Dataset/train/images\",\n    \"val\":   f\"{base_path}/Starter_Dataset/val/images\",\n    \"test\":  f\"{base_path}/testImages/images\",\n    \"nc\": 2,\n    \"names\": [\"cheerios\", \"soup\"]\n}\n\n# Write to file\nwith open(yaml_path, \"w\") as f:\n    yaml.dump(data_yaml, f, default_flow_style=False)\n\nprint(\"✅ yolo_params.yaml updated successfully at:\", yaml_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-21T23:45:17.898934Z","iopub.execute_input":"2025-07-21T23:45:17.899181Z","iopub.status.idle":"2025-07-21T23:45:17.924237Z","shell.execute_reply.started":"2025-07-21T23:45:17.899163Z","shell.execute_reply":"2025-07-21T23:45:17.923439Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#with open(\"/kaggle/working/yolo_params.yaml\", \"r\") as f:\n#    print(f.read())\n#","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-21T23:45:17.979476Z","iopub.execute_input":"2025-07-21T23:45:17.979894Z","iopub.status.idle":"2025-07-21T23:45:17.983063Z","shell.execute_reply.started":"2025-07-21T23:45:17.979874Z","shell.execute_reply":"2025-07-21T23:45:17.982326Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import os\n# import cv2\n# import matplotlib.pyplot as plt\n\n# # Paths\n# base_path = \"/kaggle/input/multi-class-object-detection-challenge/Dataset\"\n\n# images_dir = f\"{base_path}/train/images\"\n# labels_dir = f\"{base_path}/train/labels\"\n# class_names = ['cheerios', 'soup']  # Make sure these match the dataset classes\n\n# def plot_yolo_label(img_path, label_path):\n#     image = cv2.imread(img_path)\n#     image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n#     h, w = image.shape[:2]\n\n#     if not os.path.exists(label_path):\n#         print(f\"Label not found: {label_path}\")\n#         return image\n\n#     with open(label_path, 'r') as f:\n#         lines = f.readlines()\n\n#     for i, line in enumerate(lines):\n#         parts = line.strip().split()\n#         if len(parts) != 5:\n#             print(f\"Skipping invalid line {i} in {label_path}: {parts}\")\n#             continue\n\n#         class_id = int(parts[0])\n#         x_center, y_center, box_w, box_h = map(float, parts[1:])\n\n#         # Convert normalized to pixel coordinates\n#         x1 = int((x_center - box_w / 2) * w)\n#         y1 = int((y_center - box_h / 2) * h)\n#         x2 = int((x_center + box_w / 2) * w)\n#         y2 = int((y_center + box_h / 2) * h)\n\n#         # Clip to image boundaries\n#         x1, y1 = max(0, x1), max(0, y1)\n#         x2, y2 = min(w - 1, x2), min(h - 1, y2)\n\n#         # Draw box and label\n#         label = f\"{class_names[class_id]}\"\n#         cv2.rectangle(image, (x1, y1), (x2, y2), (255, 0, 0), 4)\n#         cv2.putText(image, label, (x1, max(15, y1 - 10)), cv2.FONT_HERSHEY_SIMPLEX, 2.5, (0, 0, 255), 10)\n\n#         #print(f\"[{img_path}] Box {i}: {label} → ({x1},{y1}) to ({x2},{y2})\")\n\n#     return image\n\n# # Show 5 sample images with labels\n# sample_images = os.listdir(images_dir)[:5]\n\n# plt.figure(figsize=(15, 10))\n# for i, image_file in enumerate(sample_images):\n#     img_path = os.path.join(images_dir, image_file)\n#     label_file = image_file.replace(\".png\", \".txt\").replace(\".jpg\", \".txt\")\n#     label_path = os.path.join(labels_dir, label_file)\n\n#     img = plot_yolo_label(img_path, label_path)\n#     plt.subplot(1, 5, i + 1)\n#     plt.imshow(img)\n#     plt.axis(\"off\")\n#     plt.title(image_file)\n\n# plt.tight_layout()\n# plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-21T23:45:18.226284Z","iopub.execute_input":"2025-07-21T23:45:18.226545Z","iopub.status.idle":"2025-07-21T23:45:18.231975Z","shell.execute_reply.started":"2025-07-21T23:45:18.226523Z","shell.execute_reply":"2025-07-21T23:45:18.231193Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"zero, one, multi = 0, 0, 0\nfor file in os.listdir(labels_dir):\n    if file.endswith(\".txt\"):\n        with open(os.path.join(labels_dir, file)) as f:\n            count = len(f.readlines())\n            if count == 0:\n                zero += 1\n            elif count == 1:\n                one += 1\n            else:\n                multi += 1\n\nprint(f\"Images with 0 boxes: {zero}\")\nprint(f\"Images with 1 box: {one}\")\nprint(f\"Images with 2+ boxes: {multi}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-21T23:45:18.382598Z","iopub.execute_input":"2025-07-21T23:45:18.382847Z","iopub.status.idle":"2025-07-21T23:45:18.447477Z","shell.execute_reply.started":"2025-07-21T23:45:18.382829Z","shell.execute_reply":"2025-07-21T23:45:18.446506Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from ultralytics import YOLO\n\nmodel = YOLO(\"yolo12m.pt\")  \n\nmodel.train(\n    data=\"/kaggle/working/yolo_params.yaml\",\n    epochs=100,\n    imgsz=640,          \n    batch=16,            \n\n    # Optimization\n    optimizer='SGD',   \n    lr0=0.001,\n    weight_decay=0.0005,\n    momentum=0.937,\n    cos_lr=True,\n\n    # Augmentations\n    mosaic=1.0,\n    close_mosaic=40,     \n    hsv_h=0.025,\n    hsv_s=0.7,\n    hsv_v=0.4,\n    fliplr=0.4,\n    translate=0.2,\n\n\n    # General settings\n    patience=30,\n    workers=4,\n    seed=42,\n    warmup_epochs=3,\n    project='runs/train',\n    name='run1',\n    save_period=5,\n    plots=True,\n    verbose=True,\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-21T23:45:19.489752Z","iopub.execute_input":"2025-07-21T23:45:19.490035Z","iopub.status.idle":"2025-07-22T01:03:06.713027Z","shell.execute_reply.started":"2025-07-21T23:45:19.490013Z","shell.execute_reply":"2025-07-22T01:03:06.712194Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = YOLO(\"/kaggle/working/runs2/train_best/yolov12l_aug_896/weights/best.pt\")\nimg_test = \"/kaggle/input/multi-class-object-detection-challenge/testImages/images\"\nmodel.predict(\n    source=img_test,\n    save=True\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport matplotlib.pyplot as plt\n# Path to YOLOv8 predictions\npredict_dir = \"/kaggle/working/runs/detect/predict\"\nimage_files = [f for f in os.listdir(predict_dir) if f.lower().endswith(('.jpg', '.png'))]\n\n# Show up to 5 predictions\nplt.figure(figsize=(15, 8))\nfor i, img_file in enumerate(image_files[:10]):\n    img_path = os.path.join(predict_dir, img_file)\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    plt.subplot(1, 10, i + 1)\n    plt.imshow(img)\n    plt.title(img_file, fontsize=9)\n    plt.axis(\"off\")\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport matplotlib.pyplot as plt\n\n# مسار الصور المتوقعة\npredict_dir = \"/kaggle/working/runs/detect/predict\"\nimage_files = [f for f in os.listdir(predict_dir) if f.lower().endswith(('.jpg', '.png'))]\n\n# نعرض حتى 200 صورة\nnum_images = min(200, len(image_files))\ncols = 5\nrows = (num_images + cols - 1) // cols  # لحساب عدد الصفوف المطلوب\n\nplt.figure(figsize=(20, rows * 4))  # تعديل الحجم حسب عدد الصفوف\nfor i in range(num_images):\n    img_path = os.path.join(predict_dir, image_files[i])\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n    plt.subplot(rows, cols, i + 1)\n    plt.imshow(img)\n    plt.title(image_files[i], fontsize=8)\n    plt.axis(\"off\")\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Define file paths\nplot_dir = \"/kaggle/working/runs2/train_best/yolov12l_aug_896\"\nplot_files = [\"confusion_matrix.png\", \"results.png\"]\n\nplt.figure(figsize=(15, 6))\n\nfor i, plot_file in enumerate(plot_files):\n    path = os.path.join(plot_dir, plot_file)\n    \n    # Check if file exists\n    if os.path.exists(path):\n        img = cv2.imread(path)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        \n        plt.subplot(1, 2, i + 1)\n        plt.imshow(img)\n        plt.title(plot_file)\n        plt.axis(\"off\")\n    else:\n        print(f\"❌ File not found: {path}\")\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from pathlib import Path\nimport cv2\nfrom ultralytics import YOLO\nmodel_path = \"/kaggle/working/runs2/train_best/yolov12l_aug_896/weights/best.pt\"\ntest_images_path = Path(\"/kaggle/input/multi-class-object-detection-challenge/testImages/images\")\noutput_img_dir = Path(\"/kaggle/working/predictions/images\")\noutput_lbl_dir = Path(\"/kaggle/working/predictions/labels\")\n\noutput_img_dir.mkdir(parents=True, exist_ok=True)\noutput_lbl_dir.mkdir(parents=True, exist_ok=True)\n\nmodel = YOLO(model_path)\n\nfor img_path in test_images_path.glob(\"*.[jp][pn]g\"):\n    results = model.predict(str(img_path), conf=0.5)\n    result = results[0]\n\n    img = result.plot()\n    out_img_path = output_img_dir / img_path.name\n    cv2.imwrite(str(out_img_path), img)\n\n    out_txt_path = output_lbl_dir / (img_path.stem + \".txt\")\n    with open(out_txt_path, \"w\") as f:\n        for box in result.boxes:\n            cls = int(box.cls[0])\n            conf = float(box.conf[0])\n            x, y, w, h = box.xywhn[0].tolist()  # normalized\n            f.write(f\"{cls} {conf:.6f} {x:.6f} {y:.6f} {w:.6f} {h:.6f}\\n\")\n\nprint(\"✅ Prediction done and saved to /kaggle/working/predictions/\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nfrom pathlib import Path\nimport csv\n\nlabels_dir = Path(\"/kaggle/working/predictions/labels\")\ntest_images_dir = Path(\"/kaggle/input/multi-class-object-detection-challenge/testImages/images\")\noutput_csv = \"/kaggle/working/submission.csv\"\n\nimage_ids = [img.stem for img in test_images_dir.glob(\"*.[jp][pn]g\")]\n\nsubmission_data = []\n\nfor image_id in image_ids:\n    label_path = labels_dir / f\"{image_id}.txt\"\n    if label_path.exists():\n        with open(label_path, \"r\") as f:\n            lines = [line.strip() for line in f if line.strip()]\n        pred_str = \" \".join(lines) if lines else \"no boxes\"\n    else:\n        pred_str = \"no boxes\"\n\n    submission_data.append({\n        \"image_id\": image_id,\n        \"prediction_string\": pred_str\n    })\n\ndf = pd.DataFrame(submission_data)\ndf.to_csv(output_csv, index=False, quoting=csv.QUOTE_NONNUMERIC)\n\nprint(f\"✅ Submission file created at: {output_csv}\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\nshutil.make_archive(\"/kaggle/working/predict_results\", 'zip', \"/kaggle/working/runs/detect/predict\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"/kaggle/working/predict_results.zip","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}