|
|
|
@ -45,10 +45,12 @@ class PoseNet(private val interpreter: Interpreter, private var gpuDelegate: Gpu
|
|
|
|
|
companion object {
|
|
|
|
|
// 设置CPU线程数
|
|
|
|
|
private const val CPU_NUM_THREADS = 4
|
|
|
|
|
|
|
|
|
|
// 图像标准化时的均值和标准差
|
|
|
|
|
private const val MEAN = 127.5f
|
|
|
|
|
private const val STD = 127.5f
|
|
|
|
|
private const val TAG = "Posenet"
|
|
|
|
|
|
|
|
|
|
// 模型文件名称
|
|
|
|
|
private const val MODEL_FILENAME = "posenet.tflite"
|
|
|
|
|
|
|
|
|
@ -60,10 +62,12 @@ class PoseNet(private val interpreter: Interpreter, private var gpuDelegate: Gpu
|
|
|
|
|
when (device) {
|
|
|
|
|
Device.CPU -> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Device.GPU -> {
|
|
|
|
|
gpuDelegate = GpuDelegate() // 使用GPU加速
|
|
|
|
|
options.addDelegate(gpuDelegate)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Device.NNAPI -> options.setUseNNAPI(true) // 使用NNAPI加速
|
|
|
|
|
}
|
|
|
|
|
return PoseNet(
|
|
|
|
@ -77,6 +81,7 @@ class PoseNet(private val interpreter: Interpreter, private var gpuDelegate: Gpu
|
|
|
|
|
|
|
|
|
|
// 保存上一次推理的时间
|
|
|
|
|
private var lastInferenceTimeNanos: Long = -1
|
|
|
|
|
|
|
|
|
|
// 获取输入张量的宽度和高度
|
|
|
|
|
private val inputWidth = interpreter.getInputTensor(0).shape()[1]
|
|
|
|
|
private val inputHeight = interpreter.getInputTensor(0).shape()[2]
|
|
|
|
@ -140,8 +145,9 @@ class PoseNet(private val interpreter: Interpreter, private var gpuDelegate: Gpu
|
|
|
|
|
fun calculateAngle(x1: Float, y1: Float, x2: Float, y2: Float): Float {
|
|
|
|
|
val Y = y2 - y1
|
|
|
|
|
val X = x2 - x1
|
|
|
|
|
return Math.toDegrees(atan2(Y.toDouble(),X.toDouble())).toFloat()
|
|
|
|
|
return Math.toDegrees(atan2(Y.toDouble(), X.toDouble())).toFloat()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun postProcessModelOuputs(
|
|
|
|
|
heatmaps: Array<Array<Array<FloatArray>>>,
|
|
|
|
|
offsets: Array<Array<Array<FloatArray>>>
|
|
|
|
@ -231,7 +237,7 @@ class PoseNet(private val interpreter: Interpreter, private var gpuDelegate: Gpu
|
|
|
|
|
return Math.toDegrees(acos(cosAngle.toDouble())).toFloat()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加角度并控制角度列表长度
|
|
|
|
|
// 添加角度
|
|
|
|
|
fun addAngle(angle: Float) {
|
|
|
|
|
angles.add(angle)
|
|
|
|
|
if (angles.size > 8) {
|
|
|
|
@ -255,20 +261,24 @@ class PoseNet(private val interpreter: Interpreter, private var gpuDelegate: Gpu
|
|
|
|
|
val leftWrist = keypointList.first { it.bodyPart == BodyPart.LEFT_WRIST }
|
|
|
|
|
calculateAndAddAngle(leftShoulder, leftElbow, leftWrist)
|
|
|
|
|
|
|
|
|
|
val rightShoulder = keypointList.first { it.bodyPart == BodyPart.RIGHT_SHOULDER }
|
|
|
|
|
val rightShoulder =
|
|
|
|
|
keypointList.first { it.bodyPart == BodyPart.RIGHT_SHOULDER }
|
|
|
|
|
val rightElbow = keypointList.first { it.bodyPart == BodyPart.RIGHT_ELBOW }
|
|
|
|
|
calculateAndAddAngle(leftShoulder, rightShoulder, rightElbow)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BodyPart.RIGHT_SHOULDER -> {
|
|
|
|
|
val rightShoulder = keypoint
|
|
|
|
|
val rightElbow = keypointList.first { it.bodyPart == BodyPart.RIGHT_ELBOW }
|
|
|
|
|
val rightWrist = keypointList.first { it.bodyPart == BodyPart.RIGHT_WRIST }
|
|
|
|
|
calculateAndAddAngle(rightShoulder, rightElbow, rightWrist)
|
|
|
|
|
|
|
|
|
|
val leftShoulder = keypointList.first { it.bodyPart == BodyPart.LEFT_SHOULDER }
|
|
|
|
|
val leftShoulder =
|
|
|
|
|
keypointList.first { it.bodyPart == BodyPart.LEFT_SHOULDER }
|
|
|
|
|
val leftElbow = keypointList.first { it.bodyPart == BodyPart.LEFT_ELBOW }
|
|
|
|
|
calculateAndAddAngle(rightShoulder, leftShoulder, leftElbow)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BodyPart.LEFT_HIP -> {
|
|
|
|
|
val leftHip = keypoint
|
|
|
|
|
val rightHip = keypointList.first { it.bodyPart == BodyPart.RIGHT_HIP }
|
|
|
|
@ -281,6 +291,7 @@ class PoseNet(private val interpreter: Interpreter, private var gpuDelegate: Gpu
|
|
|
|
|
val leftAnkle = keypointList.first { it.bodyPart == BodyPart.LEFT_ANKLE }
|
|
|
|
|
calculateAndAddAngle(leftHip, leftKnee, leftAnkle)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BodyPart.RIGHT_HIP -> {
|
|
|
|
|
val rightHip = keypoint
|
|
|
|
|
val leftHip = keypointList.first { it.bodyPart == BodyPart.LEFT_HIP }
|
|
|
|
@ -290,14 +301,23 @@ class PoseNet(private val interpreter: Interpreter, private var gpuDelegate: Gpu
|
|
|
|
|
val rightAnkle = keypointList.first { it.bodyPart == BodyPart.RIGHT_ANKLE }
|
|
|
|
|
calculateAndAddAngle(rightHip, rightKnee, rightAnkle)
|
|
|
|
|
}
|
|
|
|
|
// 这里可以继续添加其他 BodyPart 的处理分支
|
|
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
|
// 如果遇到其他没有显式列出的bodyPart,进行处理
|
|
|
|
|
println("Unknown body part: ${keypoint.bodyPart}")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提供外部访问 angles 的方法
|
|
|
|
|
fun getAngles(): List<Float> {
|
|
|
|
|
return angles.toList() // 返回 angles 的副本
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 可以选择提供修改 angles 的方法
|
|
|
|
|
fun clearAngles() {
|
|
|
|
|
angles.clear()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回上一次推理的时间
|
|
|
|
|