{"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":30627,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Enviroment setup\n\nModel comparision: https://dagshub.com/blog/best-object-detection-models/\n\nAugmentation with Albumenation: https://medium.com/red-buffer/apply-data-augmentation-on-yolov5-yolov8-dataset-958e89d4bc5d\n\nYOLO Format:\nhttps://medium.com/red-buffer/converting-a-custom-dataset-from-coco-format-to-yolo-format-6d98a4fd43fc\n\nhttps://www.kaggle.com/code/ismailehab/yolov8-wheat-detection\n\nhttps://learnopencv.com/yolov7-object-detection-paper-explanation-and-inference/\n\nhttps://learnopencv.com/fine-tuning-yolov7-on-custom-dataset/","metadata":{}},{"cell_type":"code","source":"quick_run = True","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:19.138097Z","iopub.execute_input":"2024-05-14T14:12:19.138523Z","iopub.status.idle":"2024-05-14T14:12:19.143360Z","shell.execute_reply.started":"2024-05-14T14:12:19.138482Z","shell.execute_reply":"2024-05-14T14:12:19.142270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if True:\n    !pip install -U ray[tune]\n\n    import numpy as np \n    import pandas as pd \n    import re\n    import os\n    import pathlib\n    from tqdm.auto import tqdm\n    import shutil\n    import glob\n    \n    from datetime import datetime\n    #from pathlib import Path\n    import seaborn as sns\n    from matplotlib import pyplot as plt\n    from IPython.display import Image, clear_output\n    %matplotlib inline\n\n    import cv2\n    import torch\n    print(torch.__version__)\n    import torchvision\n    from torchvision.io import read_image\n    from torchvision.utils import draw_bounding_boxes\n\n    from sklearn.model_selection import train_test_split\n    from PIL import Image, ImageDraw, ImageFont\n    from PIL import __version__ as pil_version\n    from scipy.ndimage import gaussian_filter1d\n\n    !pip install ultralytics\n    !pip install -e\n    #!pip install -r requirements.txt\n\n    import ultralytics\n    from ultralytics import YOLO\n    ultralytics.checks()","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:25:49.878512Z","iopub.execute_input":"2024-05-14T14:25:49.879711Z","iopub.status.idle":"2024-05-14T14:26:16.725022Z","shell.execute_reply.started":"2024-05-14T14:25:49.879667Z","shell.execute_reply":"2024-05-14T14:26:16.723857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_dir = '/kaggle/input/global-wheat-detection/'\ndataset_dir = '/kaggle/working/dataset/'\nworking_dir = '/kaggle/working/'\ntrain_dir = input_dir + 'train/'\ntest_dir = input_dir + 'test/'\n\nrandom_state = 42\n\nIMG_SIZE = 1024\nBATCH_SIZE = 16\nEPOCHS = 100","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:24:04.191955Z","iopub.execute_input":"2024-05-14T14:24:04.193117Z","iopub.status.idle":"2024-05-14T14:24:04.198240Z","shell.execute_reply.started":"2024-05-14T14:24:04.193077Z","shell.execute_reply":"2024-05-14T14:24:04.197212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Funktionen zum plotten der Bilder mit Boundingboxen","metadata":{}},{"cell_type":"code","source":"def display_images(df):\n    # set up the canvas for the subplots\n    plt.figure(figsize=(30,30))\n    j = 1\n    for i in range(0,900,100):\n        # Load an image\n        image = plt.imread(df.path[i])\n        \n        #image = cv2.resize(image, (IMAGE_SIZE, IMAGE_SIZE))\n        plt.subplot(3,3,j)\n        j+=1\n        plt.imshow(image)\n        plt.axis('off')\n        \ndef display_with_bbox(num, image_path, label_path, test=False):\n    bbox = []\n    plt.figure(figsize=(30,30))\n    labels_files = os.listdir(label_path)\n    \n    for index, label_file in enumerate(labels_files[:num]):\n        with open(f'{label_path}/{label_file}') as f:\n            image_file = label_file.replace('.txt', '.jpg')\n            img = read_image(f'{image_path}/{image_file}')\n            bboxes = []\n            for label in f:\n                bbox = label[:-1].split(\" \")                       # -1 to remove the newline \\n\n                bbox = bbox[1:-1] if test==True else bbox[1:]      # keep only x, y, w, h\n                bbox = [float(i) for i in bbox]\n                bbox = [i*1024 for i in bbox]\n                [x, y, w, h] = bbox\n                [xmin, ymin, xmax, ymax] = [x-w/2, y-h/2, x+w/2, y+h/2]\n                bbox = [xmin, ymin, xmax, ymax]\n                bboxes.append(bbox)\n            bboxes = torch.tensor(bboxes, dtype=torch.int)\n            img = draw_bounding_boxes(img, bboxes, width=10,colors=(255,0,0))\n            img = torchvision.transforms.ToPILImage()(img)\n            plt.subplot(num//3+num%3,3,index+1)\n            plt.imshow(img)\n            plt.axis('off')\n        \n\ndef plt_img_with_bbox(dataset_dir, img_name, split='train', test=False):\n\n    with open(f'{dataset_dir}labels/{split}/{img_name}.txt') as f:\n            img = read_image(f'{dataset_dir}images/{split}/{img_name}.jpg')\n            bboxes = []\n            for label in f:\n                bbox = label[:-1].split(\" \")                       # -1 to remove the newline \\n\n                bbox = bbox[1:-1] if test==True else bbox[1:]      # keep only x, y, w, h\n                bbox = [float(i) for i in bbox]\n                bbox = [i*1024 for i in bbox]\n                [x, y, w, h] = bbox\n                [xmin, ymin, xmax, ymax] = [x-w/2, y-h/2, x+w/2, y+h/2]\n                bbox = [xmin, ymin, xmax, ymax]\n                bboxes.append(bbox)\n            bboxes = torch.tensor(bboxes, dtype=torch.int)\n            img = draw_bounding_boxes(img, bboxes, width=10,colors=(255,0,0))\n            img = torchvision.transforms.ToPILImage()(img)\n            plt.figure()\n            plt.imshow(img)\n            plt.axis('off')\n            plt.title(img_name)\n            \ndef plt_img_with_bbox_from_file_from_df(df, img_name, test=False):\n    img = read_image(df[df['image_id'] == img_name]['path'].iloc[0])\n    bboxes = []\n    for i, row in df[df['image_id'] == img_name].iterrows():\n        x = row['bbox_x_center']*1024\n        y = row['bbox_y_center']*1024\n        w = row['bbox_width']*1024\n        h = row['bbox_height']*1024\n        [xmin, ymin, xmax, ymax] = [x-w/2, y-h/2, x+w/2, y+h/2]\n        bbox = [xmin, ymin, xmax, ymax]\n        bboxes.append(bbox)\n    bboxes = torch.tensor(bboxes, dtype=torch.int)\n    img = draw_bounding_boxes(img, bboxes, width=10,colors=(255,0,0))\n    img = torchvision.transforms.ToPILImage()(img)\n    plt.figure()\n    plt.imshow(img)\n    plt.axis('off')\n    plt.title(img_name)","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:19.259403Z","iopub.execute_input":"2024-05-14T14:12:19.260379Z","iopub.status.idle":"2024-05-14T14:12:19.281659Z","shell.execute_reply.started":"2024-05-14T14:12:19.260340Z","shell.execute_reply":"2024-05-14T14:12:19.280580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data preparing and visualizing","metadata":{}},{"cell_type":"code","source":"%cd","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:19.368665Z","iopub.execute_input":"2024-05-14T14:12:19.369077Z","iopub.status.idle":"2024-05-14T14:12:19.377260Z","shell.execute_reply.started":"2024-05-14T14:12:19.369042Z","shell.execute_reply":"2024-05-14T14:12:19.376231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#%cd /kaggle/input\n\ndf = pd.read_csv(input_dir + 'train.csv')\ndf = df.assign(path = lambda row: train_dir + row.image_id + '.jpg')\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:19.465761Z","iopub.execute_input":"2024-05-14T14:12:19.466684Z","iopub.status.idle":"2024-05-14T14:12:19.793511Z","shell.execute_reply.started":"2024-05-14T14:12:19.466642Z","shell.execute_reply":"2024-05-14T14:12:19.792335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Histogramm von Bounding Boxes\nif not quick_run:\n    counts = df['image_id'].value_counts()\n    print(f'number of boxes, range [{min(counts)}, {max(counts)}]')\n    sns.displot(counts, kde=False)\n    plt.xlabel('Bounding Boxes')\n    plt.ylabel('Images')\n    plt.title('Bounding Boxes vs. Images')\n    plt.show()\n    \n    \n    plt.figure(figsize=(9,5))\n    sns.countplot(data=df, x='source',  order = df['source'].value_counts().index)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:19.795153Z","iopub.execute_input":"2024-05-14T14:12:19.795489Z","iopub.status.idle":"2024-05-14T14:12:19.801611Z","shell.execute_reply.started":"2024-05-14T14:12:19.795443Z","shell.execute_reply":"2024-05-14T14:12:19.800609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Erzeuge normierte Boundingbox Werte mit Boundingbox Mittelpunkt als Basis\nYOLO Modell benötigt dies ","metadata":{}},{"cell_type":"code","source":"  \ndef extract_numbers(x):\n    return np.fromstring(x.strip('[]'), dtype=float, sep=',')\n\n#df[['bbox_x', 'bbox_y', 'bbox_width', 'bbox_height']] =  pd.DataFrame(df['bbox'].apply(extract_numbers). tolist(), index = df.index)\ndf[['bbox_x', 'bbox_y', 'bbox_width', 'bbox_height']] =  np.stack(df['bbox'].apply(lambda x: np.fromstring(x.strip('[]'), dtype=float, sep=',')))\n\ndf['bbox_x_center'] = (df['bbox_x'] + df['bbox_width']/2) / df['width']\ndf['bbox_y_center'] = (df['bbox_y'] + df['bbox_height']/2) / df['height']\ndf['bbox_width'] = df['bbox_width'] / df['width']\ndf['bbox_height'] = df['bbox_height'] / df['height']\ndf['bbox_area'] = df['bbox_height'] * df['bbox_width']\ndf = df.drop(columns=['bbox', 'bbox_x', 'bbox_y'])\n\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:19.802953Z","iopub.execute_input":"2024-05-14T14:12:19.803261Z","iopub.status.idle":"2024-05-14T14:12:20.376370Z","shell.execute_reply.started":"2024-05-14T14:12:19.803231Z","shell.execute_reply":"2024-05-14T14:12:20.375074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not quick_run:\n    display_images(df)","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:20.379015Z","iopub.execute_input":"2024-05-14T14:12:20.379377Z","iopub.status.idle":"2024-05-14T14:12:20.385074Z","shell.execute_reply.started":"2024-05-14T14:12:20.379343Z","shell.execute_reply":"2024-05-14T14:12:20.383757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\n#plt.subplot(1,2,1)\nsns.boxplot(data=pd.melt(df[['bbox_height', 'bbox_width', 'bbox_x_center', 'bbox_y_center', 'bbox_area']]), x='variable', y='value')\n#plt.subplot(1,2,2)\n#sns.boxplot(x=df['bbox_area'], orient='h')\n\ndf.describe()","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:20.386420Z","iopub.execute_input":"2024-05-14T14:12:20.386821Z","iopub.status.idle":"2024-05-14T14:12:21.184942Z","shell.execute_reply.started":"2024-05-14T14:12:20.386783Z","shell.execute_reply":"2024-05-14T14:12:21.183897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[df['bbox_area'] > 0.3]['image_id']","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:21.186699Z","iopub.execute_input":"2024-05-14T14:12:21.187056Z","iopub.status.idle":"2024-05-14T14:12:21.196148Z","shell.execute_reply.started":"2024-05-14T14:12:21.187024Z","shell.execute_reply":"2024-05-14T14:12:21.195252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not quick_run:\n    plt_img_with_bbox_from_file_from_df(df, 'a1321ca95')","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:21.197258Z","iopub.execute_input":"2024-05-14T14:12:21.197610Z","iopub.status.idle":"2024-05-14T14:12:21.204852Z","shell.execute_reply.started":"2024-05-14T14:12:21.197578Z","shell.execute_reply":"2024-05-14T14:12:21.203849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Lösche zu große oder zu kleine Boundingboxen","metadata":{"execution":{"iopub.status.busy":"2024-05-14T11:15:14.512870Z","iopub.execute_input":"2024-05-14T11:15:14.513253Z","iopub.status.idle":"2024-05-14T11:15:14.517767Z","shell.execute_reply.started":"2024-05-14T11:15:14.513219Z","shell.execute_reply":"2024-05-14T11:15:14.516767Z"}}},{"cell_type":"code","source":"mask = ((df['bbox_height'] < 0.4) & \n    (df['bbox_height'] > 0.001) & \n    (df['bbox_width'] < 0.4) & \n    (df['bbox_width'] > 0.001) & \n    (df['bbox_area'] < 0.1) & \n    (df['bbox_area'] > 0.001))\n\ndf = df[mask]\n\nprint(f'Es wurden {len(mask) - sum(mask)} Boundingboxen gelöscht, da sie zu groß oder zu klein waren')","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:21.206102Z","iopub.execute_input":"2024-05-14T14:12:21.206503Z","iopub.status.idle":"2024-05-14T14:12:21.243720Z","shell.execute_reply.started":"2024-05-14T14:12:21.206444Z","shell.execute_reply":"2024-05-14T14:12:21.242566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Erzeuge yolo-Format\nAngelehnt an folgendes Notebook:\nhttps://www.kaggle.com/code/ahmedelashrybdm/wheat-detection-using-yolov8\n## Erzeuge ein Validation-Split \nHyperparameter anzupassen ohne dafür den Test-Split zu verwenden","metadata":{}},{"cell_type":"code","source":"train_list, valid_list = train_test_split(df.image_id.unique(), test_size=0.2, random_state=random_state)\ntrain_df = df.loc[df.image_id.isin(train_list)]\nvalid_df = df.loc[df.image_id.isin(valid_list)]\n\ntrain_df = train_df.assign(split = 'train')\nvalid_df = valid_df.assign(split = 'valid')\n\ndf = pd.concat([train_df, valid_df]).reset_index(drop=True)\n\ndisplay(df.head(3))\ndisplay(df.tail(3))","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:21.244972Z","iopub.execute_input":"2024-05-14T14:12:21.245281Z","iopub.status.idle":"2024-05-14T14:12:21.377103Z","shell.execute_reply.started":"2024-05-14T14:12:21.245251Z","shell.execute_reply":"2024-05-14T14:12:21.376069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Erzeuge Ordnerstruktur wie von YOLO benötigt\nSiehe https://docs.ultralytics.com/datasets/detect/\n\n![image.png](attachment:b622defe-c4d4-477e-bbbd-62eb0f288892.png)","metadata":{},"attachments":{"b622defe-c4d4-477e-bbbd-62eb0f288892.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAMkAAACpCAYAAACBMhlfAAARWklEQVR4Ae1dy20juxJ1KkrJORgY4MUwO0dwMQsn4ADmwTF4YUBeeeOtNwYunAMv2OQpFqvJpiyL/dMZwNMfksWqU3W6SDUp3Tj+IwJEYBKBm8lSFhIBIuBIEgYBEWggQJI0AGIxESBJGANEoIEASdIAiMVEoEqS54cXd3N3dI+fS4D04e7vfP/x7/e7+4kawZY39zyHKZ/v7tbr/fAx3dup9aalNEunbY84/xDfphIbr7BSkgDVSzgxyLh9+oLQvsdTgx/1ugZoy/Zz8D2nzeUg/3w6Dg/P+9fLyWxJ2j1JAqgzZkQEfyuTtDxzgfK27ecE/DltLmBMFLFikkRg7l5cYnC6F4ZFdjhjy8PQSdojmDCkGo42mCcc8vqWhmOZXtohsb0K2ACy1dW5/L7VXdf/co+/X9yNzwDKBslUuBf7hFOH+oNqRrbJJNDjMT4xB2yV/l6EyNTYGTnOjW0PyJj+vYysrS1PtoehmxoGx/7F9kG5ONyEbpnsgu7GNlfzK3CFXDkm/YJ9l///hEwSg8IE4vODUg4GiMEqkBRwCUzjwAiMEEjsjPUM0AAS8kLQWII5h3paLoLQzk+GABj6sX3aa9h2dLdDfeAT8dBYwOFW/8E+KzcYLQSIbUa2Gayqcw5TL0i3fdpr56b96qWM2wTZ/v8v9/ig5o9RB/ip5I/UNvkL9Ue2qweE9mkmo8NFkyS3/ql59+KgeFkHC1y4Tm3MdQwkMdReSydWbigYBUZsn/rz9RDMymn+9uC4QChNmEGmJ3khuHJngRSJlFk5SPL7GCbwd+phInb5k7JtmaxCUGidvRR7HbqYsr0wGiiSuKZjWe/Qr/kfWODhGbHNM1dqc4pfg73ahtS+11mDJEitBUfDYEl7Om1HJxlwhBQxQBDUNjCSsSWHIEihWzpC3tC+Rjy5n+Tcv4Zz377khFw/tCtg4jtGYERcMp2SYWeTRJO8+iAQG7MOC7YV8J30q5dXaKO6AX7yyaTHAXHgfKZK/sqHksDVlJsHNOSnWFKddzptkOToHl/jGFM/bRAIYrwFrmCw1FVAK4KVg8nKDSiMnjgFcOp1gsz7p/dhuPTsx/4Pb8NHzh74khOCLGQO2NYgycOHBETZoWXbckIW9BkFMfRKINRsH9tmdGj6VflOxwO6jrqJL0fyUFHJUa8ZanrrVmMbdGmf8zZJPpOj5IkQjQcYUFzSaCwvB0c+5Jk2yzgRla0zcB9Hox9uh2MI8tvfnhwf4ck/DI0QbLbPeC0kP50k8tRVgZB0sf2EkhZJhkAqBSgET9key+DHEJRqBGDajvw69DFhf/QL/C7yBTsoGY6hHLgjLhpD+5bv8y4ucnUSSSStq9QpAMR7w7VyXlaOjCFgAeg8tYJ0dsgiqVvJFwdCtgpEG2gWKegWnBmDVbUf9S96e0nQvZ1Jhn6jU+XFLAJV9I4YxD6s7rATgTfSbZCTAs22t7ZDHoY6k35DNlS4D/KMDeI3wSbYdPv0ET4JzGzLfS52RUUz/YxtsAX+C3FR8QMqX+BYJcmPZJsnipelnafP0U8w/BIG2yc/etjDMRI0C1ptrz7fg73rsKELSfA00E+JQILwxNPnAYbG03kdWK1Ai0gCTRI81bNstwJVd6RCF5J4fPKU6FNsGhKkIYtOvZfIIjvyTM0UkEIP10iQGloXud+NJBfRjkKIwAoQIElW4ASqsG4ESJJ1+4farQCBNkle/7jDP8cVqEoViMAyCKybJJikcmK6THSw1wGBbZBEf+RJxxGBmRFYN0lmBoPdEYESAislSXxphncBOpMMQ7Cju38I2zhvHt7D0gezWtS+p9EvNj0QthzLNAJIeLkZ3+Po/ocKRr/sHVAJZt7bMgIrJQkgbbxhVstfhqBHML++qR2UCPj0sjJfFmOXetj6UQeZF9n60JXHvSKwWZIMmWEgSQj+jCTGWyFrpDf+tm52HT8sSIv2kHVAMpBo3o0/xiRezojA+ST5/Ot+HQ7uIH9/XPZBcav8JCPrmWSaJHY4lC+LCZkEQW8yhaza1Utm/DnqjzdW5UtuTjKMlTaEwPkkmcXIc0iCJ30KaptJsABTluAXCKAzyZSpIkuGY1O1WbZFBPZLEsxP8K5FJteRRNWgHpNs0rGQX5U32ZqFG0BgnSRB4OHTLRx9IMayyeFWNmR6c8/DdZqT4MseUiYxwyns40a//igkKAzlQMgNOJwqfh+BdZLk+3Z8o4WZg/iWkXinDrG+0Rmr7gCB6yMJspRkhhP3Vu/A2TThPASujyQep2w4Fj7FYhY5L4CuoVWbJNeAAm0kAhMIkCQT4LCICHgESBLGARFoINAmyaKbrv51f//3y/39yS/4NABgMRFoIUCStBBi+dUjQJIUQ+Cbb92LMqZuFpbbTFVn2aIIkCRF+EmSIixXepMkMY6XBYt6SUq2LMU3AIniSmG7LAUvLEWGXWwZ20l540uijY68nBcBkqSIN0iQgjtVs2V2mYu9Ti3TGYdbCYv1n5EkRR9ZIqhKhXVeYSk+CBUJIKuOVVs5JUkEig2cbJYkx3/0hq+D+/X/fxXc/qPjvPzPt37SeIIkhSUto58AGNUBgaAiSQIktnDcLEn6gjtBkkImmdIlZBk75yBJpjBbWxlJUvGI3c2Yqk0QKFVKZzGr5AsovykjSePZAgiQJFXQMbeIn0TppfVTm7JGn2zpDVuqM1MvJ5Gqx9PFESBJFncBFVg7AiTJ2j1E/RZHgCRZ3AVUYO0ItEmydguoHxHojABJ0hlgit8+AiTJ9n1ICzoj0CYJN111dgHFrx0BkmQpD+E9Sfb+ZSll2O8UAiRJEZ0Z3oiDJHaZfVEf3lwSAZKkiP4MJCn2y5trRIAkMV5pb7qKBPIZANnA/MoWvjZVvms4yxZmuUtW5lzo/809PsVf8hpt+DIK87I7AiRJEeKpTAKSHN3tEOC27pd7fHh38gUvxQWOvtPySmAhaSRPuFZf9l3Ulzd7IkCSFNG1ga8roSwF7mQgI9uMJuhTJLGy+ata2gNzn2+WJIttupL97XYjVXKdZAO1hz39dAPqkSRAYu3HzZKkL7DIFiUiTJWlL+OWpe/MJH1dNYN0kqQC8tmbruIcBD+JjZ2JzCQVoDdwmySpOsl8CiVzikYmkeEYftLhI/zOPNojs+ihmPoEy85vMHQD6arqsqAbAiRJN2gpeC8IkCR78STt6IYASdINWgreCwJtkuzFUtpBBM5EgCQ5Ezg2ux4ESJLr8TUtPROBNkkW3XR1plVsRgQuiMBKSYLv8t3iT8GZ9ytmla/4Du9L8P5ECvITvifJ8VjiaqUkiVD4LHbYIlG8/uW1WeJkkKRGoliRJBHEFjtZN0kWg+USHTdIcmIXJMmJQHWsRpIYcItrtkZ7QsyQ6q60ELJGEtO2kElADNm0dcel8sZNs16SJBbuESGcC8RJRHh+SOeyC3E0t6iRBB2Wy0EQrNWy12jN43wIkCQjrOMCRnnCx2AekQANy8HenJMU5yy2b2znZSYB2kscN0uSnpuuwtM77g4cMkvaKTg4KWYbPRy6EVLBjTXyTJWP2zCTAK/ljpslSV/IQrD6jVPDUEsTAJ9KSWYZB3bQrXYfmpfKx/dIEuC13JEkqWAfyHF0t5VvQsHOQwTxZTIJ5j8xc4GQnLhXvDTPbZKkhrMMqdQkPdYNE/n0C1hZtlGBXRyO1cptZho2ZR3d4+v7QFRM5Gvq8n4/BEiSfthS8k4QIEl24kia0Q8BkqQftpS8EwTaJNmJoTSDCJyLAElyLnJsdzUIkCRX42oaei4CJMm5yLHd1SBQJ8mwl+PgDv8cFwAjvnnGF7jpN94naBPeY4zfb5zQ1Dnz5XI3xRW+p0lirX0gUCfJYF/cIbgIUbwC42Uap8D+M5Kgh9Y3NaIej3tHoEGSpc0nSZb2APt3brMkkTVTcUiGtVTeqcgk+teidLmvk7c3q3yHyJjKJGY4eFdqz/DaCwLbJMnnu7t/+hIfBFKkQA3XLw7f5B4IkcpBEKyHAqmeRaI/qZFkvOcja8aL3SGwTZIYNzSDPtttWAjyWA7SBPENknBlrvHCfi/PJ8nnX/frcHAH+fvjss/BWuUnYVqbkyCA40rcOORCkI8yQ1x5G4ZcdqiUZKD9NEn8WC2szE2rfFOWOsksVtoUAueTZBYzyySxw6tTM0kgQSGTFG0BEac/SkbfGNoVRfHmphHYMEkQvCkzIBPkmWQc7Ahs1C97cNyuWA9ZRfaDFGvx5oYRWCdJEHh4mYgjXipm5eONSYEkaRhVeiFYr5NIl4ZTXtaYlFIOvTYcCFS9jsA6SVLXlyVEYHYESJLZIWeHW0OAJNmax6jv7AiQJLNDzg63hgBJsjWPUd/ZESBJZoecHW4NgZWTxC/V3+rvk2wtFKhvDQGSpIYM7xOBiABJUgyFE9+2F9uecrO83OaUlqwzPwIkSRFzkqQIy5XeJEmM47GuS5acYElMtjYLJIpLX+yylGzZjF7Sgg1heslMOLebwoxavFwQAZKkCD5IgPVaupIti0MnIZG91m1xzuEWkNjCkSQpeskSQVWKWUI/+fNVx5EAk1t6SRKF6OpPN0uSnr90Vd+665yTn2SwQyaVdUZ1VNkQEiTJ6pmhFNwsSZQNHU6/l0mmFMCSfJ15zv2qpKl+WNYPAZKkgm0I7tK23AkClWRl++tR4Zsy0IzHRRAgSaqwY24Rh1UyMfcNTJn/BAzlo0+2VJnuy9TLM42uyPOlESBJlvYA+189AiTJ6l1EBZdGgCRZ2gPsf/UIrJwkq8ePCl4BAiTJFTiZJv4MAZLkZ/ix9RUgsHKScNPVFcTg6k0kSZZyEd6T4P3KUnqw3yYCJEkRohneiIMkdpl9UR/eXBIBkqSI/gwkKfbLm2tEgCQxXmlvuooE8hkA2eDuxWXLStT9YfNWli3MkpasDL/A9eb0r3TJkhejKy/nQYAkKeI8lUlAkqO7HQLc1v1yjw/v7hNyiwscfWF5ubyQNJInXJcWWqIDHnsjQJIUEbaBryuhLAXuZCAjq4wm6FMksbJf3PTPRGj9eH5pBDZLksU2XVV/SzG5RrIB9sfrVcJSjSQRKFZ+slmS9MUV2cLuKPS9TpWlnYsyR2Em6euqGaSTJBWQz950FecgGB5hZ+J48s1MUoF+dbdJkqpLYhBjyCRzikYmkUyDrwr6cI+/1cYrZBbIxTHKt/MbDN1Auqq6LOiGAEnSDVoK3gsCJMlePEk7uiFAknSDloL3gsDKSbIXmGnHlhEgSbbsPeo+CwIkySwws5MtI0CSbNl71H0WBFZKEr8j8eAOhy3+FJx5v2JW+YpX8b5E3r9ISXbC9yQZHItcrJQkEYvXPxslite//EZdvAyS1EgUK5IkgthiJ+smyWKwXKLjBklO7IIkORGojtVIEgNucc3WaE+IGVLdlRZC1khi2hYyCYihf22Ly1KMo2a8JEks2CNC4CfcEhGeH9K5w7BpNLeokQQdlstBEJDCXqM1j/MhQJKMsI4LGOUJH4N5RAI0LAd7c05SnLPYvrGdl5uugPYSx82SpOemq/D0jrsDh8ySdgoOTorZRg+HboRUcGONPFPl4zbMJMBrueNmSdIXshCsfuPUMEfRBBgNr8aBHXSr3YfmpfLxPZIEeC13JEkq2AdyHN1t5ZtQsPMQQXyZTIL5T8xcIOQdh1sVN81ymySpwSxDKjVJj3Vlt2Hcu55lGxXYxeFYrVzmPDGbDJuxju7x9X0gKibyNXV5vx8CJEk/bCl5JwiQJDtxJM3ohwBJ0g9bSt4JAiTJThxJM/ohQJL0w5aSd4IASbITR9KMfgiQJP2wpeSdIECS7MSRNKMfAiRJP2wpeScIkCQ7cSTN6IcASdIPW0reCQIkyU4cSTP6IUCS9MOWkneCAEmyE0fSjH4IkCT9sKXknSBAkuzEkTSjHwIkST9sKXknCPwHNN90Mu61QjcAAAAASUVORK5CYII="}}},{"cell_type":"code","source":"os.makedirs(dataset_dir + 'images/train', exist_ok=True)\nos.makedirs(dataset_dir + 'images/valid', exist_ok=True)\nos.makedirs(dataset_dir + 'images/test', exist_ok=True)\n\nos.makedirs(dataset_dir + 'labels/train', exist_ok=True)\nos.makedirs(dataset_dir + 'labels/valid', exist_ok=True)\nos.makedirs(dataset_dir + 'labels/test', exist_ok=True)\n\n#%cd ../../\n#!tree kaggle/working/dataset\n\n# Move the images to relevant split folder.\nif len(os.listdir(dataset_dir + 'images/train')) == 0:\n    for i in tqdm(range(len(df))):\n        row = df.loc[i]\n        shutil.copy2(row.path, dataset_dir + f'images/{row.split}')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:21.381493Z","iopub.execute_input":"2024-05-14T14:12:21.382434Z","iopub.status.idle":"2024-05-14T14:15:34.685761Z","shell.execute_reply.started":"2024-05-14T14:12:21.382383Z","shell.execute_reply":"2024-05-14T14:15:34.684571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Move the test images to relevant split folder.\n# paths\ninput_test_dir = input_dir + 'test/'\noutput_test_dir = dataset_dir + 'images/test'\n\ntest_files=os.listdir(input_test_dir)\n\n# iterating over all the files in the source directory\nfor test_file in test_files:\n    # copying the files to the destination directory\n    shutil.copy2(input_test_dir + test_file, output_test_dir)","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:15:34.687409Z","iopub.execute_input":"2024-05-14T14:15:34.687865Z","iopub.status.idle":"2024-05-14T14:15:34.719384Z","shell.execute_reply.started":"2024-05-14T14:15:34.687822Z","shell.execute_reply":"2024-05-14T14:15:34.718236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#shutil.rmtree(dataset_dir + 'labels/train')\n#os.makedirs(dataset_dir + 'labels/train', exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:15:34.720703Z","iopub.execute_input":"2024-05-14T14:15:34.721007Z","iopub.status.idle":"2024-05-14T14:15:34.725158Z","shell.execute_reply.started":"2024-05-14T14:15:34.720978Z","shell.execute_reply":"2024-05-14T14:15:34.724158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare the txt files for bounding box\nif len(os.listdir(dataset_dir + 'labels/train')) == 0:\n    for idx, row in tqdm(df.iterrows(), total=df.shape[0]):\n        file_name = dataset_dir + f'labels/{row.split}/{row.image_id}.txt'  \n        # Hänge neue Bounding-Box in .txt-File an\n        with open(file_name, 'a') as f:\n            bbox_str = (str(0) + ' ' + \n                str(row['bbox_x_center']) + ' ' + \n                str(row['bbox_y_center']) + ' ' + \n                str(row['bbox_width']) + ' ' + \n                str(row['bbox_height'])  )\n            \n            f.write(bbox_str)\n            f.write('\\n')\n\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:15:34.726634Z","iopub.execute_input":"2024-05-14T14:15:34.727813Z","iopub.status.idle":"2024-05-14T14:15:59.574729Z","shell.execute_reply.started":"2024-05-14T14:15:34.727780Z","shell.execute_reply":"2024-05-14T14:15:59.573532Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_train_dir = dataset_dir + 'images/train/'\nlabel_train_dir = dataset_dir + 'labels/train/'","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:15:59.575991Z","iopub.execute_input":"2024-05-14T14:15:59.576316Z","iopub.status.idle":"2024-05-14T14:15:59.581430Z","shell.execute_reply.started":"2024-05-14T14:15:59.576284Z","shell.execute_reply":"2024-05-14T14:15:59.580266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_with_bbox(3, image_train_dir, label_train_dir)","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:15:59.582853Z","iopub.execute_input":"2024-05-14T14:15:59.583153Z","iopub.status.idle":"2024-05-14T14:16:01.649966Z","shell.execute_reply.started":"2024-05-14T14:15:59.583123Z","shell.execute_reply":"2024-05-14T14:16:01.648511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Erzeuge .YAML-File","metadata":{}},{"cell_type":"code","source":"%cd /kaggle/working/","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:16:01.651796Z","iopub.execute_input":"2024-05-14T14:16:01.652255Z","iopub.status.idle":"2024-05-14T14:16:01.658838Z","shell.execute_reply.started":"2024-05-14T14:16:01.652209Z","shell.execute_reply":"2024-05-14T14:16:01.657833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile dataset.yaml\npath: ../../../../../kaggle/working/dataset\ntrain: images/train\nval: images/valid\ntest: images/test\n\n# Classes\nnc: 1\nnames: ['wheat']","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:16:01.660065Z","iopub.execute_input":"2024-05-14T14:16:01.660415Z","iopub.status.idle":"2024-05-14T14:16:01.671448Z","shell.execute_reply.started":"2024-05-14T14:16:01.660381Z","shell.execute_reply":"2024-05-14T14:16:01.670445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train with YOLOv8","metadata":{}},{"cell_type":"code","source":"'''import pathlib\n# Deleting the files\nfiles_to_delete = './*.txt' # this considers only \".txt\" files. If you want to delete all files, use \"./*\"\nfiles_list = pathlib.Path(os.getcwd()).glob(files_to_delete)\nfor file_path in files_list:\n    os.remove(file_path)\n'''","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:16:01.672750Z","iopub.execute_input":"2024-05-14T14:16:01.673179Z","iopub.status.idle":"2024-05-14T14:16:01.689644Z","shell.execute_reply.started":"2024-05-14T14:16:01.673148Z","shell.execute_reply":"2024-05-14T14:16:01.688589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd ../../../\n%cd kaggle/working/\n\n# Load a COCO-pretrained YOLOv8n model\nmodel = YOLO('yolov8n.pt')\n# Display model information (optional)\nprint('--- Model Info: ---')\nmodel.info()\n\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:28:18.647596Z","iopub.execute_input":"2024-05-14T14:28:18.648705Z","iopub.status.idle":"2024-05-14T14:28:20.845481Z","shell.execute_reply.started":"2024-05-14T14:28:18.648663Z","shell.execute_reply":"2024-05-14T14:28:20.844454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Freeze:\nhttps://docs.ultralytics.com/de/yolov5/tutorials/transfer_learning_with_frozen_layers/#accuracy-comparison\n\nShallow layers in neural networks typically extract basic patterns such as lines and corners before identifying more complex patterns. Therefore, by leveraging pre-trained networks and transfer learning, where these basic patterns are already learnt and identified, we can save significant amount of time to train our own dataset if we leverage those weight pre-learnt.\n\nIn fact, there is no reason to train these layers again even we start with these pre-trained weight, so to further accelerate network training, we can freeze the earlier layers weight and let the network train just the last few layers.","metadata":{}},{"cell_type":"code","source":"!wandb off\ndate_time = datetime.now().strftime(\"%Y%m%d_%H%M\")\nsave_dir = working_dir + date_time + '_yolov8n_5ep_basis' \nmodel.train(data='dataset.yaml', \n            epochs=1, \n            imgsz=1024, \n            batch=16, \n            save_period=1, \n            freeze=10,\n            dropout=0.1\n           )\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:28:27.825136Z","iopub.execute_input":"2024-05-14T14:28:27.826075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import Javascript\nfrom time import sleep\n\nsleep(60)\nprint(“Shutdown”)\nJavascript(\"Ipython.notebook.session.delete()\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction","metadata":{}},{"cell_type":"code","source":"MODEL_PATH = 'runs/detect/train3/weights/best.pt'\nmodel = YOLO(MODEL_PATH)\nmodel.predict(source=output_test_dir, imgsz=1024, conf=0.5, iou=0.6, save_txt=True, save_conf=True)\n\n%cd ../../../\n%cd kaggle/working/\n\nPRED_PATH = 'runs/detect/predict/labels'\n!ls {PRED_PATH}\n\nprediction_files = os.listdir(PRED_PATH)\n","metadata":{"execution":{"iopub.status.busy":"2024-05-14T14:12:08.361034Z","iopub.execute_input":"2024-05-14T14:12:08.361863Z","iopub.status.idle":"2024-05-14T14:12:09.277405Z","shell.execute_reply.started":"2024-05-14T14:12:08.361822Z","shell.execute_reply":"2024-05-14T14:12:09.275964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_preds_with_box(num):\n    pred = []\n    bbox = []\n    image_id = []\n    k = 1\n    plt.figure(figsize=(30,30))\n    for i in prediction_files[:num]:\n        with open(f'{PRED_PATH}/{i}') as f:\n            img = read_image(f'{output_test_dir}/{i[:-4]}.jpg')\n            bbox = []\n            for j in f:\n                pred = i[:-4] + \" \" + j[:-1]\n                pred = pred.split(\" \")\n                pred.pop(0)\n                pred.pop(0)\n                pred.pop(-1)\n                pred = [eval(i) for i in pred]\n                pred = [i*1024 for i in pred]\n                [x, y, w, h] = pred\n                [xmin, ymin, xmax, ymax] = [x-w/2, y-h/2, x+w/2, y+h/2]\n                pred = [xmin, ymin, xmax, ymax]\n                bbox.append(pred)\n            bbox = torch.tensor(bbox, dtype=torch.int)\n            img = draw_bounding_boxes(img, bbox, width=10,colors=(255,0,0))\n            img = torchvision.transforms.ToPILImage()(img)\n            plt.subplot(num//3+num%3,3,k)\n            k+=1\n            plt.imshow(img)\n            plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2024-05-13T13:04:27.069991Z","iopub.execute_input":"2024-05-13T13:04:27.070635Z","iopub.status.idle":"2024-05-13T13:04:27.086153Z","shell.execute_reply.started":"2024-05-13T13:04:27.070601Z","shell.execute_reply":"2024-05-13T13:04:27.085048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_preds_with_box(10)","metadata":{"execution":{"iopub.status.busy":"2024-05-13T13:04:32.870044Z","iopub.execute_input":"2024-05-13T13:04:32.870454Z","iopub.status.idle":"2024-05-13T13:04:37.080562Z","shell.execute_reply.started":"2024-05-13T13:04:32.870411Z","shell.execute_reply":"2024-05-13T13:04:37.079514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Video\n","metadata":{}},{"cell_type":"code","source":"from IPython.display import clear_output\n\n! pip install pytube -qq\n\n# ! pip uninstall opencv -qq\n# ! pip install opencv-contrib-python -qq\n! pip install ffmpeg-python\n\nclear_output()\n\nimport glob\nfrom pytube import YouTube\nfrom IPython.display import Video\nimport subprocess\n\nimport cv2\nprint(cv2.__version__)","metadata":{"execution":{"iopub.status.busy":"2024-05-13T13:46:02.031462Z","iopub.execute_input":"2024-05-13T13:46:02.031912Z","iopub.status.idle":"2024-05-13T13:46:33.183658Z","shell.execute_reply.started":"2024-05-13T13:46:02.031877Z","shell.execute_reply":"2024-05-13T13:46:33.182264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nos.remove('/kaggle/working/Wheat School Wheat Pete on Fusarium in 2017-3-23-0-200.mp4')","metadata":{"execution":{"iopub.status.busy":"2024-05-13T14:09:01.674447Z","iopub.execute_input":"2024-05-13T14:09:01.674883Z","iopub.status.idle":"2024-05-13T14:09:01.682154Z","shell.execute_reply.started":"2024-05-13T14:09:01.674842Z","shell.execute_reply":"2024-05-13T14:09:01.680742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    ### URL of the YouTube video you want to download and process\n    video_url = 'https://www.youtube.com/watch?v=dTRomYW7fS4'\n    \n    ### start_time and end_tim to cut video (in seconds)\n    start_time = 0\n    end_time = 200\n    \n    ### output_path\n    output_path = '/kaggle/working/'\n    \n    \n# Create a YouTube object\nyoutube = YouTube(CFG.video_url)\n\n# Get the highest resolution stream available\nvideo_stream = youtube.streams.get_highest_resolution()\n\n# Download the video\nvideo_stream.download(output_path=CFG.output_path)\nprint(\"Download complete!\")\n\npath_to_downloaded_video = glob.glob(f'{CFG.output_path}/*.mp4')[0]\npath_to_downloaded_video","metadata":{"execution":{"iopub.status.busy":"2024-05-13T14:09:18.249949Z","iopub.execute_input":"2024-05-13T14:09:18.250382Z","iopub.status.idle":"2024-05-13T14:09:29.625151Z","shell.execute_reply.started":"2024-05-13T14:09:18.250349Z","shell.execute_reply":"2024-05-13T14:09:29.624047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cut_video(input_path = path_to_downloaded_video,\n              output_path = CFG.output_path,\n              start_time = 0,\n              end_time = 180):\n\n    cap = cv2.VideoCapture(input_path)\n\n    filename = f'{input_path.split(\"/\")[-1].split(\".\")[0]}-{start_time}-{end_time}.mp4'\n\n    if not cap.isOpened():\n        print(\"Error: Could not open video file.\")\n        return\n\n    fps = int(cap.get(cv2.CAP_PROP_FPS))\n    frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))\n    frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))\n    print(f'Image shape in video: ({frame_width}, {frame_height})')\n    print(f'Video FPS: {fps}\\n')\n\n    fourcc = cv2.VideoWriter_fourcc(*'mp4v')\n    out = cv2.VideoWriter(output_path + filename, fourcc, fps, (frame_width, frame_height))\n\n    start_frame = int(start_time * fps)\n    end_frame = int(end_time * fps)\n\n    frame_count = 0\n    while True:\n        ret, frame = cap.read()\n        if not ret:\n            break\n\n        if frame_count >= start_frame and frame_count <= end_frame:\n            out.write(frame)\n\n        frame_count += 1\n        if frame_count > end_frame:\n            break\n\n    cap.release()\n    out.release()\n#     cv2.destroyAllWindows() # bug in kaggle\n\n    print(\"Video cut and saved successfully.\")\n    print(f\"filename: '{filename}'\\n\\n\")\n    \n    return filename\n\n\n\nfilename = cut_video(\n    input_path = path_to_downloaded_video,\n    output_path = CFG.output_path,\n    start_time = CFG.start_time,\n    end_time = CFG.end_time\n)\n\ndef get_video_properties(video_path):\n    # Open the video file\n    cap = cv2.VideoCapture(video_path)\n\n    # Check if the video file is opened successfully\n    if not cap.isOpened():\n        raise ValueError(\"Could not open video file\")\n\n    # Get video properties\n    properties = {\n        \"fps\": int(cap.get(cv2.CAP_PROP_FPS)),\n        \"frame_count\": int(cap.get(cv2.CAP_PROP_FRAME_COUNT)),\n        \"duration_seconds\": int( cap.get(cv2.CAP_PROP_FRAME_COUNT) / cap.get(cv2.CAP_PROP_FPS) ),\n        \"width\": int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),\n        \"height\": int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)),\n        \"codec\": int(cap.get(cv2.CAP_PROP_FOURCC)),\n    }\n\n    # Release the video capture object\n    cap.release()\n\n    return properties\n\nvideo_properties = get_video_properties(video_path = filename)\ndisplay(video_properties)","metadata":{"execution":{"iopub.status.busy":"2024-05-13T14:09:46.589793Z","iopub.execute_input":"2024-05-13T14:09:46.590267Z","iopub.status.idle":"2024-05-13T14:10:31.231046Z","shell.execute_reply.started":"2024-05-13T14:09:46.590227Z","shell.execute_reply":"2024-05-13T14:10:31.229820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INPUT_VIDEO = f'{CFG.output_path}{filename}'\nOUT_VIDEO_NAME = 'new_codec_' + filename\n\nsubprocess.run(\n    [\n        \"ffmpeg\",  \"-i\", INPUT_VIDEO, \"-crf\",\n        \"18\", \"-preset\", \"veryfast\", \"-hide_banner\", \"-loglevel\",\n        \"error\", \"-vcodec\", \"libx264\", OUT_VIDEO_NAME\n    ]\n)\n\nVideo(\n    data = OUT_VIDEO_NAME,\n    embed = True,\n    height = int(video_properties['height'] * 0.5),\n    width = int(video_properties['width'] * 0.5)\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-13T14:10:43.919752Z","iopub.execute_input":"2024-05-13T14:10:43.920212Z","iopub.status.idle":"2024-05-13T14:11:47.481296Z","shell.execute_reply.started":"2024-05-13T14:10:43.920139Z","shell.execute_reply":"2024-05-13T14:11:47.479440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(annotated_frame)","metadata":{"execution":{"iopub.status.busy":"2024-05-13T14:28:42.609531Z","iopub.execute_input":"2024-05-13T14:28:42.609990Z","iopub.status.idle":"2024-05-13T14:28:43.156072Z","shell.execute_reply.started":"2024-05-13T14:28:42.609950Z","shell.execute_reply":"2024-05-13T14:28:43.154660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nfrom ultralytics import YOLO\n\n# Load the YOLOv8 model\nmodel = YOLO('/kaggle/working/runs/detect/train3/weights/best.pt')\n\n# Open the video file\nvideo_path = \"/kaggle/working/Wheat School Wheat Pete on Fusarium in 2017.mp4\"\ncap = cv2.VideoCapture(video_path)\nplt.figure()\n# Loop through the video frames\nwhile cap.isOpened():\n    # Read a frame from the video\n    success, frame = cap.read()\n\n    if success:\n        # Run YOLOv8 inference on the frame\n        results = model(cv2.resize(frame, (1024, 1024)))\n\n        # Visualize the results on the frame\n        annotated_frame = results[0].plot()\n\n        # Display the annotated frame\n        plt.imshow(annotated_frame)\n        plt.show()\n    else:\n        # Break the loop if the end of the video is reached\n        break\n\n# Release the video capture object and close the display window\ncap.release()\ncv2.destroyAllWindows()","metadata":{"execution":{"iopub.status.busy":"2024-05-13T14:30:29.672765Z","iopub.execute_input":"2024-05-13T14:30:29.673191Z","iopub.status.idle":"2024-05-13T14:31:21.018234Z","shell.execute_reply.started":"2024-05-13T14:30:29.673139Z","shell.execute_reply":"2024-05-13T14:31:21.016155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train with YOLOv7","metadata":{}},{"cell_type":"code","source":"!wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7_training.pt","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#%cd ../../../\n%cd /kaggle/working/yolov7\npathlib.Path().resolve()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile cfg/training/yolov7_global-wheat-detection.yaml\n# parameters\nnc: 1  # number of classes\ndepth_multiple: 1.0  # model depth multiple\nwidth_multiple: 1.0  # layer channel multiple\n \n# anchors\nanchors:\n  - [12,16, 19,36, 40,28]  # P3/8\n  - [36,75, 76,55, 72,146]  # P4/16\n  - [142,110, 192,243, 459,401]  # P5/32\n \n# yolov7 backbone\nbackbone:\n  # [from, number, module, args]\n  [[-1, 1, Conv, [32, 3, 1]],  # 0\n  \n  [-1, 1, Conv, [64, 3, 2]],  # 1-P1/2     \n  [-1, 1, Conv, [64, 3, 1]],\n  \n  [-1, 1, Conv, [128, 3, 2]],  # 3-P2/4 \n  [-1, 1, Conv, [64, 1, 1]],\n  [-2, 1, Conv, [64, 1, 1]],\n  [-1, 1, Conv, [64, 3, 1]],\n  [-1, 1, Conv, [64, 3, 1]],\n  [-1, 1, Conv, [64, 3, 1]],\n  [-1, 1, Conv, [64, 3, 1]],\n  [[-1, -3, -5, -6], 1, Concat, [1]],\n  [-1, 1, Conv, [256, 1, 1]],  # 11\n        \n  [-1, 1, MP, []],\n  [-1, 1, Conv, [128, 1, 1]],\n  [-3, 1, Conv, [128, 1, 1]],\n  [-1, 1, Conv, [128, 3, 2]],\n  [[-1, -3], 1, Concat, [1]],  # 16-P3/8 \n  [-1, 1, Conv, [128, 1, 1]],\n  [-2, 1, Conv, [128, 1, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [[-1, -3, -5, -6], 1, Concat, [1]],\n  [-1, 1, Conv, [512, 1, 1]],  # 24\n        \n  [-1, 1, MP, []],\n  [-1, 1, Conv, [256, 1, 1]],\n  [-3, 1, Conv, [256, 1, 1]],\n  [-1, 1, Conv, [256, 3, 2]],\n  [[-1, -3], 1, Concat, [1]],  # 29-P4/16 \n  [-1, 1, Conv, [256, 1, 1]],\n  [-2, 1, Conv, [256, 1, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [[-1, -3, -5, -6], 1, Concat, [1]],\n  [-1, 1, Conv, [1024, 1, 1]],  # 37\n        \n  [-1, 1, MP, []],\n  [-1, 1, Conv, [512, 1, 1]],\n  [-3, 1, Conv, [512, 1, 1]],\n  [-1, 1, Conv, [512, 3, 2]],\n  [[-1, -3], 1, Concat, [1]],  # 42-P5/32 \n  [-1, 1, Conv, [256, 1, 1]],\n  [-2, 1, Conv, [256, 1, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [[-1, -3, -5, -6], 1, Concat, [1]],\n  [-1, 1, Conv, [1024, 1, 1]],  # 50\n  ]\n \n# yolov7 head\nhead:\n  [[-1, 1, SPPCSPC, [512]], # 51\n  \n  [-1, 1, Conv, [256, 1, 1]],\n  [-1, 1, nn.Upsample, [None, 2, 'nearest']],\n  [37, 1, Conv, [256, 1, 1]], # route backbone P4\n  [[-1, -2], 1, Concat, [1]],\n  \n  [-1, 1, Conv, [256, 1, 1]],\n  [-2, 1, Conv, [256, 1, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],\n  [-1, 1, Conv, [256, 1, 1]], # 63\n  \n  [-1, 1, Conv, [128, 1, 1]],\n  [-1, 1, nn.Upsample, [None, 2, 'nearest']],\n  [24, 1, Conv, [128, 1, 1]], # route backbone P3\n  [[-1, -2], 1, Concat, [1]],\n  \n  [-1, 1, Conv, [128, 1, 1]],\n  [-2, 1, Conv, [128, 1, 1]],\n  [-1, 1, Conv, [64, 3, 1]],\n  [-1, 1, Conv, [64, 3, 1]],\n  [-1, 1, Conv, [64, 3, 1]],\n  [-1, 1, Conv, [64, 3, 1]],\n  [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],\n  [-1, 1, Conv, [128, 1, 1]], # 75\n      \n  [-1, 1, MP, []],\n  [-1, 1, Conv, [128, 1, 1]],\n  [-3, 1, Conv, [128, 1, 1]],\n  [-1, 1, Conv, [128, 3, 2]],\n  [[-1, -3, 63], 1, Concat, [1]],\n  \n  [-1, 1, Conv, [256, 1, 1]],\n  [-2, 1, Conv, [256, 1, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [-1, 1, Conv, [128, 3, 1]],\n  [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],\n  [-1, 1, Conv, [256, 1, 1]], # 88\n      \n  [-1, 1, MP, []],\n  [-1, 1, Conv, [256, 1, 1]],\n  [-3, 1, Conv, [256, 1, 1]],\n  [-1, 1, Conv, [256, 3, 2]],\n  [[-1, -3, 51], 1, Concat, [1]],\n  \n  [-1, 1, Conv, [512, 1, 1]],\n  [-2, 1, Conv, [512, 1, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [-1, 1, Conv, [256, 3, 1]],\n  [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]],\n  [-1, 1, Conv, [512, 1, 1]], # 101\n  \n  [75, 1, RepConv, [256, 3, 1]],\n  [88, 1, RepConv, [512, 3, 1]],\n  [101, 1, RepConv, [1024, 3, 1]],\n \n  [[102,103,104], 1, IDetect, [nc, anchors]],   # Detect(P3, P4, P5)\n  ]\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile dataset.yaml\ntrain: /kaggle/working/dataset/images/train\nval: /kaggle/working/dataset/images/valid\ntest: /kaggle/working/dataset/images/test\n\n# Classes\nnc: 1  # number of classes\nnames: ['wheat']  # class names","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#%cd ../../../\n%cd /kaggle/working\npathlib.Path().resolve()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wandb disabled\n!python yolov7/train.py --epochs 20 --workers 4 --device 0 --batch-size 8 --data dataset.yaml \\\n--img 1024 1024 --cfg yolov7/cfg/training/yolov7_global-wheat-detection.yaml --weights 'yolov7_training.pt' \\\n--name yolov7_global-wheat-detection_fixed_res --hyp data/hyp.scratch.custom.yaml","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = YOLO(\"yolov8n.yaml\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install wandb","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wandb off\nmodel.train(data='dataset.yaml', epochs=EPOCHS, imgsz=IMG_SIZE, batch=BATCH_SIZE, save_period=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cd /kaggle\n!ls ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluation","metadata":{}},{"cell_type":"code","source":"%matplotlib inline\n\nplot_results('/runs/detect/train2/results.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_results(file):\n    plt.figure(figsize=(30,30))\n    img = np.asarray(Image.open(file))\n    plt.imshow(img)\n    plt.axis('off');","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_results('/runs/detect/train2/results.png')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"copyfile('/runs/detect/train2/results.png','/kaggle/working/results.png')\ncopyfile('/runs/detect/train2/results.csv','/kaggle/working/results.csv')\ncopyfile('/runs/detect/train2/weights/best.pt','/kaggle/working/best.pt')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction","metadata":{}},{"cell_type":"code","source":"TEST_PATH = 'kaggle/working/dataset/images/test'\nMODEL_PATH = 'runs/detect/train2/weights/best.pt'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = YOLO(MODEL_PATH)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.predict(source=TEST_PATH, imgsz=IMG_SIZE, conf=0.5, iou=0.6, save_txt=True, save_conf=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PRED_PATH = 'runs/detect/predict/labels'\n!ls {PRED_PATH}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_with_bbox(3, TEST_PATH, PRED_PATH, test=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}