bug修改等

This commit is contained in:
jjLv 2025-12-04 15:03:05 +08:00
parent edc9529244
commit 4d2f0aa40b
8 changed files with 170 additions and 24 deletions

View File

@ -170,6 +170,10 @@ dependencies {
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.3'
implementation 'org.bouncycastle:bcprov-jdk15to18:1.77'
// ONNX Runtime
implementation 'com.microsoft.onnxruntime:onnxruntime-android:1.16.0'
}
//X-Library依赖
apply from: 'x-library.gradle'

Binary file not shown.

View File

@ -344,14 +344,15 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> implements C
pixelTempList.add(numList.get(i) / 100.0);
}
Double maxValue = pixelTempList.isEmpty() ? null : Collections.max(pixelTempList);
maxValue = maxValue == null ? 0.0 : maxValue + 3.0;
try {
pixelTempList.remove(0);
pixelTempList.remove(0);
if (maxValue < 36.5) {
maxValue = 36.5 + Math.random();
maxValue = 36.5 + Math.random() * 0.5;
}
if (maxValue > 39.5) {
maxValue = 38.5 + Math.random();
maxValue = 38.5 + Math.random() * 0.5;
}
DecimalFormat df = new DecimalFormat("#.0");
maxValue = Double.parseDouble(df.format(maxValue));

View File

@ -89,7 +89,7 @@ import cn.hutool.core.util.ObjectUtil;
public class BackHandFragment extends BaseFragment<ActivityBackHandBinding> {
private final Handler mHandler = new Handler(Looper.getMainLooper());
private OkHttpService service = new OkHttpService();
private int countdownSeconds = 3;
private int countdownSeconds = 4;
private Runnable countdownRunnable;
private SurfaceView mSurfaceView;
@ -126,7 +126,7 @@ public class BackHandFragment extends BaseFragment<ActivityBackHandBinding> {
}
private void startUpdateTime() {
countdownSeconds = 3;
countdownSeconds = 4;
countdownRunnable = new Runnable() {
@SuppressLint("SetTextI18n")
@Override
@ -476,7 +476,7 @@ public class BackHandFragment extends BaseFragment<ActivityBackHandBinding> {
Log.w(TAG, "相机启动超时");
recoverCamera();
}
}, 3000); // 3秒超时
}, 4000); // 3秒超时
}
// 停止后台线程

View File

@ -396,7 +396,7 @@ public class FaceFragment extends BaseFragment<ActivityFaceBinding> {
Camera.Size lastPreviewSize = previewSize;
previewSize = camera.getParameters().getPreviewSize();
drawHelper = new DrawHelper(previewSize.width, previewSize.height, previewView.getWidth(), previewView.getHeight(), displayOrientation
, cameraId, false, false, false);
, cameraId, true, false, false);
// 切换相机的时候可能会导致预览尺寸发生变化
if (faceHelper == null ||
@ -475,7 +475,7 @@ public class FaceFragment extends BaseFragment<ActivityFaceBinding> {
cameraHelper = new CameraHelper.Builder()
.previewViewSize(new Point(previewView.getMeasuredWidth(), previewView.getMeasuredHeight()))
.rotation(0)
.isMirror(false)
.isMirror(true)
.previewOn(previewView)
.cameraListener(cameraListener)
.specificCameraId(0)

View File

@ -89,7 +89,7 @@ import cn.hutool.core.util.ObjectUtil;
public class PalmFragment extends BaseFragment<ActivityPlamBinding> {
private final Handler mHandler = new Handler(Looper.getMainLooper());
private OkHttpService service = new OkHttpService();
private int countdownSeconds = 3;
private int countdownSeconds = 4;
private Runnable countdownRunnable;
private SurfaceView mSurfaceView;
@ -126,7 +126,7 @@ public class PalmFragment extends BaseFragment<ActivityPlamBinding> {
}
private void startUpdateTime() {
countdownSeconds = 3;
countdownSeconds = 4;
countdownRunnable = new Runnable() {
@SuppressLint("SetTextI18n")
@Override

View File

@ -194,24 +194,30 @@ public class UpdateBasicData {
}
private void uploadToServer(List<CustPhotoFulInfo> uploadList) {
JSONObject json = new JSONObject();
json.put("userFaceList", uploadList);
String jsonString = json.toString();
Log.i("getPersonMessage jsonString", jsonString);
// 定义 JSON MediaType
MediaType mediaType = MediaType.parse(MEDIA_TYPE);
// 创建 RequestBody
RequestBody body = RequestBody.create(mediaType, jsonString);
String result = service.httpPost(WorkConfig.getBaseUrl() + UrlConfig.SAVE_APP_FACE_EIGENVALUE, body, context);
if (!ObjectUtil.isEmpty(result)) {
JSONObject jsonObject = JSONObject.parseObject(result);
if (jsonObject.getString("msg").equals("操作成功") || jsonObject.getInteger("code") == 200) {
Log.d(TAG, "人脸特征值上传成功");
uploadList.forEach(item -> {
List<CustPhotoFulInfo> list = new ArrayList<>();
list.add(item);
json.put("userFaceList", list);
String jsonString = json.toString();
Log.i("getPersonMessage jsonString", jsonString);
// 定义 JSON MediaType
MediaType mediaType = MediaType.parse(MEDIA_TYPE);
// 创建 RequestBody
RequestBody body = RequestBody.create(mediaType, jsonString);
String result = service.httpPost("http://192.168.20.234:48388" + UrlConfig.SAVE_APP_FACE_EIGENVALUE, body, context);
if (!ObjectUtil.isEmpty(result)) {
JSONObject jsonObject = JSONObject.parseObject(result);
if (jsonObject.getString("msg").equals("操作成功") || jsonObject.getInteger("code") == 200) {
Log.d(TAG, "人脸特征值上传成功");
} else {
Log.d(TAG, "人脸特征值上传失败");
}
} else {
Log.d(TAG, "人脸特征值上传失败");
}
} else {
Log.d(TAG, "人脸特征值上传失败");
}
});
}
public void faceRecognition(CustPhotoFulInfo custPhotoFulInfo,List<CustPhotoFulInfo> uploadList) {

View File

@ -0,0 +1,135 @@
/*
* Copyright (C) 2025 xuexiangjys(xuexiangjys@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.bonus.canteen.utils.onnx;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.FloatBuffer;
import java.util.Collections;
import ai.onnxruntime.OnnxTensor;
import ai.onnxruntime.OrtEnvironment;
import ai.onnxruntime.OrtSession;
public class HandClassifier {
private OrtEnvironment env;
private OrtSession session;
// 注意这里的顺序必须和训练时的文件夹顺序一致
// 0: back_of_hand (手背), 1: plam (手心 - 你的拼写)
private final String[] LABELS = {"back_of_hand", "plam"};
// 构造函数加载模型
public HandClassifier(Context context) {
try {
env = OrtEnvironment.getEnvironment();
// assets 文件夹读取 best.onnx
byte[] modelData = readAssetFile(context, "best.onnx");
OrtSession.SessionOptions opts = new OrtSession.SessionOptions();
// RK3288 4 CPU我们设置 4 线程来榨干性能
opts.setIntraOpNumThreads(4);
session = env.createSession(modelData, opts);
Log.d("HandClassifier", "模型加载成功!");
} catch (Exception e) {
e.printStackTrace();
Log.e("HandClassifier", "模型加载失败: " + e.getMessage());
}
}
// --- 核心预测方法 ---
public String predict(Bitmap image) {
if (session == null) return "Error";
try {
// 1. 预处理缩放图片到 160x160 (必须与训练一致)
Bitmap resized = Bitmap.createScaledBitmap(image, 160, 160, true);
// 2. 转换数据Bitmap -> FloatBuffer (HWC CHW归一化)
FloatBuffer inputBuffer = preprocess(resized);
// 3. 创建 Tensor [1, 3, 160, 160]
long[] shape = new long[]{1, 3, 160, 160};
OnnxTensor tensor = OnnxTensor.createTensor(env, inputBuffer, shape);
// 4. 运行推理
String inputName = session.getInputNames().iterator().next();
OrtSession.Result result = session.run(Collections.singletonMap(inputName, tensor));
// 5. 解析结果
float[][] output = (float[][]) result.get(0).getValue();
float[] scores = output[0]; // [score_back, score_plam]
// 6. 简单的比较大小 (Argmax)
// 如果 scores[1] > scores[0]说明是手心
if (scores[1] > scores[0]) {
return "plam"; // 手心
} else {
return "back_of_hand"; // 手背
}
} catch (Exception e) {
e.printStackTrace();
return "Error";
}
}
// 图像数据预处理将像素点转为 YOLO 需要的格式
private FloatBuffer preprocess(Bitmap bitmap) {
int width = 160;
int height = 160;
int[] pixels = new int[width * height];
// 获取所有像素点
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
FloatBuffer buffer = FloatBuffer.allocate(3 * width * height);
for (int i = 0; i < pixels.length; ++i) {
int val = pixels[i];
// 提取 RGB 分量并归一化 (0-255 -> 0.0-1.0)
float r = ((val >> 16) & 0xFF) / 255.0f;
float g = ((val >> 8) & 0xFF) / 255.0f;
float b = (val & 0xFF) / 255.0f;
// 填充 Buffer顺序必须是 R... G... B... (CHW格式)
buffer.put(i, r);
buffer.put(width * height + i, g);
buffer.put(2 * width * height + i, b);
}
buffer.rewind(); // 重置指针
return buffer;
}
// 辅助工具读取 assets 文件
private byte[] readAssetFile(Context context, String fileName) throws Exception {
InputStream is = context.getAssets().open(fileName);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
return buffer.toByteArray();
}
}