{"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":"### References: https://www.kaggle.com/kartik2khandelwal/data-analysis-and-prediction\n\nContent\n\n* Counting no of images depending on video id\n* No of images depending on no-bbox and yes-bbox\n* No of bboxes contain for an image\n* Draw bboxes on train images (single) using Pillow ","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport plotly.express as px\nimport plotly.graph_objects as go\nimport seaborn as sns\nsns.set_style('darkgrid')\n\nfrom PIL import Image, ImageDraw\nimport tensorflow as tf\n\nimport os\nimport ast ## change str ---> list\nimport sys\nimport time\n\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport greatbarrierreef","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv('../input/tensorflow-great-barrier-reef/train.csv')\ndf_train['img_path'] = os.path.join('../input/tensorflow-great-barrier-reef/train_images')+\"/video_\"+df_train.video_id.astype(str)+\"/\"+df_train.video_frame.astype(str)+\".jpg\"\ndf_train[10:]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### EDA","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(8, 5))\nsns.countplot(df_train['video_id'], color='blue')","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:52:35.763773Z","iopub.execute_input":"2021-12-26T14:52:35.764095Z","iopub.status.idle":"2021-12-26T14:52:36.032813Z","shell.execute_reply.started":"2021-12-26T14:52:35.764062Z","shell.execute_reply":"2021-12-26T14:52:36.031889Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[df_train['annotations'] != '[]']","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:52:39.568781Z","iopub.execute_input":"2021-12-26T14:52:39.569065Z","iopub.status.idle":"2021-12-26T14:52:39.594458Z","shell.execute_reply.started":"2021-12-26T14:52:39.569035Z","shell.execute_reply":"2021-12-26T14:52:39.593584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with_annotations = len(df_train[df_train['annotations'] != '[]'])\nwithout_annotations = len(df_train[df_train['annotations'] == '[]'])\n\nlabels = ['no bbox', 'yes bbox']\nfig = go.Figure([go.Bar(x=labels,\n                        y=[without_annotations, with_annotations],\n                        width=0.6)])\nfig.update_layout(autosize=False, width=700, height=400)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:52:42.044329Z","iopub.execute_input":"2021-12-26T14:52:42.044885Z","iopub.status.idle":"2021-12-26T14:52:42.172529Z","shell.execute_reply.started":"2021-12-26T14:52:42.044852Z","shell.execute_reply":"2021-12-26T14:52:42.171559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# creating new column which contains the total number of bounding boxes\ndf_train['no_bbox'] = df_train['annotations'].apply(lambda x: x.count('{'))\n\n# Example\n\nn = df_train['no_bbox'][12843]\nprint(df_train['annotations'][12843])\nprint(f'Number of bounding boxes are : {n}.')","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:53:27.373683Z","iopub.execute_input":"2021-12-26T14:53:27.373989Z","iopub.status.idle":"2021-12-26T14:53:27.401011Z","shell.execute_reply.started":"2021-12-26T14:53:27.373956Z","shell.execute_reply":"2021-12-26T14:53:27.400094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.bar(df_train['no_bbox'].value_counts().drop(0), title='Count of bounding boxes')\nfig.update_layout(autosize=False, width=700, height=400)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:53:40.241176Z","iopub.execute_input":"2021-12-26T14:53:40.241494Z","iopub.status.idle":"2021-12-26T14:53:41.177171Z","shell.execute_reply.started":"2021-12-26T14:53:40.241457Z","shell.execute_reply":"2021-12-26T14:53:41.176212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train['annotations'] = df_train['annotations'].apply(ast.literal_eval)\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:53:57.076226Z","iopub.execute_input":"2021-12-26T14:53:57.076538Z","iopub.status.idle":"2021-12-26T14:53:57.662076Z","shell.execute_reply.started":"2021-12-26T14:53:57.076506Z","shell.execute_reply":"2021-12-26T14:53:57.661189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df2 = df_train[df_train['annotations'].astype(str) != \"[]\"]\ndf2 = df2[df2['no_bbox'] == 5]\ndf2['annotations']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data Viz","metadata":{}},{"cell_type":"code","source":"def img_viz(df_train, id):\n    image = df_train['img_path'][id]\n    img = Image.open(image)\n    \n    for box in df_train['annotations'][id]:\n        top_left = \n        shape = [box['x'], box['y'], box['x']+box['width'], box['y']+box['height']]\n        ImageDraw.Draw(img).rectangle(shape, outline =\"red\", width=3)\n    display(img)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:54:06.1831Z","iopub.execute_input":"2021-12-26T14:54:06.183379Z","iopub.status.idle":"2021-12-26T14:54:06.190135Z","shell.execute_reply.started":"2021-12-26T14:54:06.18335Z","shell.execute_reply":"2021-12-26T14:54:06.188972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_viz(df_train=df_train, id=10759)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:12:32.483486Z","iopub.status.idle":"2021-12-26T14:12:32.484634Z","shell.execute_reply.started":"2021-12-26T14:12:32.484271Z","shell.execute_reply":"2021-12-26T14:12:32.484337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### References [https://www.kaggle.com/casfranco/eda-let-s-understand-the-data-protect-the-reef]\n\nContent\n* Video frames numbers\n* Train dataframe analysis: video analysis and annotations numbers (per video and sequence)\n* Visualizing some training examples using cv2","metadata":{}},{"cell_type":"code","source":"import os\nimport ast\nimport PIL\nimport cv2\nimport pandas as pd\nfrom os import listdir\nfrom os.path import isfile, join\nimport seaborn as sns\nimport plotly.express as px\nimport plotly.graph_objects as go","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:54:24.460663Z","iopub.execute_input":"2021-12-26T14:54:24.461578Z","iopub.status.idle":"2021-12-26T14:54:24.467307Z","shell.execute_reply.started":"2021-12-26T14:54:24.461518Z","shell.execute_reply":"2021-12-26T14:54:24.466711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Dataset overview","metadata":{}},{"cell_type":"markdown","source":"#### 1 - Video frame stats","metadata":{}},{"cell_type":"code","source":"DATA_PATH = '/kaggle/input/tensorflow-great-barrier-reef'\nimages_path = join(DATA_PATH,'train_images')\ndf_train = pd.read_csv(join(DATA_PATH,'train.csv'))","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:54:26.880132Z","iopub.execute_input":"2021-12-26T14:54:26.880792Z","iopub.status.idle":"2021-12-26T14:54:26.918548Z","shell.execute_reply.started":"2021-12-26T14:54:26.88073Z","shell.execute_reply":"2021-12-26T14:54:26.91759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# getting image paths from meta csv file\ndf_train['img_path'] = os.path.join(DATA_PATH, \"train_images\")+\"/video_\"+df_train.video_id.astype(str)+\"/\"+df_train.video_frame.astype(str)+\".jpg\"\ndf_train['img_path']","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:54:29.478092Z","iopub.execute_input":"2021-12-26T14:54:29.478588Z","iopub.status.idle":"2021-12-26T14:54:29.568448Z","shell.execute_reply.started":"2021-12-26T14:54:29.478536Z","shell.execute_reply":"2021-12-26T14:54:29.5676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\n\ndef video_stats(path):\n    # Lookfor files within video folder\n    onlyfiles = [f for f in listdir(path) if isfile(join(path, f))]\n    \n    # filter files by extension\n    onlyfiles = [f for f in onlyfiles if f.endswith(\".jpg\")]\n    im = Image.open(join(path, onlyfiles[0]))\n    width, height = im.size\n    \n    print(f'Number of frames: {len(onlyfiles)} ' )\n    print(f'Frames with size (w,h): ({width}, {height})')","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:54:45.002316Z","iopub.execute_input":"2021-12-26T14:54:45.003112Z","iopub.status.idle":"2021-12-26T14:54:45.010492Z","shell.execute_reply.started":"2021-12-26T14:54:45.00306Z","shell.execute_reply":"2021-12-26T14:54:45.0092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Video 0\nprint('Video 0 Stats:')\nvideo_stats(join(images_path,'video_0'))\n\n# Video 1\nprint(\"\\n\",'Video 1 Stats:')\nvideo_stats(join(images_path,'video_1'))\n\n# Video 2\nprint(\"\\n\",'Video 2 Stats:')\nvideo_stats(join(images_path,'video_2'))","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:54:47.832981Z","iopub.execute_input":"2021-12-26T14:54:47.833474Z","iopub.status.idle":"2021-12-26T14:55:02.222337Z","shell.execute_reply.started":"2021-12-26T14:54:47.833414Z","shell.execute_reply":"2021-12-26T14:55:02.22146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 2 - Train dataframe analysis\n\n* video_id - ID number of the video the image was part of. The video ids are not meaningfully ordered.\n* video_frame - The frame number of the image within the video. Expect to see occasional gaps in the frame number from when the diver surfaced.\n* sequence - ID of a gap-free subset of a given video. The sequence ids are not meaningfully ordered.\n* sequence_frame - The frame number within a given sequence.\n* image_id - ID code for the image, in the format '{video_id}-{video_frame}'\n* annotations - The bounding boxes of any starfish detections in a string format that can be evaluated directly with Python. Does not use the same format as the predictions you will submit. Not available in test.csv. A bounding box is described by the pixel coordinate (x_min, y_min) of its upper left corner within the image together with its width and height in pixels.","metadata":{}},{"cell_type":"markdown","source":"#### 2.1 - Video details ","metadata":{}},{"cell_type":"code","source":"# Plot the number of frames per video\ndf_train_video_group = df_train.groupby('video_id')['video_frame'].max()\nlabels = {'sequence':'Video id',\n          'value': 'No of frames',\n          'variable': 'Original Column Name'}\n\nfig = px.bar(df_train_video_group,\n            color=px.colors.qualitative.Plotly[:3],\n            labels=labels,\n            title='Number of frames per video ID')\n\nfig.update_layout(xaxis=dict(type='category'), showlegend=False)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:55:09.089803Z","iopub.execute_input":"2021-12-26T14:55:09.090232Z","iopub.status.idle":"2021-12-26T14:55:09.179781Z","shell.execute_reply.started":"2021-12-26T14:55:09.090202Z","shell.execute_reply":"2021-12-26T14:55:09.179191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_seq_gp = df_train.groupby('sequence')[['sequence_frame', 'video_id']].max().sort_values(by='video_id')\ndf_train_seq_gp['video_id'] = df_train_seq_gp['video_id'].astype(str)\n\nlabels = {'sequence':'Sequence id',\n          'value': 'No of frames',\n          'variable': 'Original Column Name'}\n\nfig = px.bar(df_train_seq_gp, \n             color=\"video_id\",\n             labels=labels,\n             title=\"Number Of Frames In Each Sequence\")\n\nfig.update_layout(xaxis=dict(type='category'), showlegend=True)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:55:15.786481Z","iopub.execute_input":"2021-12-26T14:55:15.787105Z","iopub.status.idle":"2021-12-26T14:55:15.879968Z","shell.execute_reply.started":"2021-12-26T14:55:15.787046Z","shell.execute_reply":"2021-12-26T14:55:15.878976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 2.2 - Anotation analysis","metadata":{}},{"cell_type":"code","source":"# Train stats\nwithout_anno = len(df_train[df_train['annotations'] == '[]'])\nwith_anno = len(df_train) - without_anno\n\ncolors = ['lightslategray',] * 2 \ncolors[1] = 'crimson'\nlabels = ['Without bbox','With bbox']\n\nfig = go.Figure([go.Bar(x=labels,\n                        y=[without_anno, with_anno],\n                        marker_color=px.colors.qualitative.Plotly[:2]\n                       )\n                ]\n               )\nfig.show()\nprint(f'Number of training samples: {len(df_train)}')\nprint(f'Training samples without object labels: {without_anno}')\nprint(f'Training samples with object labels: {with_anno}')","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:55:26.701686Z","iopub.execute_input":"2021-12-26T14:55:26.701975Z","iopub.status.idle":"2021-12-26T14:55:26.722967Z","shell.execute_reply.started":"2021-12-26T14:55:26.701946Z","shell.execute_reply":"2021-12-26T14:55:26.722248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train['annotations'] = df_train['annotations'].apply(lambda x: ast.literal_eval(x))\ndf_train['num_boxes'] = df_train['annotations'].apply(len)\ndf_train['video_id'] = df_train['video_id'].astype(str)\ndf_train['sequence'] = df_train['sequence'].astype(str)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:55:29.924383Z","iopub.execute_input":"2021-12-26T14:55:29.924727Z","iopub.status.idle":"2021-12-26T14:55:30.372531Z","shell.execute_reply.started":"2021-12-26T14:55:29.924686Z","shell.execute_reply":"2021-12-26T14:55:30.371781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:12:32.504807Z","iopub.status.idle":"2021-12-26T14:12:32.505431Z","shell.execute_reply.started":"2021-12-26T14:12:32.50516Z","shell.execute_reply":"2021-12-26T14:12:32.505185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_annotations_count = df_train.groupby('num_boxes')['annotations'].count()\ndf_annotations_count = df_annotations_count.drop([0])","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:55:32.466096Z","iopub.execute_input":"2021-12-26T14:55:32.466559Z","iopub.status.idle":"2021-12-26T14:55:32.475549Z","shell.execute_reply.started":"2021-12-26T14:55:32.466505Z","shell.execute_reply":"2021-12-26T14:55:32.474843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Information about the number of samples with bounding boxes\nfig = px.bar(df_annotations_count)\nfig.update_layout(xaxis=dict(type='category'), showlegend=False)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:55:32.938582Z","iopub.execute_input":"2021-12-26T14:55:32.939017Z","iopub.status.idle":"2021-12-26T14:55:33.017366Z","shell.execute_reply.started":"2021-12-26T14:55:32.938988Z","shell.execute_reply":"2021-12-26T14:55:33.016141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# View nunber of bounding boxes per frame in each sequence\nfig = px.histogram(df_train, x=\"sequence\", color=\"num_boxes\",\n             labels={\"sequence\":\"Sequence ID\", \"num_boxes\":\"N° of Boxes per frame\"},\n             title=\"Number of annotations in each sequence\")\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:55:35.64004Z","iopub.execute_input":"2021-12-26T14:55:35.640345Z","iopub.status.idle":"2021-12-26T14:55:36.045291Z","shell.execute_reply.started":"2021-12-26T14:55:35.640312Z","shell.execute_reply":"2021-12-26T14:55:36.044585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Viz some traininng examples","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nimport matplotlib.pyplot as plt\nimport numpy as np\n\ndef tf_load_img(img_path, reshape_to=None):\n    img = tf.io.read_file(img_path)\n    decoded_img = tf.image.decode_image(img, channels=3)\n    \n    if reshape_to is None:\n        return decoded_img\n    else:\n        resized_img = tf.image.resize(decoded_img, reshape_to)\n        return resized_img\n    \n\ndef get_tl_br(bbox):\n    top_left = (bbox['x'], bbox['y'])\n    bottom_right = (bbox['x'] + bbox['width'], bbox['y'] + bbox['height'])\n    return top_left, bottom_right\n\ndef plot_image(img_path, annotations=None, **kwargs):\n    \"\"\" Plot an image and bounding boxes \"\"\"\n    img = np.array(tf_load_img(img_path))\n    \n    if annotations:\n        plt.figure(figsize=(20,10))\n        for i, bbox in enumerate(annotations):\n            tl_box, br_box = get_tl_br(bbox)\n            img = cv2.rectangle(img, tl_box, br_box, (255-2*i,14*i,0), 4)\n        plt.imshow(img)\n        plt.axis(False)\n        plt.title(f\"Bounding boxes plotted: ({len(annotations)})\")\n    else:\n        plt.figure(figsize=(20,10))\n        plt.imshow(img)\n        plt.axis(False)\n        plt.title(\"No bounding boxes within the image\")\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:12:32.512735Z","iopub.status.idle":"2021-12-26T14:12:32.513374Z","shell.execute_reply.started":"2021-12-26T14:12:32.513101Z","shell.execute_reply":"2021-12-26T14:12:32.513126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_bbox_for_visualization = [1, 3, 5, 7, 15]\n\nfor num_bbox in sorted(num_bbox_for_visualization):\n    ex_row = df_train[df_train.num_boxes==num_bbox].reset_index(drop=True).iloc[0]\n    print(ex_row)\n    plot_image(**ex_row)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:12:32.514662Z","iopub.status.idle":"2021-12-26T14:12:32.515259Z","shell.execute_reply.started":"2021-12-26T14:12:32.515006Z","shell.execute_reply":"2021-12-26T14:12:32.515032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### References: https://www.kaggle.com/icaram/eda-non-annotated-starfish\n\nContent : Non-annotated starfishes are found\n* This notebook is to show image with bboxes and make videos\n* to check the jump of bbox number in the sequential video frames.","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport ast\nimport json\nimport subprocess\nfrom glob import glob\nfrom tqdm.notebook import tqdm\nfrom pprint import pprint\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom IPython.display import Video","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:57:35.783133Z","iopub.execute_input":"2021-12-26T14:57:35.783617Z","iopub.status.idle":"2021-12-26T14:57:35.791797Z","shell.execute_reply.started":"2021-12-26T14:57:35.783569Z","shell.execute_reply":"2021-12-26T14:57:35.790547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INPUT_PATH = '../input/tensorflow-great-barrier-reef'\nHEIGHT = 720 # image height\nWIDTH  = 1280 # image width\n\ndf_train = pd.read_csv(INPUT_PATH + '/train.csv')\ndisplay(df_train)\nprint(df_train.info())","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:57:37.494357Z","iopub.execute_input":"2021-12-26T14:57:37.494668Z","iopub.status.idle":"2021-12-26T14:57:37.565286Z","shell.execute_reply.started":"2021-12-26T14:57:37.494625Z","shell.execute_reply":"2021-12-26T14:57:37.564213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Change the type of 'annotations' from str to list\ndf_train['annotations'] = df_train['annotations'].apply(ast.literal_eval) # str -> list\n# Add columns of image path and number of bboxes, and the difference.\ndf_train['image_path'] = INPUT_PATH + '/train_images/video_' + df_train['video_id'].astype(str) + '/' + df_train['video_frame'].astype(str) + \".jpg\"\ndf_train['num_bboxes'] = df_train['annotations'].apply(lambda x: len(x))\ndf_train['diff_num_bboxes'] = df_train['num_bboxes'].diff().fillna(0).astype(int)\ndisplay(df_train)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:57:40.533528Z","iopub.execute_input":"2021-12-26T14:57:40.533858Z","iopub.status.idle":"2021-12-26T14:57:41.045744Z","shell.execute_reply.started":"2021-12-26T14:57:40.533827Z","shell.execute_reply":"2021-12-26T14:57:41.045101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Zooming into bboxes","metadata":{}},{"cell_type":"code","source":"sample_idx = 12637\nsample = df_train.iloc[sample_idx]\nprint(sample)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:57:43.421612Z","iopub.execute_input":"2021-12-26T14:57:43.422058Z","iopub.status.idle":"2021-12-26T14:57:43.430051Z","shell.execute_reply.started":"2021-12-26T14:57:43.422026Z","shell.execute_reply":"2021-12-26T14:57:43.429317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_bboxes(annotations):\n    \n    if len(annotations) == 0:\n        return []\n    \n    boxes = pd.DataFrame(annotations, columns=['x', 'y', 'width', 'height']).astype(np.int32).values\n    boxes[:, 2] = boxes[:, 0] + boxes[:, 2]\n    boxes[:, 3] = boxes[:, 1] + boxes[:, 3]\n    return boxes\n\ndef plot_img_and_bbox(img_path, anntations):\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    fig, ax = plt.subplots(1, 1, figsize=(16,10))\n    if len(annotations)>0:\n        bboxes = get_bboxes(annotations)\n        for i, box in enumerate(bboxes):\n            # pur bbox on image\n            cv2.rectangle(img,\n                          (box[0], box[1]),\n                          (box[2], box[3]),\n                          color = (255, 0, 0),\n                          thickness = 2)\n            # numbering\n            ax.text(box[0], box[1]-5, i+1, color='red')\n\n    ax.set_axis_off()\n    ax.imshow(img)\n    \ndef zoom_bbox(img_path, annotations):\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    bboxes = get_bboxes(annotations)\n    \n    col = 7 if len(bboxes)>=7 else len(bboxes)\n    row = np.ceil(len(bboxes)/7).astype(int) if len(bboxes)>7 else 1\n    fig, ax = plt.subplots(row, col, figsize=(col*2, row*3))\n    cnt = 0\n    for i in range(row):\n        \n        for j in range(col):\n                        \n            bbox = bboxes[cnt]\n            sliced_img = img[bbox[1]:bbox[3], bbox[0]:bbox[2]]\n            \n            if row==1:\n                ax[j].imshow(sliced_img)\n                ax[j].set_title(cnt+1, color='red')\n                ax[j].set_axis_off()\n            else:\n                ax[i,j].imshow(sliced_img)\n                ax[i,j].set_title(cnt+1, color='red')\n                ax[i,j].set_axis_off()\n                \n            cnt += 1\n            \n            if cnt==len(bboxes):\n                break\n    \n        if cnt==len(bboxes):\n            break      \n            \n    plt.show() ","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:57:48.187392Z","iopub.execute_input":"2021-12-26T14:57:48.187932Z","iopub.status.idle":"2021-12-26T14:57:48.205699Z","shell.execute_reply.started":"2021-12-26T14:57:48.18787Z","shell.execute_reply":"2021-12-26T14:57:48.205005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_path    = sample['image_path']\nannotations = sample['annotations']\nprint('image_id:', sample['image_id'])\n# plot image with bboxes\nplot_img_and_bbox(img_path, annotations)\n# plot zoom of bboxes\nzoom_bbox(img_path, annotations)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:57:51.046764Z","iopub.execute_input":"2021-12-26T14:57:51.047475Z","iopub.status.idle":"2021-12-26T14:57:52.465868Z","shell.execute_reply.started":"2021-12-26T14:57:51.04742Z","shell.execute_reply":"2021-12-26T14:57:52.46496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import subprocess\ndef get_img_width_annotations(img_path, annotations):\n    img = cv2.imread(img_path)\n    \n    video_id = img_path.split('/')[4].split('_')[1]\n    frame_id = sample['image_path'].split('/')[-1].split('.')[0]\n    \n    img_id = video_id + '-' + frame_id\n    \n    if len(annotations) > 0:\n        bboxes = get_bboxes(annotations)\n        for i, bbox in enumerate(bboxes):\n            # put bbox\n            cv2.rectangle(img,\n                         (bbox[0], bbox[1]),\n                         (bbox[2], bbox[3]),\n                         color=(0, 0, 255),\n                         thickness = 2)\n            \n    # put image_id, bbox\n    cv2.putText(img, \n               f'img_id: {img_id}, bbox: {len(annotations)}',\n               color = (0, 0, 255),\n               org = (30, 50),\n               fontFace=cv2.FONT_HERSHEY_SIMPLEX,\n               fontScale=1.0,\n               thickness=3)\n    return img\n\ndef make_video(df, video_id,\n               start_frame, end_frame,\n               fps=15,\n               width=WIDTH, height=HEIGHT):\n    '''\n    df          : DataFrame\n    video_id    : 0, 1, or 2\n    start_frame : video_frame at start of video\n    num_frame   : video_frame at end of video\n    return      : path to video\n    '''\n    \n    video_path = f'video_{video_id}_{start_frame}_to_{end_frame}.mp4'\n    tmp_path = 'tmp_' + video_path # video before encode (removed after encode)\n    \n    \n    video = cv2.VideoWriter(tmp_path,\n                            cv2.VideoWriter_fourcc(*'mp4v'),\n                            fps,\n                            (width, height)\n                           )\n    \n    df = df[df['video_id']==video_id].reset_index(drop=True)\n    print(df)\n    print()\n    \n    start_idx = df[df['video_frame']==start_frame].index[0]\n    print('start_index: ', start_idx)\n    \n    end_idx = df[df['video_frame']==end_frame].index[0]\n    print('end_index: ', end_idx)\n    \n    df = df.iloc[start_idx:end_idx]\n    print(df)\n    print()\n    \n    print('#####################################')\n    print(df.iterrows())\n    \n    for idx, row in tqdm(df.iterrows(), total=(len(df))):\n        print(f'idx: {idx}, row: {row}')\n        image_path = row['image_path']\n        annotations = row['annotations']\n        print();print()\n        \n        frame = get_img_width_annotations(image_path, annotations)\n        video.write(frame)\n        \n    video.release()\n    \n    if os.path.exists(video_path):\n        os.remove(video_path)\n    \n    # encode by ffmpeg command \n    subprocess.run(\n        ['ffmpeg', \n         '-i', tmp_path, \n         '-loglevel', 'quiet', \n         '-crf', '18', \n         '-preset', 'veryfast', \n         '-vcodec', 'libx264', \n         video_path]\n    )\n    \n    os.remove(tmp_path)\n    return video_path\n        ","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:59:05.228789Z","iopub.execute_input":"2021-12-26T14:59:05.229446Z","iopub.status.idle":"2021-12-26T14:59:05.246981Z","shell.execute_reply.started":"2021-12-26T14:59:05.229405Z","shell.execute_reply":"2021-12-26T14:59:05.245921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"video_id = sample['video_id']\nstart_frame = sample['video_frame'] - 100 # peek before 100 frames\nend_frame = sample['video_frame'] + 100 # peek before 100 frames","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:59:09.46825Z","iopub.execute_input":"2021-12-26T14:59:09.468981Z","iopub.status.idle":"2021-12-26T14:59:09.473822Z","shell.execute_reply.started":"2021-12-26T14:59:09.468935Z","shell.execute_reply":"2021-12-26T14:59:09.473073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(start_frame)\nprint(end_frame)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:59:11.695707Z","iopub.execute_input":"2021-12-26T14:59:11.696486Z","iopub.status.idle":"2021-12-26T14:59:11.701515Z","shell.execute_reply.started":"2021-12-26T14:59:11.696448Z","shell.execute_reply":"2021-12-26T14:59:11.700565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'video_id: {video_id}, video_frame: {start_frame} to {end_frame}')","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:59:18.986202Z","iopub.execute_input":"2021-12-26T14:59:18.986517Z","iopub.status.idle":"2021-12-26T14:59:18.991909Z","shell.execute_reply.started":"2021-12-26T14:59:18.986483Z","shell.execute_reply":"2021-12-26T14:59:18.990738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"make_video(df_train,\n            video_id=video_id,\n            start_frame=start_frame,\n            end_frame=end_frame)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:59:21.797859Z","iopub.execute_input":"2021-12-26T14:59:21.798442Z","iopub.status.idle":"2021-12-26T14:59:36.788329Z","shell.execute_reply.started":"2021-12-26T14:59:21.798405Z","shell.execute_reply":"2021-12-26T14:59:36.787044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'video_id: {video_id}, video_frame: {start_frame} to {end_frame}')\nprint('Create video ...')\nvideo_path = make_video(df_train,\n                        video_id=video_id,\n                        start_frame=start_frame,\n                        end_frame=end_frame)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:59:45.440806Z","iopub.execute_input":"2021-12-26T14:59:45.441116Z","iopub.status.idle":"2021-12-26T14:59:59.016887Z","shell.execute_reply.started":"2021-12-26T14:59:45.441086Z","shell.execute_reply":"2021-12-26T14:59:59.015716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import Video\nVideo(video_path, width=WIDTH*0.7, height=HEIGHT*0.7)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T14:59:59.02294Z","iopub.execute_input":"2021-12-26T14:59:59.023232Z","iopub.status.idle":"2021-12-26T14:59:59.030273Z","shell.execute_reply.started":"2021-12-26T14:59:59.023199Z","shell.execute_reply":"2021-12-26T14:59:59.029708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}