{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":114094,"databundleVersionId":13610510,"sourceType":"competition"}],"dockerImageVersionId":31041,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install ultralytics > /dev/null","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:31:21.046482Z","iopub.execute_input":"2025-09-04T15:31:21.046735Z","iopub.status.idle":"2025-09-04T15:32:46.148511Z","shell.execute_reply.started":"2025-09-04T15:31:21.046707Z","shell.execute_reply":"2025-09-04T15:32:46.147473Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport shutil\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nfrom pathlib import Path\nfrom ultralytics import YOLO","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:32:46.150159Z","iopub.execute_input":"2025-09-04T15:32:46.150416Z","iopub.status.idle":"2025-09-04T15:32:50.544719Z","shell.execute_reply.started":"2025-09-04T15:32:46.150392Z","shell.execute_reply":"2025-09-04T15:32:50.544118Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_images = Path('/kaggle/input/grocery-items-multi-class-object-detection/train/train/images')\ntrain_masks = Path('/kaggle/input/grocery-items-multi-class-object-detection/train/train/labels')\n\ntest_images = Path(\"/kaggle/input/grocery-items-multi-class-object-detection/testImages/testImages/images\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:32:50.545477Z","iopub.execute_input":"2025-09-04T15:32:50.545808Z","iopub.status.idle":"2025-09-04T15:32:50.550019Z","shell.execute_reply.started":"2025-09-04T15:32:50.545791Z","shell.execute_reply":"2025-09-04T15:32:50.549217Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"output_dir = Path(\"/kaggle/working/predictions/labels\")\noutput_dir.mkdir(parents=True, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:32:50.551870Z","iopub.execute_input":"2025-09-04T15:32:50.552098Z","iopub.status.idle":"2025-09-04T15:32:50.574608Z","shell.execute_reply.started":"2025-09-04T15:32:50.552080Z","shell.execute_reply":"2025-09-04T15:32:50.573837Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 🤩 First, let's look at the images!","metadata":{}},{"cell_type":"code","source":"def visualize_random_masks(images_dir, masks_dir, counts=5):\n    \"\"\"\n    Vizualize random images with masks.\n    \n    images_dir: path to directory with images\n    masks_dir: path to directory with masks\n    counts: Numbers of images to show\n    \"\"\"\n\n    image_paths = list(images_dir.glob(\"*\"))\n    samples = np.random.choice(image_paths, counts, replace=False)\n\n    plt.figure(figsize=(counts * 5, 8))\n\n    for i, img_path in enumerate(samples, 1):\n        mask_path = masks_dir / img_path.with_suffix(\".txt\").name\n\n        image = cv2.imread(str(img_path))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        h, w, _ = image.shape\n\n        with open(mask_path, \"r\") as f:\n            lines = f.readlines()\n    \n        for line in lines:\n            parts = line.strip().split()\n\n            try:\n                class_id, x_center, y_center, box_w, box_h = map(float, parts)\n            except:\n                class_id, confidence, x_center, y_center, box_w, box_h = map(float, parts)\n\n            x_center *= w\n            y_center *= h\n            box_w *= w\n            box_h *= h\n    \n            x1 = int(x_center - box_w / 2)\n            y1 = int(y_center - box_h / 2)\n            x2 = int(x_center + box_w / 2)\n            y2 = int(y_center + box_h / 2)\n\n            cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 5)\n\n        plt.subplot(1, counts, i)\n        plt.imshow(image)\n        plt.axis(\"off\")\n        plt.tight_layout()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:32:50.575430Z","iopub.execute_input":"2025-09-04T15:32:50.575639Z","iopub.status.idle":"2025-09-04T15:32:50.592957Z","shell.execute_reply.started":"2025-09-04T15:32:50.575623Z","shell.execute_reply":"2025-09-04T15:32:50.592167Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"visualize_random_masks(train_images, train_masks)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:32:50.593797Z","iopub.execute_input":"2025-09-04T15:32:50.594083Z","iopub.status.idle":"2025-09-04T15:32:53.648707Z","shell.execute_reply.started":"2025-09-04T15:32:50.594055Z","shell.execute_reply":"2025-09-04T15:32:53.647661Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"data_yaml = \"\"\"\ntrain: /kaggle/input/grocery-items-multi-class-object-detection/train/train/images\nval: /kaggle/input/grocery-items-multi-class-object-detection/val/val/images\ntest: /kaggle/input/grocery-items-multi-class-object-detection/testImages/testImages/images\n\nnc: 3\nnames: ['cheerios', 'soup', 'candle']\n\"\"\"\n\nwith open('data.yaml', 'w') as file:\n    file.write(data_yaml)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:32:53.649818Z","iopub.execute_input":"2025-09-04T15:32:53.650056Z","iopub.status.idle":"2025-09-04T15:32:53.658709Z","shell.execute_reply.started":"2025-09-04T15:32:53.650039Z","shell.execute_reply":"2025-09-04T15:32:53.657821Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Detection models YOLOv11\n\n    yolo11n.pt 🚀✨ — Nano\n    \n    yolo11s.pt 🐦⚡ — Small\n    \n    yolo11m.pt 🦅🔥 — Medium\n    \n    yolo11l.pt 🐉💪 — Large\n    \n    yolo11x.pt 🦾🏋️‍♂️ — Extra Large\n\nDo you need more information❓\n[YOLOv11](https://docs.ultralytics.com/ru/tasks/detect/#models)","metadata":{}},{"cell_type":"code","source":"model = YOLO(\"yolo11n.pt\")\n\nresults = model.train(\n    data=\"data.yaml\",\n    epochs=80,\n    batch=4,\n    imgsz=960,\n    device=[0,1],\n    optimizer=\"Adam\",\n    seed=42,\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:32:53.659579Z","iopub.execute_input":"2025-09-04T15:32:53.659783Z","iopub.status.idle":"2025-09-04T15:35:07.470203Z","shell.execute_reply.started":"2025-09-04T15:32:53.659767Z","shell.execute_reply":"2025-09-04T15:35:07.469468Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 🎇 We predict the test dataset and save it in txt","metadata":{}},{"cell_type":"code","source":"for img_path in test_images.glob(\"*\"):\n    results = model.predict(img_path, conf=0.1, device=0, verbose=False) # 0 - GPU or \"cpu\"\n    output_txt = output_dir / f\"{img_path.stem}.txt\"\n\n    with open(output_txt, \"w\") as f:\n        found = False\n        for result in results:\n            img_height, img_width = result.orig_shape\n            boxes = result.boxes.data\n\n            if boxes is None or len(boxes) == 0:\n                continue\n\n            filtered_boxes = boxes[boxes[:, 4] >= 0.05]\n            if len(filtered_boxes) == 0:\n                continue\n\n            found = True\n            for box in filtered_boxes:\n                x1, y1, x2, y2, confidence, cls_id = box.tolist()\n\n                x_center = ((x1 + x2) / 2) / img_width\n                y_center = ((y1 + y2) / 2) / img_height\n                width = (x2 - x1) / img_width\n                height = (y2 - y1) / img_height\n\n                f.write(f\"0 {confidence:.6f} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\\n\")\n\n        if not found:\n            f.write(\"\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:35:07.471191Z","iopub.execute_input":"2025-09-04T15:35:07.471446Z","iopub.status.idle":"2025-09-04T15:35:51.659447Z","shell.execute_reply.started":"2025-09-04T15:35:07.471425Z","shell.execute_reply":"2025-09-04T15:35:51.658859Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 😎 Let's see the results","metadata":{}},{"cell_type":"code","source":"visualize_random_masks(test_images, output_dir)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:35:51.661543Z","iopub.execute_input":"2025-09-04T15:35:51.661766Z","iopub.status.idle":"2025-09-04T15:36:11.654998Z","shell.execute_reply.started":"2025-09-04T15:35:51.661750Z","shell.execute_reply":"2025-09-04T15:36:11.653825Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# ✉️ Saving the results","metadata":{}},{"cell_type":"code","source":"rows = []\ntest_imgs = {p.stem for p in test_images.glob(\"*\") if p.suffix.lower() in {\".jpg\", \".jpeg\", \".png\"}}\npredicted = set()\n\nfor file in output_dir.glob(\"*.txt\"):\n    name = file.stem\n    predicted.add(name)\n\n    try:\n        lines = [l.strip() for l in open(file) if len(l.strip().split()) == 6]\n    except:\n        lines = []\n\n    rows.append({\"image_id\": name, \"prediction_string\": \" \".join(lines) if lines else \"no boxes\"})\n\nfor name in test_imgs - predicted:\n    rows.append({\"image_id\": name, \"prediction_string\": \"no boxes\"})","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:36:11.656062Z","iopub.execute_input":"2025-09-04T15:36:11.656479Z","iopub.status.idle":"2025-09-04T15:36:11.674131Z","shell.execute_reply.started":"2025-09-04T15:36:11.656446Z","shell.execute_reply":"2025-09-04T15:36:11.673273Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Removing the excess","metadata":{}},{"cell_type":"code","source":"work_dir = '/kaggle/working'\n\nfor filename in os.listdir(work_dir):\n    file_path = os.path.join(work_dir, filename)\n\n    try:\n        if os.path.isfile(file_path) or os.path.islink(file_path):\n            os.unlink(file_path)\n        elif os.path.isdir(file_path):\n            shutil.rmtree(file_path)\n    except Exception as e:\n        print(f'Error file: {file_path}. Cause: {e}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:36:11.674845Z","iopub.execute_input":"2025-09-04T15:36:11.675083Z","iopub.status.idle":"2025-09-04T15:36:11.687710Z","shell.execute_reply.started":"2025-09-04T15:36:11.675067Z","shell.execute_reply":"2025-09-04T15:36:11.687102Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"rows = pd.DataFrame(rows)\nrows.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-04T15:36:11.688700Z","iopub.execute_input":"2025-09-04T15:36:11.688950Z","iopub.status.idle":"2025-09-04T15:36:11.701932Z","shell.execute_reply.started":"2025-09-04T15:36:11.688930Z","shell.execute_reply":"2025-09-04T15:36:11.701133Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}