瀏覽代碼

虹软请求地址变更

dev_h5stream
李俊才 1 年之前
父節點
當前提交
c4175c3bdc
共有 4 個文件被更改,包括 6 次插入1034 次删除
  1. +0
    -409
      app/src/main/java/com/aispeech/nativedemo/tengine/BitmapUtils.kt
  2. +0
    -93
      app/src/main/java/com/aispeech/nativedemo/tengine/ImageUtils.java
  3. +0
    -532
      app/src/main/java/com/aispeech/nativedemo/tengine/TEngineFaceCheckManager.kt
  4. +6
    -0
      app/src/main/java/com/aispeech/nativedemo/tengine/copyAssetFolder.kt

+ 0
- 409
app/src/main/java/com/aispeech/nativedemo/tengine/BitmapUtils.kt 查看文件

@@ -1,409 +0,0 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.aispeech.nativedemo.tengine

import android.content.Context
import android.text.TextUtils
import kotlin.jvm.JvmOverloads
import android.graphics.Bitmap.CompressFormat
import android.content.res.AssetManager
import android.graphics.*
import android.media.ExifInterface
import android.util.Log
import androidx.annotation.IntRange
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.IOException
import java.lang.Exception

object BitmapUtils {
private const val WEBP = ".webp"
private const val PNG = ".png"
private const val JEG = ".jpg"
fun getBitmap(file: File?): Bitmap? {
return if (file == null) null else BitmapFactory.decodeFile(file.absolutePath)
}

fun getBitmap(filePath: String?): Bitmap? {
return if (TextUtils.isEmpty(filePath)) null else BitmapFactory.decodeFile(filePath)
}

@JvmOverloads
fun scale(src: Bitmap, newWidth: Int, newHeight: Int, recycle: Boolean = false): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else {
val ret = Bitmap.createScaledBitmap(src, newWidth, newHeight, true)
if (recycle && !src.isRecycled) {
src.recycle()
}
ret
}
}

@JvmOverloads
fun scale(
src: Bitmap,
scaleWidth: Float,
scaleHeight: Float,
recycle: Boolean = false
): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else {
val matrix = Matrix()
matrix.setScale(scaleWidth, scaleHeight)
val ret = Bitmap.createBitmap(src, 0, 0, src.width, src.height, matrix, true)
if (recycle && !src.isRecycled) {
src.recycle()
}
ret
}
}

fun scale(
src: Bitmap,
scaleWidth: Float,
scaleHeight: Float,
px: Float,
py: Float,
recycle: Boolean
): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else {
val matrix = Matrix()
matrix.setScale(scaleWidth, scaleHeight, px, py)
val ret = Bitmap.createBitmap(src, 0, 0, src.width, src.height, matrix, true)
if (recycle && !src.isRecycled) {
src.recycle()
}
ret
}
}

@JvmOverloads
fun clip(
src: Bitmap,
x: Int,
y: Int,
width: Int,
height: Int,
recycle: Boolean = false
): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else {
val ret = Bitmap.createBitmap(src, x, y, width, height)
if (recycle && !src.isRecycled) {
src.recycle()
}
ret
}
}

fun skew(src: Bitmap, kx: Float, ky: Float, recycle: Boolean): Bitmap? {
return skew(src, kx, ky, 0.0f, 0.0f, recycle)
}

@JvmOverloads
fun skew(
src: Bitmap,
kx: Float,
ky: Float,
px: Float = 0.0f,
py: Float = 0.0f,
recycle: Boolean = false
): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else {
val matrix = Matrix()
matrix.setSkew(kx, ky, px, py)
val ret = Bitmap.createBitmap(src, 0, 0, src.width, src.height, matrix, true)
if (recycle && !src.isRecycled) {
src.recycle()
}
ret
}
}

@JvmOverloads
fun rotate(src: Bitmap, degrees: Int, px: Float, py: Float, recycle: Boolean = false): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else if (degrees == 0) {
src
} else {
val matrix = Matrix()
matrix.setRotate(degrees.toFloat(), px, py)
val ret = Bitmap.createBitmap(src, 0, 0, src.width, src.height, matrix, true)
if (recycle && !src.isRecycled) {
src.recycle()
}
ret
}
}

fun getRotateDegree(filePath: String?): Int {
return try {
val exifInterface = ExifInterface(filePath!!)
val orientation = exifInterface.getAttributeInt("Orientation", 1)
when (orientation) {
3 -> 180
6 -> 90
8 -> 270
else -> 0
}
} catch (var3: IOException) {
var3.printStackTrace()
-1
}
}

@JvmOverloads
fun compressByQuality(
src: Bitmap,
@IntRange(from = 0L, to = 100L) quality: Int,
recycle: Boolean = false
): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else {
val baos = ByteArrayOutputStream()
src.compress(CompressFormat.JPEG, quality, baos)
val bytes = baos.toByteArray()
if (recycle && !src.isRecycled) {
src.recycle()
}
BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
}
}

@JvmOverloads
fun compressByQuality(src: Bitmap, maxByteSize: Long, recycle: Boolean = false): Bitmap? {
return if (!isEmptyBitmap(src) && maxByteSize > 0L) {
var quality = 100
val baos = ByteArrayOutputStream()
src.compress(CompressFormat.JPEG, quality, baos)
while (baos.toByteArray().size.toLong() > maxByteSize && quality > 0) {
baos.reset()
src.compress(CompressFormat.JPEG, quality, baos)
quality -= 10
}
val bytes = baos.toByteArray()
if (recycle && !src.isRecycled) {
src.recycle()
}
BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
} else {
null
}
}

fun getFitSampleBitmap(file_path: String?, width: Int, height: Int): Bitmap {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(file_path, options)
options.inSampleSize = calculateInSampleSize(options, width, height)
options.inJustDecodeBounds = false
return BitmapFactory.decodeFile(file_path, options)
}

@JvmOverloads
fun compressBySampleSize(src: Bitmap, sampleSize: Int, recycle: Boolean = false): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else {
val options = BitmapFactory.Options()
options.inSampleSize = sampleSize
val baos = ByteArrayOutputStream()
src.compress(CompressFormat.JPEG, 100, baos)
val bytes = baos.toByteArray()
if (recycle && !src.isRecycled) {
src.recycle()
}
BitmapFactory.decodeByteArray(bytes, 0, bytes.size, options)
}
}

@JvmOverloads
fun compressBySampleSize(
src: Bitmap,
maxWidth: Int,
maxHeight: Int,
recycle: Boolean = false
): Bitmap? {
return if (isEmptyBitmap(src)) {
null
} else {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
val baos = ByteArrayOutputStream()
src.compress(CompressFormat.JPEG, 100, baos)
val bytes = baos.toByteArray()
BitmapFactory.decodeByteArray(bytes, 0, bytes.size, options)
options.inSampleSize = calculateInSampleSize(
options,
maxWidth,
maxHeight
)
options.inJustDecodeBounds = false
if (recycle && !src.isRecycled) {
src.recycle()
}
BitmapFactory.decodeByteArray(bytes, 0, bytes.size, options)
}
}

fun toRoundedCorner(bitmap: Bitmap?, radius: Float): Bitmap? {
return if (bitmap == null) {
null
} else {
val width = bitmap.width
val height = bitmap.height
toRoundedCorner(bitmap, width, height, radius)
}
}

fun toRoundedCorner(path: String?, radius: Float): Bitmap? {
val op = BitmapFactory.Options()
op.inJustDecodeBounds = false
val bitmap = BitmapFactory.decodeFile(path, op)
return toRoundedCorner(bitmap, radius)
}

fun toRoundedCorner(bitmap: Bitmap, width: Int, height: Int, radius: Float): Bitmap? {
return if (width > 0 && height > 0) {
val output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
val paint = Paint()
val color = -12434878
val srcRect = Rect(0, 0, bitmap.width, bitmap.height)
val destRect = Rect(0, 0, width, height)
val destRectF = RectF(destRect)
paint.isAntiAlias = true
canvas.drawARGB(0, 0, 0, 0)
paint.color = -12434878
canvas.drawRoundRect(destRectF, radius, radius, paint)
paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
canvas.drawBitmap(bitmap, srcRect, destRect, paint)
output
} else {
null
}
}

/**
* 从普通文件中读入图片
* @param fileName
* @return
*/
fun getBitmapFromFile(fileName: String?): Bitmap? {
val bitmap: Bitmap?
val file = File(fileName)
if (!file.exists()) {
return null
}
bitmap = try {
BitmapFactory.decodeFile(fileName)
} catch (e: Exception) {
Log.e("ShiTouren", "getBitmapFromFile: ", e)
null
}
return bitmap
}

fun isEmptyBitmap(src: Bitmap?): Boolean {
return src == null || src.width == 0 || src.height == 0
}

fun calculateInSampleSize(options: BitmapFactory.Options, maxWidth: Int, maxHeight: Int): Int {
var height = options.outHeight
var width = options.outWidth
var inSampleSize: Int
inSampleSize = 1
while (1.let { width = width shr it; width } >= maxWidth && 1.let {
height = height shr it; height
} >= maxHeight) {
inSampleSize = inSampleSize shl 1
}
return inSampleSize
}

fun resize(bitmap: Bitmap, newWidth: Int, newHeight: Int): Bitmap {
val scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888)
val ratioX = newWidth.toFloat() / bitmap.width.toFloat()
val ratioY = newHeight.toFloat() / bitmap.height.toFloat()
val middleX = newWidth.toFloat() / 2.0f
val middleY = newHeight.toFloat() / 2.0f
val scaleMatrix = Matrix()
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY)
val canvas = Canvas(scaledBitmap)
canvas.setMatrix(scaleMatrix)
canvas.drawBitmap(
bitmap,
middleX - (bitmap.width / 2).toFloat(),
middleY - (bitmap.height / 2).toFloat(),
Paint(2)
)
return scaledBitmap
}

fun checkBitmapFileSuffix(bitmapFileName: String, format: CompressFormat?): Boolean {
var result = true
when (format) {
CompressFormat.PNG -> if (!bitmapFileName.endsWith(".png")) {
result = false
}
CompressFormat.JPEG -> if (!bitmapFileName.endsWith(".jpg")) {
result = false
}
CompressFormat.WEBP -> if (!bitmapFileName.endsWith(".webp")) {
result = false
}

else -> {}
}
return result
}

fun addBitmapFileSuffix(bitmapFileName: String, format: CompressFormat?): String {
var bitmapFileName = bitmapFileName
when (format) {
CompressFormat.PNG -> if (!bitmapFileName.endsWith(".png")) {
bitmapFileName = "$bitmapFileName.png"
}
CompressFormat.JPEG -> if (!bitmapFileName.endsWith(".jpg")) {
bitmapFileName = "$bitmapFileName.jpg"
}
CompressFormat.WEBP -> if (!bitmapFileName.endsWith(".webp")) {
bitmapFileName = "$bitmapFileName.webp"
}

else -> {}
}
return bitmapFileName
}

/**
* 加载Assets文件夹下的图片
* @param context
* @param fileName
* @return
*/
fun getImageFromAssetsFile(context: Context, fileName: String?): Bitmap? {
var bitmap: Bitmap? = null
val manager = context.resources.assets
try {
val `is` = manager.open(fileName!!)
bitmap = BitmapFactory.decodeStream(`is`)
`is`.close()
} catch (e: IOException) {
e.printStackTrace()
}
return bitmap
}
}

+ 0
- 93
app/src/main/java/com/aispeech/nativedemo/tengine/ImageUtils.java 查看文件

@@ -1,93 +0,0 @@
package com.aispeech.nativedemo.tengine;

import static android.media.ExifInterface.ORIENTATION_ROTATE_270;
import static android.media.ExifInterface.ORIENTATION_ROTATE_90;

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

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import androidx.exifinterface.media.ExifInterface;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

public class ImageUtils {
public static int getYUVByteSize(final int width, final int height) {
final int ySize = width * height;
final int uvSize = ((width + 1) / 2) * ((height + 1) / 2) * 2;

return ySize + uvSize;
}

public static byte[] bitmap2RGB(Bitmap bitmap) {
int bytes = bitmap.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
byte[] rgba = buffer.array();
byte[] pixels = new byte[(rgba.length / 4) * 3];
int count = rgba.length / 4;
for (int i = 0; i < count; i++) {
pixels[i * 3] = rgba[i * 4];
pixels[i * 3 + 1] = rgba[i * 4 + 1];
pixels[i * 3 + 2] = rgba[i * 4 + 2];
}
return pixels;
}

public static byte[] bitmap2RGBA(Bitmap bitmap) {
int bytes = bitmap.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
byte[] rgba = buffer.array();
return rgba;
}

public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri) throws IOException {
InputStream inputStream;
inputStream = context.getContentResolver().openInputStream(photoUri);
ExifInterface exif = null;
Bitmap srcBitmap = null;
int rotate = 0;
try {
exif = new ExifInterface(inputStream);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
inputStream.close();
inputStream = context.getContentResolver().openInputStream(photoUri);
srcBitmap = BitmapFactory.decodeStream(inputStream);
if (orientation == ORIENTATION_ROTATE_90) {
rotate = 90;
} else if (orientation == ORIENTATION_ROTATE_270) {
rotate = 270;
}
if (rotate > 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
srcBitmap.getHeight(), matrix, true);
}
inputStream.close();
} catch (Exception exception) {
Log.e(LOG_TAG, "error in getCorrectlyOrientedImage");
}
return srcBitmap;
}

public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}

public static boolean isFileExists(String path) {
return TextUtils.isEmpty(path) || new File(path).exists();
}
}

+ 0
- 532
app/src/main/java/com/aispeech/nativedemo/tengine/TEngineFaceCheckManager.kt 查看文件

@@ -1,532 +0,0 @@
package com.aispeech.nativedemo.tengine

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 TEngineFaceCheckManager : 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")

}

fun copyModel(activity: Activity) {
activity.assets.copyAssetFolder(
"model",
activity.externalCacheDir?.absolutePath ?: "",
object : ModelCopyCallback {
override fun copyFinish() {
Log.i(LOG_TAG, "copyModel Success")
//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()
}

override fun copyFail() {
Log.i(LOG_TAG, "copyModel fail")
}
})
}

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
}

}

+ 6
- 0
app/src/main/java/com/aispeech/nativedemo/tengine/copyAssetFolder.kt 查看文件

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

import android.content.res.AssetManager
import android.text.TextUtils
import java.io.File
import java.io.File.separator
import java.io.FileOutputStream
@@ -57,8 +58,13 @@ fun AssetManager.copyAssetFile(srcName: String, dstName: String): Boolean {
e.printStackTrace()
false
}


}

fun isFileExists(path: String?): Boolean {
return TextUtils.isEmpty(path) || File(path).exists()
}

interface ModelCopyCallback {
fun copyFinish()


Loading…
取消
儲存