“人像姿态检测”案例源码详解 (Python)
testpose.py用于人像姿态检测
- 打开testpose人像姿态检测案例
- 定义各转化函数、图像变形函数、搜索算法函数、区域提取函数、
- 定义绘制函数
- 指定模型路径和输入形
- 设置相机并开始读图
- 启动模型
打开testpose人像姿态检测案例
在VScode中进入代码编辑状态。
导入相关库
'''
导入基础包作用详解
'''
#导入包介绍开始
#cvs包是Aid内置的代替cv2的包,基本上cv2支持的函数cvs一样支持,cvs包在X模式下和非X模式下一样执行
#cvs更多详细介绍查看官网文档OpenCVhttps://www.aidlearning.net/showdoc/web/#/5?page_id=45
from cvs import *
#math模块提供了许多对浮点数的数学运算函数。
import math
#NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
#在机器学习算法中大部分都是调用Numpy库来完成基础数值计算的。
import numpy as np
#ciPy,发音为Sigh Pi,是一个科学的python开源代码,在BSD许可下分发的库,用于执行数学,科学和工程计算。
#special包含了科学计算中的各种特殊函数
#expit函数,也称为logistic sigmoid函数,定义为expit(x)= 1 /(1 + exp(-x))。 它是logit函数的反函数。
from scipy.special import expit
#导入python时间控制包
import time
# tflite_gpu,GPU加速代码由AID提供,TensorFlow Lite 支持多种硬件加速器。GPU 是设计用来完成高吞吐量的大规模并行工作的。
# 因此,它们非常适合用在包含大量运算符的神经网络上,一些输入张量可以容易的被划分为更小的工作负载且可以同时执行,通常这会导致更低的延迟。
# 在最佳情况下,用 GPU 在实时应用程序上做推理运算已经可以运行的足够快,而这在以前是不可能的。
import tflite_gpu
#导入包介绍结束
定义各张量转化函数、图像变形函数、区域提取函数、搜索算法函数
tflite = tflite_gpu.tflite()
'''
图像变形填充函数
'''
def resize_pad(img):
""" 定义此函数用于将图像重定义大小并填充,输入到检测器
人脸检测和手掌检测网络需要256x256和128x128像素的图形作为输入。
此函数使输入图像经过填充和重定义大小,适配大小同时维持正确比例
返回值:
img1: 256x256
img2: 128x128
scale: 原图到256*256图像的缩放系数
pad: 原图的填充像素数
"""
#待处理图像的形状保存至size0变量
size0 = img.shape
#将要对图像施加的形变先参数化: w1:宽, h1:高, padw:宽填充, padh:高填充, scale:缩放系数
#如果图像0轴长于1轴,将0轴(宽width)缩小
if size0[0]>=size0[1]:
h1 = 256
w1 = 256 * size0[1] // size0[0] #'//'运算符在Python中是地板除(取整除)
padh = 0
padw = 256 - w1 #计算宽度填充,即原宽度减去应有宽度
scale = size0[1] / w1 #通过将原图宽度除以应有宽度,得到宽缩放系数
#如果图像1轴长于0轴,将1轴(高height)缩小
else:
h1 = 256 * size0[0] // size0[1] #'//'运算符在Python中是地板除(取整除)
w1 = 256
padh = 256 - h1 #计算高度填充,即原高度减去应有高度
padw = 0
scale = size0[0] / h1 #通过将原图高度除以应有高度,得到高缩放系数
#将填充值细化为1、2,分别代表地板除以2和天花板除以2得到的值
padh1 = padh//2 #地板除 floor division
padh2 = padh//2 + padh%2 #天花板除 ceiling division
padw1 = padw//2
padw2 = padw//2 + padw%2
#对原图进行重定义大小操作
#注意:cv2的resize函数需作用于Numpy.array对象
img1 = cv2.resize(img, (w1,h1))
#再进行填充操作
#方法参数:pad(array, pad_width, mode, **kwargs)
#方法返回:填充后的数组
#参数解释:
#array:表示需要填充的数组;
#pad_width:表示每个轴(axis)边缘需要填充的数值数目。
#参数输入方式为:((before_1, after_1), … (before_N, after_N)),其中(before_1, after_1)表示第1轴两边缘分别填充before_1个和after_1个数值。
#mode:表示填充的方式(取值:str字符串或用户提供的函数)
#constant’——表示连续填充相同的值,每个轴可以分别指定填充值,constant_values=(x, y)时前面用x填充,后面用y填充,缺省值填充0
img1 = np.pad(img1, ((padh1, padh2), (padw1, padw2), (0,0)), 'constant', constant_values=(0,0))
pad = (int(padh1 * scale), int(padw1 * scale))
#而这里重定义大小为128*128
img2 = cv2.resize(img1, (128,128))
return img1, img2, scale, pad
'''
图像逆归一化
'''
def denormalize_detections(detections, scale, pad):
""" 人脸检测和手掌检测网络需要256x256和128x128像素的图形作为输入。
此函数使输入图像经过填充和重定义大小,适配大小同时维持正确比例。
此函数将归一化过的坐标值恢复成原图坐标值。
输入:
detections: nxm 张量. n 为检测数,m 为 4+2*k,其中4是指边界框的坐标,k为检测器输出的额外关键点数目
scale: 曾用于缩放图像的缩放系数scalar that was used to resize the image
pad: x和y轴的填充
"""
detections[:, 0] = detections[:, 0] * scale * 256 - pad[0]
detections[:, 1] = detections[:, 1] * scale * 256 - pad[1]
detections[:, 2] = detections[:, 2] * scale * 256 - pad[0]
detections[:, 3] = detections[:, 3] * scale * 256 - pad[1]
detections[:, 4::2] = detections[:, 4::2] * scale * 256 - pad[1]
detections[:, 5::2] = detections[:, 5::2] * scale * 256 - pad[0]
return detections
#锚点框函数,得到真实坐标
def _decode_boxes(raw_boxes, anchors):
"""
通过使用锚点框,将预测结果转换为真实坐标,同一时间处理整个batch。
"""
#boxes是一个与raw_boxes相同形状的全为0的数组
boxes = np.zeros_like(raw_boxes)
x_center = raw_boxes[..., 0] / 128.0 * anchors[:, 2] + anchors[:, 0]
y_center = raw_boxes[..., 1] / 128.0 * anchors[:, 3] + anchors[:, 1]
w = raw_boxes[..., 2] / 128.0 * anchors[:, 2]
h = raw_boxes[..., 3] / 128.0 * anchors[:, 3]
boxes[...,