{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import\n\n","metadata":{}},{"cell_type":"code","source":"# import pytorch and use fasterRCNN \nimport cv2\nimport time\nimport random\nimport numpy as np\nimport pandas as pd\nfrom matplotlib import pyplot as plt\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nimport torch\nimport torchvision\nfrom torch.utils.data import DataLoader\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection import FasterRCNN","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:10.970942Z","iopub.execute_input":"2022-11-27T08:49:10.971470Z","iopub.status.idle":"2022-11-27T08:49:15.181928Z","shell.execute_reply.started":"2022-11-27T08:49:10.971385Z","shell.execute_reply":"2022-11-27T08:49:15.179780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# the path and some values \nDEVICE = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\nBASE_DIR = \"../input/tensorflow-great-barrier-reef/train_images/\"\nepochs = 10","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.184220Z","iopub.execute_input":"2022-11-27T08:49:15.185194Z","iopub.status.idle":"2022-11-27T08:49:15.261966Z","shell.execute_reply.started":"2022-11-27T08:49:15.185150Z","shell.execute_reply":"2022-11-27T08:49:15.260850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading data","metadata":{}},{"cell_type":"code","source":"df_train = pd.read_csv(\"/kaggle/input/tensorflow-great-barrier-reef/train.csv\")\ndf_train.shape","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.264769Z","iopub.execute_input":"2022-11-27T08:49:15.265198Z","iopub.status.idle":"2022-11-27T08:49:15.347460Z","shell.execute_reply.started":"2022-11-27T08:49:15.265153Z","shell.execute_reply":"2022-11-27T08:49:15.346594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Turn annotations from strings into lists of dictionaries\ndf_train = pd.read_csv(\"/kaggle/input/tensorflow-great-barrier-reef/train.csv\")\ndf_train=df_train.loc[df_train[\"annotations\"].astype(str) != \"[]\"]\ndf_train['annotations'] = df_train['annotations'].apply(eval)\n\n# Create the image path for the row\ndef image_path(r):\n    video_id = r['video_id']\n    video_frame = r['video_frame']\n    return  \"video_\" + str(video_id) + \"/\" + str(video_frame) + \".jpg\"\ndf_train['image_path'] = df_train.apply(lambda x: image_path(x), axis=1)\ndf_train.head()\n\n#make annotation to each row\n#df_extrain=df_train.explode('annotations') \n#df_extrain.reset_index(drop=True)\n#df_extrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.352903Z","iopub.execute_input":"2022-11-27T08:49:15.355075Z","iopub.status.idle":"2022-11-27T08:49:15.668393Z","shell.execute_reply.started":"2022-11-27T08:49:15.355038Z","shell.execute_reply":"2022-11-27T08:49:15.667452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(df_train['annotations'].str.len() > 0).value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.670512Z","iopub.execute_input":"2022-11-27T08:49:15.671680Z","iopub.status.idle":"2022-11-27T08:49:15.685455Z","shell.execute_reply.started":"2022-11-27T08:49:15.671642Z","shell.execute_reply":"2022-11-27T08:49:15.684295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_ids = df_train['image_id'].unique()\ntrain_ids = image_ids[:-983]\nvalid_ids = image_ids[-983:]\ntrain_df = df_train[df_train['image_id'].isin(train_ids)]\nvalid_df = df_train[df_train['image_id'].isin(valid_ids)]\nvalid_df.shape, train_df.shape","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.686904Z","iopub.execute_input":"2022-11-27T08:49:15.687465Z","iopub.status.idle":"2022-11-27T08:49:15.705864Z","shell.execute_reply.started":"2022-11-27T08:49:15.687421Z","shell.execute_reply":"2022-11-27T08:49:15.704494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ReefDataset:\n\n    def __init__(self, df, transforms=None):\n        self.df = df\n        self.transforms = transforms\n\n    def can_augment(self, boxes):\n        \"\"\" Check if bounding boxes are OK to augment\n        \n        \n        For example: image_id 1-490 has a bounding box that is partially outside of the image\n        It breaks albumentation\n        Here we check the margins are within the image to make sure the augmentation can be applied\n        \"\"\"\n        \n        box_outside_image = ((boxes[:, 0] < 0).any() or (boxes[:, 1] < 0).any() \n                             or (boxes[:, 2] > 1280).any() or (boxes[:, 3] > 720).any())\n        return not box_outside_image\n\n    def get_boxes(self, row):\n        \"\"\"Returns the bboxes for a given row as a 3D matrix with format [x_min, y_min, x_max, y_max]\"\"\"\n        \n        boxes = pd.DataFrame(row['annotations'], columns=['x', 'y', 'width', 'height']).astype(float).values\n        \n        # Change from [x_min, y_min, w, h] to [x_min, y_min, x_max, y_max]\n        boxes[:, 2] = boxes[:, 0] + boxes[:, 2]\n        boxes[:, 3] = boxes[:, 1] + boxes[:, 3]\n        return boxes\n    \n    def get_image(self, row):\n        \"\"\"Gets the image for a given row\"\"\"\n        \n        image = cv2.imread(f'{BASE_DIR}/{row[\"image_path\"]}', cv2.IMREAD_COLOR)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n        image /= 255.0\n        return image\n    \n    def __getitem__(self, i):\n\n        row = self.df.iloc[i]\n        image = self.get_image(row)\n        boxes = self.get_boxes(row)\n        \n        n_boxes = boxes.shape[0]\n        \n        # Calculate the area\n        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])\n        \n        \n        target = {\n            'boxes': torch.as_tensor(boxes, dtype=torch.float32),\n            'area': torch.as_tensor(area, dtype=torch.float32),\n            \n            'image_id': torch.tensor([i]),\n            \n            # There is only one class\n            'labels': torch.ones((n_boxes,), dtype=torch.int64),\n            \n            # Suppose all instances are not crowd\n            'iscrowd': torch.zeros((n_boxes,), dtype=torch.int64)            \n        }\n\n        if self.transforms and self.can_augment(boxes):\n            sample = {\n                'image': image,\n                'bboxes': target['boxes'],\n                'labels': target['labels']\n            }\n            sample = self.transforms(**sample)\n            image = sample['image']\n            \n            if n_boxes > 0:\n                target['boxes'] = torch.stack(tuple(map(torch.tensor, zip(*sample['bboxes'])))).permute(1, 0)\n        else:\n            image = ToTensorV2(p=1.0)(image=image)['image']\n\n        return image, target\n\n    def __len__(self):\n        return len(self.df)","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.708856Z","iopub.execute_input":"2022-11-27T08:49:15.709137Z","iopub.status.idle":"2022-11-27T08:49:15.729914Z","shell.execute_reply.started":"2022-11-27T08:49:15.709110Z","shell.execute_reply":"2022-11-27T08:49:15.728567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# here we experiment image augmentation using simple transformations \n\ndef get_train_transform():\n    return A.Compose([\n        A.Flip(0.5),\n        ToTensorV2(p=1.0)\n    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\n\ndef get_valid_transform():\n    return A.Compose([\n        ToTensorV2(p=1.0)\n    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.731689Z","iopub.execute_input":"2022-11-27T08:49:15.732020Z","iopub.status.idle":"2022-11-27T08:49:15.741678Z","shell.execute_reply.started":"2022-11-27T08:49:15.731986Z","shell.execute_reply":"2022-11-27T08:49:15.740875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_train = ReefDataset(train_df, get_train_transform())\nds_val = ReefDataset(valid_df, get_valid_transform())","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.745113Z","iopub.execute_input":"2022-11-27T08:49:15.746763Z","iopub.status.idle":"2022-11-27T08:49:15.753959Z","shell.execute_reply.started":"2022-11-27T08:49:15.746726Z","shell.execute_reply":"2022-11-27T08:49:15.753222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df[train_df.annotations.str.len() > 12].head()","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.758753Z","iopub.execute_input":"2022-11-27T08:49:15.759778Z","iopub.status.idle":"2022-11-27T08:49:15.801693Z","shell.execute_reply.started":"2022-11-27T08:49:15.759744Z","shell.execute_reply":"2022-11-27T08:49:15.800944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image, targets = ds_train[3935]\nimage","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.802965Z","iopub.execute_input":"2022-11-27T08:49:15.803584Z","iopub.status.idle":"2022-11-27T08:49:15.918402Z","shell.execute_reply.started":"2022-11-27T08:49:15.803532Z","shell.execute_reply":"2022-11-27T08:49:15.916856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"targets","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.920792Z","iopub.execute_input":"2022-11-27T08:49:15.921806Z","iopub.status.idle":"2022-11-27T08:49:15.937148Z","shell.execute_reply.started":"2022-11-27T08:49:15.921765Z","shell.execute_reply":"2022-11-27T08:49:15.933700Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"boxes = targets['boxes'].cpu().numpy().astype(np.int32)\nimg = image.permute(1,2,0).cpu().numpy()\nfig, ax = plt.subplots(1, 1, figsize=(16, 8))\n\nfor box in boxes:\n    cv2.rectangle(img,\n                  (box[0], box[1]),\n                  (box[2], box[3]),\n                  (220, 0, 0), 3)\n    \nax.set_axis_off()\nax.imshow(img);","metadata":{"execution":{"iopub.status.busy":"2022-11-27T08:49:15.938818Z","iopub.execute_input":"2022-11-27T08:49:15.939334Z","iopub.status.idle":"2022-11-27T08:49:16.809915Z","shell.execute_reply.started":"2022-11-27T08:49:15.939291Z","shell.execute_reply":"2022-11-27T08:49:16.806774Z"},"trusted":true},"execution_count":null,"outputs":[]}]}