{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","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":30840,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport random\nimport ast\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\nfrom sklearn import model_selection\nfrom sklearn.model_selection import train_test_split\nfrom tqdm import tqdm\nimport shutil","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:04.126352Z","iopub.execute_input":"2025-02-09T09:00:04.126533Z","iopub.status.idle":"2025-02-09T09:00:06.073521Z","shell.execute_reply.started":"2025-02-09T09:00:04.126515Z","shell.execute_reply":"2025-02-09T09:00:06.072629Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"\n# Process Data Function\n","metadata":{}},{"cell_type":"code","source":"output_dir = '/kaggle/working/'  \ndata_path = '/kaggle/input/global-wheat-detection/train'  \n\nos.makedirs(os.path.join(output_dir, 'labels/train'), exist_ok=True)\nos.makedirs(os.path.join(output_dir, 'labels/valid'), exist_ok=True)\nos.makedirs(os.path.join(output_dir, 'images/train'), exist_ok=True)\nos.makedirs(os.path.join(output_dir, 'images/valid'), exist_ok=True)\n\ndef process_data(data, data_type='train'):\n    for _, row in tqdm(data.iterrows(), total=len(data)):\n        image_name = row['image_id']\n        bounding_boxes = row['bboxes']\n        yolo_data = []\n        \n        for bbox in bounding_boxes:\n            x, y, w, h = bbox \n            x_center = (x + w / 2) / 1024.0  # Normalize x_center\n            y_center = (y + h / 2) / 1024.0  # Normalize y_center\n            w_norm = w / 1024.0  # Normalize width\n            h_norm = h / 1024.0  # Normalize height\n            yolo_data.append([0, x_center, y_center, w_norm, h_norm]) \n            \n        yolo_data = np.array(yolo_data)  \n    \n        np.savetxt(\n            os.path.join(output_dir, f'labels/{data_type}/{image_name}.txt'),\n            yolo_data,\n            fmt='%d %.6f %.6f %.6f %.6f',  # Format: class_id x_center y_center width height\n            delimiter=' '\n        )\n        shutil.copyfile(\n            os.path.join(data_path, f'{image_name}.jpg'),\n            os.path.join(output_dir, f'images/{data_type}/{image_name}.jpg')\n        )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:09.381564Z","iopub.execute_input":"2025-02-09T09:00:09.381860Z","iopub.status.idle":"2025-02-09T09:00:09.389640Z","shell.execute_reply.started":"2025-02-09T09:00:09.381837Z","shell.execute_reply":"2025-02-09T09:00:09.388692Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Load & Process Data","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/global-wheat-detection/train.csv\")\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:11.863945Z","iopub.execute_input":"2025-02-09T09:00:11.864249Z","iopub.status.idle":"2025-02-09T09:00:12.112224Z","shell.execute_reply.started":"2025-02-09T09:00:11.864226Z","shell.execute_reply":"2025-02-09T09:00:12.111400Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:12.673975Z","iopub.execute_input":"2025-02-09T09:00:12.674311Z","iopub.status.idle":"2025-02-09T09:00:12.724490Z","shell.execute_reply.started":"2025-02-09T09:00:12.674283Z","shell.execute_reply":"2025-02-09T09:00:12.723564Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:13.189893Z","iopub.execute_input":"2025-02-09T09:00:13.190156Z","iopub.status.idle":"2025-02-09T09:00:13.209387Z","shell.execute_reply.started":"2025-02-09T09:00:13.190138Z","shell.execute_reply":"2025-02-09T09:00:13.208673Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_show = []\ncolumns = df . columns \nfor i in columns : \n    types = df[i] . dtypes\n    unique_data = df[i] . nunique()\n    NAN_value=df[i].isnull().sum()\n    duplicated= df.duplicated().sum()  \n    \n    df_show . append ([i , types , unique_data , NAN_value,duplicated])\n        \ndf_info = pd . DataFrame (df_show)\ndf_info . columns =['name of column' , 'types' ,'unique_data' , 'NAN value',\"duplicated\"]\n\n\n\n\ndf_info.style.highlight_max(color = 'pink', axis = 0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:14.487051Z","iopub.execute_input":"2025-02-09T09:00:14.487383Z","iopub.status.idle":"2025-02-09T09:00:14.831892Z","shell.execute_reply.started":"2025-02-09T09:00:14.487355Z","shell.execute_reply":"2025-02-09T09:00:14.831152Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.bbox=df.bbox.apply(ast.literal_eval)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:16.880340Z","iopub.execute_input":"2025-02-09T09:00:16.880800Z","iopub.status.idle":"2025-02-09T09:00:18.640332Z","shell.execute_reply.started":"2025-02-09T09:00:16.880761Z","shell.execute_reply":"2025-02-09T09:00:18.639539Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = df.groupby('image_id')['bbox'].apply(list).reset_index(name='bboxes')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:18.641403Z","iopub.execute_input":"2025-02-09T09:00:18.641701Z","iopub.status.idle":"2025-02-09T09:00:18.731539Z","shell.execute_reply.started":"2025-02-09T09:00:18.641673Z","shell.execute_reply":"2025-02-09T09:00:18.730773Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train, df_vaild = train_test_split(df, test_size=0.1, random_state=42, shuffle=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:18.732919Z","iopub.execute_input":"2025-02-09T09:00:18.733217Z","iopub.status.idle":"2025-02-09T09:00:18.740148Z","shell.execute_reply.started":"2025-02-09T09:00:18.733173Z","shell.execute_reply":"2025-02-09T09:00:18.739227Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train = df_train.reset_index(drop=True)\ndf_vaild = df_vaild.reset_index(drop=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:18.741136Z","iopub.execute_input":"2025-02-09T09:00:18.741441Z","iopub.status.idle":"2025-02-09T09:00:18.762128Z","shell.execute_reply.started":"2025-02-09T09:00:18.741413Z","shell.execute_reply":"2025-02-09T09:00:18.761326Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Prepare YOLO Labels & Images","metadata":{}},{"cell_type":"code","source":"process_data(df_train, data_type='train')\nprocess_data(df_vaild, data_type='valid')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:00:19.648830Z","iopub.execute_input":"2025-02-09T09:00:19.649140Z","iopub.status.idle":"2025-02-09T09:01:02.577795Z","shell.execute_reply.started":"2025-02-09T09:00:19.649115Z","shell.execute_reply":"2025-02-09T09:01:02.577092Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Create YOLO Data Config","metadata":{}},{"cell_type":"code","source":"data_yaml_content=f\"\"\"\ntrain: {os.path.join(output_dir,'images/train')}\nval: {os.path.join(output_dir,'images/valid')}\nnc: 1\nnames: ['wheat']\n\"\"\"\n\ndata_yaml_path= os.path.join(output_dir, 'data.yaml')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:08:00.700934Z","iopub.execute_input":"2025-02-09T09:08:00.701281Z","iopub.status.idle":"2025-02-09T09:08:00.705087Z","shell.execute_reply.started":"2025-02-09T09:08:00.701257Z","shell.execute_reply":"2025-02-09T09:08:00.704305Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"with open(data_yaml_path, 'w') as file:\n    file.write(data_yaml_content)\nprint(f\"data.yaml file saved at: {data_yaml_path}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:08:01.265474Z","iopub.execute_input":"2025-02-09T09:08:01.265758Z","iopub.status.idle":"2025-02-09T09:08:01.270792Z","shell.execute_reply.started":"2025-02-09T09:08:01.265735Z","shell.execute_reply":"2025-02-09T09:08:01.269856Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"with open(data_yaml_path,'r') as file:\n    print(file.read())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:08:01.576732Z","iopub.execute_input":"2025-02-09T09:08:01.577006Z","iopub.status.idle":"2025-02-09T09:08:01.581877Z","shell.execute_reply.started":"2025-02-09T09:08:01.576982Z","shell.execute_reply":"2025-02-09T09:08:01.580987Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install ultralytics\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:07:00.428863Z","iopub.execute_input":"2025-02-09T09:07:00.429139Z","iopub.status.idle":"2025-02-09T09:07:03.766052Z","shell.execute_reply.started":"2025-02-09T09:07:00.429120Z","shell.execute_reply":"2025-02-09T09:07:03.765112Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Train YOLO Model","metadata":{}},{"cell_type":"code","source":"from ultralytics import YOLO\n\nmodel = YOLO('yolov8n.pt')  \nresults = model.train(\n    data=data_yaml_path,  \n    epochs=50,                         \n    imgsz=1024,                        \n    batch=16,                          \n    patience=10,                                                 \n    cos_lr=True,                       \n    warmup_epochs=3,                  \n    augment=True,                     \n    weight_decay=0.0005,               \n    momentum=0.937,                    \n    dropout=0.2                        \n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T09:08:05.759070Z","iopub.execute_input":"2025-02-09T09:08:05.759398Z","iopub.status.idle":"2025-02-09T10:24:02.339536Z","shell.execute_reply.started":"2025-02-09T09:08:05.759373Z","shell.execute_reply":"2025-02-09T10:24:02.338640Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#  Evaluate ","metadata":{}},{"cell_type":"code","source":"metrics = model.val(data='/kaggle/working/data.yaml', split='val')\n\nmAP50 = metrics.box.map50  \nmAP50_95 = metrics.box.map  \nprecision = metrics.box.p  \nrecall = metrics.box.r  \n\n# Print metrics\nprint(f\"mAP50: {mAP50:.4f}\")\nprint(f\"mAP50-95: {mAP50_95:.4f}\")\nprint(f\"Precision: {np.mean(precision):.4f}\")  \nprint(f\"Recall: {np.mean(recall):.4f}\") ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T11:07:02.645176Z","iopub.execute_input":"2025-02-09T11:07:02.645532Z","iopub.status.idle":"2025-02-09T11:07:19.510609Z","shell.execute_reply.started":"2025-02-09T11:07:02.645502Z","shell.execute_reply":"2025-02-09T11:07:19.509722Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Test Model on a Sample Img","metadata":{}},{"cell_type":"code","source":"sample_image_path = os.path.join(output_dir, 'images/valid', df_vaild.iloc[89]['image_id'] + '.jpg')\nimage = cv2.imread(sample_image_path)\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) \n\nresults = model.predict(source=sample_image_path, conf=0.5)  \n\nfor result in results:\n    boxes = result.boxes.xyxy.cpu().numpy()  \n    for box in boxes:\n        x1, y1, x2, y2 = box\n        cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), (255, 0, 0), 2)  \n\nplt.figure(figsize=(6, 4))\nplt.imshow(image)\nplt.axis('off')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T11:26:42.731950Z","iopub.execute_input":"2025-02-09T11:26:42.732286Z","iopub.status.idle":"2025-02-09T11:26:42.954382Z","shell.execute_reply.started":"2025-02-09T11:26:42.732254Z","shell.execute_reply":"2025-02-09T11:26:42.953512Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Save Model","metadata":{}},{"cell_type":"code","source":"model.save('custom_yolo.pt')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T11:15:17.685212Z","iopub.execute_input":"2025-02-09T11:15:17.685605Z","iopub.status.idle":"2025-02-09T11:15:17.751645Z","shell.execute_reply.started":"2025-02-09T11:15:17.685563Z","shell.execute_reply":"2025-02-09T11:15:17.750941Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Load the saved model and test it","metadata":{}},{"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt\nimport os\nfrom ultralytics import YOLO\n\nmodel = YOLO('custom_yolo.pt')\n\nfor index in range(8):\n    sample_image_path = os.path.join(output_dir, 'images/valid', df_vaild.iloc[index]['image_id'] + '.jpg')\n    image = cv2.imread(sample_image_path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  \n\n    # Make predictions on the image\n    results = model(sample_image_path)\n\n    for result in results:\n        boxes = result.boxes.xyxy.cpu().numpy() \n        for box in boxes:\n            x1, y1, x2, y2 = box\n            cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), (255, 0, 0), 2)  # Draw bounding box\n\n    plt.figure(figsize=(6, 4))\n    plt.imshow(image)\n    plt.axis('off')\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-09T11:50:15.995696Z","iopub.execute_input":"2025-02-09T11:50:15.996005Z","iopub.status.idle":"2025-02-09T11:50:17.616465Z","shell.execute_reply.started":"2025-02-09T11:50:15.995978Z","shell.execute_reply":"2025-02-09T11:50:17.615613Z"}},"outputs":[],"execution_count":null}]}