{"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":"# ISLR: Improved Landmarks Animation with selected landmark lists\n\n\nThis notebook is mainly based on the [notebook of BILZARD](https://www.kaggle.com/code/tatamikenn/islr-eda-let-s-get-landmarks-animated)\n------------------------------------------------------------------\n## Abstract\nIn this notebook, I tried basic EDA.\nIn the latter part, I made animated GIF of sampled landmarks.\n\n## Change History\n\n* version1: plot whole body\n* version2: plot only upper body (since leg part sometimes contains noise)\n* version3: output in mp4 format\n* version4: interpolate missing frames","metadata":{}},{"cell_type":"code","source":"!pip install nb-black","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-04-07T04:28:11.481080Z","iopub.execute_input":"2023-04-07T04:28:11.481524Z","iopub.status.idle":"2023-04-07T04:28:21.170608Z","shell.execute_reply.started":"2023-04-07T04:28:11.481490Z","shell.execute_reply":"2023-04-07T04:28:21.169648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from typing import Dict\nfrom pathlib import Path\nfrom types import SimpleNamespace\nfrom multiprocessing import Pool\nfrom functools import partial\n\nimport polars as pl\nimport matplotlib.pyplot as plt\nimport matplotlib.animation as animation\nfrom IPython.core.display import Video\nfrom tqdm import tqdm\n\nplt.style.use(\"ggplot\")\n\ncfg = SimpleNamespace()\ncfg.INPUT = Path(\"/kaggle/input/asl-signs\")\ncfg.OUTPUT = Path(\"/kaggle/working/animation\")\ncfg.DEBUG = True\n\n%load_ext lab_black\n%load_ext autoreload\n%autoreload 2","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-04-07T04:28:21.172369Z","iopub.execute_input":"2023-04-07T04:28:21.172675Z","iopub.status.idle":"2023-04-07T04:28:21.221119Z","shell.execute_reply.started":"2023-04-07T04:28:21.172646Z","shell.execute_reply":"2023-04-07T04:28:21.219319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pl.read_csv(cfg.INPUT / \"train.csv\")","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-04-07T04:28:21.223339Z","iopub.execute_input":"2023-04-07T04:28:21.223777Z","iopub.status.idle":"2023-04-07T04:28:21.275888Z","shell.execute_reply.started":"2023-04-07T04:28:21.223733Z","shell.execute_reply":"2023-04-07T04:28:21.274260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"#unique participants: {len(train['participant_id'].unique())}\")\nprint(f\"#unique sequence: {len(train['sequence_id'].unique()):,}\")\nprint(f\"#unique signs: {len(train['sign'].unique()):,}\")","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-04-07T04:28:21.279345Z","iopub.execute_input":"2023-04-07T04:28:21.279799Z","iopub.status.idle":"2023-04-07T04:28:21.322959Z","shell.execute_reply.started":"2023-04-07T04:28:21.279753Z","shell.execute_reply":"2023-04-07T04:28:21.321744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sequence_per_participant = (\n    train.groupby(\"participant_id\")\n    .agg(pl.col(\"sequence_id\").unique().count())\n    .with_columns(pl.col(\"participant_id\").cast(str))\n)\n\n_, ax = plt.subplots()\nax.barh(\n    y=sequence_per_participant[\"participant_id\"],\n    width=sequence_per_participant[\"sequence_id\"],\n)\nax.set(xlabel=\"#sequences\", ylabel=\"participant_id\", title=\"#sequences per participant\")\nplt.show()","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-04-07T04:28:21.324169Z","iopub.execute_input":"2023-04-07T04:28:21.325277Z","iopub.status.idle":"2023-04-07T04:28:21.604879Z","shell.execute_reply.started":"2023-04-07T04:28:21.325198Z","shell.execute_reply":"2023-04-07T04:28:21.604050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sequence_per_sign = (\n    train.groupby(\"sign\").agg(pl.col(\"sequence_id\").count()).sort(\"sequence_id\")\n)\n_, ax = plt.subplots()\nax.hist(sequence_per_sign[\"sequence_id\"], bins=20)\nax.set(xlabel=\"#sequences/sign\", ylabel=\"count\", title=\"#sequences per sign\")\nplt.show()","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-04-07T04:28:21.605905Z","iopub.execute_input":"2023-04-07T04:28:21.606419Z","iopub.status.idle":"2023-04-07T04:28:21.834140Z","shell.execute_reply.started":"2023-04-07T04:28:21.606389Z","shell.execute_reply":"2023-04-07T04:28:21.832205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Skeletical data","metadata":{}},{"cell_type":"code","source":"edges = {\n    \"left_hand\": [\n        (0, 1),\n        (1, 2),\n        (2, 3),\n        (3, 4),\n        (0, 5),\n        (0, 17),\n        (5, 6),\n        (6, 7),\n        (7, 8),\n        (5, 9),\n        (9, 10),\n        (10, 11),\n        (11, 12),\n        (9, 13),\n        (13, 14),\n        (14, 15),\n        (15, 16),\n        (13, 17),\n        (17, 18),\n        (18, 19),\n        (19, 20),\n    ],\n    \"right_hand\": [\n        (0, 1),\n        (1, 2),\n        (2, 3),\n        (3, 4),\n        (0, 5),\n        (0, 17),\n        (5, 6),\n        (6, 7),\n        (7, 8),\n        (5, 9),\n        (9, 10),\n        (10, 11),\n        (11, 12),\n        (9, 13),\n        (13, 14),\n        (14, 15),\n        (15, 16),\n        (13, 17),\n        (17, 18),\n        (18, 19),\n        (19, 20),\n    ],\n    \"pose\": [\n        (8, 6),\n        (6, 5),\n        (6, 4),\n        (4, 0),\n        (0, 1),\n        (1, 2),\n        (2, 3),\n        (3, 7),\n        (10, 9),\n        (11, 12),\n        (11, 13),\n        (11, 23),\n        (13, 15),\n        (15, 21),\n        (15, 17),\n        (15, 19),\n        (17, 19),\n        (12, 14),\n        (12, 24),\n        (14, 16),\n        (16, 22),\n        (16, 20),\n        (16, 18),\n        (18, 20),\n        (23, 24),\n        # (24, 26),\n        # (26, 28),\n        # (28, 30),\n        # (28, 32),\n        # (30, 32),\n        # (23, 25),\n        # (25, 27),\n        # (27, 29),\n        # (27, 31),\n        # (29, 31),\n    ],\n}","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-04-07T04:28:21.835612Z","iopub.execute_input":"2023-04-07T04:28:21.836037Z","iopub.status.idle":"2023-04-07T04:28:21.888122Z","shell.execute_reply.started":"2023-04-07T04:28:21.836006Z","shell.execute_reply":"2023-04-07T04:28:21.886105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lm_data = {k: v for k, v in zip(train.columns, train.row(0))}\n\ndf_landmark = pl.read_parquet(cfg.INPUT / lm_data[\"path\"])\nlm_first_frame = df_landmark.partition_by(\"frame\")[0]\nlms = lm_first_frame.partition_by(\"type\")\n\n_, axes = plt.subplots(2, 2, figsize=(8, 8))\naxes = axes.ravel()\n\nfor lm, ax in zip(lms, axes):\n    lm = lm.filter((pl.col(\"type\") != \"pose\") | (pl.col(\"landmark_index\") < 25))\n    lm_type = lm.row(0)[2]\n    ax.scatter(lm[\"x\"], 1 - lm[\"y\"])\n    if lm_type != \"face\":\n        for row in lm.iter_rows():\n            dt = {k: v for k, v in zip(lm.columns, row)}\n            x, y, idx = dt[\"x\"], dt[\"y\"], dt[\"landmark_index\"]\n\n            if (x is not None) & (y is not None):\n                ax.text(x, 1 - y, idx)\n    if lm_type in [\"left_hand\", \"right_hand\", \"pose\"]:\n        for edge in edges[lm_type]:\n            i, j = edge\n            x1, x2, y1, y2 = lm[\"x\"][i], lm[\"x\"][j], lm[\"y\"][i], lm[\"y\"][j]\n            if not ((x1 is None) | (x2 is None) | (y1 is None) | (y2 is None)):\n                ax.plot((x1, x2), (1 - y1, 1 - y2), color=\"gray\")\n    ax.set(title=f\"{lm_type}\")","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-04-07T04:28:21.890420Z","iopub.execute_input":"2023-04-07T04:28:21.890860Z","iopub.status.idle":"2023-04-07T04:28:22.722719Z","shell.execute_reply.started":"2023-04-07T04:28:21.890821Z","shell.execute_reply":"2023-04-07T04:28:22.720752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dt = {k: v for k, v in zip(lm.columns, row)}\ndt","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:22.724397Z","iopub.execute_input":"2023-04-07T04:28:22.724816Z","iopub.status.idle":"2023-04-07T04:28:22.760828Z","shell.execute_reply.started":"2023-04-07T04:28:22.724775Z","shell.execute_reply":"2023-04-07T04:28:22.759068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## show the landmark strcuture with four parts\n### Total landmarks = 468 + 33 + 21(left) + 21(right) = 543\n### (33 pose landmarks, 468 face landmarks, and 21 hand landmarks per hand).","metadata":{}},{"cell_type":"code","source":"lms","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:22.764917Z","iopub.execute_input":"2023-04-07T04:28:22.765865Z","iopub.status.idle":"2023-04-07T04:28:22.802073Z","shell.execute_reply.started":"2023-04-07T04:28:22.765828Z","shell.execute_reply":"2023-04-07T04:28:22.800308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Let's take the face landmarks as a example","metadata":{}},{"cell_type":"code","source":"lm_data = {k: v for k, v in zip(train.columns, train.row(0))}\n\ndf_landmark = pl.read_parquet(cfg.INPUT / lm_data[\"path\"])\nlm_first_frame = df_landmark.partition_by(\"frame\")[0]\nlms = lm_first_frame.partition_by(\"type\")\n\n_, axes = plt.subplots(2, 2, figsize=(8, 8))\naxes = axes.ravel()\n\nfor lm, ax in zip(lms, axes):\n    break\nlm","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2023-04-07T04:28:22.803627Z","iopub.execute_input":"2023-04-07T04:28:22.804048Z","iopub.status.idle":"2023-04-07T04:28:23.283273Z","shell.execute_reply.started":"2023-04-07T04:28:22.804011Z","shell.execute_reply":"2023-04-07T04:28:23.281887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# show all index\n\n\n# for lm, ax in zip(lms, axes):\n#     break\n# # lm\n\n_, axes = plt.subplots(1, 1, figsize=(8, 8))\n# axes = axes.ravel()\nax = axes\n\nlm_type = lm.row(0)[2]\nax.scatter(lm[\"x\"], 1 - lm[\"y\"])\n\nfor row in lm.iter_rows():\n    dt = {k: v for k, v in zip(lm.columns, row)}\n    x, y, idx = dt[\"x\"], dt[\"y\"], dt[\"landmark_index\"]\n\n    if (x is not None) & (y is not None):\n        ax.text(x, 1 - y, idx)\nax.set(title=f\"{lm_type}\")","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:23.284474Z","iopub.execute_input":"2023-04-07T04:28:23.284746Z","iopub.status.idle":"2023-04-07T04:28:25.122226Z","shell.execute_reply.started":"2023-04-07T04:28:23.284721Z","shell.execute_reply":"2023-04-07T04:28:25.120988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Notebook https://www.kaggle.com/code/dschettler8845/gislr-learn-eda-baseline\n# use the following points for facial landmarks\n# let us take a close lookat\nlm_list = [\n    0,\n    9,\n    11,\n    13,\n    14,\n    17,\n    117,\n    118,\n    119,\n    199,\n    346,\n    347,\n    348,\n]\nlm[lm_list, :]","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:25.123351Z","iopub.execute_input":"2023-04-07T04:28:25.123849Z","iopub.status.idle":"2023-04-07T04:28:25.164654Z","shell.execute_reply.started":"2023-04-07T04:28:25.123816Z","shell.execute_reply":"2023-04-07T04:28:25.163396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_, axes = plt.subplots(1, 1, figsize=(8, 8))\n# axes = axes.ravel()\nax = axes\nlm1 = lm\nlm0 = lm[lm_list, :]\nlm = lm0\n\nlm_type = lm.row(0)[2]\nax.scatter(lm[\"x\"], 1 - lm[\"y\"])\n\nfor row in lm.iter_rows():\n    dt = {k: v for k, v in zip(lm.columns, row)}\n    x, y, idx = dt[\"x\"], dt[\"y\"], dt[\"landmark_index\"]\n\n    if (x is not None) & (y is not None):\n        ax.text(x, 1 - y, idx)\n\nax.set(title=f\"{lm_type}\")","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:25.167137Z","iopub.execute_input":"2023-04-07T04:28:25.167605Z","iopub.status.idle":"2023-04-07T04:28:25.441613Z","shell.execute_reply.started":"2023-04-07T04:28:25.167563Z","shell.execute_reply":"2023-04-07T04:28:25.440109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# we can draw them on top of the whole face landmarks\n\nlm_data = {k: v for k, v in zip(train.columns, train.row(0))}\n\ndf_landmark = pl.read_parquet(cfg.INPUT / lm_data[\"path\"])\nlm_first_frame = df_landmark.partition_by(\"frame\")[0]\nlms = lm_first_frame.partition_by(\"type\")\n\n# _, axes = plt.subplots(2, 2, figsize=(8, 8))\n# axes = axes.ravel()\nfake_axes = [1, 2, 3, 4]\nfor lm, ax in zip(lms, fake_axes):\n    break\n# lm\n\n\n_, axes = plt.subplots(1, 1, figsize=(8, 8))\n# axes = axes.ravel()\nax = axes\nlm1 = lm\nlm0 = lm1[lm_list, :]\n\nlm = lm1\nax.scatter(lm[\"x\"], 1 - lm[\"y\"])\n\nfor row in lm.iter_rows():\n    dt = {k: v for k, v in zip(lm.columns, row)}\n    x, y, idx = dt[\"x\"], dt[\"y\"], dt[\"landmark_index\"]\n\n#     if (x is not None) & (y is not None):\n#         ax.text(x, 1 - y, idx)\n\nlm = lm0\nlm_type = lm.row(0)[2]\nax.scatter(lm[\"x\"], 1 - lm[\"y\"], facecolor=\"green\")\n\nfor row in lm.iter_rows():\n    dt = {k: v for k, v in zip(lm.columns, row)}\n    x, y, idx = dt[\"x\"], dt[\"y\"], dt[\"landmark_index\"]\n\n    if (x is not None) & (y is not None):\n        ax.text(x, 1 - y, idx)\n\n\nax.set(title=f\"{lm_type}\")","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:25.443222Z","iopub.execute_input":"2023-04-07T04:28:25.443623Z","iopub.status.idle":"2023-04-07T04:28:25.742190Z","shell.execute_reply.started":"2023-04-07T04:28:25.443581Z","shell.execute_reply":"2023-04-07T04:28:25.740621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# another landmark list for lips\nlm_list2 = [\n    61,\n    185,\n    40,\n    39,\n    37,\n    0,\n    267,\n    269,\n    270,\n    409,\n    291,\n    146,\n    91,\n    181,\n    84,\n    17,\n    314,\n    405,\n    321,\n    375,\n    78,\n    191,\n    80,\n    81,\n    82,\n    13,\n    312,\n    311,\n    310,\n    415,\n    95,\n    88,\n    178,\n    87,\n    14,\n    317,\n    402,\n    318,\n    324,\n    308,\n]\nlm1[lm_list2, :]","metadata":{"scrolled":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-04-07T04:28:25.743901Z","iopub.execute_input":"2023-04-07T04:28:25.744601Z","iopub.status.idle":"2023-04-07T04:28:25.789258Z","shell.execute_reply.started":"2023-04-07T04:28:25.744528Z","shell.execute_reply":"2023-04-07T04:28:25.787618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_, axes = plt.subplots(1, 1, figsize=(8, 8))\n# axes = axes.ravel()\nax = axes\n# lm1 = lm\n# lm0 = lm1[lm_list, :]\nlm2 = lm1[lm_list2, :]\n\nlm = lm1\nax.scatter(lm[\"x\"], 1 - lm[\"y\"])\n\nfor row in lm.iter_rows():\n    dt = {k: v for k, v in zip(lm.columns, row)}\n    x, y, idx = dt[\"x\"], dt[\"y\"], dt[\"landmark_index\"]\n\n#     if (x is not None) & (y is not None):\n#         ax.text(x, 1 - y, idx)\n\nlm = lm2\nlm_type = lm.row(0)[2]\nax.scatter(lm[\"x\"], 1 - lm[\"y\"], facecolor=\"green\")\n\nfor row in lm.iter_rows():\n    dt = {k: v for k, v in zip(lm.columns, row)}\n    x, y, idx = dt[\"x\"], dt[\"y\"], dt[\"landmark_index\"]\n\n    if (x is not None) & (y is not None):\n        ax.text(x, 1 - y, idx)\n\n\nax.set(title=f\"{lm_type}\")","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:25.790777Z","iopub.execute_input":"2023-04-07T04:28:25.791122Z","iopub.status.idle":"2023-04-07T04:28:26.161018Z","shell.execute_reply.started":"2023-04-07T04:28:25.791091Z","shell.execute_reply":"2023-04-07T04:28:26.159698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lm_data","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:26.163467Z","iopub.execute_input":"2023-04-07T04:28:26.163916Z","iopub.status.idle":"2023-04-07T04:28:26.200896Z","shell.execute_reply.started":"2023-04-07T04:28:26.163873Z","shell.execute_reply":"2023-04-07T04:28:26.199141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# I didn't modify the rest of the notebook.","metadata":{}},{"cell_type":"code","source":"_, axes = plt.subplots(1, 3, figsize=(12, 4))\n\nfor ax, col in zip(axes, [\"x\", \"y\", \"z\"]):\n    ax.hist(df_landmark[col], bins=20, alpha=0.5, label=col)\n    ax.set(xlabel=col)\nplt.suptitle(\"Distribution of axes of normalized coordinate\")\nplt.show()","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-04-07T04:28:26.202468Z","iopub.execute_input":"2023-04-07T04:28:26.202775Z","iopub.status.idle":"2023-04-07T04:28:26.652763Z","shell.execute_reply.started":"2023-04-07T04:28:26.202747Z","shell.execute_reply":"2023-04-07T04:28:26.651074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Making Amination","metadata":{}},{"cell_type":"code","source":"def make_animation(row, columns, fps: int = 10):\n    data = {k: v for k, v in zip(columns, row)}\n    sign, participant_id, sequence_id = (\n        data[\"sign\"],\n        data[\"participant_id\"],\n        data[\"sequence_id\"],\n    )\n\n    df_landmark = pl.read_parquet(cfg.INPUT / data[\"path\"])\n    use_cols = [\"x\", \"y\", \"z\"]\n    df_landmark = df_landmark.sort([\"frame\", \"type\", \"landmark_index\"]).with_columns(\n        [pl.col(col).interpolate().over([\"type\", \"landmark_index\"]) for col in use_cols]\n    )\n\n    fig, axes = plt.subplots(2, 2, figsize=(8, 8))\n    axes = axes.ravel()\n\n    lms_all = df_landmark.partition_by(\"frame\")\n\n    def draw_frame(frame):\n        lms = lms_all[frame].partition_by(\"type\")\n\n        for lm, ax in zip(lms, axes):\n            lm = lm.filter((pl.col(\"type\") != \"pose\") | (pl.col(\"landmark_index\") < 25))\n            ax.cla()\n            lm_type = lm.row(0)[2]\n            frame = lm.row(0)[0]\n\n            ax.scatter(lm[\"x\"], 1 - lm[\"y\"])\n            if lm_type != \"face\":\n                for row in lm.iter_rows():\n                    dt = {k: v for k, v in zip(lm.columns, row)}\n                    if (dt[\"x\"] is not None) & (dt[\"y\"] is not None):\n                        ax.text(dt[\"x\"], 1 - dt[\"y\"], dt[\"landmark_index\"])\n            if lm_type in [\"left_hand\", \"right_hand\", \"pose\"]:\n                for edge in edges[lm_type]:\n                    i, j = edge\n                    x1, x2, y1, y2 = lm[\"x\"][i], lm[\"x\"][j], lm[\"y\"][i], lm[\"y\"][j]\n                    if not ((x1 is None) | (x2 is None) | (y1 is None) | (y2 is None)):\n                        ax.plot((x1, x2), (1 - y1, 1 - y2), color=\"gray\")\n            ax.set(title=f\"{lm_type}\")\n        plt.suptitle(f'sign: \"{sign}\" [frame={frame}]')\n\n    ani = animation.FuncAnimation(\n        fig, draw_frame, frames=range(len(lms_all)), interval=1000 / fps\n    )\n\n    if not (cfg.OUTPUT / sign).exists():\n        (cfg.OUTPUT / sign).mkdir()\n    ani.save(\n        cfg.OUTPUT / sign / f\"{participant_id}_{sequence_id}.mp4\",\n        writer=\"ffmpeg\",\n        fps=fps,\n        codec=\"h264\",\n    )\n    plt.close(fig)","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2023-04-07T04:28:26.654910Z","iopub.execute_input":"2023-04-07T04:28:26.655541Z","iopub.status.idle":"2023-04-07T04:28:26.713647Z","shell.execute_reply.started":"2023-04-07T04:28:26.655502Z","shell.execute_reply":"2023-04-07T04:28:26.712055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Choose 5 samples per each group","metadata":{}},{"cell_type":"code","source":"train_unique_signs = train.filter(\n    (pl.arange(0, pl.count())).shuffle(seed=42).over(\"sign\") < 5\n)","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:26.714986Z","iopub.execute_input":"2023-04-07T04:28:26.715363Z","iopub.status.idle":"2023-04-07T04:28:26.762446Z","shell.execute_reply.started":"2023-04-07T04:28:26.715328Z","shell.execute_reply":"2023-04-07T04:28:26.761167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_unique_signs.groupby(\"sign\").agg(pl.count()).head()","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:26.764077Z","iopub.execute_input":"2023-04-07T04:28:26.764495Z","iopub.status.idle":"2023-04-07T04:28:26.801894Z","shell.execute_reply.started":"2023-04-07T04:28:26.764453Z","shell.execute_reply":"2023-04-07T04:28:26.800369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not cfg.OUTPUT.exists():\n    cfg.OUTPUT.mkdir()\n\nif cfg.DEBUG:\n    df = train_unique_signs.head(4)\nelse:\n    df = train_unique_signs\n\nfor row in tqdm(df.iter_rows(), total=len(df)):\n    make_animation(row, df.columns)","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:28:26.804127Z","iopub.execute_input":"2023-04-07T04:28:26.804696Z","iopub.status.idle":"2023-04-07T04:29:50.460364Z","shell.execute_reply.started":"2023-04-07T04:28:26.804642Z","shell.execute_reply":"2023-04-07T04:29:50.459277Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!du -sh animation","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:29:50.461604Z","iopub.execute_input":"2023-04-07T04:29:50.462559Z","iopub.status.idle":"2023-04-07T04:29:50.759302Z","shell.execute_reply.started":"2023-04-07T04:29:50.462523Z","shell.execute_reply":"2023-04-07T04:29:50.757957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!tree animation | head","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:29:50.760716Z","iopub.execute_input":"2023-04-07T04:29:50.762042Z","iopub.status.idle":"2023-04-07T04:29:51.069460Z","shell.execute_reply.started":"2023-04-07T04:29:50.761993Z","shell.execute_reply":"2023-04-07T04:29:51.067856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Generated Animations\n\nYou can access to the full 250 class of signs in [ISLR: Animated 250 Sampled Signs](https://www.kaggle.com/datasets/tatamikenn/islr-animation-250-signs).\n","metadata":{}},{"cell_type":"code","source":"!cp animation/all/26734_1247514751.mp4 sample001.mp4\n!cp animation/bug/61333_1268993802.mp4 sample002.mp4\n!cp animation/lion/29302_1271911796.mp4 sample003.mp4\n!cp animation/TV/28656_125816896.mp4 sample004.mp4","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:29:51.071124Z","iopub.execute_input":"2023-04-07T04:29:51.071540Z","iopub.status.idle":"2023-04-07T04:29:52.187430Z","shell.execute_reply.started":"2023-04-07T04:29:51.071499Z","shell.execute_reply":"2023-04-07T04:29:52.185686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Video(\"sample001.mp4\")","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:29:52.189039Z","iopub.execute_input":"2023-04-07T04:29:52.189999Z","iopub.status.idle":"2023-04-07T04:29:52.228512Z","shell.execute_reply.started":"2023-04-07T04:29:52.189953Z","shell.execute_reply":"2023-04-07T04:29:52.226247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Video(\"sample002.mp4\")","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:29:52.236038Z","iopub.execute_input":"2023-04-07T04:29:52.236506Z","iopub.status.idle":"2023-04-07T04:29:52.274442Z","shell.execute_reply.started":"2023-04-07T04:29:52.236465Z","shell.execute_reply":"2023-04-07T04:29:52.272112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Video(\"sample003.mp4\")","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:29:52.276105Z","iopub.execute_input":"2023-04-07T04:29:52.277271Z","iopub.status.idle":"2023-04-07T04:29:52.316856Z","shell.execute_reply.started":"2023-04-07T04:29:52.277179Z","shell.execute_reply":"2023-04-07T04:29:52.314387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Video(\"sample004.mp4\")","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:29:52.319253Z","iopub.execute_input":"2023-04-07T04:29:52.319719Z","iopub.status.idle":"2023-04-07T04:29:52.356382Z","shell.execute_reply.started":"2023-04-07T04:29:52.319685Z","shell.execute_reply":"2023-04-07T04:29:52.355209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!zip -r animation.zip {cfg.OUTPUT.relative_to(\"/kaggle/working\")} && rm -rf {cfg.OUTPUT}","metadata":{"execution":{"iopub.status.busy":"2023-04-07T04:29:52.358541Z","iopub.execute_input":"2023-04-07T04:29:52.359459Z","iopub.status.idle":"2023-04-07T04:29:52.720820Z","shell.execute_reply.started":"2023-04-07T04:29:52.359411Z","shell.execute_reply":"2023-04-07T04:29:52.719258Z"},"trusted":true},"execution_count":null,"outputs":[]}]}