{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":52950,"databundleVersionId":5973250,"sourceType":"competition"}],"dockerImageVersionId":30527,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"A quick notebook to extract animated landmarks from the Parquet files.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"# Processing","metadata":{}},{"cell_type":"markdown","source":"Let's start by processing a Parquet file to extract the (x, y, z) values. Notice that we need to order the landmarks so that\nthey are correctly displayed later.","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\nlandmark_id = \"1019715464\"\nlandamarks_path = f\"../input/asl-fingerspelling/train_landmarks/{landmark_id}.parquet\"\nlandmarks_df = pd.read_parquet(landamarks_path)\n\ndef get_landmarks(landmark=\"right\", \n                  frame=0, \n                  sequence_id=1975541698):\n    df = (landmarks_df.loc[sequence_id]\n                        .loc[lambda df: df[\"frame\"] == frame]\n                        .loc[:, lambda df: df.columns.str.contains(landmark)]\n                        .reset_index(drop=True))\n    d = df.stack().to_dict()\n    data = []\n    for k, v in d.items():\n        coordinate = k[1].split(\"_\")[0]\n        index = k[1].split(\"_\")[-1]\n        data.append({\"coordinate\": coordinate, \"index\": index, \"value\": v})\n\n    df = pd.DataFrame(data)\n    if df.empty:\n        return []\n    landmarks = []\n    for g, v in df.groupby(\"index\"):\n        landmarks.insert(int(g), v.set_index(\"coordinate\")\n                                  .to_dict()[\"value\"])\n    return landmarks","metadata":{"execution":{"iopub.status.busy":"2023-11-20T16:58:33.72542Z","iopub.execute_input":"2023-11-20T16:58:33.72583Z","iopub.status.idle":"2023-11-20T16:58:54.317539Z","shell.execute_reply.started":"2023-11-20T16:58:33.725799Z","shell.execute_reply":"2023-11-20T16:58:54.316344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_landmarks()","metadata":{"execution":{"iopub.status.busy":"2023-11-20T16:58:54.319924Z","iopub.execute_input":"2023-11-20T16:58:54.320255Z","iopub.status.idle":"2023-11-20T16:58:54.362606Z","shell.execute_reply.started":"2023-11-20T16:58:54.320226Z","shell.execute_reply":"2023-11-20T16:58:54.36152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Plotting utils functions","metadata":{}},{"cell_type":"markdown","source":"Here are some utility functions to plot the landmarks. We will also need to install [MediaPipe](https://developers.google.com/mediapipe) package.","metadata":{}},{"cell_type":"code","source":"!pip install mediapipe","metadata":{"execution":{"iopub.status.busy":"2023-11-20T16:58:54.365771Z","iopub.execute_input":"2023-11-20T16:58:54.366161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfrom mediapipe import solutions\nfrom mediapipe.framework.formats import landmark_pb2\n\n\ndef draw_hand_landmarks_on_image(img, hand_landmarks_collection):\n    # Draw the hand landmarks.\n    img = np.copy(img)\n    for hand_landmarks in hand_landmarks_collection:\n        hand_landmarks_proto = landmark_pb2.NormalizedLandmarkList()\n        hand_landmarks_proto.landmark.extend([\n          landmark_pb2.NormalizedLandmark(x=landmark[\"x\"], \n                                          y=landmark[\"y\"], \n                                          z=landmark[\"z\"]) \n          for landmark in hand_landmarks\n        ])\n        solutions.drawing_utils.draw_landmarks(\n          img,\n          hand_landmarks_proto,\n          solutions.hands.HAND_CONNECTIONS,\n          solutions.drawing_styles.get_default_hand_landmarks_style(),\n          solutions.drawing_styles.get_default_hand_connections_style())\n\n    return img\n\n\ndef draw_pose_landmark_on_image(img, pose_landmarks):\n    img = np.copy(img)\n    pose_landmarks_proto = landmark_pb2.NormalizedLandmarkList()\n    pose_landmarks_proto.landmark.extend([\n      landmark_pb2.NormalizedLandmark(x=landmark[\"x\"], \n                                      y=landmark[\"y\"], \n                                      z=landmark[\"z\"]) \n      for landmark in pose_landmarks\n    ])\n    solutions.drawing_utils.draw_landmarks(\n      img,\n      pose_landmarks_proto,\n      solutions.pose.POSE_CONNECTIONS,\n      solutions.drawing_styles.get_default_pose_landmarks_style())\n\n    return img","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pylab as plt\nleft_landmarks = get_landmarks(landmark=\"left\", frame=0)\nright_landmarks = get_landmarks(landmark=\"right\", frame=0)\nimg = 255 * np.zeros((512, 256, 3)).astype(np.uint8)\nimg = draw_hand_landmarks_on_image(img, [left_landmarks, right_landmarks])\nplt.imshow(img)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# From static to animated","metadata":{}},{"cell_type":"markdown","source":"Let's finish this short notebook with an animated plot.","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\nsequence_id = 1975541698\npose_img = 255 * np.zeros((512, 256, 3)).astype(np.uint8)\npose_img = np.stack([draw_pose_landmark_on_image(pose_img, get_landmarks(sequence_id=sequence_id, \n                                                           frame=frame_id, \n                                                           landmark=\"pose\")\n                                                       ) for frame_id in range(10)])\n\n\nfig = px.imshow(pose_img, animation_frame=0, binary_string=True, labels=dict(animation_frame=\"slice\"))\nfig.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I hope this was useful!","metadata":{}}]}