| @@ -1,10 +1,10 @@ | |||||
| package com.aispeech.nativedemo.tengine2 | package com.aispeech.nativedemo.tengine2 | ||||
| import android.app.Activity | |||||
| import android.graphics.Bitmap | import android.graphics.Bitmap | ||||
| import android.graphics.Rect | import android.graphics.Rect | ||||
| import android.util.Log | import android.util.Log | ||||
| import com.aispeech.nativedemo.MainActivity | import com.aispeech.nativedemo.MainActivity | ||||
| import com.aispeech.nativedemo.arcsoft.ArcSoftFaceCheckManager | |||||
| import com.aispeech.nativedemo.asr.observer.DuiMessageObserver | import com.aispeech.nativedemo.asr.observer.DuiMessageObserver | ||||
| import com.aispeech.nativedemo.entity.PersonInfo | import com.aispeech.nativedemo.entity.PersonInfo | ||||
| import com.aispeech.nativedemo.face.AngleInfo | import com.aispeech.nativedemo.face.AngleInfo | ||||
| @@ -30,6 +30,10 @@ import java.util.concurrent.ConcurrentLinkedQueue | |||||
| class TEngine2FaceCheckManager : FaceCheckInterface { | class TEngine2FaceCheckManager : FaceCheckInterface { | ||||
| var PITCH_MAX_ANGLE = 25f | |||||
| var PITCH_DANGER_ANGLE = 18f | |||||
| var YAW_MAX_ANGLE = 20f | |||||
| var YAW_DANGER_ANGLE = 18f | |||||
| companion object { | companion object { | ||||
| val instance by lazy (LazyThreadSafetyMode.SYNCHRONIZED){ | val instance by lazy (LazyThreadSafetyMode.SYNCHRONIZED){ | ||||
| TEngine2FaceCheckManager() | TEngine2FaceCheckManager() | ||||
| @@ -433,7 +437,7 @@ class TEngine2FaceCheckManager : FaceCheckInterface { | |||||
| overAngleCount++ | overAngleCount++ | ||||
| continue | continue | ||||
| } | } | ||||
| if (face.yaw > 0.3f || face.yaw < -0.3f) { | |||||
| if (face.yaw > YAW_MAX_ANGLE || face.yaw < (-1*YAW_MAX_ANGLE)) { | |||||
| overAngleCount++ | overAngleCount++ | ||||
| } else { | } else { | ||||
| LogUtils.e( | LogUtils.e( | ||||
| @@ -460,53 +464,82 @@ class TEngine2FaceCheckManager : FaceCheckInterface { | |||||
| faceList: ConcurrentLinkedQueue<FaceLandmarkInfo?> | faceList: ConcurrentLinkedQueue<FaceLandmarkInfo?> | ||||
| ): Boolean { | ): Boolean { | ||||
| val start = System.currentTimeMillis() | val start = System.currentTimeMillis() | ||||
| val isCloseMan = "closeMan-" == logTag | |||||
| var isSpeak = false | var isSpeak = false | ||||
| var mouthOpen = 0 | var mouthOpen = 0 | ||||
| var mouthClose = 0 | var mouthClose = 0 | ||||
| var mouthOther = 0 | var mouthOther = 0 | ||||
| var overAngleCount = 0 | |||||
| var pitchOverAngleCount = 0 | |||||
| var faceType = -1f | var faceType = -1f | ||||
| var mouthChangeCount = 0 | var mouthChangeCount = 0 | ||||
| var yawOverAngleCount = 0 | |||||
| val count = faceList.size | val count = faceList.size | ||||
| for (face in faceList) { | for (face in faceList) { | ||||
| if (face == null) { | if (face == null) { | ||||
| continue | continue | ||||
| } | } | ||||
| if (face.pitch > ArcSoftFaceCheckManager.PITCH_DANGER_ANGLE || face.pitch < -1 * ArcSoftFaceCheckManager.PITCH_DANGER_ANGLE) { | |||||
| mouthOther++ | |||||
| } | |||||
| if (face.yaw > ArcSoftFaceCheckManager.YAW_DANGER_ANGLE || face.yaw < -1 * ArcSoftFaceCheckManager.YAW_DANGER_ANGLE) { | |||||
| yawOverAngleCount++ | |||||
| } | |||||
| if (face.pitch > ArcSoftFaceCheckManager.PITCH_MAX_ANGLE || face.pitch < -1 * ArcSoftFaceCheckManager.PITCH_MAX_ANGLE) { | |||||
| pitchOverAngleCount++ | |||||
| continue | |||||
| } | |||||
| if (faceType >= 0 && (faceType - face.mouseClose) > 0.1f) { | if (faceType >= 0 && (faceType - face.mouseClose) > 0.1f) { | ||||
| mouthChangeCount++ | mouthChangeCount++ | ||||
| } | } | ||||
| faceType = face.mouseClose | faceType = face.mouseClose | ||||
| if (face.mouseClose < 0.9f) { | if (face.mouseClose < 0.9f) { | ||||
| mouthOpen++ | mouthOpen++ | ||||
| } else { | |||||
| } else { | |||||
| mouthClose++ | mouthClose++ | ||||
| } | } | ||||
| if (face.pitch > 0.3f || face.pitch < -0.3f) { | |||||
| overAngleCount++ | |||||
| } | |||||
| } | |||||
| if (faceList.size <= 8) { | |||||
| isSpeak = mouthChangeCount > 0 || overAngleCount > 0 | |||||
| } else if (overAngleCount > 0) { | |||||
| isSpeak = mouthChangeCount > 0 || overAngleCount * 16 >= count | |||||
| } else if (mouthOpen > 0 && mouthClose > 0 || mouthOpen > 0 && mouthOther > 0) { | |||||
| // || (mouthClose > 0 && mouthOther > 0) | |||||
| isSpeak = true | |||||
| } | } | ||||
| if (!isSpeak) { | |||||
| if (mouthChangeCount * 2 >= count) { | |||||
| var result = "一直闭嘴" | |||||
| if (pitchOverAngleCount * 3 > count) { | |||||
| isSpeak = false | |||||
| result = "pitchOverAngleCount > 0.33" | |||||
| } else { | |||||
| if (faceList.size <= 9) { | |||||
| isSpeak = mouthChangeCount > 0 || mouthOther >= 0 | |||||
| result = "faceList.size() <= 9" | |||||
| } else if (mouthOpen > 0 && mouthClose > 0) { | |||||
| isSpeak = true | isSpeak = true | ||||
| } else if (mouthOpen == 0 && count <= 20) { | |||||
| if (Math.abs(mouthClose - mouthOther) < 3 || mouthChangeCount > mouthClose || mouthChangeCount > mouthOther) { | |||||
| result = "mouthOpen > 0 && mouthClose > 0" | |||||
| } | |||||
| if (!isSpeak) { | |||||
| if (mouthChangeCount * 2 >= count) { | |||||
| isSpeak = true | |||||
| result = "mouthChangeCount * 2 >= count" | |||||
| } else if (mouthOpen == count && count > 4) { | |||||
| isSpeak = true | |||||
| result = "mouthOpen == count && count > 4" | |||||
| } else if (count - mouthOther <= 1 && count < 20 && yawOverAngleCount < 1) { | |||||
| isSpeak = true | isSpeak = true | ||||
| result = "(count - mouthOther) <= 1 && count < 20 && yawOverAngleCount < 1" | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Logger.e("djASR-嘴型检测: " + logTag + name + " is speak " + isSpeak + " mouthOpen " + mouthOpen + " mouthClose " + mouthClose + " mouthOther " + mouthOther + " mouthChangeCount " + mouthChangeCount + " leftFaceSize " + faceCount + " overAngleCount " + overAngleCount + " time " + DuiMessageObserver.mTime) | |||||
| Logger.e("djASR-嘴型检测: " + logTag + name + " is speak " + isSpeak + " mouthOpen " + mouthOpen + " mouthClose " + mouthClose + " yawOverAngleCount " + yawOverAngleCount + " mouthChangeCount " + mouthChangeCount + " leftFaceSize " + ArcSoftFaceCheckManager.faceCount + " overAngleCount " + pitchOverAngleCount + " mouthOther " + mouthOther + " time " + DuiMessageObserver.mTime) | |||||
| Log.e( | |||||
| "testface", | |||||
| logTag + name + " is speak " + isSpeak + " mouthOpen " + mouthOpen + " mouthClose " + mouthClose + " yawOverAngleCount " + yawOverAngleCount + " mouthChangeCount " + mouthChangeCount + " leftFaceSize " + ArcSoftFaceCheckManager.faceCount + " overAngleCount " + pitchOverAngleCount + " mouthOther " + mouthOther + " time " + DuiMessageObserver.mTime + " duration " + (System.currentTimeMillis() - start) | |||||
| ) | |||||
| Logger.e("djASR-嘴型检测: " + logTag + name + " time " + DuiMessageObserver.mTime + " is speak " + isSpeak + " result " + result) | |||||
| Log.e( | Log.e( | ||||
| "testface", | "testface", | ||||
| logTag + name + " is speak " + isSpeak + " mouthOpen " + mouthOpen + " mouthClose " + mouthClose + " mouthOther " + mouthOther + " mouthChangeCount " + mouthChangeCount + " leftFaceSize " + faceCount + " overAngleCount " + overAngleCount + " time " + DuiMessageObserver.mTime + " duration " + (System.currentTimeMillis() - start) | |||||
| logTag + name + " time " + DuiMessageObserver.mTime + " is speak " + isSpeak + " result " + result | |||||
| ) | ) | ||||
| if (MainActivity.instance != null) { | |||||
| if (isCloseMan) { | |||||
| MainActivity.instance.setSettingResultClose(logTag + name + " time " + DuiMessageObserver.mTime + " is speak " + isSpeak + " result " + result) | |||||
| } else { | |||||
| MainActivity.instance.setSettingResult(logTag + name + " time " + DuiMessageObserver.mTime + " is speak " + isSpeak + " result " + result) | |||||
| } | |||||
| } | |||||
| return isSpeak | return isSpeak | ||||
| } | } | ||||