{"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":19989,"databundleVersionId":1160143,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport PIL \nfrom PIL import Image\nfrom IPython.display import display\nimport matplotlib.pyplot as plt\nfrom glob import glob\nimport random\nimport cv2\nimport warnings","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-03T12:55:29.401332Z","iopub.execute_input":"2025-09-03T12:55:29.40198Z","iopub.status.idle":"2025-09-03T12:55:29.442914Z","shell.execute_reply.started":"2025-09-03T12:55:29.401946Z","shell.execute_reply":"2025-09-03T12:55:29.442182Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#%pip install ultralytics\nfrom ultralytics import YOLO\nimport pandas as pd","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-03T12:55:34.568662Z","iopub.execute_input":"2025-09-03T12:55:34.569153Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dir = '/kaggle/input/global-wheat-detection/train'\ntest_dir = '/kaggle/input/global-wheat-detection/test'\ntrain_label_dir = '/kaggle/input/global-wheat-detection/train.csv'","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Without using training data. Let's see how yolo will perform**","metadata":{}},{"cell_type":"code","source":"# Run inference on test folder\nresults = yolo_model.predict(\n    source=test_dir, \n    conf=0.25, \n    save=True  # saves predictions with boxes\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import glob\nfrom IPython.display import Image, display\n\n# YOLOv8 saves results in 'runs/detect/predict'\nfor img_path in glob.glob('runs/detect/predict/*.jpg')[:4]:\n    display(Image(filename=img_path))\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**As we see the yolo failed at this let's train and see**","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(train_label_dir)\nlen(df)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(df.info())","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(df['image_id'].nunique())\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create folders for YOLO dataset\nos.makedirs(\"wheat_dataset/labels/train\", exist_ok=True)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import ast\n\n# Parse the bbox string into numeric columns\ndef parse_bbox(s):\n    x, y, w, h = ast.literal_eval(s)  # turns string \"[..]\" into Python list\n    return pd.Series([x, y, w, h], index=['x','y','bw','bh'])\n\ndf[['x','y','bw','bh']] = df['bbox'].apply(parse_bbox)\ndf.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(df['width'].value_counts())\nprint(df['height'].value_counts())\n# all images are same size","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for img_id, group in df.groupby('image_id'):\n    img_path = f'/kaggle/input/global-wheat-detection/train/{img_id}.jpg'\n    img = cv2.imread(img_path)\n    h, w = img.shape[:2]\n    # Write YOLO label file\n    # <class_id> <x_center> <y_center> <box_width> <box_height>\n    with open(f\"wheat_dataset/labels/train/{img_id}.txt\", \"w\") as f:\n        for _, row in group.iterrows():\n            x, y, bw, bh = row[['x','y','bw','bh']]\n            \n            # Convert to YOLO format (x,y)-> coordinates of the top left corner\n            # bw -> width of the box, bh -> height of the box\n            x_center = (x + bw/2) / w \n            y_center = (y + bh/2) / h\n            bw /= w\n            bh /= h\n            \n            # Only one class (wheat_head = class 0)\n            f.write(f\"0 {x_center} {y_center} {bw} {bh}\\n\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def visualize_yolo(image_path, label_path):\n    # Load image\n    img = cv2.imread(image_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # convert BGR → RGB for matplotlib\n    h, w, _ = img.shape\n    \n    # Read label file\n    with open(label_path, \"r\") as f:\n        for line in f.readlines():\n            cls, x_center, y_center, bw, bh = map(float, line.strip().split())\n            \n            # Convert YOLO (normalized) back to pixel coordinates\n            x_center *= w\n            y_center *= h\n            bw *= w\n            bh *= h\n            \n            x1 = int(x_center - bw/2)\n            y1 = int(y_center - bh/2)\n            x2 = int(x_center + bw/2)\n            y2 = int(y_center + bh/2)\n            \n            # Draw rectangle\n            cv2.rectangle(img, (x1, y1), (x2, y2), (255,0,0), 2)\n            cv2.putText(img, f\"class {int(cls)}\", (x1, y1-5),\n                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)\n    \n    # Show image\n    plt.figure(figsize=(8,8))\n    plt.imshow(img)\n    plt.axis(\"off\")\n    plt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\n\n# Pick 4 random image_ids\nsample_ids = random.sample(list(df['image_id'].unique()), 4)\n\nfor image_id in sample_ids:\n    image_path = f\"/kaggle/input/global-wheat-detection/train/{image_id}.jpg\"\n    label_path = f\"wheat_dataset/labels/train/{image_id}.txt\"\n    \n    print(f\"Showing {image_id}\")\n    visualize_yolo(image_path, label_path)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os, random, shutil\nfrom pathlib import Path\n\n# Original paths\nimages_dir = Path(\"/kaggle/input/global-wheat-detection/train\")\nlabels_dir = Path(\"/kaggle/working/wheat_dataset/labels/train\")  # currently everything is here\n\n# Make a backup folder for all labels\nall_labels_dir = Path(\"/kaggle/working/wheat_dataset/labels_all\")\nif not all_labels_dir.exists():\n    shutil.move(str(labels_dir), str(all_labels_dir))   # move the whole \"train\" folder into labels_all\n    labels_dir = all_labels_dir\n\n# New dataset structure\nbase_dir = Path(\"/kaggle/working/wheat_dataset\")\nfor sub in [\"images/train\", \"images/val\", \"labels/train\", \"labels/val\"]:\n    (base_dir / sub).mkdir(parents=True, exist_ok=True)\n\n# Split 90% train / 10% val\nimage_files = list(images_dir.glob(\"*.jpg\"))\nrandom.shuffle(image_files)\nsplit_idx = int(0.9 * len(image_files))\n\ntrain_files = image_files[:split_idx]\nval_files   = image_files[split_idx:]\n\ndef move_files(files, split):\n    for img_path in files:\n        label_path = labels_dir / f\"{img_path.stem}.txt\"\n        if not label_path.exists():\n            continue\n        # Copy image and label to split\n        shutil.copy(img_path, base_dir / f\"images/{split}\" / img_path.name)\n        shutil.copy(label_path, base_dir / f\"labels/{split}\" / label_path.name)\n\nmove_files(train_files, \"train\")\nmove_files(val_files, \"val\")\n\nprint(f\"Train: {len(train_files)} images\")\nprint(f\"Val:   {len(val_files)} images\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\n\ndef visualize_random_samples(split=\"train\", num_samples=4):\n    img_dir = base_dir / f\"images/{split}\"\n    label_dir = base_dir / f\"labels/{split}\"\n\n    all_images = list(img_dir.glob(\"*.jpg\"))\n    samples = random.sample(all_images, min(num_samples, len(all_images)))\n\n    for img_path in samples:\n        label_path = label_dir / f\"{img_path.stem}.txt\"\n        if label_path.exists():\n            visualize_yolo(str(img_path), str(label_path))\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"visualize_random_samples(\"train\", 2)  # 2 train samples\nvisualize_random_samples(\"val\", 2)    # 2 val samples\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"yaml_content = \"\"\"\npath: /kaggle/working/wheat_dataset\ntrain: images/train\nval: images/val\n\nnames:\n  0: wheat_head\n\"\"\"\n\nwith open(\"/kaggle/working/wheat_dataset.yaml\", \"w\") as f:\n    f.write(yaml_content)\n\nprint(\"✅ dataset.yaml created\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from ultralytics import YOLO\n\n# Load pretrained model\nmodel = YOLO(\"yolov8m.pt\")\n\n# Train\nmodel.train(\n    data=\"/kaggle/working/wheat_dataset.yaml\",\n    epochs=7,\n    imgsz=640,\n    batch=16\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.val()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"results = model.predict(source=\"/kaggle/working/wheat_dataset/images/val\", save=True, conf=0.25)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\nfrom pathlib import Path\n\n# Paths\nval_images_dir = Path(\"/kaggle/working/wheat_dataset/images/val\")\nval_labels_dir = Path(\"/kaggle/working/wheat_dataset/labels/val\")\n\n# Pick 4 random images from val set\nval_images = list(val_images_dir.glob(\"*.jpg\"))\nsample_imgs = random.sample(val_images, 4)\n\n# Show them\nfor img_path in sample_imgs:\n    img_id = img_path.stem  # file name without extension\n    lbl_path = val_labels_dir / f\"{img_id}.txt\"\n\n    print(f\"Showing {img_id}\")\n    visualize_yolo(str(img_path), str(lbl_path))\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# Run inference on test images\nresults = model.predict(\n    source=\"/kaggle/input/global-wheat-detection/test\",  # test images folder\n    save=True,     # saves images with predictions\n    conf=0.25      # confidence threshold\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"results = model.predict(\n    source=\"/kaggle/input/global-wheat-detection/test\",  # path to your images\n    save=True,          # save annotated images\n    conf=0.25,          # confidence threshold\n    project=\"/kaggle/working/runs/detect\",  # where to save\n    name=\"val_predictions\",  # folder name for this prediction\n    exist_ok=True       # overwrite if folder exists\n)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nfrom matplotlib import pyplot as plt\n\n# Load the image\nimg = cv2.imread('/kaggle/working/runs/detect/val_predictions/2fd875eaa.jpg')\n\n# Convert BGR (OpenCV default) to RGB for matplotlib\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n\n# Display inline\nplt.imshow(img)\nplt.axis('off')  # optional: remove axes\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nfrom pathlib import Path\n\nsubmission = []\n\nfor result in results:\n    img_path = Path(result.path)\n    image_id = img_path.stem  # filename without extension\n    prediction_string = \"\"\n    \n    # Loop through all detected boxes\n    if result.boxes is not None and len(result.boxes) > 0:\n        boxes = result.boxes.xyxy.cpu().numpy()  # x1, y1, x2, y2\n        scores = result.boxes.conf.cpu().numpy()\n        for box, score in zip(boxes, scores):\n            x1, y1, x2, y2 = box\n            width = x2 - x1\n            height = y2 - y1\n            # Convert to YOLO normalized format (x_center, y_center, w, h)\n            x_center = x1 + width / 2\n            y_center = y1 + height / 2\n            \n            # Normalize by image size\n            h, w = result.orig_shape[:2]\n            x_center /= w\n            y_center /= h\n            width /= w\n            height /= h\n            \n            # Append to prediction string\n            prediction_string += f\"1 {score:.4f} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f} \"\n    \n    submission.append({\n        \"image_id\": image_id,\n        \"PredictionString\": prediction_string.strip()\n    })\n\n# Create submission DataFrame\nsubmission_df = pd.DataFrame(submission)\n\n# Save CSV\nsubmission_df.to_csv(\"/kaggle/working/submission.csv\", index=False)\nprint(\"Submission saved!\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}