312 lines (311 with data), 16.4 kB
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import cv2\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import os\n",
"import urllib.request\n",
"import sys\n",
"import torch\n",
"import time\n",
"import datetime\n",
"\n",
"from torchvision import transforms\n",
"from PIL import Image\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"YOLOV7_MODEL = [\n",
" \"https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt\",\n",
" \"https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt\",\n",
" \"https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7x.pt\",\n",
" \"https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-w6.pt\",\n",
" \"https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-e6.pt\",\n",
" \"https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-d6.pt\",\n",
" \"https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-e6e.pt\",\n",
" \"https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-w6-pose.pt\",\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def get_yolov7_model(modelistid=1):\n",
" \"\"\"\n",
" Download YoloV7 model from a yoloV7 model list\n",
" \"\"\"\n",
" modelid = YOLOV7_MODEL[modelistid]\n",
"\n",
" if not os.path.exists(modelid):\n",
" print(\"Downloading the model:\",\n",
" os.path.basename(modelid), \"from:\", modelid)\n",
" urllib.request.urlretrieve(modelid, \n",
" filename=os.path.basename(modelid))\n",
" print(\"Done\\n\")\n",
" !ls yolo*.pt -lh\n",
"\n",
" if os.path.exists(modelid):\n",
" print(\"Downloaded model files:\")\n",
" !ls yolo*.pt -lh"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"from utils.datasets import letterbox\n",
"from utils.general import non_max_suppression_kpt\n",
"from utils.plots import output_to_keypoint, plot_skeleton_kpts"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def image_view(imagefile, w=15, h=10):\n",
" \"\"\"\n",
" Displaying an image from an image file\n",
" \"\"\"\n",
" %matplotlib inline\n",
" plt.figure(figsize=(w, h))\n",
" plt.axis('off')\n",
" plt.imshow(cv2.cvtColor(cv2.imread(imagefile), \n",
" cv2.COLOR_BGR2RGB))"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"def running_inference(image):\n",
" global model\n",
" \"\"\"\n",
" Running yolov7 model inference\n",
" \"\"\"\n",
" image = letterbox(image, 960, \n",
" stride=64,\n",
" auto=True)[0] # shape: (567, 960, 3)\n",
" image = transforms.ToTensor()(image) # torch.Size([3, 567, 960])\n",
"\n",
" if torch.cuda.is_available():\n",
" image = image.half().to(device)\n",
"\n",
" image = image.unsqueeze(0) # torch.Size([1, 3, 567, 960])\n",
"\n",
" with torch.no_grad():\n",
" output, _ = model(image)\n",
"\n",
" return output, image"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"def loading_yolov7_model(yolomodel):\n",
" \"\"\"\n",
" Loading yolov7 model\n",
" \"\"\"\n",
" print(\"Loading model:\", yolomodel)\n",
" model = torch.load(yolomodel, map_location=device)['model']\n",
" model.float().eval()\n",
"\n",
" if torch.cuda.is_available():\n",
" # half() turns predictions into float16 tensors\n",
" # which significantly lowers inference time\n",
" model.half().to(device)\n",
"\n",
" return model, yolomodel"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Downloading the model: yolov7-tiny.pt from: https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt\n",
"Done\n",
"\n",
"-rw-r--r-- 1 g g 13M Aug 16 21:30 yolov7-tiny.pt\n"
]
}
],
"source": [
"model = get_yolov7_model(0)\n"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loading the model...\n",
"Loading model: yolov7-tiny.pt\n",
"Using the yolov7-tiny.pt model\n",
"Done\n"
]
}
],
"source": [
"YOLOV7MODEL = os.path.basename(YOLOV7_MODEL[0])\n",
"\n",
"try:\n",
" print(\"Loading the model...\")\n",
" model, yolomodel = loading_yolov7_model(yolomodel=YOLOV7MODEL)\n",
" print(\"Using the\", YOLOV7MODEL, \"model\")\n",
" print(\"Done\")\n",
"\n",
"except:\n",
" print(\"[Error] Cannot load the model\", YOLOV7MODEL)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"def draw_keypoints(output, image, confidence=0.25, threshold=0.65):\n",
" \"\"\"\n",
" Draw YoloV7 pose keypoints\n",
" \"\"\"\n",
" output = non_max_suppression_kpt(\n",
" output,\n",
" confidence, # Confidence Threshold\n",
" threshold, # IoU Threshold\n",
" nc=model.yaml['nc'], # Number of Classes\n",
" nkpt=model.yaml['nkpt'], # Number of Keypoints\n",
" kpt_label=True)\n",
"\n",
" with torch.no_grad():\n",
" output = output_to_keypoint(output)\n",
"\n",
" nimg = image[0].permute(1, 2, 0) * 255\n",
" nimg = cv2.cvtColor(nimg.cpu().numpy().astype(np.uint8), cv2.COLOR_RGB2BGR)\n",
"\n",
" for idx in range(output.shape[0]):\n",
" plot_skeleton_kpts(nimg, output[idx, 7:].T, 3)\n",
"\n",
" return nimg"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n"
]
},
{
"ename": "AttributeError",
"evalue": "'Upsample' object has no attribute 'recompute_scale_factor'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[25], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m imagefile \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39m../assets/messi.jpg\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m 2\u001b[0m \u001b[39mprint\u001b[39m(os\u001b[39m.\u001b[39mpath\u001b[39m.\u001b[39mexists(imagefile))\n\u001b[0;32m----> 3\u001b[0m output, image \u001b[39m=\u001b[39m running_inference(cv2\u001b[39m.\u001b[39;49mimread(imagefile))\n\u001b[1;32m 4\u001b[0m pose_image \u001b[39m=\u001b[39m draw_keypoints(output, image, confidence\u001b[39m=\u001b[39m\u001b[39m0.25\u001b[39m, threshold\u001b[39m=\u001b[39m\u001b[39m0.65\u001b[39m)\n\u001b[1;32m 6\u001b[0m plt\u001b[39m.\u001b[39mfigure(figsize\u001b[39m=\u001b[39m(\u001b[39m30\u001b[39m, \u001b[39m7\u001b[39m))\n",
"Cell \u001b[0;32mIn[23], line 17\u001b[0m, in \u001b[0;36mrunning_inference\u001b[0;34m(image)\u001b[0m\n\u001b[1;32m 14\u001b[0m image \u001b[39m=\u001b[39m image\u001b[39m.\u001b[39munsqueeze(\u001b[39m0\u001b[39m) \u001b[39m# torch.Size([1, 3, 567, 960])\u001b[39;00m\n\u001b[1;32m 16\u001b[0m \u001b[39mwith\u001b[39;00m torch\u001b[39m.\u001b[39mno_grad():\n\u001b[0;32m---> 17\u001b[0m output, _ \u001b[39m=\u001b[39m model(image)\n\u001b[1;32m 19\u001b[0m \u001b[39mreturn\u001b[39;00m output, image\n",
"File \u001b[0;32m~/.local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n",
"File \u001b[0;32m~/Documents/autoposture/repo/landmark_extraction_yolo/models/yolo.py:514\u001b[0m, in \u001b[0;36mModel.forward\u001b[0;34m(self, x, augment, profile)\u001b[0m\n\u001b[1;32m 512\u001b[0m \u001b[39mreturn\u001b[39;00m torch\u001b[39m.\u001b[39mcat(y, \u001b[39m1\u001b[39m), \u001b[39mNone\u001b[39;00m \u001b[39m# augmented inference, train\u001b[39;00m\n\u001b[1;32m 513\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m--> 514\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mforward_once(x, profile)\n",
"File \u001b[0;32m~/Documents/autoposture/repo/landmark_extraction_yolo/models/yolo.py:540\u001b[0m, in \u001b[0;36mModel.forward_once\u001b[0;34m(self, x, profile)\u001b[0m\n\u001b[1;32m 537\u001b[0m dt\u001b[39m.\u001b[39mappend((time_synchronized() \u001b[39m-\u001b[39m t) \u001b[39m*\u001b[39m \u001b[39m100\u001b[39m)\n\u001b[1;32m 538\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39m%10.1f\u001b[39;00m\u001b[39m%10.0f\u001b[39;00m\u001b[39m%10.1f\u001b[39;00m\u001b[39mms \u001b[39m\u001b[39m%-40s\u001b[39;00m\u001b[39m'\u001b[39m \u001b[39m%\u001b[39m (o, m\u001b[39m.\u001b[39mnp, dt[\u001b[39m-\u001b[39m\u001b[39m1\u001b[39m], m\u001b[39m.\u001b[39mtype))\n\u001b[0;32m--> 540\u001b[0m x \u001b[39m=\u001b[39m m(x) \u001b[39m# run\u001b[39;00m\n\u001b[1;32m 542\u001b[0m y\u001b[39m.\u001b[39mappend(x \u001b[39mif\u001b[39;00m m\u001b[39m.\u001b[39mi \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39msave \u001b[39melse\u001b[39;00m \u001b[39mNone\u001b[39;00m) \u001b[39m# save output\u001b[39;00m\n\u001b[1;32m 544\u001b[0m \u001b[39mif\u001b[39;00m profile:\n",
"File \u001b[0;32m~/.local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n",
"File \u001b[0;32m~/.local/lib/python3.11/site-packages/torch/nn/modules/upsampling.py:157\u001b[0m, in \u001b[0;36mUpsample.forward\u001b[0;34m(self, input)\u001b[0m\n\u001b[1;32m 155\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mforward\u001b[39m(\u001b[39mself\u001b[39m, \u001b[39minput\u001b[39m: Tensor) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m Tensor:\n\u001b[1;32m 156\u001b[0m \u001b[39mreturn\u001b[39;00m F\u001b[39m.\u001b[39minterpolate(\u001b[39minput\u001b[39m, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39msize, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mscale_factor, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mmode, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39malign_corners,\n\u001b[0;32m--> 157\u001b[0m recompute_scale_factor\u001b[39m=\u001b[39m\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mrecompute_scale_factor)\n",
"File \u001b[0;32m~/.local/lib/python3.11/site-packages/torch/nn/modules/module.py:1614\u001b[0m, in \u001b[0;36mModule.__getattr__\u001b[0;34m(self, name)\u001b[0m\n\u001b[1;32m 1612\u001b[0m \u001b[39mif\u001b[39;00m name \u001b[39min\u001b[39;00m modules:\n\u001b[1;32m 1613\u001b[0m \u001b[39mreturn\u001b[39;00m modules[name]\n\u001b[0;32m-> 1614\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mAttributeError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39m'\u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m object has no attribute \u001b[39m\u001b[39m'\u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mformat(\n\u001b[1;32m 1615\u001b[0m \u001b[39mtype\u001b[39m(\u001b[39mself\u001b[39m)\u001b[39m.\u001b[39m\u001b[39m__name__\u001b[39m, name))\n",
"\u001b[0;31mAttributeError\u001b[0m: 'Upsample' object has no attribute 'recompute_scale_factor'"
]
}
],
"source": [
"imagefile = \"../assets/messi.jpg\"\n",
"output, image = running_inference(cv2.imread(imagefile))\n",
"pose_image = draw_keypoints(output, image, confidence=0.25, threshold=0.65)\n",
"\n",
"plt.figure(figsize=(30, 7))\n",
"plt.axis(\"off\")\n",
"plt.imshow(pose_image)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"output, image = running_inference(cv2.imread(imagefile))\n",
"pose_image = draw_keypoints(output, image, confidence=0.25, threshold=0.65)\n",
"\n",
"plt.figure(figsize=(30, 7))\n",
"plt.axis(\"off\")\n",
"plt.imshow(pose_image)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}