{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","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"},{"sourceId":8592023,"sourceType":"datasetVersion","datasetId":5139468}],"dockerImageVersionId":30716,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-06-03T08:52:43.216552Z","iopub.execute_input":"2024-06-03T08:52:43.217389Z","iopub.status.idle":"2024-06-03T08:52:43.829136Z","shell.execute_reply.started":"2024-06-03T08:52:43.217354Z","shell.execute_reply":"2024-06-03T08:52:43.828171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import os\n\n# import numpy as np\n# import pandas as pd\n# import seaborn as sns\n# from albumentations import Flip\n# from matplotlib import pyplot as plt\n# from PIL import Image\n\n# # 添加数据\n# # train.csv - 训练集\n# # sample_submission.csv - a sample submission file in the correct format\n# # train.zip - 训练图片\n# # test.zip - 测试图片\n\n# DIR_INPUT = '/kaggle/input/global-wheat-detection'\n# DIR_TRAIN = f'{DIR_INPUT}/train'\n# DIR_TEST = f'{DIR_INPUT}/test'\n\n# #读取数据\n\n# train_df = pd.read_csv(f'{DIR_INPUT}/train.csv')\n# train_df.head()\n\n# print(train_df)\n\n# #将box中的数据进行分割\n# train_df[['x','y','w','h']] = 0\n# train_df[['x','y','w','h']] = np.stack(train_df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=','))).astype(np.float64)\n# train_df.drop(columns=['bbox'], inplace=True)\n# train_df.head()\n\n# print(train_df)\n\n# #分析数据，查看有多少张图片\n# train_df.shape\n\n# #查看有多少张图片\n# train_df['image_id'].nunique()\n\n# #查看训练集中图片个数\n# len(os.listdir(DIR_TRAIN))\n\n# #计算训练图片的大小分布\n\n# train_df['width'].unique(), train_df['height'].unique()\n\n# #计算边界框数量的分布\n# counts = train_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('boxes')\n# plt.ylabel('images')\n# plt.title('boxes vs. images')\n# plt.show()\n\n\n# #边界框大小分布\n# train_df['cx'] = train_df['x'] + train_df['w'] / 2\n# train_df['cy'] = train_df['y'] + train_df['h'] / 2\n\n# ax = plt.subplots(1, 4, figsize=(16, 4), tight_layout=True)[1].ravel()\n# ax[0].set_title('x vs. y')\n# ax[0].set_xlim(0, 1024)\n# ax[0].set_ylim(0, 1024)\n# ax[1].set_title('cx vs. cy')\n# ax[1].set_xlim(0, 1024)\n# ax[1].set_ylim(0, 1024)\n# ax[2].set_title('w vs. h')\n# ax[3].set_title('area size')\n# sns.histplot(data=train_df, x='x', y='y', ax=ax[0], bins=50, pmax=0.9)\n# sns.histplot(data=train_df, x='cx', y='cy', ax=ax[1], bins=50, pmax=0.9)\n# sns.histplot(data=train_df, x='w', y='h', ax=ax[2], bins=50, pmax=0.9)\n# sns.histplot(train_df['w'] * train_df['h'], ax=ax[3], bins=50, kde=False)\n# plt.show()\n\n# #将数据分为80%的训练集及20%的验证集\n# image_ids = train_df['image_id'].unique()\n\n# split_len = round(len(image_ids)*0.8)\n\n# train_ids = image_ids[:split_len]\n# valid_ids = image_ids[split_len:]\n\n# train = train_df[train_df['image_id'].isin(train_ids)]\n# valid = train_df[train_df['image_id'].isin(valid_ids)]\n\n# train.shape, valid.shape\n\n# #展示图片\n# def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):\n#   figsize = (num_cols * scale, num_rows * scale)\n#   _, axes = plt.subplots(num_rows, num_cols, figsize=figsize)\n#   axes = axes.flatten()\n#   for i, (ax, img) in enumerate(zip(axes, imgs)):\n#     ax.imshow(img)\n#     ax.axes.get_xaxis().set_visible(False)\n#     ax.axes.get_yaxis().set_visible(False)\n#     if titles and len(titles) > i:\n#       ax.set_title(titles[i])\n#   return axes\n\n# def show_bboxes(axes, bboxes, labels=None, colors=None):\n#   def _make_list(obj, default_values=None):\n#     if obj is None:\n#       obj = default_values\n#     elif not isinstance(obj, (list, tuple)):\n#       obj = [obj]\n#     return obj\n\n#   labels = _make_list(labels)\n#   colors = _make_list(colors, ['b', 'g', 'r', 'm', 'c'])\n#   for i, bbox in enumerate(bboxes):\n#     color = colors[i % len(colors)]\n#     rect = plt.Rectangle(\n#       xy=(bbox[0], bbox[1]),\n#       width=bbox[2] - bbox[0],\n#       height=bbox[3] - bbox[1],\n#       fill=False,\n#       edgecolor=color,\n#       linewidth=2)\n#     axes.add_patch(rect)\n#     if labels and len(labels) > i:\n#       text_color = 'k' if color == 'w' else 'w'\n#       axes.text(rect.xy[0], rect.xy[1], labels[i], va='center',\n#                 ha='center', fontsize=9, color=text_color,\n#                 bbox=dict(facecolor=color, lw=0))\n\n# #展示没有识别框的图片\n# num_rows, num_cols = 2, 4\n# imgs = [plt.imread(f'{DIR_TRAIN}/{n}.jpg') for n in train_df['image_id'].unique()[:num_rows*num_cols]]\n# show_images(imgs, num_rows, num_cols, scale=4)\n# plt.show()\n\n# #展示有识别框的图片\n# num_rows, num_cols = 1, 2\n# ids = train_df['image_id'].unique()[:num_rows*num_cols]\n# imgs = [plt.imread(f'{DIR_TRAIN}/{n}.jpg') for n in ids]\n# axes = show_images(imgs, num_rows, num_cols, scale=8)\n# for ax, id in zip(axes, ids):\n#   datas = train_df[train_df['image_id'] == id]\n#   bboxes = [(d['x'], d['y'], d['x']+d['w'], d['y']+d['h']) for _, d in datas.iterrows()]\n#   show_bboxes(ax, bboxes, labels=None, colors=['w'])\n# plt.show()\n\n# import cv2 as cv\n# import numpy as np\n\n# import albumentations as A\n# from albumentations.pytorch.transforms import ToTensorV2\n\n# import torch\n# from torch.utils.data import Dataset\n\n\n\n# class Wheat(Dataset):\n#   def __init__(self, dataframe, image_dir, transforms=None):\n#     super().__init__()\n#     self.image_ids = dataframe['image_id'].unique()\n#     self.df = dataframe\n#     self.image_dir = image_dir\n#     self.transforms = transforms\n\n#   def __getitem__(self, idx: int):\n#     image_id = self.image_ids[idx]\n#     records = self.df[self.df['image_id'] == image_id]\n\n#     image = cv.imread(f'{self.image_dir}/{image_id}.jpg', cv.IMREAD_COLOR)\n#     image = cv.cvtColor(image, cv.COLOR_BGR2RGB).astype(np.float32)\n#     image /= 255.0\n\n#     boxes = records[['x', 'y', 'w', 'h']].values\n\n#     area = boxes[:, 2] * boxes[:, 3]\n#     area = torch.as_tensor(area, dtype=torch.float32)\n\n#     boxes[:, 2] = boxes[:, 0] + boxes[:, 2]\n#     boxes[:, 3] = boxes[:, 1] + boxes[:, 3]\n\n#     # there is only one class\n#     labels = torch.ones((records.shape[0],), dtype=torch.int64)\n#     # suppose all instances are not crowd\n#     iscrowd = torch.zeros((records.shape[0],), dtype=torch.uint8)\n\n#     target = {}\n#     target['boxes'] = boxes\n#     target['labels'] = labels\n#     target['image_id'] = torch.tensor([idx])\n#     target['area'] = area\n#     target['iscrowd'] = iscrowd\n\n#     if self.transforms:\n#       sample = {\n#         'image': image,\n#         'bboxes': target['boxes'],\n#         'labels': labels,\n#       }\n#       sample = self.transforms(**sample)\n#       image = sample['image']\n#       target['boxes'] = torch.stack(tuple(map(torch.tensor, zip(*sample['bboxes'])))).permute(1, 0)\n\n#     return image, target, image_id\n\n#   def __len__(self) -> int:\n#     return len(self.image_ids)\n\n#   # albumentations\n#   #  https://github.com/albumentations-team/albumentations\n\n#   @staticmethod\n#   def get_train_transform():\n#     return A.Compose([\n#       #A.Flip(0.5),\n#       Flip(p=0.5),\n#       ToTensorV2(p=1.0)\n#     ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\n\n#   @staticmethod\n#   def get_valid_transform():\n#     return A.Compose([\n#       ToTensorV2(p=1.0)\n#     ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\n\n# train_dataset = Wheat(train, DIR_TRAIN, Wheat.get_train_transform())\n# valid_dataset = Wheat(valid, DIR_TRAIN, Wheat.get_valid_transform())\n\n# datas = [train_dataset[i] for i in range(2)]\n# imgs = [d[0].permute(1, 2, 0).numpy() for d in datas]\n# axes = show_images(imgs, 1, 2, scale=8)\n# for ax, (image, target, image_id) in zip(axes, datas):\n#       show_bboxes(ax, target['boxes'], labels=None, colors=['w'])\n# plt.show()\n\n\n# import torchvision\n# from torchvision.models.detection.faster_rcnn import FastRCNNPredictor\n# from torchvision.models.detection import FasterRCNN\n# from torchvision.models.detection.rpn import AnchorGenerator\n\n# #创建Faster R-CNN模型\n# model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)\n\n# print(model.roi_heads.box_predictor)\n\n# num_classes = 2 # wheat or not(background)\n\n# # get number of input features for the classifier\n# in_features = model.roi_heads.box_predictor.cls_score.in_features\n\n# # replace the pre-trained model's head with a new one\n# model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\n\n# print(model.roi_heads.box_predictor)\n\n# #********************************************************************************************8\n\n# from torch.utils.data import DataLoader\n\n# def collate_fn(batch):\n#   return tuple(zip(*batch))\n\n# train_data_loader = DataLoader(\n#   train_dataset,\n#   batch_size=16,\n#   shuffle=False,\n#   num_workers=4,\n#   collate_fn=collate_fn\n# )\n\n# valid_data_loader = DataLoader(\n#   valid_dataset,\n#   batch_size=16,\n#   shuffle=False,\n#   num_workers=4,\n#   collate_fn=collate_fn\n# )\n\n# # train on the GPU or on the CPU, if a GPU is not available\n# device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\n\n# # move model to the right device\n# model.to(device)\n\n# # create an optimizer\n# params = [p for p in model.parameters() if p.requires_grad]\n# optimizer = torch.optim.SGD(params, lr=0.005, momentum=0.9, weight_decay=0.0005)\n\n# # create a learning rate scheduler\n# # lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=3, gamma=0.1)\n# lr_scheduler = None\n\n# # train it for 10 epochs\n# num_epochs = 10\n\n\n\n# import time\n# # from tqdm import tqdm\n# from tqdm.notebook import tqdm as tqdm\n\n# itr = 1\n\n# total_train_loss = []\n# total_valid_loss = []\n\n# losses_value = 0\n\n# for epoch in range(num_epochs):\n\n#   start_time = time.time()\n\n#   # train ------------------------------\n\n#   model.train()\n#   train_loss = []\n\n\n#   pbar = tqdm(train_data_loader, desc='let\\'s train')\n#   for images, targets, image_ids in pbar:\n#     images = list(image.to(device) for image in images)\n#     targets = [{k: v.to(device) for k, v in t.items()} for t in targets]\n\n#     loss_dict = model(images, targets)\n\n#     losses = sum(loss for loss in loss_dict.values())\n#     losses_value = losses.item()\n#     train_loss.append(losses_value)\n\n#     optimizer.zero_grad()\n#     losses.backward()\n#     optimizer.step()\n\n#     pbar.set_description(f\"Epoch: {epoch + 1}, Batch: {itr}, Loss: {losses_value}\")\n#     itr += 1\n\n#   epoch_train_loss = np.mean(train_loss)\n#   total_train_loss.append(epoch_train_loss)\n\n#   # update the learning rate\n#   if lr_scheduler is not None:\n#     lr_scheduler.step()\n\n#   # valid ------------------------------\n\n#   with torch.no_grad():\n#     valid_loss = []\n\n#     for images, targets, image_ids in valid_data_loader:\n#       images = list(image.to(device) for image in images)\n#       targets = [{k: v.to(device) for k, v in t.items()} for t in targets]\n\n#       loss_dict = model(images, targets)\n\n#       losses = sum(loss for loss in loss_dict.values())\n#       loss_value = losses.item()\n#       valid_loss.append(loss_value)\n\n#   epoch_valid_loss = np.mean(valid_loss)\n#   total_valid_loss.append(epoch_valid_loss)\n\n#   # print ------------------------------\n\n#   print(f\"Epoch Completed: {epoch + 1}/{num_epochs}, Time: {time.time() - start_time}, \"\n#         f\"Train Loss: {epoch_train_loss}, Valid Loss: {epoch_valid_loss}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:43.830963Z","iopub.execute_input":"2024-06-03T08:52:43.831461Z","iopub.status.idle":"2024-06-03T08:52:43.847217Z","shell.execute_reply.started":"2024-06-03T08:52:43.831430Z","shell.execute_reply":"2024-06-03T08:52:43.846277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plt.figure(figsize=(8, 5))\n# sns.set_style(style=\"whitegrid\")\n# sns.lineplot(x=range(1, len(total_train_loss)+1), y=total_train_loss, label=\"Train Loss\")\n# sns.lineplot(x=range(1, len(total_train_loss)+1), y=total_valid_loss, label=\"Valid Loss\")\n# plt.xlabel(\"Epochs\")\n# plt.ylabel(\"Loss\")\n# plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:43.848208Z","iopub.execute_input":"2024-06-03T08:52:43.848445Z","iopub.status.idle":"2024-06-03T08:52:43.860946Z","shell.execute_reply.started":"2024-06-03T08:52:43.848423Z","shell.execute_reply":"2024-06-03T08:52:43.860111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# torch.save(model.state_dict(), 'fasterrcnn_resnet50_fpn.pth')","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:43.863005Z","iopub.execute_input":"2024-06-03T08:52:43.863374Z","iopub.status.idle":"2024-06-03T08:52:43.870878Z","shell.execute_reply.started":"2024-06-03T08:52:43.863351Z","shell.execute_reply":"2024-06-03T08:52:43.870121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib import pyplot as plt\nfrom PIL import Image\n\nDIR_INPUT = '/kaggle/input/global-wheat-detection'\nDIR_TRAIN = f'{DIR_INPUT}/train'\nDIR_TEST = f'{DIR_INPUT}/test'\n\nDIR_WEIGHTS = '/kaggle/input/model1'\nWEIGHTS_FILE = f'{DIR_WEIGHTS}/fasterrcnn_resnet50_fpn.pth'\ntest_df = pd.read_csv(f'{DIR_INPUT}/sample_submission.csv')\ntest_df.tail()","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:43.871764Z","iopub.execute_input":"2024-06-03T08:52:43.872010Z","iopub.status.idle":"2024-06-03T08:52:43.888986Z","shell.execute_reply.started":"2024-06-03T08:52:43.871988Z","shell.execute_reply":"2024-06-03T08:52:43.888120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2 as cv\nimport numpy as np\n\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\n\nimport torch\nfrom torch.utils.data import Dataset\n\n\nclass WheatTest(Dataset):\n\n  def __init__(self, image_ids, image_dir, transforms=None):\n    super().__init__()\n    self.image_ids = image_ids\n    self.image_dir = image_dir\n    self.transforms = transforms\n\n  def __getitem__(self, idx: int):\n    image_id = self.image_ids[idx]\n\n    image = cv.imread(f'{self.image_dir}/{image_id}.jpg', cv.IMREAD_COLOR)\n    image = cv.cvtColor(image, cv.COLOR_BGR2RGB).astype(np.float32)\n    image /= 255.0\n\n    if self.transforms:\n      sample = {\n        'image': image,\n      }\n      sample = self.transforms(**sample)\n      image = sample['image']\n\n    return image, image_id\n\n  def __len__(self) -> int:\n    return len(self.image_ids)\n\n  @staticmethod\n  def get_test_transform():\n    return A.Compose([\n      ToTensorV2(p=1.0)\n    ])\ndef get_image_ids(p):\n  import glob\n  image_ids = []\n  for p in glob.glob(f'{p}/*.jpg'):\n    n, _ = os.path.splitext(os.path.basename(p))\n    image_ids.append(n)\n  return image_ids\n\n# try more images for submission\n#test_dataset = WheatTest(get_image_ids(DIR_TRAIN), DIR_TRAIN, WheatTest.get_test_transform())\n\ntest_dataset = WheatTest(test_df[\"image_id\"].unique(), DIR_TEST, WheatTest.get_test_transform())","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:43.890309Z","iopub.execute_input":"2024-06-03T08:52:43.890680Z","iopub.status.idle":"2024-06-03T08:52:43.901986Z","shell.execute_reply.started":"2024-06-03T08:52:43.890650Z","shell.execute_reply":"2024-06-03T08:52:43.901098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import DataLoader\n\ndef collate_fn(batch):\n  return tuple(zip(*batch))\n\ntest_data_loader = DataLoader(\n  test_dataset,\n  batch_size=8, # GPU not enough if inference 16 images\n  shuffle=False,\n  num_workers=4,\n  drop_last=False,\n  collate_fn=collate_fn\n)","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:43.903112Z","iopub.execute_input":"2024-06-03T08:52:43.903377Z","iopub.status.idle":"2024-06-03T08:52:43.911571Z","shell.execute_reply.started":"2024-06-03T08:52:43.903355Z","shell.execute_reply":"2024-06-03T08:52:43.910833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection import FasterRCNN\nfrom torchvision.models.detection.rpn import AnchorGenerator\n\ndevice = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\n\n# create a Faster R-CNN model without pre-trained\nmodel = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False, pretrained_backbone=False)\n\nnum_classes = 2 # wheat or not(background)\n\n# get number of input features for the classifier\nin_features = model.roi_heads.box_predictor.cls_score.in_features\n\n# replace the pre-trained model's head with a new one\nmodel.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\n\n# load the trained weights\nmodel.load_state_dict(torch.load(WEIGHTS_FILE, map_location=device))\nmodel.eval()\n\n# move model to the right device\n_ = model.to(device)","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:43.912823Z","iopub.execute_input":"2024-06-03T08:52:43.913439Z","iopub.status.idle":"2024-06-03T08:52:44.834052Z","shell.execute_reply.started":"2024-06-03T08:52:43.913405Z","shell.execute_reply":"2024-06-03T08:52:44.833096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"score_threshold = 0.7\nimage_outputs = []\n\nfor images, image_ids in test_data_loader:\n  images = list(image.to(device) for image in images)\n  outputs = model(images)\n    \n  for image_id, output in zip(image_ids, outputs):\n    boxes = output['boxes'].data.cpu().numpy()\n    scores = output['scores'].data.cpu().numpy()\n    \n    mask = scores >= score_threshold\n    boxes = boxes[mask].astype(np.int32)\n    scores = scores[mask]\n\n    image_outputs.append((image_id, boxes, scores))","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:44.835326Z","iopub.execute_input":"2024-06-03T08:52:44.835662Z","iopub.status.idle":"2024-06-03T08:52:45.839800Z","shell.execute_reply.started":"2024-06-03T08:52:44.835630Z","shell.execute_reply":"2024-06-03T08:52:45.838549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_rows, num_cols = 1, 2\nscale = 16\nfigsize = (num_rows * scale, num_cols * scale)\n_, axes = plt.subplots(num_rows, num_cols, figsize=figsize)\naxes = axes.flatten()\n\nfig_n = num_rows * num_cols\nfig_i = 0\n\nfor i in range(1, 1+fig_n):\n  image, image_id = test_dataset[i]\n  _, boxes, scores = image_outputs[i]\n\n  sample = image.permute(1, 2, 0).cpu().numpy()\n\n  for box in boxes:\n    cv.rectangle(sample, (box[0], box[1]), (box[2], box[3]), (220, 0, 0), 2)\n\n  axes[fig_i].imshow(sample)\n  fig_i += 1","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:45.843520Z","iopub.execute_input":"2024-06-03T08:52:45.844107Z","iopub.status.idle":"2024-06-03T08:52:47.451707Z","shell.execute_reply.started":"2024-06-03T08:52:45.844046Z","shell.execute_reply":"2024-06-03T08:52:47.450663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def format_prediction_string(boxes, scores):\n  pred_strings = []\n  for score, box in zip(scores, boxes):\n    pred_strings.append(round(score, 4))\n    pred_strings.extend(box)\n  return ' '.join(map(str, pred_strings))\n\nresults = []\n\nfor image_id, boxes, scores in image_outputs:\n  #boxes = boxes_.copy()\n  boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n  boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n\n  result = {\n    'image_id': image_id,\n    'PredictionString': format_prediction_string(boxes, scores)\n  }\n  results.append(result)\n\nresults[0]","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:47.453029Z","iopub.execute_input":"2024-06-03T08:52:47.453375Z","iopub.status.idle":"2024-06-03T08:52:47.468951Z","shell.execute_reply.started":"2024-06-03T08:52:47.453346Z","shell.execute_reply":"2024-06-03T08:52:47.468003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:47.469999Z","iopub.execute_input":"2024-06-03T08:52:47.470301Z","iopub.status.idle":"2024-06-03T08:52:47.481323Z","shell.execute_reply.started":"2024-06-03T08:52:47.470277Z","shell.execute_reply":"2024-06-03T08:52:47.480397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-06-03T08:52:47.482513Z","iopub.execute_input":"2024-06-03T08:52:47.482788Z","iopub.status.idle":"2024-06-03T08:52:47.490573Z","shell.execute_reply.started":"2024-06-03T08:52:47.482765Z","shell.execute_reply":"2024-06-03T08:52:47.489575Z"},"trusted":true},"execution_count":null,"outputs":[]}]}