日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

tensorflow官方posenet模型解析

發布時間:2023/12/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tensorflow官方posenet模型解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

tensorflow官方有個姿態估計項目,這個輸入和openpose還有點不一樣,這里寫個單人情況下的模型輸出解析方案。

國際慣例,參考博客:

博客: 使用 TensorFlow.js 在瀏覽器端上實現實時人體姿勢檢測

tensorflow中posnet的IOS代碼

解析

不要下載官方overview網址下的posenet模型multi_person_mobilenet_v1_075_float.tflite,要去下載IOS端的posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite模型,在github上一搜有一堆,文末放網盤下載地址。

讀取模型

先載入必要的工具包:

import numpy as np import tensorflow as tf import cv2 as cv import matplotlib.pyplot as plt import time

使用tflite載入模型文件

model = tf.lite.Interpreter('posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite') model.allocate_tensors() input_details = model.get_input_details() output_details = model.get_output_details()

看看輸入輸出分別是什么

print(input_details) print(output_details) ''' [{'name': 'sub_2', 'index': 93, 'shape': array([ 1, 257, 257, 3], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}] [{'name': 'MobilenetV1/heatmap_2/BiasAdd', 'index': 87, 'shape': array([ 1, 9, 9, 17], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}, {'name': 'MobilenetV1/offset_2/BiasAdd', 'index': 90, 'shape': array([ 1, 9, 9, 34], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}, {'name': 'MobilenetV1/displacement_fwd_2/BiasAdd', 'index': 84, 'shape': array([ 1, 9, 9, 32], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}, {'name': 'MobilenetV1/displacement_bwd_2/BiasAdd', 'index': 81, 'shape': array([ 1, 9, 9, 32], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}] '''

很容易看出輸入是(257,257)尺寸的彩色圖像。

輸出就比較麻煩了,有兩塊:(9,9,17)的稱為heatmap的熱度圖;(9,9,34)的稱為offset的偏移圖。其實想想也能知道,熱度圖定位關節的大概位置,用偏移圖做進一步的矯正。接下來逐步分析怎么利用這兩個輸出將關節位置定位的。

輸入圖像推斷

必須將圖像resize一下再丟進去,但是tensorflowjs里面說不用resize的方法,我還沒試過。

img = cv.imread('../../photo/1.jpeg') input_img = tf.reshape(tf.image.resize(img, [257,257]), [1,257,257,3]) floating_model = input_details[0]['dtype'] == np.float32 if floating_model:input_img = (np.float32(input_img) - 127.5) / 127.5 model.set_tensor(input_details[0]['index'], input_img) start = time.time() model.invoke() print('time:',time.time()-start) output_data = model.get_tensor(output_details[0]['index']) offset_data = model.get_tensor(output_details[1]['index']) heatmaps = np.squeeze(output_data) offsets = np.squeeze(offset_data) print("output shape: {}".format(output_data.shape)) ''' time: 0.12212681770324707 output shape: (1, 9, 9, 17) '''

可視化變換后的圖

show_img = np.squeeze((input_img.copy()*127.5+127.5)/255.0)[:,:,::-1] show_img = np.array(show_img*255,np.uint8) plt.imshow(show_img) plt.axis('off')

解析輸出

一句話概括原理:熱度圖將圖像劃分網格,每個網格的得分代表當前關節在此網格點附近的概率;偏移圖代表xy兩個坐標相對于網格點的偏移情況。

假設提取第2個關節的坐標位置:

  • 先得到最可能的網格點:

    i=1 joint_heatmap = heatmaps[...,i] max_val_pos = np.squeeze(np.argwhere(joint_heatmap==np.max(joint_heatmap))) remap_pos = np.array(max_val_pos/8*257,dtype=np.int32)
  • 把offset加上去,前1-17是x坐標偏移,后18-34是y坐標偏移

    refine_pos = np.zeros((2),dtype=int) refine_pos[0] = int(remap_pos[0] + offsets[max_val_pos[0],max_val_pos[1],i]) refine_pos[1] = int(remap_pos[1] + offsets[max_val_pos[0],max_val_pos[1],i+heatmaps.shape[-1]])

可視化看看

show_img = np.squeeze((input_img.copy()*127.5+127.5)/255.0)[:,:,::-1] show_img = np.array(show_img*255,np.uint8) plt.figure(figsize=(8,8)) plt.imshow(cv.circle(show_img,(refine_pos[1],refine_pos[0]),2,(0,255,0),-1))

映射原圖

因為上面是把原圖resize乘(257,257)以后的坐標,所以根據原圖的縮放系數,重新映射回去

ratio_x = img.shape[0]/257 ratio_y = img.shape[1]/257 refine_pos[0]=refine_pos[0]*ratio_x refine_pos[1]=refine_pos[1]*ratio_y

可視化

show_img1 = img[:,:,::-1] plt.figure(figsize=(8,8)) plt.imshow(cv.circle(show_img1.copy(),(refine_pos[1],refine_pos[0]),2,(0,255,0),-1))

封裝函數

上面是提取單個關節的,寫成函數提取所有關節的坐標就是

def parse_output(heatmap_data,offset_data):joint_num = heatmap_data.shape[-1]pose_kps = np.zeros((joint_num,2),np.uint8)for i in range(heatmap_data.shape[-1]):joint_heatmap = heatmap_data[...,i]max_val_pos = np.squeeze(np.argwhere(joint_heatmap==np.max(joint_heatmap)))remap_pos = np.array(max_val_pos/8*257,dtype=np.int32)pose_kps[i,0] = int(remap_pos[0] + offset_data[max_val_pos[0],max_val_pos[1],i])pose_kps[i,1] = int(remap_pos[1] + offset_data[max_val_pos[0],max_val_pos[1],i+joint_num])return pose_kps

畫圖的函數也很容易

def draw_kps(show_img,kps):for i in range(kps.shape[0]):cv.circle(show_img,(kps[i,1],kps[i,0]),2,(0,255,0),-1)return show_img

畫出來瞅瞅

kps = parse_output(heatmaps,offsets) plt.figure(figsize=(8,8)) plt.imshow(draw_kps(show_img.copy(),kps)) plt.axis('off')

后記

模型文件:鏈接:https://pan.baidu.com/s/1heRKFFz28yvpAmvFqDeAXw 密碼:5tuw

博客代碼:鏈接:https://pan.baidu.com/s/1Y7WXfQ4WC9QyOGkkN2-kUQ 密碼:ono0

本文已經同步到微信公眾號中,公眾號與本博客將持續同步更新運動捕捉、機器學習、深度學習、計算機視覺算法,敬請關注

總結

以上是生活随笔為你收集整理的tensorflow官方posenet模型解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。