Browse Source

tengine2

dev_h5stream
李俊才 1 year ago
parent
commit
7020a2ad8c
19 changed files with 596 additions and 62 deletions
  1. BIN
      app/libs/tengine-kit-sdk1.0.1.aar
  2. BIN
      app/libs/tenginekit-body.aar
  3. BIN
      app/libs/tenginekit-face.aar
  4. BIN
      app/libs/tenginekit-hand.aar
  5. BIN
      app/libs/tenginekit.aar
  6. BIN
      app/src/main/assets/model/tenginekit_body_detect.tmfile
  7. BIN
      app/src/main/assets/model/tenginekit_body_detect_yf.tmfile
  8. BIN
      app/src/main/assets/model/tenginekit_face_attribute.tmfile
  9. BIN
      app/src/main/assets/model/tenginekit_face_attribute_if.tmfile
  10. BIN
      app/src/main/assets/model/tenginekit_face_detect.tmfile
  11. BIN
      app/src/main/assets/model/tenginekit_face_iris.tmfile
  12. BIN
      app/src/main/assets/model/tenginekit_face_landmark_2d.tmfile
  13. BIN
      app/src/main/assets/model/tenginekit_insightface_scrfd2.5g_bnkps.tmfile
  14. BIN
      app/src/main/assets/model/tenginekit_seg_human_portrait.tmfile
  15. +0
    -2
      app/src/main/java/com/aispeech/nativedemo/face/FaceManager.java
  16. +1
    -1
      app/src/main/java/com/aispeech/nativedemo/tengine/ImageUtils.java
  17. +84
    -57
      app/src/main/java/com/aispeech/nativedemo/tengine/TEngineFaceCheckManager.kt
  18. +0
    -2
      app/src/main/java/com/aispeech/nativedemo/tengine/copyAssetFolder.kt
  19. +511
    -0
      app/src/main/java/com/aispeech/nativedemo/tengine2/TEngine2FaceCheckManager.kt

BIN
app/libs/tengine-kit-sdk1.0.1.aar View File


BIN
app/libs/tenginekit-body.aar View File


BIN
app/src/main/assets/model/tenginekit_body_landmark.tmfile → app/libs/tenginekit-face.aar View File


BIN
app/libs/tenginekit-hand.aar View File


BIN
app/libs/tenginekit.aar View File


BIN
app/src/main/assets/model/tenginekit_body_detect.tmfile View File


BIN
app/src/main/assets/model/tenginekit_body_detect_yf.tmfile View File


BIN
app/src/main/assets/model/tenginekit_face_attribute.tmfile View File


BIN
app/src/main/assets/model/tenginekit_face_attribute_if.tmfile View File


BIN
app/src/main/assets/model/tenginekit_face_detect.tmfile View File


BIN
app/src/main/assets/model/tenginekit_face_iris.tmfile View File


BIN
app/src/main/assets/model/tenginekit_face_landmark_2d.tmfile View File


BIN
app/src/main/assets/model/tenginekit_insightface_scrfd2.5g_bnkps.tmfile View File


BIN
app/src/main/assets/model/tenginekit_seg_human_portrait.tmfile View File


+ 0
- 2
app/src/main/java/com/aispeech/nativedemo/face/FaceManager.java View File

@@ -23,7 +23,6 @@ import com.aispeech.nativedemo.entity.PersonInfo;
import com.aispeech.nativedemo.entity.Stranger; import com.aispeech.nativedemo.entity.Stranger;
import com.aispeech.nativedemo.log.Logger; import com.aispeech.nativedemo.log.Logger;
import com.aispeech.nativedemo.network.ws.MessageUtils; import com.aispeech.nativedemo.network.ws.MessageUtils;
import com.aispeech.nativedemo.tengine.TEngineFaceCheckManager;
import com.aispeech.nativedemo.utils.CommandExecution; import com.aispeech.nativedemo.utils.CommandExecution;
import com.aispeech.nativedemo.utils.HttpUtil; import com.aispeech.nativedemo.utils.HttpUtil;
import com.aispeech.nativedemo.widget.CameraTextureView; import com.aispeech.nativedemo.widget.CameraTextureView;
@@ -37,7 +36,6 @@ import com.shareopen.library.helper.StatusUtils;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONTokener; import org.json.JSONTokener;


import java.io.IOException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;


+ 1
- 1
app/src/main/java/com/aispeech/nativedemo/tengine/ImageUtils.java View File

@@ -3,7 +3,7 @@ package com.aispeech.nativedemo.tengine;
import static android.media.ExifInterface.ORIENTATION_ROTATE_270; import static android.media.ExifInterface.ORIENTATION_ROTATE_270;
import static android.media.ExifInterface.ORIENTATION_ROTATE_90; import static android.media.ExifInterface.ORIENTATION_ROTATE_90;


import static com.aispeech.nativedemo.tengine.TEngineFaceCheckManager.LOG_TAG;
import static com.aispeech.nativedemo.tengine.TEngine2FaceCheckManager.LOG_TAG;


import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;


+ 84
- 57
app/src/main/java/com/aispeech/nativedemo/tengine/TEngineFaceCheckManager.kt View File

@@ -2,6 +2,7 @@ package com.aispeech.nativedemo.tengine


import android.app.Activity import android.app.Activity
import android.graphics.Bitmap import android.graphics.Bitmap
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.asr.observer.DuiMessageObserver import com.aispeech.nativedemo.asr.observer.DuiMessageObserver
@@ -13,13 +14,16 @@ import com.aispeech.nativedemo.log.Logger
import com.aispeech.nativedemo.utils.Utils import com.aispeech.nativedemo.utils.Utils
import com.lenovo.lefacecamerademo.ConfigClass.PROGRAM_ROOT_PATH import com.lenovo.lefacecamerademo.ConfigClass.PROGRAM_ROOT_PATH
import com.lenovo.lefacesdk.MultiAtt import com.lenovo.lefacesdk.MultiAtt
import com.shareopen.library.MVVM.application.AppContext
import com.shareopen.library.helper.LogUtils import com.shareopen.library.helper.LogUtils
import com.tenginekit.engine.core.ImageConfig
import com.tenginekit.engine.core.SdkConfig
import com.tenginekit.engine.core.TengineKitSdk
import com.tenginekit.engine.face.Face
import com.tenginekit.engine.face.FaceConfig
import com.tenginekit.AndroidConfig
import com.tenginekit.KitCore
import com.tenginekit.face.Face
import com.tenginekit.face.FaceDetectInfo
import com.tenginekit.face.FaceLandmarkInfo
import com.tenginekit.model.TenginekitPoint
import java.io.File import java.io.File
import java.nio.ByteBuffer
import java.util.concurrent.ArrayBlockingQueue import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.ConcurrentLinkedQueue


@@ -28,7 +32,7 @@ class TEngineFaceCheckManager : FaceCheckInterface {


companion object { companion object {
val instance by lazy (LazyThreadSafetyMode.SYNCHRONIZED){ val instance by lazy (LazyThreadSafetyMode.SYNCHRONIZED){
TEngineFaceCheckManager()
TEngine2FaceCheckManager()
} }
const val LOG_TAG = "TengineKitApp" const val LOG_TAG = "TengineKitApp"
} }
@@ -39,12 +43,12 @@ class TEngineFaceCheckManager : FaceCheckInterface {
@Volatile @Volatile
var faceCount = 0 var faceCount = 0
var faceQueue = ArrayBlockingQueue<PersonInfo>(10) var faceQueue = ArrayBlockingQueue<PersonInfo>(10)
var faceListInVad = ConcurrentLinkedQueue<Face?>()
var faceListInVad = ConcurrentLinkedQueue<FaceLandmarkInfo?>()
var faceStrListInVad = ConcurrentLinkedQueue<String>() var faceStrListInVad = ConcurrentLinkedQueue<String>()
var faceRectListInVad = ConcurrentLinkedQueue<MultiAtt>() var faceRectListInVad = ConcurrentLinkedQueue<MultiAtt>()




var faceListCloseInVad = ConcurrentLinkedQueue<Face?>()
var faceListCloseInVad = ConcurrentLinkedQueue<FaceLandmarkInfo?>()
var faceStrListCloseInVad = ConcurrentLinkedQueue<String>() var faceStrListCloseInVad = ConcurrentLinkedQueue<String>()
var faceRectListCloseInVad = ConcurrentLinkedQueue<MultiAtt>() var faceRectListCloseInVad = ConcurrentLinkedQueue<MultiAtt>()


@@ -64,7 +68,18 @@ class TEngineFaceCheckManager : FaceCheckInterface {


override fun init() { override fun init() {
Log.i(LOG_TAG, "start init") Log.i(LOG_TAG, "start init")
copyModel(MainActivity.instance)
/**
* 初始化
* */
KitCore.init(
AppContext.getInstance(),
AndroidConfig
.create()
.setNormalMode()
.setDefaultFunc()
.setInputImageFormat(AndroidConfig.ImageFormat.RGBA))
// .setInputImageSize(Image_w, Image_h)
// .setOutputImageSize(Image_w as Int, Image_h as Int)
Log.i(LOG_TAG, "init Success") Log.i(LOG_TAG, "init Success")


} }
@@ -77,11 +92,11 @@ class TEngineFaceCheckManager : FaceCheckInterface {
override fun copyFinish() { override fun copyFinish() {
Log.i(LOG_TAG, "copyModel Success") Log.i(LOG_TAG, "copyModel Success")
//modelCopyFinished = true //modelCopyFinished = true
val sdkConfig = SdkConfig()
sdkConfig.setAllowReport(false)
//TengineKitSdk.getInstance().initSdk(PROGRAM_ROOT_PATH, sdkConfig, AppContext.getInstance())
TengineKitSdk.getInstance().initSdk(activity.externalCacheDir!!.absolutePath, sdkConfig, activity)
TengineKitSdk.getInstance().initFaceDetect()
// val sdkConfig = SdkConfig()
// sdkConfig.setAllowReport(false)
// //TengineKitSdk.getInstance().initSdk(PROGRAM_ROOT_PATH, sdkConfig, AppContext.getInstance())
// TengineKitSdk.getInstance().initSdk(activity.externalCacheDir!!.absolutePath, sdkConfig, activity)
// TengineKitSdk.getInstance().initFaceDetect()
} }


override fun copyFail() { override fun copyFail() {
@@ -179,53 +194,55 @@ class TEngineFaceCheckManager : FaceCheckInterface {
return null return null
} }


fun doDetect(bitmap: Bitmap, personInfo: PersonInfo) : Face? {
fun doDetect(bitmap: Bitmap, personInfo: PersonInfo) : FaceLandmarkInfo? {
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
var faceResult : Face? = null;
var faceResult : FaceLandmarkInfo? = null;
bitmap?.let { bitmap?.let {
val byte = ImageUtils.bitmap2RGB(bitmap)
val config = FaceConfig().apply {
detect = true
landmark2d = true
/**
* 获取人脸信息
*/
/**
* 获取人脸信息
*/
val data: ByteArray = bitmap2Bytes(bitmap)
val faceDetect = Face.detect(data)
var faceDetectInfos: List<FaceDetectInfo>? = ArrayList()
var landmarkInfos: List<FaceLandmarkInfo> = ArrayList()
if (faceDetect.faceCount > 0) {
faceDetectInfos = faceDetect.detectInfos
landmarkInfos = faceDetect.landmark2d()
} }
val imageConfig = ImageConfig().apply {
data = byte
degree = 0
mirror = false
height = it.height
width = it.width
format = ImageConfig.FaceImageFormat.RGB
}
val faces = TengineKitSdk.getInstance().detectFace(imageConfig, config)
if (faces.isNotEmpty()) {
Log.i(LOG_TAG, "faces length:" + faces.size + " duration " + (System.currentTimeMillis() - start))


Log.d("#####", "Face Num: " + faceDetectInfos!!.size)
if (faceDetectInfos != null && faceDetectInfos.size > 0) {
val face_landmarks: List<List<TenginekitPoint>> = ArrayList()
for (i in faceDetectInfos.indices) {
var rect: Rect? = Rect()
rect = faceDetectInfos[i].asRect()
Log.d(
"#####",
"mouseClose: " + landmarkInfos[i].mouseClose + "pitch: " + landmarkInfos[i].pitch + "yaw: " + landmarkInfos[i].yaw
)
}
} }
Log.i(LOG_TAG, "end detect") Log.i(LOG_TAG, "end detect")
val sb = StringBuilder() val sb = StringBuilder()
if (faces != null) {
LogUtils.e("access123", "faces length " + faces.size)
for (face in faces) {
sb.append("· ").append("性别:").append(if (face.gender == 1) "女" else "男")
.append("\n")
sb.append("· ").append("年龄:").append(face.age).append("\n")
// sb.append("· ").append("模糊度:").append(df.format(face.blurness.toDouble()))
// .append("\n")
// sb.append("· ").append("置信度:").append(df.format(face.confidence.toDouble()))
// .append("\n")
if (landmarkInfos != null) {
LogUtils.e("access123", "faces length " + landmarkInfos.size)
for (face in landmarkInfos) {
var expression = "" var expression = ""
sb.append("· ").append("表情:").append(expression).append("\n") sb.append("· ").append("表情:").append(expression).append("\n")
sb.append("· ").append("眼部状态(左眼):").append(face.leftEyeClose) sb.append("· ").append("眼部状态(左眼):").append(face.leftEyeClose)
.append("\n") .append("\n")
sb.append("· ").append("眼部状态(右眼):").append(face.rightEyeClose) sb.append("· ").append("眼部状态(右眼):").append(face.rightEyeClose)
.append("\n") .append("\n")
sb.append("· ").append("嘴部状态:").append("闭嘴${(face.mouthClose*100).toInt()}%")
sb.append("· ").append("嘴部状态:").append("闭嘴${(face.mouseClose*100).toInt()}%")
.append("\n") .append("\n")
sb.append("· ").append("嘴部状态bigopen:").append("闭嘴${(face.mouthBigOpen*100).toInt()}%")
sb.append("· ").append("嘴部状态bigopen:").append("闭嘴${(face.mouseOpenBig*100).toInt()}%")
.append("\n") .append("\n")
sb.append("· ").append("3DPose:{pitch=").append(face.headX).append(",roll=")
.append(face.headZ).append(",yaw=").append(face.headY).append("}\n")
sb.append("· ").append("关键点个数:").append("" + face.landmark.size).append("\n")
sb.append("· ").append("3DPose:{pitch=").append(face.pitch).append(",roll=")
.append(face.roll).append(",yaw=").append(face.yaw).append("}\n")
sb.append("· ").append("关键点个数:").append("" + face.landmarks.size).append("\n")
sb.append("\n") sb.append("\n")
Log.e(LOG_TAG, "bitmapDetected: $sb") Log.e(LOG_TAG, "bitmapDetected: $sb")
faceResult = face faceResult = face
@@ -242,6 +259,14 @@ class TEngineFaceCheckManager : FaceCheckInterface {
return faceResult; return faceResult;
} }


private fun bitmap2Bytes(image: Bitmap): ByteArray {
// calculate how many bytes our image consists of
val bytes = image.byteCount
val buffer = ByteBuffer.allocate(bytes) // Create a new buffer
image.copyPixelsToBuffer(buffer) // Move the byte data to the buffer
return buffer.array()
}

private fun getEyeStatus(eyeType: Int): String? { private fun getEyeStatus(eyeType: Int): String? {
var reuslt = "" var reuslt = ""
when (eyeType) { when (eyeType) {
@@ -266,14 +291,14 @@ class TEngineFaceCheckManager : FaceCheckInterface {
return result return result
} }


fun addFaceInVad(faceResult: Face?, faceStr: String?, faceMultiAtt: MultiAtt?) {
fun addFaceInVad(faceResult: FaceLandmarkInfo?, faceStr: String?, faceMultiAtt: MultiAtt?) {
faceListInVad.offer(faceResult) faceListInVad.offer(faceResult)
faceStrListInVad.offer(faceStr) faceStrListInVad.offer(faceStr)
faceRectListInVad.offer(faceMultiAtt) faceRectListInVad.offer(faceMultiAtt)
} }


fun addFaceInVadClose( fun addFaceInVadClose(
faceResult: Face?,
faceResult: FaceLandmarkInfo?,
faceStr: String?, faceStr: String?,
faceMultiAtt: MultiAtt? faceMultiAtt: MultiAtt?
) { ) {
@@ -306,7 +331,9 @@ class TEngineFaceCheckManager : FaceCheckInterface {
return checkSpeak(name, " BeforeASR ", faceListInVad) return checkSpeak(name, " BeforeASR ", faceListInVad)
} }


override fun onDestroy() {}
override fun onDestroy() {
KitCore.release()
}




override fun getCurrentSpeak(name: String, isClear: Boolean): Boolean { override fun getCurrentSpeak(name: String, isClear: Boolean): Boolean {
@@ -415,7 +442,7 @@ class TEngineFaceCheckManager : FaceCheckInterface {




private fun checkAngle( private fun checkAngle(
faceList: ConcurrentLinkedQueue<Face?>,
faceList: ConcurrentLinkedQueue<FaceLandmarkInfo?>,
name: String name: String
): Boolean { ): Boolean {
val count = faceList.size val count = faceList.size
@@ -425,12 +452,12 @@ class TEngineFaceCheckManager : FaceCheckInterface {
overAngleCount++ overAngleCount++
continue continue
} }
if (face.headY > 0.3f || face.headY < -0.3f) {
if (face.yaw > 0.3f || face.yaw < -0.3f) {
overAngleCount++ overAngleCount++
} else { } else {
LogUtils.e( LogUtils.e(
"testtwoface", "testtwoface",
"face.yaw " + face.headY + " time " + DuiMessageObserver.mTime + " " + name
"face.yaw " + face.yaw + " time " + DuiMessageObserver.mTime + " " + name
) )
} }
} }
@@ -449,7 +476,7 @@ class TEngineFaceCheckManager : FaceCheckInterface {
fun checkSpeak( fun checkSpeak(
name: String, name: String,
logTag: String, logTag: String,
faceList: ConcurrentLinkedQueue<Face?>
faceList: ConcurrentLinkedQueue<FaceLandmarkInfo?>
): Boolean { ): Boolean {
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
var isSpeak = false var isSpeak = false
@@ -464,16 +491,16 @@ class TEngineFaceCheckManager : FaceCheckInterface {
if (face == null) { if (face == null) {
continue continue
} }
if (faceType >= 0 && (faceType - face.mouthClose) > 0.1f) {
if (faceType >= 0 && (faceType - face.mouseClose) > 0.1f) {
mouthChangeCount++ mouthChangeCount++
} }
faceType = face.mouthClose
if (face.mouthClose < 0.9f) {
faceType = face.mouseClose
if (face.mouseClose < 0.9f) {
mouthOpen++ mouthOpen++
} else { } else {
mouthClose++ mouthClose++
} }
if (face.headX > 0.3f || face.headX < -0.3f) {
if (face.pitch > 0.3f || face.pitch < -0.3f) {
overAngleCount++ overAngleCount++
} }
} }


+ 0
- 2
app/src/main/java/com/aispeech/nativedemo/tengine/copyAssetFolder.kt View File

@@ -1,8 +1,6 @@
package com.aispeech.nativedemo.tengine package com.aispeech.nativedemo.tengine


import android.content.res.AssetManager import android.content.res.AssetManager
import com.aispeech.nativedemo.tengine.ImageUtils.isFileExists
import com.shareopen.library.helper.util.FileUtils
import java.io.File import java.io.File
import java.io.File.separator import java.io.File.separator
import java.io.FileOutputStream import java.io.FileOutputStream


+ 511
- 0
app/src/main/java/com/aispeech/nativedemo/tengine2/TEngine2FaceCheckManager.kt View File

@@ -0,0 +1,511 @@
package com.aispeech.nativedemo.tengine2

import android.app.Activity
import android.graphics.Bitmap
import android.graphics.Rect
import android.util.Log
import com.aispeech.nativedemo.MainActivity
import com.aispeech.nativedemo.asr.observer.DuiMessageObserver
import com.aispeech.nativedemo.entity.PersonInfo
import com.aispeech.nativedemo.face.AngleInfo
import com.aispeech.nativedemo.face.FaceCheckInterface
import com.aispeech.nativedemo.face.FaceManager
import com.aispeech.nativedemo.log.Logger
import com.aispeech.nativedemo.utils.Utils
import com.lenovo.lefacecamerademo.ConfigClass.PROGRAM_ROOT_PATH
import com.lenovo.lefacesdk.MultiAtt
import com.shareopen.library.MVVM.application.AppContext
import com.shareopen.library.helper.LogUtils
import com.tenginekit.AndroidConfig
import com.tenginekit.KitCore
import com.tenginekit.face.Face
import com.tenginekit.face.FaceDetectInfo
import com.tenginekit.face.FaceLandmarkInfo
import com.tenginekit.model.TenginekitPoint
import java.io.File
import java.nio.ByteBuffer
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.ConcurrentLinkedQueue


class TEngine2FaceCheckManager : FaceCheckInterface {

companion object {
val instance by lazy (LazyThreadSafetyMode.SYNCHRONIZED){
TEngine2FaceCheckManager()
}
const val LOG_TAG = "TengineKitApp"
}
var hasInitKs = false
private val TAG = "KSFaceCheckManager"
var needKSCheck = false

@Volatile
var faceCount = 0
var faceQueue = ArrayBlockingQueue<PersonInfo>(10)
var faceListInVad = ConcurrentLinkedQueue<FaceLandmarkInfo?>()
var faceStrListInVad = ConcurrentLinkedQueue<String>()
var faceRectListInVad = ConcurrentLinkedQueue<MultiAtt>()


var faceListCloseInVad = ConcurrentLinkedQueue<FaceLandmarkInfo?>()
var faceStrListCloseInVad = ConcurrentLinkedQueue<String>()
var faceRectListCloseInVad = ConcurrentLinkedQueue<MultiAtt>()

var needFaceCheck = true
var needFaceAngleCheck = true

// fun getInstance(): TEngineFaceCheckManager? {
// if (TEngineFaceCheckManager.mInstance == null) {
// synchronized(KSFaceCheckManager::class.java) {
// if (TEngineFaceCheckManager.mInstance == null) {
// TEngineFaceCheckManager.mInstance = TEngineFaceCheckManager()
// }
// }
// }
// return TEngineFaceCheckManager.mInstance
// }

override fun init() {
Log.i(LOG_TAG, "start init")
/**
* 初始化
* */
KitCore.init(
AppContext.getInstance(),
AndroidConfig
.create()
.setNormalMode()
.setDefaultFunc()
.setInputImageFormat(AndroidConfig.ImageFormat.RGBA))
// .setInputImageSize(Image_w, Image_h)
// .setOutputImageSize(Image_w as Int, Image_h as Int)
Log.i(LOG_TAG, "init Success")

}

override fun bitmapDetected(bitmap: Bitmap?, personInfo: PersonInfo) {
if (!needKSCheck || !hasInitKs) {
return
}
if (personInfo.result == null || DuiMessageObserver.needPause) {
return
}
val start = System.currentTimeMillis()
val bitmap1 = Utils.CompressBmpByHD(bitmap, personInfo.result)
?: return
personInfo.faceStr = ""
val faceResult = doDetect(bitmap1, personInfo)
if (faceResult != null) {
addFaceInVad(faceResult, personInfo.faceStr, personInfo.result)
} else {
LogUtils.e(
"testface",
" faceData.faceResult == null $personInfo"
)
}
// faceQueue.offer(personInfo);
// faceCount++;
Log.e(
"testtwo",
"selectMan CompressBmpByHD duration " + (System.currentTimeMillis() - start)
)
if (MainActivity.instance != null) {
MainActivity.instance.setSettingLog(personInfo.faceStr)
}
}

override fun bitmapDetectedClose(bitmap: Bitmap?, personInfo: PersonInfo) {
if (!needKSCheck || !hasInitKs) {
return
}
if (personInfo.result == null || DuiMessageObserver.needPause) {
LogUtils.e("testtwo", " personInfo.result == null$personInfo")
return
}
val start = System.currentTimeMillis()
val bitmap1 = Utils.CompressBmpByHD(bitmap, personInfo.result)
?: return
personInfo.faceStr = ""
val faceResult = doDetect(bitmap1, personInfo)
val time = System.currentTimeMillis()
if (faceResult != null) {
addFaceInVadClose(faceResult, personInfo.faceStr, personInfo.result)
} else {
LogUtils.e(
"testtwo",
" faceData.faceResult == null $personInfo"
)
val file: File =
File(PROGRAM_ROOT_PATH + "/" + DuiMessageObserver.mTime + "_" + personInfo.faceWidth + "_" + time + "_" + "last.jpg")
//BitmapUtil.saveBitmap(file.getAbsolutePath(), bitmap1);
}
// faceQueue.offer(personInfo);
// faceCount++;
Log.e("testtwo", "close man face width " + personInfo.faceWidth + " time " + time)
Log.e(
"testtwo",
"close CompressBmpByHD duration " + (System.currentTimeMillis() - start) + " facestr " + personInfo.faceStr + " person " + personInfo + " time " + time
)
if (MainActivity.instance != null) {
MainActivity.instance.setSettingLogClose(personInfo.faceStr)
}
}

override fun onVadBegin() {
while (faceListInVad.size > 2) {
faceListInVad.poll()
}
Log.e("testface", "before vad " + faceListInVad.size)
}

override fun setFaceCheck(faceCheck: Boolean,
needMouthCheck: Boolean,
needAngleCheck: Boolean) {
needKSCheck = faceCheck
needFaceCheck = needMouthCheck
needFaceAngleCheck = needAngleCheck;

Log.i(LOG_TAG, "setFaceCheck ")
}

override fun getAngle(bitmap: Bitmap?, personInfo: PersonInfo?): AngleInfo? {
return null
}

fun doDetect(bitmap: Bitmap, personInfo: PersonInfo) : FaceLandmarkInfo? {
val start = System.currentTimeMillis()
var faceResult : FaceLandmarkInfo? = null;
bitmap?.let {
/**
* 获取人脸信息
*/
/**
* 获取人脸信息
*/
val data: ByteArray = bitmap2Bytes(bitmap)
val faceDetect = Face.detect(data)
var faceDetectInfos: List<FaceDetectInfo>? = ArrayList()
var landmarkInfos: List<FaceLandmarkInfo> = ArrayList()
if (faceDetect.faceCount > 0) {
faceDetectInfos = faceDetect.detectInfos
landmarkInfos = faceDetect.landmark2d()
}

Log.d("#####", "Face Num: " + faceDetectInfos!!.size)
if (faceDetectInfos != null && faceDetectInfos.size > 0) {
val face_landmarks: List<List<TenginekitPoint>> = ArrayList()
for (i in faceDetectInfos.indices) {
var rect: Rect? = Rect()
rect = faceDetectInfos[i].asRect()
Log.d(
"#####",
"mouseClose: " + landmarkInfos[i].mouseClose + "pitch: " + landmarkInfos[i].pitch + "yaw: " + landmarkInfos[i].yaw
)
}
}
Log.i(LOG_TAG, "end detect")
val sb = StringBuilder()
if (landmarkInfos != null) {
LogUtils.e("access123", "faces length " + landmarkInfos.size)
for (face in landmarkInfos) {
var expression = ""
sb.append("· ").append("表情:").append(expression).append("\n")
sb.append("· ").append("眼部状态(左眼):").append(face.leftEyeClose)
.append("\n")
sb.append("· ").append("眼部状态(右眼):").append(face.rightEyeClose)
.append("\n")
sb.append("· ").append("嘴部状态:").append("闭嘴${(face.mouseClose*100).toInt()}%")
.append("\n")
sb.append("· ").append("嘴部状态bigopen:").append("闭嘴${(face.mouseOpenBig*100).toInt()}%")
.append("\n")
sb.append("· ").append("3DPose:{pitch=").append(face.pitch).append(",roll=")
.append(face.roll).append(",yaw=").append(face.yaw).append("}\n")
sb.append("· ").append("关键点个数:").append("" + face.landmarks.size).append("\n")
sb.append("\n")
Log.e(LOG_TAG, "bitmapDetected: $sb")
faceResult = face
}
}
val faceStr = sb.toString()
personInfo.faceStr = faceStr
LogUtils.e("access123", "faceStr $faceStr")
LogUtils.e(
"testface",
"face duration " + (System.currentTimeMillis() - start) + " lx x1 " + personInfo.result.fa_x1 + " lx y1 " + personInfo.result.fa_y1 + " lx w " + personInfo.result.fa_w + " lx h " + personInfo.result.fa_h
)
}
return faceResult;
}

private fun bitmap2Bytes(image: Bitmap): ByteArray {
// calculate how many bytes our image consists of
val bytes = image.byteCount
val buffer = ByteBuffer.allocate(bytes) // Create a new buffer
image.copyPixelsToBuffer(buffer) // Move the byte data to the buffer
return buffer.array()
}

private fun getEyeStatus(eyeType: Int): String? {
var reuslt = ""
when (eyeType) {
0 -> reuslt = "不戴眼镜,并且睁着眼"
1 -> reuslt = "不戴眼镜,并且闭着眼"
2 -> reuslt = "戴着普通眼镜,并且睁着眼"
3 -> reuslt = "戴着普通眼镜,并且闭着眼"
4 -> reuslt = "戴着墨镜"
5 -> reuslt = "眼镜被遮挡"
}
return reuslt
}

private fun getMouthStatus(mouthStatus: Int): String? {
var result = ""
when (mouthStatus) {
0 -> result = "带着面具或者带着口罩"
1 -> result = "被其他东西遮挡着嘴巴"
2 -> result = "闭嘴状态"
3 -> result = "张嘴状态"
}
return result
}

fun addFaceInVad(faceResult: FaceLandmarkInfo?, faceStr: String?, faceMultiAtt: MultiAtt?) {
faceListInVad.offer(faceResult)
faceStrListInVad.offer(faceStr)
faceRectListInVad.offer(faceMultiAtt)
}

fun addFaceInVadClose(
faceResult: FaceLandmarkInfo?,
faceStr: String?,
faceMultiAtt: MultiAtt?
) {
faceListCloseInVad.offer(faceResult)
faceStrListCloseInVad.offer(faceStr)
faceRectListCloseInVad.offer(faceMultiAtt)
}

override fun getCurrentSpeakBeforeASR(name: String): Boolean {
if (!needKSCheck || !hasInitKs) {
return true
}
if (!needFaceCheck) {
return if (!needFaceAngleCheck) {
true
} else {
checkAngle(faceListInVad, name)
}
}
if (faceListInVad.size == 0) {
Log.e("testface", "BeforeASR size 0 is speak false")
return false
}
if (needFaceAngleCheck) {
val isAngleOk = checkAngle(faceListInVad, name)
if (!isAngleOk) {
return false
}
}
return checkSpeak(name, " BeforeASR ", faceListInVad)
}

override fun onDestroy() {
KitCore.release()
}


override fun getCurrentSpeak(name: String, isClear: Boolean): Boolean {
Log.e("testkd2", "FaceManager.needKSCheck " + needKSCheck)
if (!needKSCheck || !hasInitKs) {
return true
}
if (!needFaceCheck) {
return if (!needFaceAngleCheck) {
true
} else {
val isRightAngle = checkAngle(faceListInVad, name)
faceListInVad.clear()
faceStrListInVad.clear()
faceRectListInVad.clear()
isRightAngle
}
}
if (faceListInVad.size == 0) {
Log.e("testface2", "close size 0 is speak false")
return false
}
if (needFaceAngleCheck) {
val isAngleOk = checkAngle(faceListInVad, name)
Log.e("testtwoface", "$name isAngleOk $isAngleOk")
if (!isAngleOk) {
faceListInVad.clear()
faceStrListInVad.clear()
faceRectListInVad.clear()
return false
}
}
//needPause = true;
val start = System.currentTimeMillis()
//if (FaceManager.faceCount == 1 && faceListInVad.size() < 20)
run {}
// while (FaceManager.faceCount != 0) {
// try {
// Thread.sleep(20);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// }
val isSpeak = checkSpeak(name, "closeMan", faceListInVad)
if (!isSpeak) {
}
faceListInVad.clear()
faceStrListInVad.clear()
faceRectListInVad.clear()
return isSpeak
}

override fun getCurrentCloseSpeak(closeName: String, isClear: Boolean): Boolean {
if (!FaceManager.needKSCheck || !hasInitKs) {
return true
}
if (!needFaceCheck) {
return if (!needFaceAngleCheck) {
true
} else {
val isRightAngle = checkAngle(
faceListCloseInVad,
"closeName-$closeName"
)
faceListCloseInVad.clear()
faceStrListCloseInVad.clear()
faceRectListCloseInVad.clear()
isRightAngle
}
}
if (faceListCloseInVad.size == 0) {
Log.e("testface", "size 0 is speak false")
return false
}
if (needFaceAngleCheck) {
val isAngleOk = checkAngle(
faceListCloseInVad,
"closeName-$closeName"
)
if (!isAngleOk) {
faceListCloseInVad.clear()
faceStrListCloseInVad.clear()
faceRectListCloseInVad.clear()
return false
}
}
//needPause = true;
val start = System.currentTimeMillis()
//if (FaceManager.faceCount == 1 && faceListInVad.size() < 20)
run {}
// while (FaceManager.faceCount != 0) {
// try {
// Thread.sleep(20);
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
// }
val isSpeak = checkSpeak(closeName, "", faceListCloseInVad)
if (!isSpeak) {
}
faceListCloseInVad.clear()
faceStrListCloseInVad.clear()
faceRectListCloseInVad.clear()
return isSpeak
}


private fun checkAngle(
faceList: ConcurrentLinkedQueue<FaceLandmarkInfo?>,
name: String
): Boolean {
val count = faceList.size
var overAngleCount = 0
for (face in faceList) {
if (face == null) {
overAngleCount++
continue
}
if (face.yaw > 0.3f || face.yaw < -0.3f) {
overAngleCount++
} else {
LogUtils.e(
"testtwoface",
"face.yaw " + face.yaw + " time " + DuiMessageObserver.mTime + " " + name
)
}
}
val rightAngleCount = count - overAngleCount
LogUtils.e(
"testtwoface",
"face.yaw overAngleCount $overAngleCount count $count name $name"
)
return if (count <= 12) {
rightAngleCount * 10 > count
} else {
rightAngleCount * 3 > count
}
}

fun checkSpeak(
name: String,
logTag: String,
faceList: ConcurrentLinkedQueue<FaceLandmarkInfo?>
): Boolean {
val start = System.currentTimeMillis()
var isSpeak = false
var mouthOpen = 0
var mouthClose = 0
var mouthOther = 0
var overAngleCount = 0
var faceType = -1f
var mouthChangeCount = 0
val count = faceList.size
for (face in faceList) {
if (face == null) {
continue
}
if (faceType >= 0 && (faceType - face.mouseClose) > 0.1f) {
mouthChangeCount++
}
faceType = face.mouseClose
if (face.mouseClose < 0.9f) {
mouthOpen++
} else {
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) {
isSpeak = true
} else if (mouthOpen == 0 && count <= 20) {
if (Math.abs(mouthClose - mouthOther) < 3 || mouthChangeCount > mouthClose || mouthChangeCount > mouthOther) {
isSpeak = true
}
}
}
Logger.e("djASR-嘴型检测: " + logTag + name + " is speak " + isSpeak + " mouthOpen " + mouthOpen + " mouthClose " + mouthClose + " mouthOther " + mouthOther + " mouthChangeCount " + mouthChangeCount + " leftFaceSize " + faceCount + " overAngleCount " + overAngleCount + " time " + DuiMessageObserver.mTime)
Log.e(
"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)
)
return isSpeak
}

}

Loading…
Cancel
Save