From 719632926d617cf16620bb35330b7ecaa6bab9e2 Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Sat, 27 Apr 2024 08:04:15 -0500 Subject: [PATCH 01/12] added csv outline code --- PrototypeR2.ipynb | 619 +++++++++++++++++++--------------------------- 1 file changed, 249 insertions(+), 370 deletions(-) diff --git a/PrototypeR2.ipynb b/PrototypeR2.ipynb index 2aa3392..f195cd8 100644 --- a/PrototypeR2.ipynb +++ b/PrototypeR2.ipynb @@ -1,27 +1,13 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "provenance": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, "cells": [ { "cell_type": "markdown", - "source": [ - "# **STEP ONE**" - ], "metadata": { "id": "uGVhyDnnPJsx" - } + }, + "source": [ + "# **STEP ONE**" + ] }, { "cell_type": "code", @@ -36,15 +22,20 @@ }, { "cell_type": "markdown", - "source": [ - "# **STEP TWO**" - ], "metadata": { "id": "8-SUS1VRPXny" - } + }, + "source": [ + "# **STEP TWO**" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "whZwvEdKIksm" + }, + "outputs": [], "source": [ "import mediapipe as mp\n", "from mediapipe.tasks import python\n", @@ -63,21 +54,19 @@ "import io\n", "\n", "import matplotlib.pyplot as plt\n", - "\n", "import time\n", - "\n", "import os\n", - "\n", - "import glob" - ], - "metadata": { - "id": "whZwvEdKIksm" - }, - "execution_count": null, - "outputs": [] + "import glob\n", + "import csv" + ] }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "RHyJwan8acCz" + }, + "outputs": [], "source": [ "# Class that is able to conviently store all poselandmarker data\n", "# Input a poselandmarker dstruct and it outputs the x y or z of any specific body part\n", @@ -128,236 +117,37 @@ " return np.arccos(np.dot((pointax, pointay, pointaz), (pointcx, pointcy, pointcz)) / (np.sqrt(pointax**2 + pointay**2 + pointaz**2) * np.sqrt(pointcx**2 + pointcy**2 + pointcz**2))) * 180 / np.pi\n", "\n", " def feedback(self, exercise):\n", - " if exercise == \"squat\":\n", - " left_hkh = self.angle(self.left_heel, self.left_knee, self.left_hip)\n", - " right_hkh = self.angle(self.right_heel, self.right_knee, self.right_hip)\n", - " left_khs = self.angle(self.left_knee, self.left_hip, self.left_shoulder)\n", - " right_khs = self.angle(self.right_knee, self.right_hip, self.right_shoulder)\n", - "\n", - " if (left_hkh >= 150) or (right_hkh >= 150):\n", - " if (left_khs >= 150) or (right_khs >= 150):\n", - " return \"Bad Form - Back Not Straight At Beginning\"\n", - " else: # In the squat\n", - " if (left_hkh > 100) or (right_hkh > 100):\n", - " return \"Bad Form - Squat Not Deep Enough\"\n", - " if not ((left_khs - 15) <= left_hkh <= (left_khs + 20)):\n", - " return \"Bad Form - Back not straight in Squat\"\n", - "\n", - " return \"Good Form\"" - ], - "metadata": { - "id": "RHyJwan8acCz" - }, - "execution_count": null, - "outputs": [] + " with open('{exercise}.csv') as anglefile:\n", + " anglereader = csv.reader(anglefile)\n", + " for row in anglereader:\n", + " print(row)" + ] }, { "cell_type": "markdown", + "metadata": { + "id": "e1sSWM10JfE7" + }, "source": [ "Make sure to import **Pose Landmarker Lite** into Drive folder before next step\n", "\n", "Can be found in Drive folder: https://drive.google.com/drive/folders/1RFTh9ed50zVZaIyutPCo6-VTEQanqE4_?usp=sharing\n", "\n", "If needed, download latest from MediaPipe website: https://developers.google.com/mediapipe/solutions/vision/pose_landmarker/index#models" - ], - "metadata": { - "id": "e1sSWM10JfE7" - } + ] }, { "cell_type": "markdown", - "source": [ - "# **STEP THREE**" - ], "metadata": { "id": "h7suIPY_PbaD" - } + }, + "source": [ + "# **STEP THREE**" + ] }, { "cell_type": "code", - "source": [ - "model_path = '/content/drive/MyDrive/Exercise App Resources/pose_landmarker_lite.task'\n", - "BaseOptions = python.BaseOptions # Basic Options Object\n", - "PoseLandmarker = vision.PoseLandmarker # Pose Landmarker Model Object\n", - "PoseLandmarkerOptions = vision.PoseLandmarkerOptions # Overall Options Object\n", - "VisionRunningMode = vision.RunningMode # Mode Object (Image, Video, Livestream)\n", - "PoseLandmarkerResult = vision.PoseLandmarkerResult # Stores result from model\n", - "out_video = cv.VideoWriter('/content/drive/MyDrive/Exercise App Resources/Videos/' + time.asctime(time.localtime()) + '.mp4',cv.VideoWriter_fourcc(*'DIVX'), 24, (640, 480))\n", - "landmarks_list = []\n", - "feedback_list = [\"\"]\n", - "\n", - "# Create a pose landmarker instance with the live stream mode:\n", - "def print_result(result: PoseLandmarkerResult, output_image: mp.Image, timestamp_ms: int):\n", - " if result.pose_landmarks:\n", - " annotated_image = np.copy(output_image.numpy_view())\n", - " landmarks_list.append(result.pose_landmarks[0]) # Adds landmark data for pic to list\n", - " for landmark in result.pose_landmarks[0]:\n", - " pose_landmarks_proto = landmark_pb2.NormalizedLandmarkList()\n", - " pose_landmarks_proto.landmark.extend(\n", - " [landmark_pb2.NormalizedLandmark(x=landmark.x, y=landmark.y, z=landmark.z) for landmark in result.pose_landmarks[0]])\n", - " solutions.drawing_utils.draw_landmarks(\n", - " annotated_image,\n", - " pose_landmarks_proto,\n", - " solutions.pose.POSE_CONNECTIONS,\n", - " solutions.drawing_styles.get_default_pose_landmarks_style())\n", - "\n", - " # print(\"Frame\", timestamp_ms)\n", - " lol = lm_dstruct(landmarks_list[-1])\n", - " feedback_temp = lol.feedback(\"squat\")\n", - " if feedback_list[-1] != feedback_temp:\n", - " print(feedback_temp)\n", - " feedback_list.append(feedback_temp)\n", - " out_video.write(annotated_image)\n", - "\n", - "options = PoseLandmarkerOptions(\n", - " base_options=BaseOptions(model_asset_path=model_path),\n", - " running_mode=VisionRunningMode.LIVE_STREAM,\n", - " result_callback=print_result) # Callback function to deal w/ results\n", - "\n", - "\n", - "### CAMERA FUNCTIONALITY ###\n", - "\n", - "def jsob_to_image(js_object):\n", - " # decode base64 image\n", - " image_bytes = b64decode(js_object.split(',')[1])\n", - " # convert bytes to numpy array\n", - " img_array = np.frombuffer(image_bytes, dtype=np.uint8)\n", - " # convert numpy array into OpenCV BGR\n", - " frame = cv.imdecode(img_array, flags=1)\n", - "\n", - " return frame\n", - "\n", - "def video_stream():\n", - " js = Javascript('''\n", - " var video;\n", - " var div = null;\n", - " var stream;\n", - " var captureCanvas;\n", - " var imgElement;\n", - " var labelElement;\n", - "\n", - " var pendingResolve = null;\n", - " var shutdown = false;\n", - "\n", - " function removeDom() {\n", - " stream.getVideoTracks()[0].stop();\n", - " video.remove();\n", - " div.remove();\n", - " video = null;\n", - " div = null;\n", - " stream = null;\n", - " imgElement = null;\n", - " captureCanvas = null;\n", - " labelElement = null;\n", - " }\n", - "\n", - " function onAnimationFrame() {\n", - " if (!shutdown) {\n", - " window.requestAnimationFrame(onAnimationFrame);\n", - " }\n", - " if (pendingResolve) {\n", - " var result = \"\";\n", - " if (!shutdown) {\n", - " captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);\n", - " result = captureCanvas.toDataURL('image/jpeg', 0.8)\n", - " }\n", - " var lp = pendingResolve;\n", - " pendingResolve = null;\n", - " lp(result);\n", - " }\n", - " }\n", - "\n", - " async function createDom() {\n", - " if (div !== null) {\n", - " return stream;\n", - " }\n", - " div = document.createElement('div');\n", - " div.style.border = '2px solid black';\n", - " div.style.padding = '3px';\n", - " div.style.width = '100%';\n", - " div.style.maxWidth = '600px';\n", - " document.body.appendChild(div);\n", - "\n", - "\n", - " video = document.createElement('video');\n", - " video.style.display = 'block';\n", - " video.width = div.clientWidth - 6;\n", - " video.setAttribute('playsinline', '');\n", - " video.onclick = () => { shutdown = true; };\n", - " stream = await navigator.mediaDevices.getUserMedia(\n", - " {video: { facingMode: \"environment\"}});\n", - " div.appendChild(video);\n", - " imgElement = document.createElement('img');\n", - " imgElement.style.position = 'absolute';\n", - " imgElement.style.zIndex = 1;\n", - " imgElement.onclick = () => { shutdown = true; };\n", - " div.appendChild(imgElement);\n", - "\n", - " const instruction = document.createElement('div');\n", - " instruction.innerHTML =\n", - " '' +\n", - " 'click here to stop the video';\n", - " div.appendChild(instruction);\n", - " instruction.onclick = () => { shutdown = true; };\n", - "\n", - " video.srcObject = stream;\n", - " await video.play();\n", - " captureCanvas = document.createElement('canvas');\n", - " captureCanvas.width = 640;\n", - " captureCanvas.height = 480;\n", - " window.requestAnimationFrame(onAnimationFrame);\n", - "\n", - " return stream;\n", - " }\n", - " async function stream_frame() {\n", - " if (shutdown) {\n", - " removeDom();\n", - " shutdown = false;\n", - " return '';\n", - " }\n", - " var preCreate = Date.now();\n", - " stream = await createDom();\n", - "\n", - " var preShow = Date.now();\n", - "\n", - "\n", - "\n", - " var preCapture = Date.now();\n", - " var result = await new Promise(function(resolve, reject) {\n", - " pendingResolve = resolve;\n", - " });\n", - " shutdown = false;\n", - "\n", - " return {'create': preShow - preCreate,\n", - " 'show': preCapture - preShow,\n", - " 'capture': Date.now() - preCapture,\n", - " 'img': result};\n", - " }\n", - " ''')\n", - "\n", - " display(js)\n", - "\n", - "def video_frame():\n", - " data = eval_js('stream_frame()')\n", - " return data\n", - "\n", - "### END OF CAMERA CODE ###\n", - "\n", - "with PoseLandmarker.create_from_options(options) as landmarker:\n", - " frame_timestamp_ms = 0\n", - " video_stream()\n", - " while True:\n", - " frame_timestamp_ms += 1\n", - " frame_js = video_frame()\n", - " if not frame_js:\n", - " break\n", - " img = jsob_to_image(frame_js[\"img\"])\n", - " mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=img)\n", - "\n", - " landmarker.detect_async(mp_image, frame_timestamp_ms)\n", - "\n", - "out_video.release()" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -366,128 +156,20 @@ "id": "GHzmhoO6Jc50", "outputId": "9aaa88fa-87c2-4c10-9b49-e0afad3188a2" }, - "execution_count": null, "outputs": [ { - "output_type": "display_data", "data": { + "application/javascript": "\n var video;\n var div = null;\n var stream;\n var captureCanvas;\n var imgElement;\n var labelElement;\n\n var pendingResolve = null;\n var shutdown = false;\n\n function removeDom() {\n stream.getVideoTracks()[0].stop();\n video.remove();\n div.remove();\n video = null;\n div = null;\n stream = null;\n imgElement = null;\n captureCanvas = null;\n labelElement = null;\n }\n\n function onAnimationFrame() {\n if (!shutdown) {\n window.requestAnimationFrame(onAnimationFrame);\n }\n if (pendingResolve) {\n var result = \"\";\n if (!shutdown) {\n captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);\n result = captureCanvas.toDataURL('image/jpeg', 0.8)\n }\n var lp = pendingResolve;\n pendingResolve = null;\n lp(result);\n }\n }\n\n async function createDom() {\n if (div !== null) {\n return stream;\n }\n div = document.createElement('div');\n div.style.border = '2px solid black';\n div.style.padding = '3px';\n div.style.width = '100%';\n div.style.maxWidth = '600px';\n document.body.appendChild(div);\n\n\n video = document.createElement('video');\n video.style.display = 'block';\n video.width = div.clientWidth - 6;\n video.setAttribute('playsinline', '');\n video.onclick = () => { shutdown = true; };\n stream = await navigator.mediaDevices.getUserMedia(\n {video: { facingMode: \"environment\"}});\n div.appendChild(video);\n imgElement = document.createElement('img');\n imgElement.style.position = 'absolute';\n imgElement.style.zIndex = 1;\n imgElement.onclick = () => { shutdown = true; };\n div.appendChild(imgElement);\n\n const instruction = document.createElement('div');\n instruction.innerHTML =\n '' +\n 'click here to stop the video';\n div.appendChild(instruction);\n instruction.onclick = () => { shutdown = true; };\n\n video.srcObject = stream;\n await video.play();\n captureCanvas = document.createElement('canvas');\n captureCanvas.width = 640;\n captureCanvas.height = 480;\n window.requestAnimationFrame(onAnimationFrame);\n\n return stream;\n }\n async function stream_frame() {\n if (shutdown) {\n removeDom();\n shutdown = false;\n return '';\n }\n var preCreate = Date.now();\n stream = await createDom();\n\n var preShow = Date.now();\n\n\n\n var preCapture = Date.now();\n var result = await new Promise(function(resolve, reject) {\n pendingResolve = resolve;\n });\n shutdown = false;\n\n return {'create': preShow - preCreate,\n 'show': preCapture - preShow,\n 'capture': Date.now() - preCapture,\n 'img': result};\n }\n ", "text/plain": [ "" - ], - "application/javascript": [ - "\n", - " var video;\n", - " var div = null;\n", - " var stream;\n", - " var captureCanvas;\n", - " var imgElement;\n", - " var labelElement;\n", - "\n", - " var pendingResolve = null;\n", - " var shutdown = false;\n", - "\n", - " function removeDom() {\n", - " stream.getVideoTracks()[0].stop();\n", - " video.remove();\n", - " div.remove();\n", - " video = null;\n", - " div = null;\n", - " stream = null;\n", - " imgElement = null;\n", - " captureCanvas = null;\n", - " labelElement = null;\n", - " }\n", - "\n", - " function onAnimationFrame() {\n", - " if (!shutdown) {\n", - " window.requestAnimationFrame(onAnimationFrame);\n", - " }\n", - " if (pendingResolve) {\n", - " var result = \"\";\n", - " if (!shutdown) {\n", - " captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);\n", - " result = captureCanvas.toDataURL('image/jpeg', 0.8)\n", - " }\n", - " var lp = pendingResolve;\n", - " pendingResolve = null;\n", - " lp(result);\n", - " }\n", - " }\n", - "\n", - " async function createDom() {\n", - " if (div !== null) {\n", - " return stream;\n", - " }\n", - " div = document.createElement('div');\n", - " div.style.border = '2px solid black';\n", - " div.style.padding = '3px';\n", - " div.style.width = '100%';\n", - " div.style.maxWidth = '600px';\n", - " document.body.appendChild(div);\n", - "\n", - "\n", - " video = document.createElement('video');\n", - " video.style.display = 'block';\n", - " video.width = div.clientWidth - 6;\n", - " video.setAttribute('playsinline', '');\n", - " video.onclick = () => { shutdown = true; };\n", - " stream = await navigator.mediaDevices.getUserMedia(\n", - " {video: { facingMode: \"environment\"}});\n", - " div.appendChild(video);\n", - " imgElement = document.createElement('img');\n", - " imgElement.style.position = 'absolute';\n", - " imgElement.style.zIndex = 1;\n", - " imgElement.onclick = () => { shutdown = true; };\n", - " div.appendChild(imgElement);\n", - "\n", - " const instruction = document.createElement('div');\n", - " instruction.innerHTML =\n", - " '' +\n", - " 'click here to stop the video';\n", - " div.appendChild(instruction);\n", - " instruction.onclick = () => { shutdown = true; };\n", - "\n", - " video.srcObject = stream;\n", - " await video.play();\n", - " captureCanvas = document.createElement('canvas');\n", - " captureCanvas.width = 640;\n", - " captureCanvas.height = 480;\n", - " window.requestAnimationFrame(onAnimationFrame);\n", - "\n", - " return stream;\n", - " }\n", - " async function stream_frame() {\n", - " if (shutdown) {\n", - " removeDom();\n", - " shutdown = false;\n", - " return '';\n", - " }\n", - " var preCreate = Date.now();\n", - " stream = await createDom();\n", - "\n", - " var preShow = Date.now();\n", - "\n", - "\n", - "\n", - " var preCapture = Date.now();\n", - " var result = await new Promise(function(resolve, reject) {\n", - " pendingResolve = resolve;\n", - " });\n", - " shutdown = false;\n", - "\n", - " return {'create': preShow - preCreate,\n", - " 'show': preCapture - preShow,\n", - " 'capture': Date.now() - preCapture,\n", - " 'img': result};\n", - " }\n", - " " ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Bad Form - Squat Not Deep Enough\n", "Bad Form - Back Not Straight At Beginning\n", @@ -674,24 +356,205 @@ "Good Form\n" ] } + ], + "source": [ + "model_path = '/content/drive/MyDrive/Exercise App Resources/pose_landmarker_lite.task'\n", + "BaseOptions = python.BaseOptions # Basic Options Object\n", + "PoseLandmarker = vision.PoseLandmarker # Pose Landmarker Model Object\n", + "PoseLandmarkerOptions = vision.PoseLandmarkerOptions # Overall Options Object\n", + "VisionRunningMode = vision.RunningMode # Mode Object (Image, Video, Livestream)\n", + "PoseLandmarkerResult = vision.PoseLandmarkerResult # Stores result from model\n", + "out_video = cv.VideoWriter('/content/drive/MyDrive/Exercise App Resources/Videos/' + time.asctime(time.localtime()) + '.mp4',cv.VideoWriter_fourcc(*'DIVX'), 24, (640, 480))\n", + "landmarks_list = []\n", + "feedback_list = [\"\"]\n", + "\n", + "# Create a pose landmarker instance with the live stream mode:\n", + "def print_result(result: PoseLandmarkerResult, output_image: mp.Image, timestamp_ms: int):\n", + " if result.pose_landmarks:\n", + " annotated_image = np.copy(output_image.numpy_view())\n", + " landmarks_list.append(result.pose_landmarks[0]) # Adds landmark data for pic to list\n", + " for landmark in result.pose_landmarks[0]:\n", + " pose_landmarks_proto = landmark_pb2.NormalizedLandmarkList()\n", + " pose_landmarks_proto.landmark.extend(\n", + " [landmark_pb2.NormalizedLandmark(x=landmark.x, y=landmark.y, z=landmark.z) for landmark in result.pose_landmarks[0]])\n", + " solutions.drawing_utils.draw_landmarks(\n", + " annotated_image,\n", + " pose_landmarks_proto,\n", + " solutions.pose.POSE_CONNECTIONS,\n", + " solutions.drawing_styles.get_default_pose_landmarks_style())\n", + "\n", + " # print(\"Frame\", timestamp_ms)\n", + " lol = lm_dstruct(landmarks_list[-1])\n", + " feedback_temp = lol.feedback(\"squat\")\n", + " if feedback_list[-1] != feedback_temp:\n", + " print(feedback_temp)\n", + " feedback_list.append(feedback_temp)\n", + " out_video.write(annotated_image)\n", + "\n", + "options = PoseLandmarkerOptions(\n", + " base_options=BaseOptions(model_asset_path=model_path),\n", + " running_mode=VisionRunningMode.LIVE_STREAM,\n", + " result_callback=print_result) # Callback function to deal w/ results\n", + "\n", + "\n", + "### CAMERA FUNCTIONALITY ###\n", + "\n", + "def jsob_to_image(js_object):\n", + " # decode base64 image\n", + " image_bytes = b64decode(js_object.split(',')[1])\n", + " # convert bytes to numpy array\n", + " img_array = np.frombuffer(image_bytes, dtype=np.uint8)\n", + " # convert numpy array into OpenCV BGR\n", + " frame = cv.imdecode(img_array, flags=1)\n", + "\n", + " return frame\n", + "\n", + "def video_stream():\n", + " js = Javascript('''\n", + " var video;\n", + " var div = null;\n", + " var stream;\n", + " var captureCanvas;\n", + " var imgElement;\n", + " var labelElement;\n", + "\n", + " var pendingResolve = null;\n", + " var shutdown = false;\n", + "\n", + " function removeDom() {\n", + " stream.getVideoTracks()[0].stop();\n", + " video.remove();\n", + " div.remove();\n", + " video = null;\n", + " div = null;\n", + " stream = null;\n", + " imgElement = null;\n", + " captureCanvas = null;\n", + " labelElement = null;\n", + " }\n", + "\n", + " function onAnimationFrame() {\n", + " if (!shutdown) {\n", + " window.requestAnimationFrame(onAnimationFrame);\n", + " }\n", + " if (pendingResolve) {\n", + " var result = \"\";\n", + " if (!shutdown) {\n", + " captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);\n", + " result = captureCanvas.toDataURL('image/jpeg', 0.8)\n", + " }\n", + " var lp = pendingResolve;\n", + " pendingResolve = null;\n", + " lp(result);\n", + " }\n", + " }\n", + "\n", + " async function createDom() {\n", + " if (div !== null) {\n", + " return stream;\n", + " }\n", + " div = document.createElement('div');\n", + " div.style.border = '2px solid black';\n", + " div.style.padding = '3px';\n", + " div.style.width = '100%';\n", + " div.style.maxWidth = '600px';\n", + " document.body.appendChild(div);\n", + "\n", + "\n", + " video = document.createElement('video');\n", + " video.style.display = 'block';\n", + " video.width = div.clientWidth - 6;\n", + " video.setAttribute('playsinline', '');\n", + " video.onclick = () => { shutdown = true; };\n", + " stream = await navigator.mediaDevices.getUserMedia(\n", + " {video: { facingMode: \"environment\"}});\n", + " div.appendChild(video);\n", + " imgElement = document.createElement('img');\n", + " imgElement.style.position = 'absolute';\n", + " imgElement.style.zIndex = 1;\n", + " imgElement.onclick = () => { shutdown = true; };\n", + " div.appendChild(imgElement);\n", + "\n", + " const instruction = document.createElement('div');\n", + " instruction.innerHTML =\n", + " '' +\n", + " 'click here to stop the video';\n", + " div.appendChild(instruction);\n", + " instruction.onclick = () => { shutdown = true; };\n", + "\n", + " video.srcObject = stream;\n", + " await video.play();\n", + " captureCanvas = document.createElement('canvas');\n", + " captureCanvas.width = 640;\n", + " captureCanvas.height = 480;\n", + " window.requestAnimationFrame(onAnimationFrame);\n", + "\n", + " return stream;\n", + " }\n", + " async function stream_frame() {\n", + " if (shutdown) {\n", + " removeDom();\n", + " shutdown = false;\n", + " return '';\n", + " }\n", + " var preCreate = Date.now();\n", + " stream = await createDom();\n", + "\n", + " var preShow = Date.now();\n", + "\n", + "\n", + "\n", + " var preCapture = Date.now();\n", + " var result = await new Promise(function(resolve, reject) {\n", + " pendingResolve = resolve;\n", + " });\n", + " shutdown = false;\n", + "\n", + " return {'create': preShow - preCreate,\n", + " 'show': preCapture - preShow,\n", + " 'capture': Date.now() - preCapture,\n", + " 'img': result};\n", + " }\n", + " ''')\n", + "\n", + " display(js)\n", + "\n", + "def video_frame():\n", + " data = eval_js('stream_frame()')\n", + " return data\n", + "\n", + "### END OF CAMERA CODE ###\n", + "\n", + "with PoseLandmarker.create_from_options(options) as landmarker:\n", + " frame_timestamp_ms = 0\n", + " video_stream()\n", + " while True:\n", + " frame_timestamp_ms += 1\n", + " frame_js = video_frame()\n", + " if not frame_js:\n", + " break\n", + " img = jsob_to_image(frame_js[\"img\"])\n", + " mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=img)\n", + "\n", + " landmarker.detect_async(mp_image, frame_timestamp_ms)\n", + "\n", + "out_video.release()" ] }, { "cell_type": "code", - "source": [ - "lol = lm_dstruct(landmarks_list[20])" - ], + "execution_count": null, "metadata": { "id": "e-A0f1NDoT9J" }, - "execution_count": null, - "outputs": [] + "outputs": [], + "source": [ + "lol = lm_dstruct(landmarks_list[20])" + ] }, { "cell_type": "code", - "source": [ - "lol.angle(lol.left_shoulder, lol.left_elbow, lol.left_wrist)" - ], + "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -699,19 +562,35 @@ "id": "FfeROmq0pkAG", "outputId": "d29078aa-d168-4e28-d86c-3175caa53a5a" }, - "execution_count": null, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "117.35933841748007" ] }, + "execution_count": 47, "metadata": {}, - "execution_count": 47 + "output_type": "execute_result" } + ], + "source": [ + "lol.angle(lol.left_shoulder, lol.left_elbow, lol.left_wrist)" ] } - ] -} \ No newline at end of file + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} From 52b2658a1d56cc905e1c2ede5089622023b89812 Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Sat, 27 Apr 2024 08:10:48 -0500 Subject: [PATCH 02/12] also changed path for csv --- PrototypeR2.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PrototypeR2.ipynb b/PrototypeR2.ipynb index f195cd8..ccbb1bb 100644 --- a/PrototypeR2.ipynb +++ b/PrototypeR2.ipynb @@ -117,7 +117,7 @@ " return np.arccos(np.dot((pointax, pointay, pointaz), (pointcx, pointcy, pointcz)) / (np.sqrt(pointax**2 + pointay**2 + pointaz**2) * np.sqrt(pointcx**2 + pointcy**2 + pointcz**2))) * 180 / np.pi\n", "\n", " def feedback(self, exercise):\n", - " with open('{exercise}.csv') as anglefile:\n", + " with open(f'/content/drive/MyDrive/Exercise App Resources/{exercise}.csv') as anglefile:\n", " anglereader = csv.reader(anglefile)\n", " for row in anglereader:\n", " print(row)" From 9516b6c07ff42a90733649880c643dec2e943e57 Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Mon, 6 May 2024 05:53:38 -0500 Subject: [PATCH 03/12] Complete CSV Functionality --- Prototype_2_Electric_Boogalooo.ipynb | 667 +++++++++++++++++++++++++++ 1 file changed, 667 insertions(+) create mode 100644 Prototype_2_Electric_Boogalooo.ipynb diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb new file mode 100644 index 0000000..8b6a31e --- /dev/null +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -0,0 +1,667 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", + "authorship_tag": "ABX9TyOsULy/r2XnRaqkWFm54635", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "source": [ + "# **STEP ONE**" + ], + "metadata": { + "id": "uGVhyDnnPJsx" + } + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "gmwahO7oITMz" + }, + "outputs": [], + "source": [ + "!pip install -q mediapipe==0.10.0" + ] + }, + { + "cell_type": "markdown", + "source": [ + "# **STEP TWO**" + ], + "metadata": { + "id": "8-SUS1VRPXny" + } + }, + { + "cell_type": "code", + "source": [ + "import mediapipe as mp\n", + "from mediapipe.tasks import python\n", + "from mediapipe.tasks.python import vision\n", + "from mediapipe import solutions\n", + "from mediapipe.framework.formats import landmark_pb2\n", + "\n", + "import numpy as np\n", + "import cv2 as cv\n", + "\n", + "from IPython.display import display, Javascript, Image, clear_output, HTML\n", + "from google.colab.output import eval_js\n", + "import html\n", + "from base64 import b64decode, b64encode\n", + "import PIL\n", + "import io\n", + "\n", + "import matplotlib.pyplot as plt\n", + "import time\n", + "import os\n", + "import glob\n", + "import csv" + ], + "metadata": { + "id": "whZwvEdKIksm" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Class that is able to conviently store all poselandmarker data\n", + "# Input a poselandmarker dstruct and it outputs the x y or z of any specific body part\n", + "# lm_dstruct.nose.x\n", + "class lm_dstruct:\n", + " def __init__(self, pll):\n", + " self.left_shoulder = pll[11]\n", + " self.right_shoulder = pll[12]\n", + " self.left_elbow = pll[13]\n", + " self.right_elbow = pll[14]\n", + " self.left_wrist = pll[15]\n", + " self.right_wrist = pll[16]\n", + " self.left_thumb = pll[21]\n", + " self.right_thumb = pll[22]\n", + " self.left_hip = pll[23]\n", + " self.right_hip = pll[24]\n", + " self.left_knee = pll[25]\n", + " self.right_knee = pll[26]\n", + " self.left_ankle = pll[27]\n", + " self.right_ankle = pll[28]\n", + " self.left_heel = pll[29]\n", + " self.right_heel = pll[30]\n", + " self.left_foot_index = pll[31]\n", + " self.right_foot_index = pll[32]\n", + "\n", + " # Returns the angle formed by any three points, with pointb as the center\n", + " def angle(self, pointa, pointb, pointc):\n", + " pointax = pointa.x - pointb.x\n", + " pointay = pointa.y - pointb.y\n", + " pointaz = pointa.z - pointb.z\n", + " pointcx = pointc.x - pointb.x\n", + " pointcy = pointc.y - pointb.y\n", + " pointcz = pointc.z - pointb.z\n", + " lineba = np.sqrt(np.sqrt(((pointax**2) + (pointay**2))**2) + (pointax**2))\n", + " linebc = np.sqrt(np.sqrt(((pointcx**2) + (pointcy**2))**2) + (pointcx**2))\n", + " lineac = np.sqrt(np.sqrt((((pointax - pointcx)**2) + ((pointay - pointcy)**2))**2) + ((pointaz - pointcz)**2))\n", + " return np.arccos(((lineba**2) + (linebc**2) - (lineac**2)) / (2 * lineba * linebc)) * 180 / np.pi\n", + "\n", + " # Feedback function\n", + " # Opens the csv for the selected exercise\n", + " # Calculates the angles the exercise requires (determines necessity if weight value signals its needed)\n", + " # Compares the calculated angle with the min-max of the exercise\n", + " def feedback(self, exercise):\n", + " with open(f'/content/drive/MyDrive/Exercise App Resources/{exercise}.csv') as anglefile:\n", + " anglereader = csv.reader(anglefile)\n", + " for row in anglereader:\n", + " # First check to see if you should calculate the angle\n", + " if row[3] == '1':\n", + " # Then figure out what angle you need to calculate\n", + " # Arm, Grip, Back, Arms by Side, Leg, Hip Angle, Calf\n", + " if row[0] == 'Arm':\n", + " if self.right_elbow.visibility > self.left_elbow.visibility: # Finds the better side and uses that for angles\n", + " working_angle = self.angle(self.right_shoulder, self.right_elbow, self.right_wrist)\n", + " else:\n", + " working_angle = self.angle(self.left_shoulder, self.left_elbow, self.left_wrist)\n", + " if working_angle < int(row[1]): # See if the angle is within bounds\n", + " return \"Try Straightening Your Arm Somewhat\"\n", + " if working_angle > int(row[2]):\n", + " return \"Try Bending Your Elbow More\"\n", + "\n", + " elif row[0] == 'Wrist Angle':\n", + " if self.right_wrist.visibility > self.left_wrist.visibility:\n", + " working_angle = self.angle(self.right_elbow, self.right_wrist, self.right_thumb)\n", + " else:\n", + " working_angle = self.angle(self.left_elbow, self.left_wrist, self.left_thumb)\n", + " if working_angle < int(row[1]):\n", + " return \"Try Straightening Your Wrist Somewhat\"\n", + " if working_angle > int(row[2]):\n", + " return \"Try Bending Your Wrist More\"\n", + "\n", + "\n", + " elif row[0] == 'Hip Angle':\n", + " if self.right_hip.visibility > self.left_hip.visibility:\n", + " working_angle = self.angle(self.right_shoulder, self.right_hip, self.right_knee)\n", + " else:\n", + " working_angle = self.angle(self.left_shoulder, self.left_hip, self.left_knee)\n", + " if working_angle < int(row[1]):\n", + " return \"Try Straightening Your Hip Somewhat\"\n", + " if working_angle > int(row[2]):\n", + " return \"Try Bending Over More\"\n", + "\n", + " elif row[0] == 'Arms by Side':\n", + " if self.right_shoulder.visibility > self.left_shoulder.visibility:\n", + " working_angle = self.angle(self.right_elbow, self.right_shoulder, self.right_hip)\n", + " else:\n", + " working_angle = self.angle(self.left_elbow, self.left_shoulder, self.left_hip)\n", + " if working_angle < int(row[1]):\n", + " return \"Try Spreading Your Arms Out More\"\n", + " if working_angle > int(row[2]):\n", + " return \"Try Bringing Your Arms Somewhat Closer To Your Body\"\n", + "\n", + " elif row[0] == 'Leg':\n", + " if self.right_knee.visibility > self.left_knee.visibility:\n", + " working_angle = self.angle(self.right_hip, self.right_knee, self.right_ankle)\n", + " else:\n", + " working_angle = self.angle(self.left_hip, self.left_knee, self.left_ankle)\n", + " if working_angle < int(row[1]):\n", + " return \"Try Straightening Your Legs More\"\n", + " if working_angle > int(row[2]):\n", + " return \"Try Bending Your Legs More\"\n", + "\n", + " elif row[0] == 'Calf':\n", + " if self.right_heel.visibility > self.left_heel.visibility:\n", + " working_angle = self.angle(self.right_ankle, self.right_heel, self.right_foot_index)\n", + " else:\n", + " working_angle = self.angle(self.left_ankle, self.left_heel, self.left_foot_index)\n", + " if working_angle < int(row[1]):\n", + " return \"Try Pointing Your Feet More (Tiptoe position)\"\n", + " if working_angle > int(row[2]):\n", + " return \"Try Flattening Your Feet More\"\n", + "\n", + " return \"Good Form\"" + ], + "metadata": { + "id": "RHyJwan8acCz" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Make sure to import **Pose Landmarker Lite** into Drive folder before next step\n", + "\n", + "Can be found in Drive folder: https://drive.google.com/drive/folders/1RFTh9ed50zVZaIyutPCo6-VTEQanqE4_?usp=sharing\n", + "\n", + "If needed, download latest from MediaPipe website: https://developers.google.com/mediapipe/solutions/vision/pose_landmarker/index#models" + ], + "metadata": { + "id": "e1sSWM10JfE7" + } + }, + { + "cell_type": "markdown", + "source": [ + "# **STEP THREE**" + ], + "metadata": { + "id": "h7suIPY_PbaD" + } + }, + { + "cell_type": "code", + "source": [ + "model_path = '/content/drive/MyDrive/Exercise App Resources/pose_landmarker_lite.task'\n", + "BaseOptions = python.BaseOptions # Basic Options Object\n", + "PoseLandmarker = vision.PoseLandmarker # Pose Landmarker Model Object\n", + "PoseLandmarkerOptions = vision.PoseLandmarkerOptions # Overall Options Object\n", + "VisionRunningMode = vision.RunningMode # Mode Object (Image, Video, Livestream)\n", + "PoseLandmarkerResult = vision.PoseLandmarkerResult # Stores result from model\n", + "out_video = cv.VideoWriter('/content/drive/MyDrive/Exercise App Resources/Videos/' + time.asctime(time.localtime()) + '.mp4',cv.VideoWriter_fourcc(*'DIVX'), 24, (640, 480))\n", + "landmarks_list = []\n", + "feedback_list = [\"\"]\n", + "\n", + "# Create a pose landmarker instance with the live stream mode:\n", + "def print_result(result: PoseLandmarkerResult, output_image: mp.Image, timestamp_ms: int):\n", + " if result.pose_landmarks:\n", + " annotated_image = np.copy(output_image.numpy_view())\n", + " landmarks_list.append(result.pose_landmarks[0]) # Adds landmark data for pic to list\n", + " for landmark in result.pose_landmarks[0]:\n", + " pose_landmarks_proto = landmark_pb2.NormalizedLandmarkList()\n", + " pose_landmarks_proto.landmark.extend(\n", + " [landmark_pb2.NormalizedLandmark(x=landmark.x, y=landmark.y, z=landmark.z) for landmark in result.pose_landmarks[0]])\n", + " solutions.drawing_utils.draw_landmarks(\n", + " annotated_image,\n", + " pose_landmarks_proto,\n", + " solutions.pose.POSE_CONNECTIONS,\n", + " solutions.drawing_styles.get_default_pose_landmarks_style())\n", + "\n", + " # print(\"Frame\", timestamp_ms)\n", + " lol = lm_dstruct(landmarks_list[-1])\n", + " feedback_temp = lol.feedback(\"squat\")\n", + " if feedback_list[-1] != feedback_temp:\n", + " print(feedback_temp)\n", + " feedback_list.append(feedback_temp)\n", + " out_video.write(annotated_image)\n", + "\n", + "options = PoseLandmarkerOptions(\n", + " base_options=BaseOptions(model_asset_path=model_path),\n", + " running_mode=VisionRunningMode.LIVE_STREAM,\n", + " result_callback=print_result) # Callback function to deal w/ results\n", + "\n", + "\n", + "### CAMERA FUNCTIONALITY ###\n", + "\n", + "def jsob_to_image(js_object):\n", + " # decode base64 image\n", + " image_bytes = b64decode(js_object.split(',')[1])\n", + " # convert bytes to numpy array\n", + " img_array = np.frombuffer(image_bytes, dtype=np.uint8)\n", + " # convert numpy array into OpenCV BGR\n", + " frame = cv.imdecode(img_array, flags=1)\n", + "\n", + " return frame\n", + "\n", + "def video_stream():\n", + " js = Javascript('''\n", + " var video;\n", + " var div = null;\n", + " var stream;\n", + " var captureCanvas;\n", + " var imgElement;\n", + " var labelElement;\n", + "\n", + " var pendingResolve = null;\n", + " var shutdown = false;\n", + "\n", + " function removeDom() {\n", + " stream.getVideoTracks()[0].stop();\n", + " video.remove();\n", + " div.remove();\n", + " video = null;\n", + " div = null;\n", + " stream = null;\n", + " imgElement = null;\n", + " captureCanvas = null;\n", + " labelElement = null;\n", + " }\n", + "\n", + " function onAnimationFrame() {\n", + " if (!shutdown) {\n", + " window.requestAnimationFrame(onAnimationFrame);\n", + " }\n", + " if (pendingResolve) {\n", + " var result = \"\";\n", + " if (!shutdown) {\n", + " captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);\n", + " result = captureCanvas.toDataURL('image/jpeg', 0.8)\n", + " }\n", + " var lp = pendingResolve;\n", + " pendingResolve = null;\n", + " lp(result);\n", + " }\n", + " }\n", + "\n", + " async function createDom() {\n", + " if (div !== null) {\n", + " return stream;\n", + " }\n", + " div = document.createElement('div');\n", + " div.style.border = '2px solid black';\n", + " div.style.padding = '3px';\n", + " div.style.width = '100%';\n", + " div.style.maxWidth = '600px';\n", + " document.body.appendChild(div);\n", + "\n", + "\n", + " video = document.createElement('video');\n", + " video.style.display = 'block';\n", + " video.width = div.clientWidth - 6;\n", + " video.setAttribute('playsinline', '');\n", + " video.onclick = () => { shutdown = true; };\n", + " stream = await navigator.mediaDevices.getUserMedia(\n", + " {video: { facingMode: \"environment\"}});\n", + " div.appendChild(video);\n", + " imgElement = document.createElement('img');\n", + " imgElement.style.position = 'absolute';\n", + " imgElement.style.zIndex = 1;\n", + " imgElement.onclick = () => { shutdown = true; };\n", + " div.appendChild(imgElement);\n", + "\n", + " const instruction = document.createElement('div');\n", + " instruction.innerHTML =\n", + " '' +\n", + " 'click here to stop the video';\n", + " div.appendChild(instruction);\n", + " instruction.onclick = () => { shutdown = true; };\n", + "\n", + " video.srcObject = stream;\n", + " await video.play();\n", + " captureCanvas = document.createElement('canvas');\n", + " captureCanvas.width = 640;\n", + " captureCanvas.height = 480;\n", + " window.requestAnimationFrame(onAnimationFrame);\n", + "\n", + " return stream;\n", + " }\n", + " async function stream_frame() {\n", + " if (shutdown) {\n", + " removeDom();\n", + " shutdown = false;\n", + " return '';\n", + " }\n", + " var preCreate = Date.now();\n", + " stream = await createDom();\n", + "\n", + " var preShow = Date.now();\n", + "\n", + "\n", + "\n", + " var preCapture = Date.now();\n", + " var result = await new Promise(function(resolve, reject) {\n", + " pendingResolve = resolve;\n", + " });\n", + " shutdown = false;\n", + "\n", + " return {'create': preShow - preCreate,\n", + " 'show': preCapture - preShow,\n", + " 'capture': Date.now() - preCapture,\n", + " 'img': result};\n", + " }\n", + " ''')\n", + "\n", + " display(js)\n", + "\n", + "def video_frame():\n", + " data = eval_js('stream_frame()')\n", + " return data\n", + "\n", + "### END OF CAMERA CODE ###\n", + "\n", + "with PoseLandmarker.create_from_options(options) as landmarker:\n", + " frame_timestamp_ms = 0\n", + " video_stream()\n", + " while True:\n", + " frame_timestamp_ms += 1\n", + " frame_js = video_frame()\n", + " if not frame_js:\n", + " break\n", + " img = jsob_to_image(frame_js[\"img\"])\n", + " mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=img)\n", + "\n", + " landmarker.detect_async(mp_image, frame_timestamp_ms)\n", + "\n", + "out_video.release()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "GHzmhoO6Jc50", + "outputId": "d50ae689-0f00-4c7a-b7e9-78e738eea773" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "" + ], + "application/javascript": [ + "\n", + " var video;\n", + " var div = null;\n", + " var stream;\n", + " var captureCanvas;\n", + " var imgElement;\n", + " var labelElement;\n", + "\n", + " var pendingResolve = null;\n", + " var shutdown = false;\n", + "\n", + " function removeDom() {\n", + " stream.getVideoTracks()[0].stop();\n", + " video.remove();\n", + " div.remove();\n", + " video = null;\n", + " div = null;\n", + " stream = null;\n", + " imgElement = null;\n", + " captureCanvas = null;\n", + " labelElement = null;\n", + " }\n", + "\n", + " function onAnimationFrame() {\n", + " if (!shutdown) {\n", + " window.requestAnimationFrame(onAnimationFrame);\n", + " }\n", + " if (pendingResolve) {\n", + " var result = \"\";\n", + " if (!shutdown) {\n", + " captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);\n", + " result = captureCanvas.toDataURL('image/jpeg', 0.8)\n", + " }\n", + " var lp = pendingResolve;\n", + " pendingResolve = null;\n", + " lp(result);\n", + " }\n", + " }\n", + "\n", + " async function createDom() {\n", + " if (div !== null) {\n", + " return stream;\n", + " }\n", + " div = document.createElement('div');\n", + " div.style.border = '2px solid black';\n", + " div.style.padding = '3px';\n", + " div.style.width = '100%';\n", + " div.style.maxWidth = '600px';\n", + " document.body.appendChild(div);\n", + "\n", + "\n", + " video = document.createElement('video');\n", + " video.style.display = 'block';\n", + " video.width = div.clientWidth - 6;\n", + " video.setAttribute('playsinline', '');\n", + " video.onclick = () => { shutdown = true; };\n", + " stream = await navigator.mediaDevices.getUserMedia(\n", + " {video: { facingMode: \"environment\"}});\n", + " div.appendChild(video);\n", + " imgElement = document.createElement('img');\n", + " imgElement.style.position = 'absolute';\n", + " imgElement.style.zIndex = 1;\n", + " imgElement.onclick = () => { shutdown = true; };\n", + " div.appendChild(imgElement);\n", + "\n", + " const instruction = document.createElement('div');\n", + " instruction.innerHTML =\n", + " '' +\n", + " 'click here to stop the video';\n", + " div.appendChild(instruction);\n", + " instruction.onclick = () => { shutdown = true; };\n", + "\n", + " video.srcObject = stream;\n", + " await video.play();\n", + " captureCanvas = document.createElement('canvas');\n", + " captureCanvas.width = 640;\n", + " captureCanvas.height = 480;\n", + " window.requestAnimationFrame(onAnimationFrame);\n", + "\n", + " return stream;\n", + " }\n", + " async function stream_frame() {\n", + " if (shutdown) {\n", + " removeDom();\n", + " shutdown = false;\n", + " return '';\n", + " }\n", + " var preCreate = Date.now();\n", + " stream = await createDom();\n", + "\n", + " var preShow = Date.now();\n", + "\n", + "\n", + "\n", + " var preCapture = Date.now();\n", + " var result = await new Promise(function(resolve, reject) {\n", + " pendingResolve = resolve;\n", + " });\n", + " shutdown = false;\n", + "\n", + " return {'create': preShow - preCreate,\n", + " 'show': preCapture - preShow,\n", + " 'capture': Date.now() - preCapture,\n", + " 'img': result};\n", + " }\n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + ":36: RuntimeWarning: invalid value encountered in arccos\n", + " return np.arccos(((lineba**2) + (linebc**2) - (lineac**2)) / (2 * lineba * linebc)) * 180 / np.pi\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Try Straightening Your Legs More\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Straightening Your Legs More\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Try Straightening Your Hip Somewhat\n", + "Try Bending Your Elbow More\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", + "Try Straightening Your Hip Somewhat\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", + "Try Bending Your Elbow More\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", + "Try Bending Your Elbow More\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", + "Try Bending Your Elbow More\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", + "Try Bending Your Elbow More\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", + "Try Bending Your Elbow More\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", + "Try Bending Your Elbow More\n", + "Good Form\n", + "Try Straightening Your Hip Somewhat\n", + "Good Form\n", + "Try Bending Your Elbow More\n", + "Try Straightening Your Hip Somewhat\n", + "Good Form\n", + "Try Straightening Your Hip Somewhat\n", + "Try Bending Your Elbow More\n", + "Try Straightening Your Hip Somewhat\n", + "Try Bending Your Elbow More\n", + "Try Straightening Your Hip Somewhat\n", + "Try Bending Your Elbow More\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "lol = lm_dstruct(landmarks_list[20])" + ], + "metadata": { + "id": "e-A0f1NDoT9J" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "lol.angle(lol.left_shoulder, lol.left_elbow, lol.left_wrist)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "FfeROmq0pkAG", + "outputId": "d29078aa-d168-4e28-d86c-3175caa53a5a" + }, + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "117.35933841748007" + ] + }, + "metadata": {}, + "execution_count": 47 + } + ] + } + ] +} \ No newline at end of file From 9cb1ca04bb332ddc6043c2faf69bd24edb70d5cc Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Mon, 6 May 2024 06:07:27 -0500 Subject: [PATCH 04/12] Changed paths for folders Allowed the user to select the exercise they wanted to track Minorly cleaned up code --- Prototype_2_Electric_Boogalooo.ipynb | 135 ++++++--------------------- 1 file changed, 26 insertions(+), 109 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index 8b6a31e..744a970 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyOsULy/r2XnRaqkWFm54635", + "authorship_tag": "ABX9TyMt2GKMMV8/XYPfg7DL7W+p", "include_colab_link": true }, "kernelspec": { @@ -38,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "id": "gmwahO7oITMz" }, @@ -84,7 +84,7 @@ "metadata": { "id": "whZwvEdKIksm" }, - "execution_count": null, + "execution_count": 5, "outputs": [] }, { @@ -132,7 +132,7 @@ " # Calculates the angles the exercise requires (determines necessity if weight value signals its needed)\n", " # Compares the calculated angle with the min-max of the exercise\n", " def feedback(self, exercise):\n", - " with open(f'/content/drive/MyDrive/Exercise App Resources/{exercise}.csv') as anglefile:\n", + " with open(f'/content/drive/MyDrive/Exercise App Resources/CSV Files/{exercise}.csv') as anglefile:\n", " anglereader = csv.reader(anglefile)\n", " for row in anglereader:\n", " # First check to see if you should calculate the angle\n", @@ -205,7 +205,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": null, + "execution_count": 8, "outputs": [] }, { @@ -242,6 +242,8 @@ "out_video = cv.VideoWriter('/content/drive/MyDrive/Exercise App Resources/Videos/' + time.asctime(time.localtime()) + '.mp4',cv.VideoWriter_fourcc(*'DIVX'), 24, (640, 480))\n", "landmarks_list = []\n", "feedback_list = [\"\"]\n", + "selected_exercise = input(\"What exercise are you tracking?\\n\")\n", + "\n", "\n", "# Create a pose landmarker instance with the live stream mode:\n", "def print_result(result: PoseLandmarkerResult, output_image: mp.Image, timestamp_ms: int):\n", @@ -259,13 +261,14 @@ " solutions.drawing_styles.get_default_pose_landmarks_style())\n", "\n", " # print(\"Frame\", timestamp_ms)\n", - " lol = lm_dstruct(landmarks_list[-1])\n", - " feedback_temp = lol.feedback(\"squat\")\n", + " working_dstruct = lm_dstruct(landmarks_list[-1])\n", + " feedback_temp = working_dstruct.feedback(selected_exercise)\n", " if feedback_list[-1] != feedback_temp:\n", " print(feedback_temp)\n", " feedback_list.append(feedback_temp)\n", " out_video.write(annotated_image)\n", "\n", + "\n", "options = PoseLandmarkerOptions(\n", " base_options=BaseOptions(model_asset_path=model_path),\n", " running_mode=VisionRunningMode.LIVE_STREAM,\n", @@ -418,13 +421,21 @@ "metadata": { "colab": { "base_uri": "https://localhost:8080/", - "height": 1000 + "height": 285 }, "id": "GHzmhoO6Jc50", - "outputId": "d50ae689-0f00-4c7a-b7e9-78e738eea773" + "outputId": "fd9a36c0-0f67-4701-c1a5-c4a03cec65cb" }, - "execution_count": null, + "execution_count": 9, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "What exercise are you tracking?\n", + "squat\n" + ] + }, { "output_type": "display_data", "data": { @@ -546,7 +557,7 @@ "output_type": "stream", "name": "stderr", "text": [ - ":36: RuntimeWarning: invalid value encountered in arccos\n", + ":36: RuntimeWarning: invalid value encountered in arccos\n", " return np.arccos(((lineba**2) + (linebc**2) - (lineac**2)) / (2 * lineba * linebc)) * 180 / np.pi\n" ] }, @@ -555,113 +566,19 @@ "name": "stdout", "text": [ "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Try Straightening Your Legs More\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Straightening Your Legs More\n", - "Try Bending Your Elbow More\n", - "Good Form\n", - "Try Bending Your Elbow More\n", - "Try Straightening Your Hip Somewhat\n", - "Try Bending Your Elbow More\n", "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Try Straightening Your Hip Somewhat\n", - "Try Bending Your Elbow More\n", "Good Form\n", - "Try Bending Your Elbow More\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Try Bending Your Elbow More\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Try Bending Your Elbow More\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Try Bending Your Elbow More\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Try Bending Your Elbow More\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Try Bending Your Elbow More\n", "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Try Bending Your Elbow More\n", "Good Form\n", - "Try Straightening Your Hip Somewhat\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", "Good Form\n", - "Try Bending Your Elbow More\n", - "Try Straightening Your Hip Somewhat\n", + "Try Bringing Your Arms Somewhat Closer To Your Body\n", "Good Form\n", - "Try Straightening Your Hip Somewhat\n", - "Try Bending Your Elbow More\n", - "Try Straightening Your Hip Somewhat\n", - "Try Bending Your Elbow More\n", - "Try Straightening Your Hip Somewhat\n", - "Try Bending Your Elbow More\n" + "Try Bringing Your Arms Somewhat Closer To Your Body\n", + "Good Form\n" ] } ] - }, - { - "cell_type": "code", - "source": [ - "lol = lm_dstruct(landmarks_list[20])" - ], - "metadata": { - "id": "e-A0f1NDoT9J" - }, - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "lol.angle(lol.left_shoulder, lol.left_elbow, lol.left_wrist)" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "FfeROmq0pkAG", - "outputId": "d29078aa-d168-4e28-d86c-3175caa53a5a" - }, - "execution_count": null, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "117.35933841748007" - ] - }, - "metadata": {}, - "execution_count": 47 - } - ] } ] } \ No newline at end of file From 5dde9a277e123741fd51140607d6feeeffbbcb44 Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Mon, 6 May 2024 06:15:09 -0500 Subject: [PATCH 05/12] Suppressed numpy warnings --- Prototype_2_Electric_Boogalooo.ipynb | 175 ++------------------------- 1 file changed, 11 insertions(+), 164 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index 744a970..7740cef 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyMt2GKMMV8/XYPfg7DL7W+p", + "authorship_tag": "ABX9TyMdRnDYTMazzcb7M0oDna3k", "include_colab_link": true }, "kernelspec": { @@ -38,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 10, "metadata": { "id": "gmwahO7oITMz" }, @@ -79,12 +79,13 @@ "import time\n", "import os\n", "import glob\n", - "import csv" + "import csv\n", + "import warnings" ], "metadata": { "id": "whZwvEdKIksm" }, - "execution_count": 5, + "execution_count": 11, "outputs": [] }, { @@ -116,6 +117,8 @@ "\n", " # Returns the angle formed by any three points, with pointb as the center\n", " def angle(self, pointa, pointb, pointc):\n", + " warnings.filterwarnings('ignore')\n", + "\n", " pointax = pointa.x - pointb.x\n", " pointay = pointa.y - pointb.y\n", " pointaz = pointa.z - pointb.z\n", @@ -205,7 +208,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": 8, + "execution_count": 12, "outputs": [] }, { @@ -419,166 +422,10 @@ "out_video.release()" ], "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 285 - }, - "id": "GHzmhoO6Jc50", - "outputId": "fd9a36c0-0f67-4701-c1a5-c4a03cec65cb" + "id": "GHzmhoO6Jc50" }, - "execution_count": 9, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "What exercise are you tracking?\n", - "squat\n" - ] - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "" - ], - "application/javascript": [ - "\n", - " var video;\n", - " var div = null;\n", - " var stream;\n", - " var captureCanvas;\n", - " var imgElement;\n", - " var labelElement;\n", - "\n", - " var pendingResolve = null;\n", - " var shutdown = false;\n", - "\n", - " function removeDom() {\n", - " stream.getVideoTracks()[0].stop();\n", - " video.remove();\n", - " div.remove();\n", - " video = null;\n", - " div = null;\n", - " stream = null;\n", - " imgElement = null;\n", - " captureCanvas = null;\n", - " labelElement = null;\n", - " }\n", - "\n", - " function onAnimationFrame() {\n", - " if (!shutdown) {\n", - " window.requestAnimationFrame(onAnimationFrame);\n", - " }\n", - " if (pendingResolve) {\n", - " var result = \"\";\n", - " if (!shutdown) {\n", - " captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);\n", - " result = captureCanvas.toDataURL('image/jpeg', 0.8)\n", - " }\n", - " var lp = pendingResolve;\n", - " pendingResolve = null;\n", - " lp(result);\n", - " }\n", - " }\n", - "\n", - " async function createDom() {\n", - " if (div !== null) {\n", - " return stream;\n", - " }\n", - " div = document.createElement('div');\n", - " div.style.border = '2px solid black';\n", - " div.style.padding = '3px';\n", - " div.style.width = '100%';\n", - " div.style.maxWidth = '600px';\n", - " document.body.appendChild(div);\n", - "\n", - "\n", - " video = document.createElement('video');\n", - " video.style.display = 'block';\n", - " video.width = div.clientWidth - 6;\n", - " video.setAttribute('playsinline', '');\n", - " video.onclick = () => { shutdown = true; };\n", - " stream = await navigator.mediaDevices.getUserMedia(\n", - " {video: { facingMode: \"environment\"}});\n", - " div.appendChild(video);\n", - " imgElement = document.createElement('img');\n", - " imgElement.style.position = 'absolute';\n", - " imgElement.style.zIndex = 1;\n", - " imgElement.onclick = () => { shutdown = true; };\n", - " div.appendChild(imgElement);\n", - "\n", - " const instruction = document.createElement('div');\n", - " instruction.innerHTML =\n", - " '' +\n", - " 'click here to stop the video';\n", - " div.appendChild(instruction);\n", - " instruction.onclick = () => { shutdown = true; };\n", - "\n", - " video.srcObject = stream;\n", - " await video.play();\n", - " captureCanvas = document.createElement('canvas');\n", - " captureCanvas.width = 640;\n", - " captureCanvas.height = 480;\n", - " window.requestAnimationFrame(onAnimationFrame);\n", - "\n", - " return stream;\n", - " }\n", - " async function stream_frame() {\n", - " if (shutdown) {\n", - " removeDom();\n", - " shutdown = false;\n", - " return '';\n", - " }\n", - " var preCreate = Date.now();\n", - " stream = await createDom();\n", - "\n", - " var preShow = Date.now();\n", - "\n", - "\n", - "\n", - " var preCapture = Date.now();\n", - " var result = await new Promise(function(resolve, reject) {\n", - " pendingResolve = resolve;\n", - " });\n", - " shutdown = false;\n", - "\n", - " return {'create': preShow - preCreate,\n", - " 'show': preCapture - preShow,\n", - " 'capture': Date.now() - preCapture,\n", - " 'img': result};\n", - " }\n", - " " - ] - }, - "metadata": {} - }, - { - "output_type": "stream", - "name": "stderr", - "text": [ - ":36: RuntimeWarning: invalid value encountered in arccos\n", - " return np.arccos(((lineba**2) + (linebc**2) - (lineac**2)) / (2 * lineba * linebc)) * 180 / np.pi\n" - ] - }, - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Good Form\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Good Form\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Good Form\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Good Form\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Good Form\n", - "Try Bringing Your Arms Somewhat Closer To Your Body\n", - "Good Form\n" - ] - } - ] + "execution_count": null, + "outputs": [] } ] } \ No newline at end of file From 47e22a0cf97b9734a75bdbeb44f332977924394a Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Sat, 11 May 2024 22:17:51 -0500 Subject: [PATCH 06/12] added drive mounting --- Prototype_2_Electric_Boogalooo.ipynb | 69 ++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index 7740cef..cea381b 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyMdRnDYTMazzcb7M0oDna3k", + "authorship_tag": "ABX9TyMPz1058xNhiDNts/6UkwO5", "include_colab_link": true }, "kernelspec": { @@ -38,15 +38,40 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 1, "metadata": { - "id": "gmwahO7oITMz" + "id": "gmwahO7oITMz", + "outputId": "8de4163f-bec3-40fa-e706-623ca5d95c9e", + "colab": { + "base_uri": "https://localhost:8080/" + } }, - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[31mERROR: Operation cancelled by user\u001b[0m\u001b[31m\n", + "\u001b[0m" + ] + } + ], "source": [ "!pip install -q mediapipe==0.10.0" ] }, + { + "cell_type": "code", + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/drive')" + ], + "metadata": { + "id": "8xGt3oqXze3o" + }, + "execution_count": null, + "outputs": [] + }, { "cell_type": "markdown", "source": [ @@ -83,10 +108,38 @@ "import warnings" ], "metadata": { - "id": "whZwvEdKIksm" + "id": "whZwvEdKIksm", + "outputId": "799f6c43-026b-49ad-bfb1-ea7bbb54a38a", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 393 + } }, - "execution_count": 11, - "outputs": [] + "execution_count": 2, + "outputs": [ + { + "output_type": "error", + "ename": "ModuleNotFoundError", + "evalue": "No module named 'mediapipe'", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mmediapipe\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mmp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmediapipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtasks\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpython\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmediapipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtasks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpython\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mvision\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmediapipe\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0msolutions\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmediapipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mframework\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformats\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mlandmark_pb2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'mediapipe'", + "", + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0;32m\nNOTE: If your import is failing due to a missing package, you can\nmanually install dependencies using either !pip or !apt.\n\nTo view examples of installing some common dependencies, click the\n\"Open Examples\" button below.\n\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n" + ], + "errorDetails": { + "actions": [ + { + "action": "open_url", + "actionText": "Open Examples", + "url": "/notebooks/snippets/importing_libraries.ipynb" + } + ] + } + } + ] }, { "cell_type": "code", @@ -208,7 +261,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": 12, + "execution_count": null, "outputs": [] }, { From b02da9474f9479e5f209ff91aa5a4fc9f86a66d0 Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Thu, 6 Jun 2024 19:35:28 -0500 Subject: [PATCH 07/12] Added Avging for Vis Checks --- Prototype_2_Electric_Boogalooo.ipynb | 220 +++++++++++++++++++++------ 1 file changed, 172 insertions(+), 48 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index cea381b..4609a87 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyMPz1058xNhiDNts/6UkwO5", + "authorship_tag": "ABX9TyNWN8PShQAAFqcdVLX8FWQs", "include_colab_link": true }, "kernelspec": { @@ -41,7 +41,7 @@ "execution_count": 1, "metadata": { "id": "gmwahO7oITMz", - "outputId": "8de4163f-bec3-40fa-e706-623ca5d95c9e", + "outputId": "110ba097-a5c4-4494-a7c1-aa65c48dcfdc", "colab": { "base_uri": "https://localhost:8080/" } @@ -51,8 +51,8 @@ "output_type": "stream", "name": "stdout", "text": [ - "\u001b[31mERROR: Operation cancelled by user\u001b[0m\u001b[31m\n", - "\u001b[0m" + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m33.9/33.9 MB\u001b[0m \u001b[31m26.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" ] } ], @@ -67,10 +67,22 @@ "drive.mount('/content/drive')" ], "metadata": { - "id": "8xGt3oqXze3o" + "id": "8xGt3oqXze3o", + "outputId": "c03887ef-25c2-457b-bfaf-0a57168034ae", + "colab": { + "base_uri": "https://localhost:8080/" + } }, - "execution_count": null, - "outputs": [] + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Mounted at /content/drive\n" + ] + } + ] }, { "cell_type": "markdown", @@ -108,38 +120,10 @@ "import warnings" ], "metadata": { - "id": "whZwvEdKIksm", - "outputId": "799f6c43-026b-49ad-bfb1-ea7bbb54a38a", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 393 - } + "id": "whZwvEdKIksm" }, - "execution_count": 2, - "outputs": [ - { - "output_type": "error", - "ename": "ModuleNotFoundError", - "evalue": "No module named 'mediapipe'", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mmediapipe\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mmp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmediapipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtasks\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpython\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmediapipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtasks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpython\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mvision\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmediapipe\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0msolutions\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmediapipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mframework\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformats\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mlandmark_pb2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'mediapipe'", - "", - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0;32m\nNOTE: If your import is failing due to a missing package, you can\nmanually install dependencies using either !pip or !apt.\n\nTo view examples of installing some common dependencies, click the\n\"Open Examples\" button below.\n\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n" - ], - "errorDetails": { - "actions": [ - { - "action": "open_url", - "actionText": "Open Examples", - "url": "/notebooks/snippets/importing_libraries.ipynb" - } - ] - } - } - ] + "execution_count": 3, + "outputs": [] }, { "cell_type": "code", @@ -196,7 +180,7 @@ " # Then figure out what angle you need to calculate\n", " # Arm, Grip, Back, Arms by Side, Leg, Hip Angle, Calf\n", " if row[0] == 'Arm':\n", - " if self.right_elbow.visibility > self.left_elbow.visibility: # Finds the better side and uses that for angles\n", + " if ((self.right_shoulder.visibility + self.right_elbow.visibility + self.right_wrist.visibility) / 3) > ((self.left_shoulder.visibility + self.left_elbow.visibility + self.left_wrist.visibility) / 3): # Finds the better side and uses that for angles\n", " working_angle = self.angle(self.right_shoulder, self.right_elbow, self.right_wrist)\n", " else:\n", " working_angle = self.angle(self.left_shoulder, self.left_elbow, self.left_wrist)\n", @@ -206,7 +190,7 @@ " return \"Try Bending Your Elbow More\"\n", "\n", " elif row[0] == 'Wrist Angle':\n", - " if self.right_wrist.visibility > self.left_wrist.visibility:\n", + " if ((self.right_elbow.visibility + self.right_wrist.visibility + self.right_thumb.visibility) / 3) > ((self.left_elbow.visibility + self.left_wrist.visibility + self.left_thumb.visibility) / 3):\n", " working_angle = self.angle(self.right_elbow, self.right_wrist, self.right_thumb)\n", " else:\n", " working_angle = self.angle(self.left_elbow, self.left_wrist, self.left_thumb)\n", @@ -217,7 +201,7 @@ "\n", "\n", " elif row[0] == 'Hip Angle':\n", - " if self.right_hip.visibility > self.left_hip.visibility:\n", + " if ((self.right_shoulder.visibility + self.right_hip.visibility + self.right_knee.visibility) / 3) > ((self.left_shoulder.visibility + self.left_hip.visibility + self.left_knee.visibility) / 3):\n", " working_angle = self.angle(self.right_shoulder, self.right_hip, self.right_knee)\n", " else:\n", " working_angle = self.angle(self.left_shoulder, self.left_hip, self.left_knee)\n", @@ -227,7 +211,7 @@ " return \"Try Bending Over More\"\n", "\n", " elif row[0] == 'Arms by Side':\n", - " if self.right_shoulder.visibility > self.left_shoulder.visibility:\n", + " if ((self.right_elbow.visibility + self.right_shoulder.visibility + self.right_hip.visibility) / 3) > ((self.left_elbow.visibility + self.left_shoulder.visibility + self.left_hip.visibility) / 3):\n", " working_angle = self.angle(self.right_elbow, self.right_shoulder, self.right_hip)\n", " else:\n", " working_angle = self.angle(self.left_elbow, self.left_shoulder, self.left_hip)\n", @@ -237,7 +221,7 @@ " return \"Try Bringing Your Arms Somewhat Closer To Your Body\"\n", "\n", " elif row[0] == 'Leg':\n", - " if self.right_knee.visibility > self.left_knee.visibility:\n", + " if ((self.right_hip.visibility + self.right_knee.visibility + self.right_ankle.visibility) / 3) > ((self.left_hip.visibility + self.left_knee.visibility + self.left_ankle.visibility) / 3):\n", " working_angle = self.angle(self.right_hip, self.right_knee, self.right_ankle)\n", " else:\n", " working_angle = self.angle(self.left_hip, self.left_knee, self.left_ankle)\n", @@ -247,7 +231,7 @@ " return \"Try Bending Your Legs More\"\n", "\n", " elif row[0] == 'Calf':\n", - " if self.right_heel.visibility > self.left_heel.visibility:\n", + " if ((self.right_ankle.visibility + self.right_heel.visibility + self.right_foot_index.visibility) / 3) > ((self.left_ankle.visibility + self.left_heel.visibility + self.left_foot_index.visibility) / 3):\n", " working_angle = self.angle(self.right_ankle, self.right_heel, self.right_foot_index)\n", " else:\n", " working_angle = self.angle(self.left_ankle, self.left_heel, self.left_foot_index)\n", @@ -261,7 +245,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": null, + "execution_count": 6, "outputs": [] }, { @@ -475,10 +459,150 @@ "out_video.release()" ], "metadata": { - "id": "GHzmhoO6Jc50" + "id": "GHzmhoO6Jc50", + "outputId": "a0292dd6-07a1-4ee8-d18a-576d9741bc5f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + } }, - "execution_count": null, - "outputs": [] + "execution_count": 7, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "What exercise are you tracking?\n", + "Push Up\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "" + ], + "application/javascript": [ + "\n", + " var video;\n", + " var div = null;\n", + " var stream;\n", + " var captureCanvas;\n", + " var imgElement;\n", + " var labelElement;\n", + "\n", + " var pendingResolve = null;\n", + " var shutdown = false;\n", + "\n", + " function removeDom() {\n", + " stream.getVideoTracks()[0].stop();\n", + " video.remove();\n", + " div.remove();\n", + " video = null;\n", + " div = null;\n", + " stream = null;\n", + " imgElement = null;\n", + " captureCanvas = null;\n", + " labelElement = null;\n", + " }\n", + "\n", + " function onAnimationFrame() {\n", + " if (!shutdown) {\n", + " window.requestAnimationFrame(onAnimationFrame);\n", + " }\n", + " if (pendingResolve) {\n", + " var result = \"\";\n", + " if (!shutdown) {\n", + " captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);\n", + " result = captureCanvas.toDataURL('image/jpeg', 0.8)\n", + " }\n", + " var lp = pendingResolve;\n", + " pendingResolve = null;\n", + " lp(result);\n", + " }\n", + " }\n", + "\n", + " async function createDom() {\n", + " if (div !== null) {\n", + " return stream;\n", + " }\n", + " div = document.createElement('div');\n", + " div.style.border = '2px solid black';\n", + " div.style.padding = '3px';\n", + " div.style.width = '100%';\n", + " div.style.maxWidth = '600px';\n", + " document.body.appendChild(div);\n", + "\n", + "\n", + " video = document.createElement('video');\n", + " video.style.display = 'block';\n", + " video.width = div.clientWidth - 6;\n", + " video.setAttribute('playsinline', '');\n", + " video.onclick = () => { shutdown = true; };\n", + " stream = await navigator.mediaDevices.getUserMedia(\n", + " {video: { facingMode: \"environment\"}});\n", + " div.appendChild(video);\n", + " imgElement = document.createElement('img');\n", + " imgElement.style.position = 'absolute';\n", + " imgElement.style.zIndex = 1;\n", + " imgElement.onclick = () => { shutdown = true; };\n", + " div.appendChild(imgElement);\n", + "\n", + " const instruction = document.createElement('div');\n", + " instruction.innerHTML =\n", + " '' +\n", + " 'click here to stop the video';\n", + " div.appendChild(instruction);\n", + " instruction.onclick = () => { shutdown = true; };\n", + "\n", + " video.srcObject = stream;\n", + " await video.play();\n", + " captureCanvas = document.createElement('canvas');\n", + " captureCanvas.width = 640;\n", + " captureCanvas.height = 480;\n", + " window.requestAnimationFrame(onAnimationFrame);\n", + "\n", + " return stream;\n", + " }\n", + " async function stream_frame() {\n", + " if (shutdown) {\n", + " removeDom();\n", + " shutdown = false;\n", + " return '';\n", + " }\n", + " var preCreate = Date.now();\n", + " stream = await createDom();\n", + "\n", + " var preShow = Date.now();\n", + "\n", + "\n", + "\n", + " var preCapture = Date.now();\n", + " var result = await new Promise(function(resolve, reject) {\n", + " pendingResolve = resolve;\n", + " });\n", + " shutdown = false;\n", + "\n", + " return {'create': preShow - preCreate,\n", + " 'show': preCapture - preShow,\n", + " 'capture': Date.now() - preCapture,\n", + " 'img': result};\n", + " }\n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Good Form\n", + "Try Straightening Your Arm Somewhat\n", + "Good Form\n" + ] + } + ] } ] } \ No newline at end of file From 86db5c9b3b4465063c9f2f59aead18848645d2cc Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:15:58 -0500 Subject: [PATCH 08/12] Fixed angle calc (w/ debug statements) --- Prototype_2_Electric_Boogalooo.ipynb | 56 ++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index 4609a87..38cd598 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyNWN8PShQAAFqcdVLX8FWQs", + "authorship_tag": "ABX9TyOqwpNhw3eY++8XOsP1KDzU", "include_colab_link": true }, "kernelspec": { @@ -68,10 +68,10 @@ ], "metadata": { "id": "8xGt3oqXze3o", - "outputId": "c03887ef-25c2-457b-bfaf-0a57168034ae", "colab": { "base_uri": "https://localhost:8080/" - } + }, + "outputId": "c03887ef-25c2-457b-bfaf-0a57168034ae" }, "execution_count": 2, "outputs": [ @@ -122,7 +122,7 @@ "metadata": { "id": "whZwvEdKIksm" }, - "execution_count": 3, + "execution_count": 1, "outputs": [] }, { @@ -162,10 +162,10 @@ " pointcx = pointc.x - pointb.x\n", " pointcy = pointc.y - pointb.y\n", " pointcz = pointc.z - pointb.z\n", - " lineba = np.sqrt(np.sqrt(((pointax**2) + (pointay**2))**2) + (pointax**2))\n", - " linebc = np.sqrt(np.sqrt(((pointcx**2) + (pointcy**2))**2) + (pointcx**2))\n", - " lineac = np.sqrt(np.sqrt((((pointax - pointcx)**2) + ((pointay - pointcy)**2))**2) + ((pointaz - pointcz)**2))\n", - " return np.arccos(((lineba**2) + (linebc**2) - (lineac**2)) / (2 * lineba * linebc)) * 180 / np.pi\n", + " lineba = np.sqrt((pointax**2) + (pointay**2) + (pointaz**2))\n", + " linebc = np.sqrt((pointcx**2) + (pointcy**2) + (pointcz**2))\n", + " lineac = np.sqrt((lineba**2) + (linebc**2))\n", + " return np.arccos(((lineba**2) + (linebc**2) - (lineac**2)) / (2 * lineba * linebc)) * 180 / np.pi # use law of cos to find angle\n", "\n", " # Feedback function\n", " # Opens the csv for the selected exercise\n", @@ -180,10 +180,16 @@ " # Then figure out what angle you need to calculate\n", " # Arm, Grip, Back, Arms by Side, Leg, Hip Angle, Calf\n", " if row[0] == 'Arm':\n", + " print('right', ((self.right_shoulder.visibility + self.right_elbow.visibility + self.right_wrist.visibility) / 3), 'left', ((self.left_shoulder.visibility + self.left_elbow.visibility + self.left_wrist.visibility) / 3))\n", " if ((self.right_shoulder.visibility + self.right_elbow.visibility + self.right_wrist.visibility) / 3) > ((self.left_shoulder.visibility + self.left_elbow.visibility + self.left_wrist.visibility) / 3): # Finds the better side and uses that for angles\n", + " print('a')\n", " working_angle = self.angle(self.right_shoulder, self.right_elbow, self.right_wrist)\n", " else:\n", + " print('b')\n", " working_angle = self.angle(self.left_shoulder, self.left_elbow, self.left_wrist)\n", + " print(working_angle)\n", + " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", + " return \"Arm Joints Not Visible\"\n", " if working_angle < int(row[1]): # See if the angle is within bounds\n", " return \"Try Straightening Your Arm Somewhat\"\n", " if working_angle > int(row[2]):\n", @@ -194,6 +200,8 @@ " working_angle = self.angle(self.right_elbow, self.right_wrist, self.right_thumb)\n", " else:\n", " working_angle = self.angle(self.left_elbow, self.left_wrist, self.left_thumb)\n", + " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", + " return \"Wrist Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Wrist Somewhat\"\n", " if working_angle > int(row[2]):\n", @@ -205,6 +213,8 @@ " working_angle = self.angle(self.right_shoulder, self.right_hip, self.right_knee)\n", " else:\n", " working_angle = self.angle(self.left_shoulder, self.left_hip, self.left_knee)\n", + " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", + " return \"Hip Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Hip Somewhat\"\n", " if working_angle > int(row[2]):\n", @@ -215,6 +225,8 @@ " working_angle = self.angle(self.right_elbow, self.right_shoulder, self.right_hip)\n", " else:\n", " working_angle = self.angle(self.left_elbow, self.left_shoulder, self.left_hip)\n", + " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", + " return \"Arm/Hip Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Spreading Your Arms Out More\"\n", " if working_angle > int(row[2]):\n", @@ -225,6 +237,8 @@ " working_angle = self.angle(self.right_hip, self.right_knee, self.right_ankle)\n", " else:\n", " working_angle = self.angle(self.left_hip, self.left_knee, self.left_ankle)\n", + " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", + " return \"Leg Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Legs More\"\n", " if working_angle > int(row[2]):\n", @@ -235,6 +249,8 @@ " working_angle = self.angle(self.right_ankle, self.right_heel, self.right_foot_index)\n", " else:\n", " working_angle = self.angle(self.left_ankle, self.left_heel, self.left_foot_index)\n", + " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", + " return \"Calf Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Pointing Your Feet More (Tiptoe position)\"\n", " if working_angle > int(row[2]):\n", @@ -245,7 +261,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": 6, + "execution_count": 19, "outputs": [] }, { @@ -460,13 +476,13 @@ ], "metadata": { "id": "GHzmhoO6Jc50", - "outputId": "a0292dd6-07a1-4ee8-d18a-576d9741bc5f", "colab": { "base_uri": "https://localhost:8080/", - "height": 106 - } + "height": 285 + }, + "outputId": "ee33d84b-a2ee-4c6c-d329-2b36543ff424" }, - "execution_count": 7, + "execution_count": 16, "outputs": [ { "name": "stdout", @@ -597,9 +613,19 @@ "output_type": "stream", "name": "stdout", "text": [ - "Good Form\n", + "right 0.5081661157310009 left 0.4834045519431432\n", + "a\n", + "0.3836904078580625 0.5041786653681622 0.6335727706386282\n", + "-1.4347784071275053e-16\n", "Try Straightening Your Arm Somewhat\n", - "Good Form\n" + "right 0.5045340520640215 left 0.480838676293691\n", + "a\n", + "0.41954266260476114 0.5695087721777218 0.707358669511351\n", + "0.0\n", + "right 0.5034001295765241 left 0.4951862966020902\n", + "a\n", + "0.39034791696895443 0.5047606067738446 0.6380868016443386\n", + "0.0\n" ] } ] From e3895da71103fa798e9292d9cb99662b18b5d3dd Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:36:08 -0500 Subject: [PATCH 09/12] 90 degree error but wanna save latest rev --- Prototype_2_Electric_Boogalooo.ipynb | 103 ++++++++++++++++++--------- 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index 38cd598..aab7eea 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyOqwpNhw3eY++8XOsP1KDzU", + "authorship_tag": "ABX9TyOoSdmIwcnRtNDwE6FOVEpE", "include_colab_link": true }, "kernelspec": { @@ -180,16 +180,11 @@ " # Then figure out what angle you need to calculate\n", " # Arm, Grip, Back, Arms by Side, Leg, Hip Angle, Calf\n", " if row[0] == 'Arm':\n", - " print('right', ((self.right_shoulder.visibility + self.right_elbow.visibility + self.right_wrist.visibility) / 3), 'left', ((self.left_shoulder.visibility + self.left_elbow.visibility + self.left_wrist.visibility) / 3))\n", " if ((self.right_shoulder.visibility + self.right_elbow.visibility + self.right_wrist.visibility) / 3) > ((self.left_shoulder.visibility + self.left_elbow.visibility + self.left_wrist.visibility) / 3): # Finds the better side and uses that for angles\n", - " print('a')\n", " working_angle = self.angle(self.right_shoulder, self.right_elbow, self.right_wrist)\n", " else:\n", - " print('b')\n", " working_angle = self.angle(self.left_shoulder, self.left_elbow, self.left_wrist)\n", " print(working_angle)\n", - " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", - " return \"Arm Joints Not Visible\"\n", " if working_angle < int(row[1]): # See if the angle is within bounds\n", " return \"Try Straightening Your Arm Somewhat\"\n", " if working_angle > int(row[2]):\n", @@ -200,8 +195,6 @@ " working_angle = self.angle(self.right_elbow, self.right_wrist, self.right_thumb)\n", " else:\n", " working_angle = self.angle(self.left_elbow, self.left_wrist, self.left_thumb)\n", - " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", - " return \"Wrist Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Wrist Somewhat\"\n", " if working_angle > int(row[2]):\n", @@ -213,8 +206,6 @@ " working_angle = self.angle(self.right_shoulder, self.right_hip, self.right_knee)\n", " else:\n", " working_angle = self.angle(self.left_shoulder, self.left_hip, self.left_knee)\n", - " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", - " return \"Hip Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Hip Somewhat\"\n", " if working_angle > int(row[2]):\n", @@ -225,8 +216,6 @@ " working_angle = self.angle(self.right_elbow, self.right_shoulder, self.right_hip)\n", " else:\n", " working_angle = self.angle(self.left_elbow, self.left_shoulder, self.left_hip)\n", - " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", - " return \"Arm/Hip Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Spreading Your Arms Out More\"\n", " if working_angle > int(row[2]):\n", @@ -237,8 +226,6 @@ " working_angle = self.angle(self.right_hip, self.right_knee, self.right_ankle)\n", " else:\n", " working_angle = self.angle(self.left_hip, self.left_knee, self.left_ankle)\n", - " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", - " return \"Leg Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Legs More\"\n", " if working_angle > int(row[2]):\n", @@ -249,8 +236,6 @@ " working_angle = self.angle(self.right_ankle, self.right_heel, self.right_foot_index)\n", " else:\n", " working_angle = self.angle(self.left_ankle, self.left_heel, self.left_foot_index)\n", - " if str(working_angle) == 'nan': # Check to see if angle is actually present\n", - " return \"Calf Joints Not Visible\"\n", " if working_angle < int(row[1]):\n", " return \"Try Pointing Your Feet More (Tiptoe position)\"\n", " if working_angle > int(row[2]):\n", @@ -261,7 +246,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": 19, + "execution_count": 22, "outputs": [] }, { @@ -478,11 +463,11 @@ "id": "GHzmhoO6Jc50", "colab": { "base_uri": "https://localhost:8080/", - "height": 285 + "height": 1000 }, - "outputId": "ee33d84b-a2ee-4c6c-d329-2b36543ff424" + "outputId": "097010c7-cdfd-4860-d1b6-cb01c4b68245" }, - "execution_count": 16, + "execution_count": 23, "outputs": [ { "name": "stdout", @@ -613,19 +598,73 @@ "output_type": "stream", "name": "stdout", "text": [ - "right 0.5081661157310009 left 0.4834045519431432\n", - "a\n", - "0.3836904078580625 0.5041786653681622 0.6335727706386282\n", - "-1.4347784071275053e-16\n", + "90.0\n", "Try Straightening Your Arm Somewhat\n", - "right 0.5045340520640215 left 0.480838676293691\n", - "a\n", - "0.41954266260476114 0.5695087721777218 0.707358669511351\n", - "0.0\n", - "right 0.5034001295765241 left 0.4951862966020902\n", - "a\n", - "0.39034791696895443 0.5047606067738446 0.6380868016443386\n", - "0.0\n" + "90.00000000000001\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.00000000000001\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.00000000000001\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.00000000000001\n", + "89.99999999999999\n", + "90.0\n", + "90.0\n", + "89.99999999999999\n", + "90.0\n", + "89.99999999999999\n", + "90.00000000000001\n", + "90.0\n", + "89.99999999999999\n", + "90.0\n", + "90.0\n", + "90.00000000000001\n", + "90.00000000000001\n", + "89.99999999999999\n", + "90.0\n", + "90.00000000000001\n", + "90.00000000000001\n", + "90.00000000000001\n", + "90.0\n", + "90.00000000000001\n", + "90.0\n", + "90.00000000000001\n", + "90.0\n", + "90.0\n", + "90.00000000000001\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.0\n", + "90.00000000000001\n", + "90.0\n", + "90.0\n", + "90.00000000000001\n", + "90.0\n", + "90.00000000000001\n" ] } ] From 20406f852712615c34bee525291a54f14cfc918c Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Fri, 7 Jun 2024 10:42:32 -0500 Subject: [PATCH 10/12] fixed the 90 degree issue and implemented correct angle calculations (prob more optimized tho tbh) --- Prototype_2_Electric_Boogalooo.ipynb | 135 ++++++++++++--------------- 1 file changed, 59 insertions(+), 76 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index aab7eea..04effd9 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyOoSdmIwcnRtNDwE6FOVEpE", + "authorship_tag": "ABX9TyP54LxKBJts0KXl7EfJYOpo", "include_colab_link": true }, "kernelspec": { @@ -41,7 +41,7 @@ "execution_count": 1, "metadata": { "id": "gmwahO7oITMz", - "outputId": "110ba097-a5c4-4494-a7c1-aa65c48dcfdc", + "outputId": "0da9dc4e-93dc-42cf-b100-08d7b4c71d37", "colab": { "base_uri": "https://localhost:8080/" } @@ -51,7 +51,7 @@ "output_type": "stream", "name": "stdout", "text": [ - "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m33.9/33.9 MB\u001b[0m \u001b[31m26.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m33.9/33.9 MB\u001b[0m \u001b[31m25.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25h" ] } @@ -71,7 +71,7 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "outputId": "c03887ef-25c2-457b-bfaf-0a57168034ae" + "outputId": "da995b40-a76c-4fb6-aa62-053f9857a59f" }, "execution_count": 2, "outputs": [ @@ -122,7 +122,7 @@ "metadata": { "id": "whZwvEdKIksm" }, - "execution_count": 1, + "execution_count": 3, "outputs": [] }, { @@ -164,7 +164,7 @@ " pointcz = pointc.z - pointb.z\n", " lineba = np.sqrt((pointax**2) + (pointay**2) + (pointaz**2))\n", " linebc = np.sqrt((pointcx**2) + (pointcy**2) + (pointcz**2))\n", - " lineac = np.sqrt((lineba**2) + (linebc**2))\n", + " lineac = np.sqrt(((pointax - pointcx)**2) + ((pointay - pointcy)**2) + ((pointaz - pointcz)**2))\n", " return np.arccos(((lineba**2) + (linebc**2) - (lineac**2)) / (2 * lineba * linebc)) * 180 / np.pi # use law of cos to find angle\n", "\n", " # Feedback function\n", @@ -246,7 +246,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": 22, + "execution_count": 9, "outputs": [] }, { @@ -463,11 +463,11 @@ "id": "GHzmhoO6Jc50", "colab": { "base_uri": "https://localhost:8080/", - "height": 1000 + "height": 946 }, - "outputId": "097010c7-cdfd-4860-d1b6-cb01c4b68245" + "outputId": "1e6496c0-a400-42f6-c3e7-32bc40138807" }, - "execution_count": 23, + "execution_count": 10, "outputs": [ { "name": "stdout", @@ -598,73 +598,56 @@ "output_type": "stream", "name": "stdout", "text": [ - "90.0\n", + "151.74670426095005\n", + "Try Straightening Your Legs More\n", + "145.63584187183648\n", + "Try Straightening Your Hip Somewhat\n", + "125.48940335322602\n", + "Try Straightening Your Arm Somewhat\n", + "119.90699298115345\n", + "131.5003810391885\n", + "Try Straightening Your Hip Somewhat\n", + "144.48894921799766\n", + "148.0784247451263\n", + "142.3273248196901\n", + "151.00213414568185\n", + "143.7034300667958\n", + "151.03920238505685\n", + "140.1864742235204\n", + "151.03631684921675\n", + "137.69514306790325\n", + "Good Form\n", + "136.23460516244432\n", + "145.3138472669328\n", + "64.77438320935693\n", + "Try Straightening Your Arm Somewhat\n", + "132.3635310195223\n", + "Good Form\n", + "162.21729692070457\n", + "Try Straightening Your Hip Somewhat\n", + "160.55587511041517\n", + "113.46127060312281\n", + "Try Straightening Your Arm Somewhat\n", + "144.24639824297526\n", + "Try Straightening Your Hip Somewhat\n", + "142.63812073569318\n", + "73.9877011177219\n", + "Try Straightening Your Arm Somewhat\n", + "111.79160583383167\n", + "96.26150067712139\n", + "161.21508426527072\n", + "Try Straightening Your Hip Somewhat\n", + "49.27067916017131\n", "Try Straightening Your Arm Somewhat\n", - "90.00000000000001\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.00000000000001\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.00000000000001\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.00000000000001\n", - "89.99999999999999\n", - "90.0\n", - "90.0\n", - "89.99999999999999\n", - "90.0\n", - "89.99999999999999\n", - "90.00000000000001\n", - "90.0\n", - "89.99999999999999\n", - "90.0\n", - "90.0\n", - "90.00000000000001\n", - "90.00000000000001\n", - "89.99999999999999\n", - "90.0\n", - "90.00000000000001\n", - "90.00000000000001\n", - "90.00000000000001\n", - "90.0\n", - "90.00000000000001\n", - "90.0\n", - "90.00000000000001\n", - "90.0\n", - "90.0\n", - "90.00000000000001\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.0\n", - "90.00000000000001\n", - "90.0\n", - "90.0\n", - "90.00000000000001\n", - "90.0\n", - "90.00000000000001\n" + "127.23101723124641\n", + "135.6345074470225\n", + "Try Straightening Your Legs More\n", + "160.15049269556965\n", + "Try Straightening Your Hip Somewhat\n", + "155.35445283586643\n", + "168.57687558518435\n", + "164.40498506301168\n", + "135.97759158323575\n" ] } ] From 9f9fb5d311c4434cf2249c8874c467e6ffb67e42 Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Fri, 7 Jun 2024 10:58:14 -0500 Subject: [PATCH 11/12] added vis threshold + feedback --- Prototype_2_Electric_Boogalooo.ipynb | 60 +++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index 04effd9..9b4a8b1 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyP54LxKBJts0KXl7EfJYOpo", + "authorship_tag": "ABX9TyPkTtXM08RbtO4T0HwiFsGT", "include_colab_link": true }, "kernelspec": { @@ -151,6 +151,7 @@ " self.right_heel = pll[30]\n", " self.left_foot_index = pll[31]\n", " self.right_foot_index = pll[32]\n", + " self.threshold = 66\n", "\n", " # Returns the angle formed by any three points, with pointb as the center\n", " def angle(self, pointa, pointb, pointc):\n", @@ -180,21 +181,34 @@ " # Then figure out what angle you need to calculate\n", " # Arm, Grip, Back, Arms by Side, Leg, Hip Angle, Calf\n", " if row[0] == 'Arm':\n", - " if ((self.right_shoulder.visibility + self.right_elbow.visibility + self.right_wrist.visibility) / 3) > ((self.left_shoulder.visibility + self.left_elbow.visibility + self.left_wrist.visibility) / 3): # Finds the better side and uses that for angles\n", + " right_vis = (self.right_shoulder.visibility + self.right_elbow.visibility + self.right_wrist.visibility) / 3\n", + " left_vis = (self.left_shoulder.visibility + self.left_elbow.visibility + self.left_wrist.visibility) / 3\n", + " if right_vis > left_vis: # Finds the better side and uses that for angles\n", + " if right_vis < self.threshold:\n", + " return \"Right Arm Isn't Visible\"\n", " working_angle = self.angle(self.right_shoulder, self.right_elbow, self.right_wrist)\n", " else:\n", + " if left_vis < self.threshold:\n", + " return \"Left Arm Isn't Visible\"\n", " working_angle = self.angle(self.left_shoulder, self.left_elbow, self.left_wrist)\n", - " print(working_angle)\n", + "\n", " if working_angle < int(row[1]): # See if the angle is within bounds\n", " return \"Try Straightening Your Arm Somewhat\"\n", " if working_angle > int(row[2]):\n", " return \"Try Bending Your Elbow More\"\n", "\n", " elif row[0] == 'Wrist Angle':\n", - " if ((self.right_elbow.visibility + self.right_wrist.visibility + self.right_thumb.visibility) / 3) > ((self.left_elbow.visibility + self.left_wrist.visibility + self.left_thumb.visibility) / 3):\n", + " right_vis = (self.right_elbow.visibility + self.right_wrist.visibility + self.right_thumb.visibility) / 3\n", + " left_vis = (self.left_elbow.visibility + self.left_wrist.visibility + self.left_thumb.visibility) / 3\n", + " if right_vis > left_vis:\n", + " if right_vis < self.threshold:\n", + " return \"Right Wrist Isn't Visible\"\n", " working_angle = self.angle(self.right_elbow, self.right_wrist, self.right_thumb)\n", " else:\n", + " if left_vis < self.threshold:\n", + " return \"Left Wrist Isn't Visible\"\n", " working_angle = self.angle(self.left_elbow, self.left_wrist, self.left_thumb)\n", + "\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Wrist Somewhat\"\n", " if working_angle > int(row[2]):\n", @@ -202,40 +216,68 @@ "\n", "\n", " elif row[0] == 'Hip Angle':\n", - " if ((self.right_shoulder.visibility + self.right_hip.visibility + self.right_knee.visibility) / 3) > ((self.left_shoulder.visibility + self.left_hip.visibility + self.left_knee.visibility) / 3):\n", + " right_vis = (self.right_shoulder.visibility + self.right_hip.visibility + self.right_knee.visibility) / 3\n", + " left_vis = (self.left_shoulder.visibility + self.left_hip.visibility + self.left_knee.visibility) / 3\n", + " if right_vis > left_vis:\n", + " if right_vis < self.threshold:\n", + " return \"Right Side of Body Isn't Visible\"\n", " working_angle = self.angle(self.right_shoulder, self.right_hip, self.right_knee)\n", " else:\n", + " if left_vis < self.threshold:\n", + " return \"Left Side of Body Isn't Visible\"\n", " working_angle = self.angle(self.left_shoulder, self.left_hip, self.left_knee)\n", + "\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Hip Somewhat\"\n", " if working_angle > int(row[2]):\n", " return \"Try Bending Over More\"\n", "\n", " elif row[0] == 'Arms by Side':\n", - " if ((self.right_elbow.visibility + self.right_shoulder.visibility + self.right_hip.visibility) / 3) > ((self.left_elbow.visibility + self.left_shoulder.visibility + self.left_hip.visibility) / 3):\n", + " right_vis = (self.right_elbow.visibility + self.right_shoulder.visibility + self.right_hip.visibility) / 3\n", + " left_vis = (self.left_elbow.visibility + self.left_shoulder.visibility + self.left_hip.visibility) / 3\n", + " if right_vis > left_vis:\n", + " if right_vis < self.threshold:\n", + " return \"Right Arm and Hip Isn't Visible\"\n", " working_angle = self.angle(self.right_elbow, self.right_shoulder, self.right_hip)\n", " else:\n", + " if left_vis < self.threshold:\n", + " return \"Left Arm and Hip Isn't Visible\"\n", " working_angle = self.angle(self.left_elbow, self.left_shoulder, self.left_hip)\n", + "\n", " if working_angle < int(row[1]):\n", " return \"Try Spreading Your Arms Out More\"\n", " if working_angle > int(row[2]):\n", " return \"Try Bringing Your Arms Somewhat Closer To Your Body\"\n", "\n", " elif row[0] == 'Leg':\n", - " if ((self.right_hip.visibility + self.right_knee.visibility + self.right_ankle.visibility) / 3) > ((self.left_hip.visibility + self.left_knee.visibility + self.left_ankle.visibility) / 3):\n", + " right_vis = (self.right_hip.visibility + self.right_knee.visibility + self.right_ankle.visibility) / 3\n", + " left_vis = (self.left_hip.visibility + self.left_knee.visibility + self.left_ankle.visibility) / 3\n", + " if right_vis > left_vis:\n", + " if right_vis < self.threshold:\n", + " return \"Right Leg Isn't Visible\"\n", " working_angle = self.angle(self.right_hip, self.right_knee, self.right_ankle)\n", " else:\n", + " if left_vis < self.threshold:\n", + " return \"Left Leg Isn't Visible\"\n", " working_angle = self.angle(self.left_hip, self.left_knee, self.left_ankle)\n", + "\n", " if working_angle < int(row[1]):\n", " return \"Try Straightening Your Legs More\"\n", " if working_angle > int(row[2]):\n", " return \"Try Bending Your Legs More\"\n", "\n", " elif row[0] == 'Calf':\n", - " if ((self.right_ankle.visibility + self.right_heel.visibility + self.right_foot_index.visibility) / 3) > ((self.left_ankle.visibility + self.left_heel.visibility + self.left_foot_index.visibility) / 3):\n", + " right_vis = (self.right_ankle.visibility + self.right_heel.visibility + self.right_foot_index.visibility) / 3\n", + " left_vis = (self.left_ankle.visibility + self.left_heel.visibility + self.left_foot_index.visibility) / 3\n", + " if right_vis > left_vis:\n", + " if right_vis < self.threshold:\n", + " return \"Right Foot Isn't Visible\"\n", " working_angle = self.angle(self.right_ankle, self.right_heel, self.right_foot_index)\n", " else:\n", + " if left_vis < self.threshold:\n", + " return \"Left Foot Isn't Visible\"\n", " working_angle = self.angle(self.left_ankle, self.left_heel, self.left_foot_index)\n", + "\n", " if working_angle < int(row[1]):\n", " return \"Try Pointing Your Feet More (Tiptoe position)\"\n", " if working_angle > int(row[2]):\n", @@ -246,7 +288,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": 9, + "execution_count": 11, "outputs": [] }, { From 3e1edae3298f227e93e0357934fa4ecda280216c Mon Sep 17 00:00:00 2001 From: pythonioncoder <70725762+pythonioncoder@users.noreply.github.com> Date: Fri, 7 Jun 2024 17:15:51 -0500 Subject: [PATCH 12/12] fixed threshold val --- Prototype_2_Electric_Boogalooo.ipynb | 84 ++++++++-------------------- 1 file changed, 22 insertions(+), 62 deletions(-) diff --git a/Prototype_2_Electric_Boogalooo.ipynb b/Prototype_2_Electric_Boogalooo.ipynb index 9b4a8b1..9b247bc 100644 --- a/Prototype_2_Electric_Boogalooo.ipynb +++ b/Prototype_2_Electric_Boogalooo.ipynb @@ -5,7 +5,7 @@ "colab": { "provenance": [], "mount_file_id": "1YJfEK8zha4PfUk2yP9y-XbO4vtmn83gE", - "authorship_tag": "ABX9TyPkTtXM08RbtO4T0HwiFsGT", + "authorship_tag": "ABX9TyOyhs6wOIUjt8ldGL3tny7R", "include_colab_link": true }, "kernelspec": { @@ -38,7 +38,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "id": "gmwahO7oITMz", "outputId": "0da9dc4e-93dc-42cf-b100-08d7b4c71d37", @@ -71,15 +71,15 @@ "colab": { "base_uri": "https://localhost:8080/" }, - "outputId": "da995b40-a76c-4fb6-aa62-053f9857a59f" + "outputId": "a819fc96-3036-4e7e-8905-925448d12589" }, - "execution_count": 2, + "execution_count": 25, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ - "Mounted at /content/drive\n" + "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n" ] } ] @@ -122,7 +122,7 @@ "metadata": { "id": "whZwvEdKIksm" }, - "execution_count": 3, + "execution_count": 26, "outputs": [] }, { @@ -151,7 +151,7 @@ " self.right_heel = pll[30]\n", " self.left_foot_index = pll[31]\n", " self.right_foot_index = pll[32]\n", - " self.threshold = 66\n", + " self.threshold = .66\n", "\n", " # Returns the angle formed by any three points, with pointb as the center\n", " def angle(self, pointa, pointb, pointc):\n", @@ -288,7 +288,7 @@ "metadata": { "id": "RHyJwan8acCz" }, - "execution_count": 11, + "execution_count": 29, "outputs": [] }, { @@ -505,18 +505,18 @@ "id": "GHzmhoO6Jc50", "colab": { "base_uri": "https://localhost:8080/", - "height": 946 + "height": 231 }, - "outputId": "1e6496c0-a400-42f6-c3e7-32bc40138807" + "outputId": "e733f64b-4fd4-4081-c2b0-06fce7b19b0a" }, - "execution_count": 10, + "execution_count": 30, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "What exercise are you tracking?\n", - "Push Up\n" + "Bicep Curl\n" ] }, { @@ -640,56 +640,16 @@ "output_type": "stream", "name": "stdout", "text": [ - "151.74670426095005\n", - "Try Straightening Your Legs More\n", - "145.63584187183648\n", - "Try Straightening Your Hip Somewhat\n", - "125.48940335322602\n", - "Try Straightening Your Arm Somewhat\n", - "119.90699298115345\n", - "131.5003810391885\n", - "Try Straightening Your Hip Somewhat\n", - "144.48894921799766\n", - "148.0784247451263\n", - "142.3273248196901\n", - "151.00213414568185\n", - "143.7034300667958\n", - "151.03920238505685\n", - "140.1864742235204\n", - "151.03631684921675\n", - "137.69514306790325\n", - "Good Form\n", - "136.23460516244432\n", - "145.3138472669328\n", - "64.77438320935693\n", - "Try Straightening Your Arm Somewhat\n", - "132.3635310195223\n", - "Good Form\n", - "162.21729692070457\n", - "Try Straightening Your Hip Somewhat\n", - "160.55587511041517\n", - "113.46127060312281\n", - "Try Straightening Your Arm Somewhat\n", - "144.24639824297526\n", - "Try Straightening Your Hip Somewhat\n", - "142.63812073569318\n", - "73.9877011177219\n", - "Try Straightening Your Arm Somewhat\n", - "111.79160583383167\n", - "96.26150067712139\n", - "161.21508426527072\n", - "Try Straightening Your Hip Somewhat\n", - "49.27067916017131\n", - "Try Straightening Your Arm Somewhat\n", - "127.23101723124641\n", - "135.6345074470225\n", - "Try Straightening Your Legs More\n", - "160.15049269556965\n", - "Try Straightening Your Hip Somewhat\n", - "155.35445283586643\n", - "168.57687558518435\n", - "164.40498506301168\n", - "135.97759158323575\n" + "Right Arm Isn't Visible\n", + "Left Arm Isn't Visible\n", + "Right Arm Isn't Visible\n", + "Left Arm Isn't Visible\n", + "Right Arm Isn't Visible\n", + "Left Arm Isn't Visible\n", + "Right Arm Isn't Visible\n", + "Left Arm Isn't Visible\n", + "Right Arm Isn't Visible\n", + "Left Arm Isn't Visible\n" ] } ]