From c4175c3bdc8c8fb162633b15b3ab4cd409818fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E4=BF=8A=E6=89=8D?= <61060866@qq.com> Date: Tue, 23 Apr 2024 17:00:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=99=B9=E8=BD=AF=E8=AF=B7=E6=B1=82=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nativedemo/tengine/BitmapUtils.kt | 409 -------------- .../nativedemo/tengine/ImageUtils.java | 93 --- .../tengine/TEngineFaceCheckManager.kt | 532 ------------------ .../nativedemo/tengine/copyAssetFolder.kt | 6 + 4 files changed, 6 insertions(+), 1034 deletions(-) delete mode 100644 app/src/main/java/com/aispeech/nativedemo/tengine/BitmapUtils.kt delete mode 100644 app/src/main/java/com/aispeech/nativedemo/tengine/ImageUtils.java delete mode 100644 app/src/main/java/com/aispeech/nativedemo/tengine/TEngineFaceCheckManager.kt diff --git a/app/src/main/java/com/aispeech/nativedemo/tengine/BitmapUtils.kt b/app/src/main/java/com/aispeech/nativedemo/tengine/BitmapUtils.kt deleted file mode 100644 index c92c8b1..0000000 --- a/app/src/main/java/com/aispeech/nativedemo/tengine/BitmapUtils.kt +++ /dev/null @@ -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 - } -} diff --git a/app/src/main/java/com/aispeech/nativedemo/tengine/ImageUtils.java b/app/src/main/java/com/aispeech/nativedemo/tengine/ImageUtils.java deleted file mode 100644 index f9f6f71..0000000 --- a/app/src/main/java/com/aispeech/nativedemo/tengine/ImageUtils.java +++ /dev/null @@ -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(); - } -} diff --git a/app/src/main/java/com/aispeech/nativedemo/tengine/TEngineFaceCheckManager.kt b/app/src/main/java/com/aispeech/nativedemo/tengine/TEngineFaceCheckManager.kt deleted file mode 100644 index 09126e9..0000000 --- a/app/src/main/java/com/aispeech/nativedemo/tengine/TEngineFaceCheckManager.kt +++ /dev/null @@ -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(10) - var faceListInVad = ConcurrentLinkedQueue() - var faceStrListInVad = ConcurrentLinkedQueue() - var faceRectListInVad = ConcurrentLinkedQueue() - - - var faceListCloseInVad = ConcurrentLinkedQueue() - var faceStrListCloseInVad = ConcurrentLinkedQueue() - var faceRectListCloseInVad = ConcurrentLinkedQueue() - - 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? = ArrayList() - var landmarkInfos: List = 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> = 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, - 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 - ): 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 - } - -} diff --git a/app/src/main/java/com/aispeech/nativedemo/tengine/copyAssetFolder.kt b/app/src/main/java/com/aispeech/nativedemo/tengine/copyAssetFolder.kt index 23d334e..97df60a 100644 --- a/app/src/main/java/com/aispeech/nativedemo/tengine/copyAssetFolder.kt +++ b/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()