{"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":"# Data Exploration","metadata":{}},{"cell_type":"code","source":"# 下载数据集\n\nimport numpy as np\nimport pandas as pd\nimport cv2\nfrom pathlib import Path\nfrom colorama import Fore, Back, Style\nimport matplotlib.pyplot as plt\nimport ipywidgets as widgets\nfrom IPython.display import display, Image\n\n\nROOT_DIR = Path(\"/kaggle/input/tensorflow-great-barrier-reef\")\n\nTRAIN_CSV = ROOT_DIR / \"train.csv\"\nTRAIN_DF = pd.read_csv(TRAIN_CSV)\n\nTEST_CSV = ROOT_DIR / \"test.csv\"\nTEST_DF = pd.read_csv(TEST_CSV)\n\nlist(ROOT_DIR.iterdir())","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-12-01T12:44:18.051177Z","iopub.execute_input":"2021-12-01T12:44:18.051849Z","iopub.status.idle":"2021-12-01T12:44:18.464272Z","shell.execute_reply.started":"2021-12-01T12:44:18.051733Z","shell.execute_reply":"2021-12-01T12:44:18.463465Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 用常用的东西来扩充","metadata":{}},{"cell_type":"code","source":"import json\n\n# 计数检测\nif \"detection_count\" not in TRAIN_DF.columns:\n    det_counts = TRAIN_DF.apply(lambda row: len(eval(row.annotations)), axis=1)\n    TRAIN_DF[\"detection_count\"] = det_counts","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:18.465901Z","iopub.execute_input":"2021-12-01T12:44:18.466133Z","iopub.status.idle":"2021-12-01T12:44:19.242608Z","shell.execute_reply.started":"2021-12-01T12:44:18.466104Z","shell.execute_reply":"2021-12-01T12:44:19.241797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 列","metadata":{}},{"cell_type":"code","source":"print(TRAIN_DF.info())\nprint()","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:19.243867Z","iopub.execute_input":"2021-12-01T12:44:19.244112Z","iopub.status.idle":"2021-12-01T12:44:19.270157Z","shell.execute_reply.started":"2021-12-01T12:44:19.244081Z","shell.execute_reply":"2021-12-01T12:44:19.269032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### sequence_frame与video_frame","metadata":{}},{"cell_type":"code","source":"eq_frames = TRAIN_DF[TRAIN_DF[\"video_frame\"] == TRAIN_DF[\"sequence_frame\"]]\nuneq_frames = TRAIN_DF[TRAIN_DF[\"video_frame\"] != TRAIN_DF[\"sequence_frame\"]]\nprint(\"eq frames, uneq frames:\", eq_frames.size, uneq_frames.size)\nprint()\n#序列从0开始，可能在看不到海星的地方剪辑了视频\n#视频被分割成序列，每个序列从0帧到n帧","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:19.271627Z","iopub.execute_input":"2021-12-01T12:44:19.271923Z","iopub.status.idle":"2021-12-01T12:44:19.2819Z","shell.execute_reply.started":"2021-12-01T12:44:19.27189Z","shell.execute_reply":"2021-12-01T12:44:19.280914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## sequence_frames从0到N","metadata":{}},{"cell_type":"code","source":"print(\"Sequence frames sequential and start from 0?\")\nfor seq_name in TRAIN_DF[\"sequence\"].unique():\n    sequential = True\n    numbers = TRAIN_DF[TRAIN_DF[\"sequence\"] == seq_name][\"sequence_frame\"].values\n    numbers.sort()\n    \n    i = 0\n    for num in numbers:\n        while i < num:\n            print(f\"Seq {seq_name}: {Fore.RED}Missing {i}{Fore.RESET}\")\n            i += 1\n        i += 1\n\n    if sequential:\n        print(f\"Seq {seq_name}: {Fore.GREEN}Yes{Fore.RESET}\")\nprint()\n# 可以  ","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:19.284841Z","iopub.execute_input":"2021-12-01T12:44:19.285174Z","iopub.status.idle":"2021-12-01T12:44:19.332005Z","shell.execute_reply.started":"2021-12-01T12:44:19.28513Z","shell.execute_reply":"2021-12-01T12:44:19.331429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### video_frames顺序","metadata":{}},{"cell_type":"code","source":"print(\"Video frames sequential?\")\nfor seq_name in TRAIN_DF[\"sequence\"].unique():\n    sequential = True\n    numbers = TRAIN_DF[TRAIN_DF[\"sequence\"] == seq_name][\"video_frame\"].values\n    numbers.sort()\n    \n    i = numbers[0]\n    for num in numbers:\n        while i < num:\n            print(f\"Seq {seq_name}: {Fore.RED}Missing {i}{Fore.RESET}\")\n            i += 1\n        i += 1\n\n    if sequential:\n        print(f\"Seq {seq_name}: {Fore.GREEN}Yes{Fore.RESET}\")\nprint()\n#在评估时是否会给出顺序数据。\n# image id是否只连接frame id和video id \nnew_vid_ids = TRAIN_DF[\"video_id\"].astype(str) + \"-\" + TRAIN_DF[\"video_frame\"].astype(str)\nprint(\"How many images have strange image_ids:\", (TRAIN_DF[\"image_id\"] != new_vid_ids).sum())\n# 是的","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:19.33326Z","iopub.execute_input":"2021-12-01T12:44:19.333511Z","iopub.status.idle":"2021-12-01T12:44:19.4619Z","shell.execute_reply.started":"2021-12-01T12:44:19.333481Z","shell.execute_reply":"2021-12-01T12:44:19.460964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 视频独特的序列名¶","metadata":{}},{"cell_type":"code","source":"vid_seq_pairs = TRAIN_DF[[\"video_id\", \"sequence\"]].drop_duplicates()\nrepeated_sequence_count = (vid_seq_pairs[\"sequence\"].value_counts() != 1).sum()\nprint(\"How many repeated sequences:\", repeated_sequence_count)\n# 序列是唯一的","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:19.464459Z","iopub.execute_input":"2021-12-01T12:44:19.46469Z","iopub.status.idle":"2021-12-01T12:44:19.477251Z","shell.execute_reply.started":"2021-12-01T12:44:19.464663Z","shell.execute_reply":"2021-12-01T12:44:19.476386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##注释的分发","metadata":{}},{"cell_type":"code","source":"print(f\"Starfish per image:\", TRAIN_DF[\"detection_count\"].value_counts())\n\nbin_count = len(TRAIN_DF[\"detection_count\"].unique())\nplot = TRAIN_DF.hist(column=\"detection_count\", figsize=(16,6), bins=bin_count)\nax = plot[0][0]\nax.set_title(\"Starfish count, per image\")\n\nTRAIN_DF_WITH_STARFISH = TRAIN_DF[TRAIN_DF[\"detection_count\"] > 0]\nbin_count = len(TRAIN_DF_WITH_STARFISH[\"detection_count\"].unique())\nplot = TRAIN_DF_WITH_STARFISH.hist(column=\"detection_count\", figsize=(16,4), bins=bin_count)\nax = plot[0][0]\nax.set_title(\"Starfish count, per image (with 0 detections removed)\");","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:19.478158Z","iopub.execute_input":"2021-12-01T12:44:19.478391Z","iopub.status.idle":"2021-12-01T12:44:20.112579Z","shell.execute_reply.started":"2021-12-01T12:44:19.478356Z","shell.execute_reply":"2021-12-01T12:44:20.111526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 在帧中检测如何改变的","metadata":{}},{"cell_type":"code","source":"import math \n\n\nSEQUENCE_COUNT = len(TRAIN_DF[\"sequence\"].drop_duplicates())\nFIG_COLS = 3\nFIG_ROWS = math.ceil(SEQUENCE_COUNT / FIG_COLS)\nfig = plt.figure(figsize=(30, 30), constrained_layout=True)\n# fig.tight_layout(pad=10.0)\n# fig.tight_layout()\n\ndet_data = TRAIN_DF[[\"sequence\", \"video_id\", \"sequence_frame\", \"detection_count\"]].drop_duplicates()\nfor i, seq_num in enumerate(det_data[\"sequence\"].unique()):  # we know seq numbers are unique in train data\n    #获取数据\n    seq_data = det_data[det_data[\"sequence\"] == seq_num].sort_values(by=\"sequence_frame\")\n    seq_data = seq_data.set_index(seq_data[\"sequence_frame\"]).drop(columns=\"sequence_frame\")\n    video_id = seq_data[\"video_id\"].iloc[0]\n    \n    #选择图形位置\n    col = (i % FIG_COLS) + 1\n    row = (i // FIG_COLS) + 1\n    \n    #细节\n    ax = plt.subplot(FIG_ROWS, FIG_COLS, i+1)\n    ax = seq_data[\"detection_count\"].plot.line(ax=ax)\n    ax.set_title(f\"Video {video_id}, Sequence {seq_num}\", fontsize=22)\n    ax.yaxis.set_major_locator(plt.MaxNLocator(integer=True))\n    ax.set_xlabel('Detections', fontsize=16)\n    ax.set_ylabel('Sequence Frame', fontsize=16)\n    \n","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:20.114386Z","iopub.execute_input":"2021-12-01T12:44:20.114779Z","iopub.status.idle":"2021-12-01T12:44:25.452116Z","shell.execute_reply.started":"2021-12-01T12:44:20.11473Z","shell.execute_reply":"2021-12-01T12:44:25.451395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 注释","metadata":{}},{"cell_type":"code","source":"#缓存\nvideo_ids = TRAIN_DF[\"video_id\"].unique()\nsel_video_id = 0\nsel_video_df = TRAIN_DF[TRAIN_DF[\"video_id\"] == sel_video_id]\n\nsequences = sel_video_df[\"sequence\"].unique()\nsel_sequence = sequences[0]\nsel_sequence_df = sel_video_df[sel_video_df[\"sequence\"] == sel_sequence]\n\nlast_frame = sel_sequence_df[\"sequence_frame\"].max()\nsel_sequence_frame = 0\nsel_sequence_frames = sel_sequence_df[sel_sequence_df[\"sequence_frame\"] == sel_sequence_frame]\nassert len(sel_sequence_frames) == 1\nsel_video_frame = sel_sequence_frames[\"video_frame\"].values[0]\nsel_annotation = eval(sel_sequence_frames[\"annotations\"].values[0])\n  \n#UI元素\ndd_video_id = widgets.Dropdown(options=video_ids, description='Video ID:')\ndd_sequence = widgets.Dropdown(options=sequences, description='Sequence:')\nbtn_first = widgets.Button(description=\"⏮️\")\nbtn_back_50 = widgets.Button(description=\"⏪\")\nbtn_back = widgets.Button(description=\"◀️\")\nbtn_forward = widgets.Button(description=\"▶️\")\nbtn_forward_50 = widgets.Button(description=\"⏩\")\nbtn_last = widgets.Button(description=\"⏯\")\n\nout = widgets.Output()\n\ndd_row = widgets.HBox([dd_video_id, dd_sequence])\nbtn_row = widgets.HBox([btn_first, btn_back_50, btn_back, btn_forward, btn_forward_50, btn_last])\nall_widgets = widgets.VBox([dd_row, btn_row, out])\n\n#选择助手-只更改数据\ndef set_frame(new_number):\n    global sel_sequence_frame\n    global sel_sequence_frames\n    global sel_video_frame\n    global sel_annotation\n    \n    sel_sequence_frame = max(0, min(new_number, last_frame))\n    sel_sequence_frames = sel_sequence_df[sel_sequence_df[\"sequence_frame\"] == sel_sequence_frame]\n    assert len(sel_sequence_frames) == 1\n    sel_video_frame = sel_sequence_frames[\"video_frame\"].values[0]\n    \n    sel_annotation = eval(sel_sequence_frames[\"annotations\"].values[0])\n\ndef set_sequence(new_number):\n    global sel_sequence\n    global sel_sequence_df\n    global last_frame\n\n    sel_sequence = new_number\n    sel_sequence_df = sel_video_df[sel_video_df[\"sequence\"] == sel_sequence]\n    last_frame = sel_sequence_df[\"sequence_frame\"].max()\n\n    set_frame(0)\n    \ndef set_video_id(new_id):\n    global sel_video_id\n    global sel_video_df\n    global sequences\n    \n    sel_video_id = new_id\n    sel_video_df = TRAIN_DF[TRAIN_DF[\"video_id\"] == sel_video_id]\n\n    sequences = sel_video_df[\"sequence\"].unique()\n    set_sequence(sequences[0])\n    \n#UI助手-处理UI事件+调用选择助手\ndef clear_output():\n    out.clear_output()\n    \ndef draw_image():\n    img_path = ROOT_DIR / \"train_images\" / f\"video_{sel_video_id}\" / f\"{sel_video_frame}.jpg\"\n    assert img_path.is_file(), f\"Cannot find image {img_path}\"\n    cv_img = cv2.imread(str(img_path))\n    cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)\n    \n    draw_bboxes(cv_img, sel_annotation)\n\n    with out:\n        print(\"Image\", img_path)\n\n        #找到一种方法来更新图像而不清除输出\n        img_fig = plt.figure(figsize=(20,16), facecolor=\"#123456ff\", frameon=False)\n        img_ax = img_fig.add_subplot(1, 1, 1)\n        img_ax.get_xaxis().set_visible(False)\n        img_ax.get_yaxis().set_visible(False)\n        img_ax.use_sticky_edges = False\n        # img_ax.margins(x=0)  \n        #用颜色透明代替作为一个hack。\n\n        img_ax.imshow(cv_img)\n        plt.show()\n\n    \ndef draw_bboxes(cv_img, annotations):\n    BBOX_COLOR_RGB = (255,126,0)\n    for ann in annotations:\n        cv2.rectangle(\n            cv_img,\n            (ann[\"x\"] ,ann[\"y\"]),\n            (ann[\"x\"] + ann[\"width\"], ann[\"y\"] + ann[\"height\"]),\n            color=BBOX_COLOR_RGB,\n            thickness=3\n        )\n\ndef on_click_forward(b):\n    with out:\n        set_frame(sel_sequence_frame + 1)\n        clear_output()\n        draw_image()\nbtn_forward.on_click(on_click_forward)\ndef on_click_back(b):\n    with out:\n        set_frame(sel_sequence_frame - 1)\n        clear_output()\n        draw_image()\nbtn_back.on_click(on_click_back)\ndef on_click_forward_50(b):\n    with out:\n        set_frame(sel_sequence_frame + 50)\n        clear_output()\n        draw_image()\nbtn_forward_50.on_click(on_click_forward_50)\ndef on_click_back_50(b):\n    with out:\n        set_frame(sel_sequence_frame - 50)\n        clear_output()\n        draw_image()\nbtn_back_50.on_click(on_click_back_50)\ndef on_click_first(b):\n    with out:\n        set_frame(0)\n        clear_output()\n        draw_image()\nbtn_first.on_click(on_click_first)\ndef on_click_last(b):\n    with out:\n        set_frame(last_frame)\n        clear_output()\n        draw_image()\nbtn_last.on_click(on_click_last)\n\ndef on_sequence_change(change):\n    with out:\n        if change[\"old\"] == change[\"new\"]:\n            return\n        set_sequence(change[\"new\"])\n\n        clear_output()\n        draw_image()\ndd_sequence.observe(on_sequence_change, names=\"value\")\n\ndef on_video_id_change(change):\n    with out:\n        if change[\"old\"] == change[\"new\"]:\n            return\n        set_video_id(change[\"new\"])\n        dd_sequence.options = sequences\n        \n        clear_output()\n        draw_image()\ndd_video_id.observe(on_video_id_change, names=\"value\")\n\n\ndisplay(all_widgets)\ndraw_image()","metadata":{"execution":{"iopub.status.busy":"2021-12-01T12:44:25.453778Z","iopub.execute_input":"2021-12-01T12:44:25.454224Z","iopub.status.idle":"2021-12-01T12:44:26.35124Z","shell.execute_reply.started":"2021-12-01T12:44:25.454171Z","shell.execute_reply":"2021-12-01T12:44:26.350533Z"},"trusted":true},"execution_count":null,"outputs":[]}]}