Commit 13d1c0c1 authored by zhangyanan's avatar zhangyanan

feat:完善跳跃计数。

parent 51faae0d
package com.health.actiondemo package com.health.actiondemo
import android.app.Activity import android.app.Activity
import android.graphics.PointF
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
...@@ -10,12 +11,15 @@ import android.widget.TextView ...@@ -10,12 +11,15 @@ import android.widget.TextView
import com.alibaba.fastjson.JSON import com.alibaba.fastjson.JSON
import com.health.baselibrary.utils.StringUtils import com.health.baselibrary.utils.StringUtils
import com.health.videoplay.bean.StandardConditonsModel import com.health.videoplay.bean.StandardConditonsModel
import com.health.videoplay.util.AngleCalculateHelper
import com.health.videoplay.util.CalFrameDelegate import com.health.videoplay.util.CalFrameDelegate
import com.healthhope.opengl.PoseCameraView import com.healthhope.opengl.PoseCameraView
import com.healthhope.opengl.utils.LimitQueue
import java.io.BufferedReader import java.io.BufferedReader
import java.io.InputStreamReader import java.io.InputStreamReader
import java.lang.StringBuilder import java.lang.StringBuilder
import java.util.HashMap import java.util.*
import kotlin.math.abs
class ActionCountActivity : Activity() { class ActionCountActivity : Activity() {
...@@ -32,11 +36,14 @@ class ActionCountActivity : Activity() { ...@@ -32,11 +36,14 @@ class ActionCountActivity : Activity() {
private val mainHandler = Handler(Looper.getMainLooper()) private val mainHandler = Handler(Looper.getMainLooper())
private var containJump = false private var containJump = false
private var aCount = 0 private var aCount = 0
private var actionType = 0
var mLimitQueue = LimitQueue<Array<PointF?>?>(5)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_action_count) setContentView(R.layout.activity_action_count)
initInfo() // initInfo()
textInfo = findViewById(R.id.text_info) textInfo = findViewById(R.id.text_info)
textCount = findViewById(R.id.text_count) textCount = findViewById(R.id.text_count)
textResult = findViewById(R.id.result_info) textResult = findViewById(R.id.result_info)
...@@ -45,16 +52,17 @@ class ActionCountActivity : Activity() { ...@@ -45,16 +52,17 @@ class ActionCountActivity : Activity() {
textDebug2 = findViewById(R.id.text_debug_2) textDebug2 = findViewById(R.id.text_debug_2)
textDebug3 = findViewById(R.id.text_debug_3) textDebug3 = findViewById(R.id.text_debug_3)
val intExtra = intent.getIntExtra("actionType", 0) actionType = intent.getIntExtra("actionType", 0)
//动作检查 //动作检查
calFrameDelegate.setCheckType(CalFrameDelegate.TYPE_ACTION_CHECK) calFrameDelegate.setCheckType(CalFrameDelegate.TYPE_ACTION_CHECK)
when(intExtra) { when(actionType) {
//蹲起 //蹲起
0 -> { 0 -> {
textInfo?.text = "蹲起:" textInfo?.text = "蹲起:"
val info:List<StandardConditonsModel> = JSON.parseArray(getRawText(R.raw.action_dunqi), StandardConditonsModel::class.java) val info:MutableList<StandardConditonsModel> = JSON.parseArray(getRawText(R.raw.action_dunqi), StandardConditonsModel::class.java)
calFrameDelegate.setActionCheckConditions(info) calFrameDelegate.setActionCheckConditions(info)
Log.i("ademoademo","info---》" + Arrays.toString(info.toTypedArray()))
} }
//开合跳 //开合跳
1 -> { 1 -> {
...@@ -66,19 +74,17 @@ class ActionCountActivity : Activity() { ...@@ -66,19 +74,17 @@ class ActionCountActivity : Activity() {
//跳 //跳
2 -> { 2 -> {
textInfo?.text = "跳跃:" textInfo?.text = "跳跃:"
} }
} }
calFrameDelegate.setGainResultListener(object: CalFrameDelegate.OnGainResultListener{ calFrameDelegate.setGainResultListener(object: CalFrameDelegate.OnGainResultListener{
override fun onResult(conditonsModel: StandardConditonsModel?, result: Byte) { override fun onResult(conditonsModel: StandardConditonsModel?, result: Byte) {
Log.i("ademo","result--->" + result)
setResult(result.toString()) setResult(result.toString())
when (result) { when (result) {
CalFrameDelegate.ResultCode.RESULT_OK -> { CalFrameDelegate.ResultCode.RESULT_OK -> {
if (containJump) { if (containJump) {
// if (poseView?.getRenderHelper()?.isJump == true) { if (poseView?.getRenderHelper()?.isJump == true) {
updateInfo() updateInfo()
// } }
} else { } else {
updateInfo() updateInfo()
} }
...@@ -91,73 +97,122 @@ class ActionCountActivity : Activity() { ...@@ -91,73 +97,122 @@ class ActionCountActivity : Activity() {
} }
}) })
calFrameDelegate.setInfoListener(object: CalFrameDelegate.OnInfoListener{ // calFrameDelegate.setInfoListener(object: CalFrameDelegate.OnInfoListener{
override fun onConstantInfo(constants: MutableMap<String, Double>?) { // override fun onConstantInfo(constants: MutableMap<String, Double>?) {
val sb = StringBuilder() // val sb = StringBuilder()
for ((key, value) in constants!!) { // for ((key, value) in constants!!) {
sb.append(transConstantsNameToCh(key) + ":" + StringUtils.formatNum(value, 1)) // sb.append(transConstantsNameToCh(key) + ":" + StringUtils.formatNum(value, 1))
.append("\n") // .append("\n")
} // }
mainHandler.post{ // mainHandler.post{
textDebug1?.text = sb.toString() // textDebug1?.text = sb.toString()
//
// }
// }
//
// override fun onCondition(conditionType: String?, bodyKeys: MutableList<String>?, ax: Double, a: Double, b: Double, by: Double) {
// if (TextUtils.isEmpty(conditionType)) {
// runOnUiThread { textDebug2?.setText("无标注信息") }
// return
// }
// val sb = StringBuilder()
//
// if ("0" == conditionType) {
// sb.append("角度").append("\n")
// } else if ("1" == conditionType) {
// sb.append("高差").append("\n")
// } else if ("2" == conditionType) {
// sb.append("水平差").append("\n")
// } else {
// sb.append("距离").append("\n")
// }
//// sb.append("conditionType:" + conditionType).append("\n");
// // sb.append("conditionType:" + conditionType).append("\n");
// sb.append("calPoints:")
// for (i in bodyKeys!!.indices) {
// if (i < bodyKeys.size - 1) {
// sb.append(pointChNames.get(bodyKeys[i])).append("_")
// } else {
// sb.append(pointChNames.get(bodyKeys[i]))
// }
// }
// sb.append("\n")
// sb.append("ax=").append(StringUtils.formatNum(ax, 1)).append("\n")
// .append("a=").append(StringUtils.formatNum(a, 1)).append("\n")
// .append("b=").append(StringUtils.formatNum(b, 1)).append("\n")
// .append("by=").append(StringUtils.formatNum(by, 1))
// runOnUiThread { textDebug2?.setText(sb.toString()) }
// }
//
// override fun onCalInfo(calResult: Double) {
// var cal = calResult
// if (java.lang.Double.isNaN(cal) || java.lang.Double.isInfinite(cal)) {
// cal = 0.0
// }
// runOnUiThread {
// textDebug3?.setText(
// """
// calResult:
// ${StringUtils.formatNum(cal, 1)}
// """.trimIndent()
// )
// }
// }
//
// })
poseView = findViewById(R.id.pose_camera)
poseView?.getRenderHelper()?.setOnFrameListener { pointFS ->
if (actionType != 2) {
calFrameDelegate.onFrame(pointFS)
} else {
if (mLimitQueue.size == 0) {
mLimitQueue.offer(pointFS)
} else if (mOrderFlag % 2 == 0) {
mLimitQueue.offer(pointFS)
mOrderFlag = 0
} }
mOrderFlag++
checkJump()
} }
}
}
override fun onCondition(conditionType: String?, bodyKeys: MutableList<String>?, ax: Double, a: Double, b: Double, by: Double) { //每隔一帧取一次
if (TextUtils.isEmpty(conditionType)) { private var mOrderFlag = 0
runOnUiThread { textDebug2?.setText("无标注信息") } private var isUp = false
return
} private fun checkJump() {
val sb = StringBuilder() if (mLimitQueue.size > 1) {
val queue = Array(mLimitQueue.size) { arrayOfNulls<PointF>(14) }
if ("0" == conditionType) { mLimitQueue.toArray(queue)
sb.append("角度").append("\n") //阈值为鼻子到脖子之间的距离
} else if ("1" == conditionType) { val thresholdVal =
sb.append("高差").append("\n") abs(AngleCalculateHelper.yDiff(queue[0][1], queue[0][0])) * 0.1f
} else if ("2" == conditionType) { val last = queue.size - 1
sb.append("水平差").append("\n") val movedistance1 =
} else { AngleCalculateHelper.yDiff(queue[last][2], queue[last - 1][2])
sb.append("距离").append("\n") // MLog.d(TAG, "__部位:左肩_____________竖直移动距离:$movedistance1")
} val movedistance2 =
// sb.append("conditionType:" + conditionType).append("\n"); AngleCalculateHelper.yDiff(queue[last][5], queue[last - 1][5])
// sb.append("conditionType:" + conditionType).append("\n"); // MLog.d(TAG, "__部位:右肩_____________竖直移动距离:$movedistance2")
sb.append("calPoints:") val movedistance3 =
for (i in bodyKeys!!.indices) { AngleCalculateHelper.yDiff(queue[last][8], queue[last - 1][8])
if (i < bodyKeys.size - 1) { // MLog.d(TAG, "__部位:左髋_____________竖直移动距离:$movedistance3")
sb.append(pointChNames.get(bodyKeys[i])).append("_") val movedistance4 =
} else { AngleCalculateHelper.yDiff(queue[last][11], queue[last - 1][11])
sb.append(pointChNames.get(bodyKeys[i]))
} if (movedistance1 > 0 && movedistance2 > 0 || movedistance3 > 0 && movedistance4 > 0 ) {
} isUp = false
sb.append("\n")
sb.append("ax=").append(StringUtils.formatNum(ax, 1)).append("\n")
.append("a=").append(StringUtils.formatNum(a, 1)).append("\n")
.append("b=").append(StringUtils.formatNum(b, 1)).append("\n")
.append("by=").append(StringUtils.formatNum(by, 1))
runOnUiThread { textDebug2?.setText(sb.toString()) }
} }
override fun onCalInfo(calResult: Double) { if (isUp) {
var cal = calResult return
if (java.lang.Double.isNaN(cal) || java.lang.Double.isInfinite(cal)) { }
cal = 0.0 if (movedistance1 < 0 && abs(movedistance1) > thresholdVal && movedistance2 < 0 && abs(movedistance2) > thresholdVal || movedistance3 < 0 && abs(movedistance3) > thresholdVal && movedistance4 < 0 && abs(movedistance4) > thresholdVal) {
} updateInfo()
runOnUiThread { isUp = true
textDebug3?.setText(
"""
calResult:
${StringUtils.formatNum(cal, 1)}
""".trimIndent()
)
}
} }
})
poseView = findViewById(R.id.pose_camera)
poseView?.getRenderHelper()?.setOnFrameListener { pointFS ->
Log.i("ademo","on onFrame")
calFrameDelegate.onFrame(pointFS)
} }
} }
...@@ -191,57 +246,57 @@ class ActionCountActivity : Activity() { ...@@ -191,57 +246,57 @@ class ActionCountActivity : Activity() {
} }
// private val bodyConstants = HashMap<String, Double>() // private val bodyConstants = HashMap<String, Double>()
private val pointChNames = HashMap<String, String>() // private val pointChNames = HashMap<String, String>()
fun initInfo() {
// /** 头顶-脖子 高差 */
// bodyConstants["OH_NK_1"] = -65.36
// /** 左膝-左踝 高差*/
// bodyConstants["LK_LA_1"] = -76.64
// /** 右膝-右踝 高差 */
// bodyConstants["RK_RA_1"] = -69.72
// /** 左胯-左膝 高差 */
// bodyConstants["LP_LK_1"] = -75.49
// /** 右胯-右膝 高差 */
// bodyConstants["RP_RK_1"] = -82.85
// /** 左肩-右肩 水平*/
// bodyConstants["LS_RS_2"] = -80.90
// /** 左肩-右肩 连线*/
// bodyConstants["LS_RS_3"] = 80.91
pointChNames["RK"] = "右膝"
pointChNames["LK"] = "左膝"
pointChNames["RA"] = "右踝"
pointChNames["LA"] = "左踝"
pointChNames["LW"] = "左腕"
pointChNames["RW"] = "右腕"
pointChNames["LE"] = "左耳"
pointChNames["RE"] = "右耳"
pointChNames["LS"] = "左肩"
pointChNames["RS"] = "右肩"
pointChNames["LL"] = "左水平"
pointChNames["RL"] = "右水平"
pointChNames["LP"] = "左髋"
pointChNames["RP"] = "右髋"
pointChNames["LEW"] = "左肘"
pointChNames["REW"] = "右肘"
pointChNames["OH"] = "头顶"
pointChNames["NK"] = "脖子"
}
private fun transConstantsNameToCh(key: String): String? { // fun initInfo() {
val sb = StringBuilder() //// /** 头顶-脖子 高差 */
val s = key.split("_").toTypedArray() //// bodyConstants["OH_NK_1"] = -65.36
sb.append(pointChNames[s[0]]).append("_") //// /** 左膝-左踝 高差*/
sb.append(pointChNames[s[1]]).append("_") //// bodyConstants["LK_LA_1"] = -76.64
if ("0" == s[2]) { //// /** 右膝-右踝 高差 */
sb.append("角度") //// bodyConstants["RK_RA_1"] = -69.72
} else if ("1" == s[2]) { //// /** 左胯-左膝 高差 */
sb.append("高差") //// bodyConstants["LP_LK_1"] = -75.49
} else if ("2" == s[2]) { //// /** 右胯-右膝 高差 */
sb.append("水平差") //// bodyConstants["RP_RK_1"] = -82.85
} else { //// /** 左肩-右肩 水平*/
sb.append("距离") //// bodyConstants["LS_RS_2"] = -80.90
} //// /** 左肩-右肩 连线*/
return sb.toString() //// bodyConstants["LS_RS_3"] = 80.91
} // pointChNames["RK"] = "右膝"
// pointChNames["LK"] = "左膝"
// pointChNames["RA"] = "右踝"
// pointChNames["LA"] = "左踝"
// pointChNames["LW"] = "左腕"
// pointChNames["RW"] = "右腕"
// pointChNames["LE"] = "左耳"
// pointChNames["RE"] = "右耳"
// pointChNames["LS"] = "左肩"
// pointChNames["RS"] = "右肩"
// pointChNames["LL"] = "左水平"
// pointChNames["RL"] = "右水平"
// pointChNames["LP"] = "左髋"
// pointChNames["RP"] = "右髋"
// pointChNames["LEW"] = "左肘"
// pointChNames["REW"] = "右肘"
// pointChNames["OH"] = "头顶"
// pointChNames["NK"] = "脖子"
// }
// private fun transConstantsNameToCh(key: String): String? {
// val sb = StringBuilder()
// val s = key.split("_").toTypedArray()
// sb.append(pointChNames[s[0]]).append("_")
// sb.append(pointChNames[s[1]]).append("_")
// if ("0" == s[2]) {
// sb.append("角度")
// } else if ("1" == s[2]) {
// sb.append("高差")
// } else if ("2" == s[2]) {
// sb.append("水平差")
// } else {
// sb.append("距离")
// }
// return sb.toString()
// }
} }
\ No newline at end of file
...@@ -16,23 +16,5 @@ ...@@ -16,23 +16,5 @@
"innerStandardLimitPrompt": "完美", "innerStandardLimitPrompt": "完美",
"innerErrorLimitA2XPrompt": "", "innerErrorLimitA2XPrompt": "",
"innerErrorLimitB2YPrompt": "双臂伸直,举过头顶" "innerErrorLimitB2YPrompt": "双臂伸直,举过头顶"
},
{
"conditionType": "0",
"angleDifferenceLimit": {
"standardAngleA": "75",
"standardAngleB": "0",
"errorAngleA2X": "85",
"errorAngleB2Y": null,
"caculateUserAnglePoint": [
"LP",
"LK",
"RL"
]
},
"positionDifferenceLimit": null,
"innerStandardLimitPrompt": "完美",
"innerErrorLimitA2XPrompt": "双腿左右尽量分开",
"innerErrorLimitB2YPrompt": ""
} }
] ]
\ No newline at end of file
...@@ -16,23 +16,5 @@ ...@@ -16,23 +16,5 @@
"innerStandardLimitPrompt": "完美", "innerStandardLimitPrompt": "完美",
"innerErrorLimitA2XPrompt": "", "innerErrorLimitA2XPrompt": "",
"innerErrorLimitB2YPrompt": "双臂伸直,举过头顶" "innerErrorLimitB2YPrompt": "双臂伸直,举过头顶"
},
{
"conditionType": "0",
"angleDifferenceLimit": {
"standardAngleA": "75",
"standardAngleB": "0",
"errorAngleA2X": "85",
"errorAngleB2Y": null,
"caculateUserAnglePoint": [
"LP",
"LK",
"RL"
]
},
"positionDifferenceLimit": null,
"innerStandardLimitPrompt": "完美",
"innerErrorLimitA2XPrompt": "双腿左右尽量分开",
"innerErrorLimitB2YPrompt": ""
} }
] ]
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment