{"metadata":{"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":67836,"databundleVersionId":7527339,"sourceType":"competition"}],"dockerImageVersionId":30636,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"},"papermill":{"default_parameters":{},"duration":222.008164,"end_time":"2024-01-23T06:06:15.378227","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2024-01-23T06:02:33.370063","version":"2.4.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 1. Necessary Imports","metadata":{"papermill":{"duration":0.010145,"end_time":"2024-01-23T06:02:37.085889","exception":false,"start_time":"2024-01-23T06:02:37.075744","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom collections import Counter\nfrom decimal import Decimal\nimport csv\nimport random\nfrom PIL import Image, ImageDraw\nimport cv2\nfrom xml.etree.ElementTree import Element, SubElement, tostring\nfrom xml.dom import minidom\nimport torch\nimport xml.etree.ElementTree as ET\nimport torchvision.transforms.functional as F\nfrom tqdm import tqdm\nfrom IPython.display import display\nimport shutil","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":0.963025,"end_time":"2024-01-23T06:02:38.058587","exception":false,"start_time":"2024-01-23T06:02:37.095562","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-01-24T09:43:20.289491Z","iopub.execute_input":"2024-01-24T09:43:20.289824Z","iopub.status.idle":"2024-01-24T09:43:24.430610Z","shell.execute_reply.started":"2024-01-24T09:43:20.289800Z","shell.execute_reply":"2024-01-24T09:43:24.429740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm '/kaggle/working/train' -r","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:43:24.432341Z","iopub.execute_input":"2024-01-24T09:43:24.432781Z","iopub.status.idle":"2024-01-24T09:43:25.396210Z","shell.execute_reply.started":"2024-01-24T09:43:24.432753Z","shell.execute_reply":"2024-01-24T09:43:25.395281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Make XMLs","metadata":{}},{"cell_type":"code","source":"def create_csv_from_directory(directory, output_filename):\n    with open(output_filename, 'w', newline='') as f:\n        writer = csv.writer(f)\n        writer.writerow(['filename', 'id', 'x_center', 'y_center', 'width', 'height'])\n\n        # Get list of all text files in the directory\n        files = [f for f in os.listdir(directory) if f.endswith('.txt')]\n\n        for i, filename in enumerate(files):\n            with open(os.path.join(directory, filename), 'r') as f:\n                lines = f.readlines()\n\n            for j, line in enumerate(lines):\n                parts = line.strip().split() # Remove trailing newline and split by spaces\n                key = int(parts[0]) # Convert the first part to an integer\n                x_center, y_center, width, height = map(float, parts[1:]) # Convert the rest to floats\n                writer.writerow([filename.replace('.txt',''), key, x_center, y_center, width, height])","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:43:25.397514Z","iopub.execute_input":"2024-01-24T09:43:25.397787Z","iopub.status.idle":"2024-01-24T09:43:25.407227Z","shell.execute_reply.started":"2024-01-24T09:43:25.397762Z","shell.execute_reply":"2024-01-24T09:43:25.406265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_xml_object(row, _width, _height):\n    obj_elem = Element('object')\n    SubElement(obj_elem, 'id_num').text = str(row['id'])\n    SubElement(obj_elem, 'id').text = classNames[row['id']]\n    x_center, y_center, width, height = row['x_center'], row['y_center'], row['width'], row['height']\n    x_center, y_center, width, height = x_center * _width, y_center * _height, width * _width, height *_height\n    xmin, ymin = x_center - width // 2, y_center - height // 2\n    xmax, ymax = x_center + width // 2, y_center + height // 2\n    \n    bndbox_elem = SubElement(obj_elem, 'bndbox')\n    SubElement(bndbox_elem, 'xmin').text = str(xmin)\n    SubElement(bndbox_elem, 'ymin').text = str(ymin)\n    SubElement(bndbox_elem, 'xmax').text = str(xmax)\n    SubElement(bndbox_elem, 'ymax').text = str(ymax)\n\n    return obj_elem\n\ndef make_xml(_image_id):\n    filtered_df = train_df[train_df['filename'] == _image_id]\n    \n    image = np.array(Image.open(filtered_df['image_path'].iloc[0]))\n    _width  = image.shape[1]\n    _height = image.shape[0]\n    \n    root = Element('annotation')\n    SubElement(root, 'path').text = filtered_df['image_path'].iloc[0]\n    SubElement(root, 'filename').text = filtered_df['filename'].iloc[0]\n    \n    size_elem = SubElement(root, 'size')\n    SubElement(size_elem, 'width').text = str(_width)\n    SubElement(size_elem, 'height').text = str(_height)\n    \n    for index, row in filtered_df.iterrows():\n        obj_elem = create_xml_object(row, _width, _height)\n        root.append(obj_elem)\n        \n    xml_str = minidom.parseString(tostring(root)).toprettyxml(indent=\"    \")\n    output = '/kaggle/working/train/'+filtered_df['filename'].iloc[0]+'.xml'\n    with open(output, 'w') as xml_file:\n        xml_file.write(xml_str)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:43:25.408478Z","iopub.execute_input":"2024-01-24T09:43:25.408731Z","iopub.status.idle":"2024-01-24T09:43:25.420970Z","shell.execute_reply.started":"2024-01-24T09:43:25.408699Z","shell.execute_reply":"2024-01-24T09:43:25.420188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_csv_from_directory('/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/labels/train', 'train.csv')\ntrain_df = pd.read_csv('/kaggle/working/train.csv')\nIMG_PATH= '/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/images/'\ntrain_df['image_path'] = f'{IMG_PATH}/train/' + train_df['filename'] + '.jpg'\ntrain_df","metadata":{"papermill":{"duration":3.780392,"end_time":"2024-01-23T06:03:00.068513","exception":false,"start_time":"2024-01-23T06:02:56.288121","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-01-24T09:43:25.423464Z","iopub.execute_input":"2024-01-24T09:43:25.424070Z","iopub.status.idle":"2024-01-24T09:43:53.490996Z","shell.execute_reply.started":"2024-01-24T09:43:25.424040Z","shell.execute_reply":"2024-01-24T09:43:53.490024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classNames= {0: 'auto_rickshaw',\n 1: 'bicycle',\n 2: 'bus',\n 3: 'car',\n 4: 'cart_vehicle',\n 5: 'construction_vehicle',\n 6: 'motorbike',\n 7: 'person',\n 8: 'priority_vehicle',\n 9: 'three_wheeler',\n 10: 'train',\n 11: 'truck',\n 12: 'wheelchair'}\nse = set(train_df['filename'])\nimage_list = list(set(train_df['filename']))\ndirectory_path = '/kaggle/working/train/'\nos.makedirs(directory_path, exist_ok=True)\nfor image_id in tqdm(se, desc=\"Processing Images\"):\n    make_xml(image_id)\nsource_directory1 = '/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/images/train'\ndestination_directory = '/kaggle/working/train'\nshutil.copytree(source_directory1, destination_directory, dirs_exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:43:53.492127Z","iopub.execute_input":"2024-01-24T09:43:53.492403Z","iopub.status.idle":"2024-01-24T09:48:01.443789Z","shell.execute_reply.started":"2024-01-24T09:43:53.492379Z","shell.execute_reply":"2024-01-24T09:48:01.442827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Augmentation\n","metadata":{}},{"cell_type":"code","source":"voc_labels = ('auto_rickshaw','bicycle','bus','car','cart_vehicle','construction_vehicle',\n 'motorbike','person','priority_vehicle','three_wheeler','train','truck','wheelchair')\nlabel_map = {k: v+1 for v, k in enumerate(voc_labels)}\n#Inverse mapping\nrev_label_map = {v: k for k, v in label_map.items()}\n#Colormap for bounding box\nCLASSES = 13\ndistinct_colors = [\"#\"+''.join([random.choice('0123456789ABCDEF') for j in range(6)])\n                   for i in range(CLASSES)]\nlabel_color_map  = {k: distinct_colors[i] for i, k in enumerate(label_map.keys())}","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:01.445129Z","iopub.execute_input":"2024-01-24T09:48:01.445778Z","iopub.status.idle":"2024-01-24T09:48:01.452365Z","shell.execute_reply.started":"2024-01-24T09:48:01.445742Z","shell.execute_reply":"2024-01-24T09:48:01.451534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def parse_annot(annotation_path):\n    tree = ET.parse(annotation_path)\n    root = tree.getroot()\n\n    boxes = list()\n    labels = list()\n    \n    for object in root.iter(\"object\"):\n        label = object.find(\"id\").text.lower().strip()\n        if label not in label_map:\n            print(\"{0} not in label map.\".format(label))\n            assert label in label_map\n            \n        bbox =  object.find(\"bndbox\")\n        xmin = float(bbox.find(\"xmin\").text)\n        ymin = float(bbox.find(\"ymin\").text)\n        xmax = float(bbox.find(\"xmax\").text)\n        ymax = float(bbox.find(\"ymax\").text)\n        \n        boxes.append([xmin, ymin, xmax, ymax])\n        labels.append(label_map[label])\n        \n    return {\"boxes\": boxes, \"labels\": labels}\n\ndef draw_PIL_image(image, boxes, labels):\n    '''\n        Draw PIL image\n        image: A PIL image\n        labels: A tensor of dimensions (#objects,)\n        boxes: A tensor of dimensions (#objects, 4)\n    '''\n    if type(image) != PIL.Image.Image:\n        image = F.to_pil_image(image)\n    new_image = image.copy()\n    labels = labels.tolist()\n    draw = ImageDraw.Draw(new_image)\n    boxes = boxes.tolist()\n    for i in range(len(boxes)):\n        draw.rectangle(xy= boxes[i], outline= label_color_map[rev_label_map[labels[i]]])\n    \n    display(new_image)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:01.453583Z","iopub.execute_input":"2024-01-24T09:48:01.453855Z","iopub.status.idle":"2024-01-24T09:48:01.464594Z","shell.execute_reply.started":"2024-01-24T09:48:01.453831Z","shell.execute_reply":"2024-01-24T09:48:01.463815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import PIL\nbase = '/kaggle/working/train/'\nn = random.randint(0, len(image_list)-1)\none = base + str(image_list[n])\nimage = Image.open(one+\".jpg\", mode= \"r\")\nimage = image.convert(\"RGB\")\nobjects= parse_annot(one+\".xml\")\nboxes = torch.FloatTensor(objects['boxes'])\nlabels = torch.LongTensor(objects['labels']) \ndraw_PIL_image(image, boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:01.465573Z","iopub.execute_input":"2024-01-24T09:48:01.465912Z","iopub.status.idle":"2024-01-24T09:48:01.828305Z","shell.execute_reply.started":"2024-01-24T09:48:01.465869Z","shell.execute_reply":"2024-01-24T09:48:01.827235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Adjust Contrast","metadata":{}},{"cell_type":"code","source":"def Adjust_contrast(image):\n    return F.adjust_contrast(image,2)\nnew_image = Adjust_contrast(image)\ndraw_PIL_image(new_image, boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:01.829374Z","iopub.execute_input":"2024-01-24T09:48:01.829628Z","iopub.status.idle":"2024-01-24T09:48:02.125783Z","shell.execute_reply.started":"2024-01-24T09:48:01.829606Z","shell.execute_reply":"2024-01-24T09:48:02.124945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Adjust Brightness","metadata":{}},{"cell_type":"code","source":"def Adjust_brightness(image):\n    return F.adjust_brightness(image, 2)\nnew_image = Adjust_brightness(image)\ndraw_PIL_image(new_image, boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:02.126962Z","iopub.execute_input":"2024-01-24T09:48:02.127276Z","iopub.status.idle":"2024-01-24T09:48:02.348711Z","shell.execute_reply.started":"2024-01-24T09:48:02.127249Z","shell.execute_reply":"2024-01-24T09:48:02.347899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Adjust Saturation","metadata":{}},{"cell_type":"code","source":"def Adjust_saturation(image):\n    return F.adjust_saturation(image, 2)\nnew_image = Adjust_saturation(image)\ndraw_PIL_image(new_image, boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:02.349991Z","iopub.execute_input":"2024-01-24T09:48:02.350300Z","iopub.status.idle":"2024-01-24T09:48:02.672054Z","shell.execute_reply.started":"2024-01-24T09:48:02.350275Z","shell.execute_reply":"2024-01-24T09:48:02.671179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Lightning Noise","metadata":{}},{"cell_type":"code","source":"def lighting_noise(image):\n    '''\n        color channel swap in image\n        image: A PIL image\n    '''\n    new_image = image\n    perms = ((0, 1, 2), (0, 2, 1), (1, 0, 2), \n             (1, 2, 0), (2, 0, 1), (2, 1, 0))\n    swap = perms[random.randint(0, len(perms)- 1)]\n    new_image = F.to_tensor(new_image)\n    new_image = new_image[swap, :, :]\n    new_image = F.to_pil_image(new_image)\n    return new_image\n\nnew_image = lighting_noise(image)\ndraw_PIL_image(new_image, boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:02.673342Z","iopub.execute_input":"2024-01-24T09:48:02.673668Z","iopub.status.idle":"2024-01-24T09:48:03.071956Z","shell.execute_reply.started":"2024-01-24T09:48:02.673639Z","shell.execute_reply":"2024-01-24T09:48:03.071089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Flip","metadata":{}},{"cell_type":"code","source":"def flip(image, boxes):\n    '''\n        Flip image horizontally.\n        image: a PIL image\n        boxes: Bounding boxes, a tensor of dimensions (#objects, 4)\n    '''\n    new_image = F.hflip(image)\n    \n    #flip boxes \n    new_boxes = boxes.clone()\n    new_boxes[:, 0] = image.width - boxes[:, 0]\n    new_boxes[:, 2] = image.width - boxes[:, 2]\n    new_boxes = new_boxes[:, [2, 1, 0, 3]]\n    return new_image, new_boxes\n\nnew_image, new_boxes = flip(image, boxes)\ndraw_PIL_image(new_image, new_boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:03.077080Z","iopub.execute_input":"2024-01-24T09:48:03.077648Z","iopub.status.idle":"2024-01-24T09:48:03.420830Z","shell.execute_reply.started":"2024-01-24T09:48:03.077617Z","shell.execute_reply":"2024-01-24T09:48:03.419950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Rotate (Bugs)","metadata":{}},{"cell_type":"code","source":"# def rotate(image, boxes, angle):\n#     '''\n#         Rotate image and bounding box\n#         image: A Pil image (w, h)\n#         boxes: A tensors of dimensions (#objects, 4)\n        \n#         Out: rotated image (w, h), rotated boxes\n#     '''\n#     new_image = image.copy()\n#     new_boxes = boxes.clone()\n    \n#     #Rotate image, expand = True\n#     w = image.width\n#     h = image.height\n#     cx = w/2\n#     cy = h/2\n#     new_image = new_image.rotate(angle, expand= True)\n#     angle = np.radians(angle)\n#     alpha = np.cos(angle)\n#     beta = np.sin(angle)\n#     #Get affine matrix\n#     AffineMatrix = torch.tensor([[alpha, beta, (1-alpha)*cx - beta*cy],\n#                                  [-beta, alpha, beta*cx + (1-alpha)*cy]])\n    \n#     #Rotation boxes\n#     box_width = (boxes[:,2] - boxes[:,0]).reshape(-1,1)\n#     box_height = (boxes[:,3] - boxes[:,1]).reshape(-1,1)\n    \n#     #Get corners for boxes\n#     x1 = boxes[:,0].reshape(-1,1)\n#     y1 = boxes[:,1].reshape(-1,1)\n    \n#     x2 = x1 + box_width\n#     y2 = y1 \n    \n#     x3 = x1\n#     y3 = y1 + box_height\n    \n#     x4 = boxes[:,2].reshape(-1,1)\n#     y4 = boxes[:,3].reshape(-1,1)\n    \n#     corners = torch.stack((x1,y1,x2,y2,x3,y3,x4,y4), dim= 1)\n#     corners.reshape(8, 8) \n# #     corners = corners.reshape(-1, 8)  # Tensors of dimensions (#objects, 8)\n#     #Tensors of dimensions (#objects, 8)\n#     corners = corners.reshape(-1,2) #Tensors of dimension (4* #objects, 2)\n#     corners = torch.cat((corners, torch.ones(corners.shape[0], 1)), dim= 1) #(Tensors of dimension (4* #objects, 3))\n    \n#     cos = np.abs(AffineMatrix[0, 0])\n#     sin = np.abs(AffineMatrix[0, 1])\n    \n#     nW = int((h * sin) + (w * cos))\n#     nH = int((h * cos) + (w * sin))\n#     AffineMatrix[0, 2] += (nW / 2) - cx\n#     AffineMatrix[1, 2] += (nH / 2) - cy\n    \n#     #Apply affine transform\n#     rotate_corners = torch.mm(AffineMatrix, corners.t().double()).t()\n# #     rotate_corners = torch.mm(AffineMatrix.double(), corners.t().double()).t()\n\n#     rotate_corners = rotate_corners.reshape(-1,8)\n    \n#     x_corners = rotate_corners[:,[0,2,4,6]]\n#     y_corners = rotate_corners[:,[1,3,5,7]]\n    \n#     #Get (x_min, y_min, x_max, y_max)\n#     x_min, _ = torch.min(x_corners, dim= 1)\n#     x_min = x_min.reshape(-1, 1)\n#     y_min, _ = torch.min(y_corners, dim= 1)\n#     y_min = y_min.reshape(-1, 1)\n#     x_max, _ = torch.max(x_corners, dim= 1)\n#     x_max = x_max.reshape(-1, 1)\n#     y_max, _ = torch.max(y_corners, dim= 1)\n#     y_max = y_max.reshape(-1, 1)\n    \n#     new_boxes = torch.cat((x_min, y_min, x_max, y_max), dim= 1)\n    \n#     scale_x = new_image.width / w\n#     scale_y = new_image.height / h\n    \n#     #Resize new image to (w, h)\n#     new_image = new_image.resize((500, 333))\n    \n#     #Resize boxes\n#     new_boxes /= torch.Tensor([scale_x, scale_y, scale_x, scale_y])\n#     new_boxes[:, 0] = torch.clamp(new_boxes[:, 0], 0, w)\n#     new_boxes[:, 1] = torch.clamp(new_boxes[:, 1], 0, h)\n#     new_boxes[:, 2] = torch.clamp(new_boxes[:, 2], 0, w)\n#     new_boxes[:, 3] = torch.clamp(new_boxes[:, 3], 0, h)\n#     return new_image, new_boxes\n# new_image, new_boxes= rotate(image, boxes, 10)\n# draw_PIL_image(new_image, new_boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:03.422305Z","iopub.execute_input":"2024-01-24T09:48:03.422598Z","iopub.status.idle":"2024-01-24T09:48:03.483427Z","shell.execute_reply.started":"2024-01-24T09:48:03.422573Z","shell.execute_reply":"2024-01-24T09:48:03.482402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Random Crop","metadata":{}},{"cell_type":"code","source":"def intersect(boxes1, boxes2):\n    '''\n        Find intersection of every box combination between two sets of box\n        boxes1: bounding boxes 1, a tensor of dimensions (n1, 4)\n        boxes2: bounding boxes 2, a tensor of dimensions (n2, 4)\n        \n        Out: Intersection each of boxes1 with respect to each of boxes2, \n             a tensor of dimensions (n1, n2)\n    '''\n    n1 = boxes1.size(0)\n    n2 = boxes2.size(0)\n    max_xy =  torch.min(boxes1[:, 2:].unsqueeze(1).expand(n1, n2, 2),\n                        boxes2[:, 2:].unsqueeze(0).expand(n1, n2, 2))\n    \n    min_xy = torch.max(boxes1[:, :2].unsqueeze(1).expand(n1, n2, 2),\n                       boxes2[:, :2].unsqueeze(0).expand(n1, n2, 2))\n    inter = torch.clamp(max_xy - min_xy , min=0)  # (n1, n2, 2)\n    return inter[:, :, 0] * inter[:, :, 1]  #(n1, n2)\ndef find_IoU(boxes1, boxes2):\n    '''\n        Find IoU between every boxes set of boxes \n        boxes1: a tensor of dimensions (n1, 4) (left, top, right , bottom)\n        boxes2: a tensor of dimensions (n2, 4)\n        \n        Out: IoU each of boxes1 with respect to each of boxes2, a tensor of \n             dimensions (n1, n2)\n        \n        Formula: \n        (box1 ∩ box2) / (box1 u box2) = (box1 ∩ box2) / (area(box1) + area(box2) - (box1 ∩ box2 ))\n    '''\n    inter = intersect(boxes1, boxes2)\n    area_boxes1 = (boxes1[:, 2] - boxes1[:, 0]) * (boxes1[:, 3] - boxes1[:, 1])\n    area_boxes2 = (boxes2[:, 2] - boxes2[:, 0]) * (boxes2[:, 3] - boxes2[:, 1])\n    \n    area_boxes1 = area_boxes1.unsqueeze(1).expand_as(inter) #(n1, n2)\n    area_boxes2 = area_boxes2.unsqueeze(0).expand_as(inter)  #(n1, n2)\n    union = (area_boxes1 + area_boxes2 - inter)\n    return inter / union","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:03.484622Z","iopub.execute_input":"2024-01-24T09:48:03.484931Z","iopub.status.idle":"2024-01-24T09:48:03.496077Z","shell.execute_reply.started":"2024-01-24T09:48:03.484904Z","shell.execute_reply":"2024-01-24T09:48:03.495136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def random_crop(image, boxes, labels):\n    '''\n        image: A PIL image\n        boxes: Bounding boxes, a tensor of dimensions (#objects, 4)\n        labels: labels of object, a tensor of dimensions (#objects)\n        difficulties: difficulties of detect object, a tensor of dimensions (#objects)\n        \n        Out: cropped image , new boxes, new labels, new difficulties\n    '''\n    if type(image) == PIL.Image.Image:\n        image = F.to_tensor(image)\n    original_h = image.size(1)\n    original_w = image.size(2)\n    \n    while True:\n        mode = random.choice([0.1, 0.3, 0.5, 0.9, None])\n        \n        if mode is None:\n            return image, boxes, labels\n        \n        new_image = image\n        new_boxes = boxes\n        new_labels = labels\n        for _ in range(50):\n            # Crop dimensions: [0.3, 1] of original dimensions\n            new_h = random.uniform(0.3*original_h, original_h)\n            new_w = random.uniform(0.3*original_w, original_w)\n            \n            # Aspect ratio constraint b/t .5 & 2\n            if new_h/new_w < 0.5 or new_h/new_w > 2:\n                continue\n            \n            #Crop coordinate\n            left = random.uniform(0, original_w - new_w)\n            right = left + new_w\n            top = random.uniform(0, original_h - new_h)\n            bottom = top + new_h\n            crop = torch.FloatTensor([int(left), int(top), int(right), int(bottom)])\n            \n            # Calculate IoU  between the crop and the bounding boxes\n            overlap = find_IoU(crop.unsqueeze(0), boxes) #(1, #objects)\n            overlap = overlap.squeeze(0)\n            # If not a single bounding box has a IoU of greater than the minimum, try again\n            if overlap.max().item() < mode:\n                continue\n            \n            #Crop\n            new_image = image[:, int(top):int(bottom), int(left):int(right)] #(3, new_h, new_w)\n            \n            #Center of bounding boxes\n            center_bb = (boxes[:, :2] + boxes[:, 2:])/2.0\n            \n            #Find bounding box has been had center in crop\n            center_in_crop = (center_bb[:, 0] >left) * (center_bb[:, 0] < right\n                             ) *(center_bb[:, 1] > top) * (center_bb[:, 1] < bottom)    #( #objects)\n            \n            if not center_in_crop.any():\n                continue\n            \n            #take matching bounding box\n            new_boxes = boxes[center_in_crop, :]\n            \n            #take matching labels\n            new_labels = labels[center_in_crop]\n            \n            #Use the box left and top corner or the crop's\n            new_boxes[:, :2] = torch.max(new_boxes[:, :2], crop[:2])\n            \n            #adjust to crop\n            new_boxes[:, :2] -= crop[:2]\n            \n            new_boxes[:, 2:] = torch.min(new_boxes[:, 2:],crop[2:])\n            \n            #adjust to crop\n            new_boxes[:, 2:] -= crop[:2]\n            \n            return F.to_pil_image(new_image), new_boxes, new_labels","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:03.497304Z","iopub.execute_input":"2024-01-24T09:48:03.497592Z","iopub.status.idle":"2024-01-24T09:48:03.512522Z","shell.execute_reply.started":"2024-01-24T09:48:03.497570Z","shell.execute_reply":"2024-01-24T09:48:03.511531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_image,new_boxes, new_labels= random_crop(image, boxes,labels)\ndraw_PIL_image(new_image, new_boxes, new_labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:03.513690Z","iopub.execute_input":"2024-01-24T09:48:03.514011Z","iopub.status.idle":"2024-01-24T09:48:03.944768Z","shell.execute_reply.started":"2024-01-24T09:48:03.513986Z","shell.execute_reply":"2024-01-24T09:48:03.943757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Zoom Out","metadata":{}},{"cell_type":"code","source":"def zoom_out(image, boxes):\n    '''\n        Zoom out image (max scale = 4)\n        image: A PIL image\n        boxes: bounding boxes, a tensor of dimensions (#objects, 4)\n        \n        Out: new_image, new_boxes\n    '''\n    if type(image) == PIL.Image.Image:\n        image = F.to_tensor(image)\n    original_h = image.size(1)\n    original_w = image.size(2)\n    max_scale = 4\n    scale = random.uniform(1, max_scale)\n    new_h = int(scale*original_h)\n    new_w = int(scale*original_w)\n    \n    #Create an image with the filler\n    filler = [0.485, 0.456, 0.406]\n    filler = torch.FloatTensor(filler) #(3)\n    new_image = torch.ones((3, new_h, new_w), dtype= torch.float) * filler.unsqueeze(1).unsqueeze(1)\n    \n\n    left = random.randint(0, new_w - original_w)\n    right = left + original_w\n    top = random.randint(0, new_h - original_h)\n    bottom = top + original_h\n    \n    new_image[:, top:bottom, left:right] = image\n    \n    #Adjust bounding box\n    new_boxes = boxes + torch.FloatTensor([left, top, left, top]).unsqueeze(0)\n    \n    return new_image, new_boxes","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:03.946104Z","iopub.execute_input":"2024-01-24T09:48:03.946430Z","iopub.status.idle":"2024-01-24T09:48:03.956215Z","shell.execute_reply.started":"2024-01-24T09:48:03.946402Z","shell.execute_reply":"2024-01-24T09:48:03.955142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_image, new_boxes = zoom_out(image, boxes)\ndraw_PIL_image(new_image, new_boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:03.957498Z","iopub.execute_input":"2024-01-24T09:48:03.957761Z","iopub.status.idle":"2024-01-24T09:48:04.511667Z","shell.execute_reply.started":"2024-01-24T09:48:03.957738Z","shell.execute_reply":"2024-01-24T09:48:04.510704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Rotate Only Boundary Boxes","metadata":{}},{"cell_type":"code","source":"def rotate_only_bboxes(image, boxes, angle):\n    new_image = image.copy()\n    new_image = F.to_tensor(new_image)\n    for i in range(boxes.shape[0]):\n        x_min, y_min, x_max, y_max = map(int, boxes[i,:].tolist())\n        bbox = new_image[:,  y_min:y_max+1, x_min:x_max+1]\n        bbox = F.to_pil_image(bbox)\n        bbox = bbox.rotate(angle)\n        \n        new_image[:,y_min:y_max+1, x_min:x_max+1] = F.to_tensor(bbox)\n    return F.to_pil_image(new_image)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:04.512865Z","iopub.execute_input":"2024-01-24T09:48:04.513189Z","iopub.status.idle":"2024-01-24T09:48:04.519671Z","shell.execute_reply.started":"2024-01-24T09:48:04.513164Z","shell.execute_reply":"2024-01-24T09:48:04.518816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_image = rotate_only_bboxes(image, boxes, 5)\ndraw_PIL_image(new_image, boxes, labels)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:04.520754Z","iopub.execute_input":"2024-01-24T09:48:04.521027Z","iopub.status.idle":"2024-01-24T09:48:04.885204Z","shell.execute_reply.started":"2024-01-24T09:48:04.521006Z","shell.execute_reply":"2024-01-24T09:48:04.884367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Cutout","metadata":{}},{"cell_type":"code","source":"def cutout(image, boxes, labels, fill_val= 0, bbox_remove_thres= 0.4):\n    '''\n        Cutout augmentation\n        image: A PIL image\n        boxes: bounding boxes, a tensor of dimensions (#objects, 4)\n        labels: labels of object, a tensor of dimensions (#objects)\n        fill_val: Value filled in cut out\n        bbox_remove_thres: Theshold to remove bbox cut by cutout\n        \n        Out: new image, new_boxes, new_labels\n    '''\n    if type(image) == PIL.Image.Image:\n        image = F.to_tensor(image)\n    original_h = image.size(1)\n    original_w = image.size(2)\n    original_channel = image.size(0)\n    \n    new_image = image\n    new_boxes = boxes\n    new_labels = labels\n    \n    for _ in range(50):\n        #Random cutout size: [0.15, 0.5] of original dimension\n        cutout_size_h = random.uniform(0.15*original_h, 0.5*original_h)\n        cutout_size_w = random.uniform(0.15*original_w, 0.5*original_w)\n        \n        #Random position for cutout\n        left = random.uniform(0, original_w - cutout_size_w)\n        right = left + cutout_size_w\n        top = random.uniform(0, original_h - cutout_size_h)\n        bottom = top + cutout_size_h\n        cutout = torch.FloatTensor([int(left), int(top), int(right), int(bottom)])\n        \n        #Calculate intersect between cutout and bounding boxes\n        overlap_size = intersect(cutout.unsqueeze(0), boxes)\n        area_boxes = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])\n        ratio = overlap_size / area_boxes\n        #If all boxes have Iou greater than bbox_remove_thres, try again\n        if ratio.min().item() > bbox_remove_thres:\n            continue\n        \n        cutout_arr = torch.full((original_channel,int(bottom) - int(top),int(right) - int(left)), fill_val)\n        new_image[:, int(top):int(bottom), int(left):int(right)] = cutout_arr\n        \n        #Create new boxes and labels\n        boolean = ratio < bbox_remove_thres\n        \n        new_boxes = boxes[boolean[0], :]\n        \n        new_labels = labels[boolean[0]]\n        \n        return F.to_pil_image(new_image), new_boxes, new_labels\n","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:04.886376Z","iopub.execute_input":"2024-01-24T09:48:04.886660Z","iopub.status.idle":"2024-01-24T09:48:04.898316Z","shell.execute_reply.started":"2024-01-24T09:48:04.886636Z","shell.execute_reply":"2024-01-24T09:48:04.897401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nnew_image,new_boxes, new_labels = cutout(image, boxes,labels)\ndraw_PIL_image(new_image, new_boxes, new_labels)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:04.899565Z","iopub.execute_input":"2024-01-24T09:48:04.899864Z","iopub.status.idle":"2024-01-24T09:48:05.212958Z","shell.execute_reply.started":"2024-01-24T09:48:04.899837Z","shell.execute_reply":"2024-01-24T09:48:05.212111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Mixup\n","metadata":{}},{"cell_type":"code","source":"# image2 = Image.open(\"./data/000055.jpg\", mode= \"r\")\n# image2 = image2.convert(\"RGB\")\n# objects2= parse_annot(\"./data/000055.xml\")\n# boxes2 = torch.FloatTensor(objects2['boxes'])\n# labels2 = torch.LongTensor(objects2['labels']) \n# difficulties2 = torch.ByteTensor(objects2['difficulties'])\n# draw_PIL_image(image2, boxes2, labels2)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:48:05.214090Z","iopub.execute_input":"2024-01-24T09:48:05.214370Z","iopub.status.idle":"2024-01-24T09:48:05.218326Z","shell.execute_reply.started":"2024-01-24T09:48:05.214346Z","shell.execute_reply":"2024-01-24T09:48:05.217535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import PIL\nbase = '/kaggle/working/train/'\nn = random.randint(0, len(image_list)-1)\none = base + str(image_list[n])\nimage1 = Image.open(one+\".jpg\", mode= \"r\")\nimage1 = image.convert(\"RGB\")\nobjects1= parse_annot(one+\".xml\")\nboxes1 = torch.FloatTensor(objects['boxes'])\nlabels1 = torch.LongTensor(objects['labels']) \ndraw_PIL_image(image1, boxes1, labels1)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:52:53.064807Z","iopub.execute_input":"2024-01-24T09:52:53.065661Z","iopub.status.idle":"2024-01-24T09:52:53.391302Z","shell.execute_reply.started":"2024-01-24T09:52:53.065625Z","shell.execute_reply":"2024-01-24T09:52:53.390434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import PIL\nbase = '/kaggle/working/train/'\nn = random.randint(0, len(image_list)-1)\none = base + str(image_list[423])\nimage2 = Image.open(one+\".jpg\", mode= \"r\")\nimage2 = image.convert(\"RGB\")\nobjects2= parse_annot(one+\".xml\")\nboxes2 = torch.FloatTensor(objects['boxes'])\nlabels2 = torch.LongTensor(objects['labels']) \ndraw_PIL_image(image2, boxes2, labels2)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:53:40.282269Z","iopub.execute_input":"2024-01-24T09:53:40.283021Z","iopub.status.idle":"2024-01-24T09:53:40.607841Z","shell.execute_reply.started":"2024-01-24T09:53:40.282990Z","shell.execute_reply":"2024-01-24T09:53:40.606953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_info_1 = {\"image\": F.to_tensor(image1), \"label\": labels1, \"box\": boxes1}\nimage_info_2 = {\"image\": F.to_tensor(image2), \"label\": labels2, \"box\": boxes2}","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:52:05.886829Z","iopub.execute_input":"2024-01-24T09:52:05.887542Z","iopub.status.idle":"2024-01-24T09:52:05.907464Z","shell.execute_reply.started":"2024-01-24T09:52:05.887510Z","shell.execute_reply":"2024-01-24T09:52:05.906487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mixup(image_info_1, image_info_2, lambd):\n    '''\n        Mixup 2 image\n        \n        image_info_1, image_info_2: Info dict 2 image with keys = {\"image\", \"label\", \"box\", \"difficult\"}\n        lambd: Mixup ratio\n        \n        Out: mix_image (Temsor), mix_boxes, mix_labels, mix_difficulties\n    '''\n    img1 = image_info_1[\"image\"]    #Tensor\n    img2 = image_info_2[\"image\"]    #Tensor\n    mixup_width = max(img1.shape[2], img2.shape[2])\n    mix_up_height = max(img1.shape[1], img2.shape[1])\n    \n    mix_img = torch.zeros(3, mix_up_height, mixup_width)\n    mix_img[:, :img1.shape[1], :img1.shape[2]] = img1 * lambd\n    mix_img[:, :img2.shape[1], :img2.shape[2]] += img2 * (1. - lambd)\n    \n    mix_labels = torch.cat((image_info_1[\"label\"], image_info_2[\"label\"]), dim= 0)\n\n    \n    mix_boxes = torch.cat((image_info_1[\"box\"], image_info_2[\"box\"]), dim= 0)\n    \n    return mix_img, mix_boxes, mix_labels","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:52:06.659482Z","iopub.execute_input":"2024-01-24T09:52:06.659843Z","iopub.status.idle":"2024-01-24T09:52:06.667554Z","shell.execute_reply.started":"2024-01-24T09:52:06.659814Z","shell.execute_reply":"2024-01-24T09:52:06.666639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lambd = random.uniform(0, 1)\nmix_img, mix_boxes, mix_labels = mixup(image_info_1, image_info_2, lambd)\ndraw_PIL_image(F.to_pil_image(mix_img), mix_boxes, mix_labels)\nprint(\"Lambda: \",lambd)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T09:52:40.706251Z","iopub.execute_input":"2024-01-24T09:52:40.707135Z","iopub.status.idle":"2024-01-24T09:52:41.061771Z","shell.execute_reply.started":"2024-01-24T09:52:40.707098Z","shell.execute_reply":"2024-01-24T09:52:41.060933Z"},"trusted":true},"execution_count":null,"outputs":[]}]}