{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Convert label files for use with YOLO\n\nFor use with YOLOv4 directly, or other YOLO versions through the CSV.\n\nIt is also possible to remove all \"no finding\" bounding boxes.\n\nThe given bboxes are in the format of (xmin, ymin, xmax, ymax) in pixels but YOLO requires (xmin, ymin, width, heght) in relative values. Fortunately, this means that these labels can be used at any resolution or different aspect ratio\n\nReferences:\n- https://www.kaggle.com/pabloberhauser/creating-label-files-for-use-in-yolov4\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport pydicom\nimport glob\n\ntrain_df = pd.read_csv(\"../input/vinbigdata-chest-xray-abnormalities-detection/train.csv\")\ntrain_df = train_df[train_df.class_id!=14].reset_index(drop = True)\n\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dicom_metadata = [pydicom.filereader.dcmread(f\"../input/vinbigdata-chest-xray-abnormalities-detection/train/{image_id}.dicom\", stop_before_pixels=True) for image_id in train_df['image_id']]\n\ntrain_df['width'] = [i.Columns for i in dicom_metadata]\ntrain_df['height'] = [i.Rows for i in dicom_metadata]\n\ntrain_df['x_min'] = train_df.apply(lambda row: row.x_min/row.width, axis =1)\ntrain_df['y_min'] = train_df.apply(lambda row: row.y_min/row.height, axis =1)\n\ntrain_df['x_max'] = train_df.apply(lambda row: row.x_max/row.width, axis =1)\ntrain_df['y_max'] = train_df.apply(lambda row: row.y_max/row.height, axis =1)\n\ntrain_df['x_mid'] = train_df.apply(lambda row: (row.x_max+row.x_min)/2, axis =1)\ntrain_df['y_mid'] = train_df.apply(lambda row: (row.y_max+row.y_min)/2, axis =1)\n\ntrain_df['w'] = train_df.apply(lambda row: (row.x_max-row.x_min), axis =1)\ntrain_df['h'] = train_df.apply(lambda row: (row.y_max-row.y_min), axis =1)\n\ntrain_df['area'] = train_df['w']*train_df['h']\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['yolo_box'] = train_df[['x_min', 'y_min', 'w', 'h']].values.tolist()\n\nprint(\"We have {} unique images with boxes.\".format(len(train_df.image_id.unique())))\nunique_img_ids = train_df.image_id.unique()\n\n!mkdir vbd_train_data\nfolder_location = \"vbd_train_data\"\n\nfor img_id in unique_img_ids: # loop through all unique image ids. Remove the slice to do all images\n    filt_df = train_df.query(\"image_id == @img_id\") # filter the df to a specific id\n    #all_boxes = filt_df.yolo_box.values\n    file_name = \"{}/{}.txt\".format(folder_location,img_id) # specify the name of the folder and get a file name\n\n    with open(file_name, 'w+') as file: # append lines to file\n        for i in filt_df.iterrows():\n            s = f\"{i[1].class_id} %s %s %s %s \\n\" # The first number is the class name\n            new_line = (s % tuple(i[1].yolo_box))\n            file.write(new_line)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create labels for training images that do not have bounding boxes\n# If you wish to train on only images with a finding, remove this code cell\nall_imgs = glob.glob(\"../input/vinbigdata-chest-xray-abnormalities-detection/train/*.dicom\")\nall_imgs = [i.split(\"/\")[-1].replace(\".dicom\", \"\") for i in all_imgs]\npositive_imgs = train_df.image_id.unique()\n\nnegative_images = set(all_imgs) - set(positive_imgs)\nprint('All images:', len(all_imgs), 'Positive images:', len(positive_imgs))\n\nfor i in list(negative_images):\n    file_name = \"{}/{}.txt\".format(folder_location, i)\n    #print(file_name)\n    with open(file_name, 'w') as fp:\n        pass","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%capture\n\n# zip to make files easier to download\n\n!zip -r yolo_labels.zip vbd_train_data\n\n!rm -r vbd_train_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}