|
rt,我在安卓平板上部署rknn算法,通过python运行的推理结果和通过android部署的c++代码运行结果不一致,但如果输入参数为0则一致,求解
截图:
全部参数为0:
python 代码
- import os
- import urllib
- import traceback
- import time
- import sys
- import numpy as np
- import cv2
- from rknn.api import RKNN
- from blazefacenumpy import BlazeFace
- ONNX_MODEL = 'best.onnx' # onnx 模型的路径
- ONNX_MODEL = 'rppg_new.onnx' # onnx 模型的路径
- ONNX_MODEL = 'blazeface128.onnx' # onnx 模型的路径
- # ONNX_MODEL = 'v3.onnx' # onnx 模型的路径
- # ONNX_MODEL = 'alexnet.onnx' # onnx 模型的路径
- TFLITE_MODEL = 'face_detection_front.tflite'
- # TFLITE_MODEL = 'alexnet_float32.tflite'
- RKNN_MODEL = './yolov8-ghost-pose.rknn' # 转换后的 RKNN 模型保存路径
- RKNN_MODEL = './bz128_3568.rknn' # 转换后的 RKNN 模型保存路径
- # RKNN_MODEL = './facenet——3568.rknn' # 转换后的 RKNN 模型保存路径
- # RKNN_MODEL = './pfldv3.rknn' # 转换后的 RKNN 模型保存路径
- DATASET = './test.txt' # 数据集文件路径
-
- QUANTIZE_ON = False # 是否进行量化
- if __name__ == '__main__':
-
- # 创建 RKNN 对象
- rknn = RKNN(verbose=False)
-
- # 检查 ONNX 模型文件是否存在
- if not os.path.exists(ONNX_MODEL):
- print('model not exist')
- exit(-1)
-
- # 配置模型预处理参数
- print('--> Config model')
- rknn.config(#reorder_channel='0 1 2', # 表示 RGB 通道
-
- mean_values=[[128, 128, 128]], # 每个通道的像素均值,预处理时对应通道减去该值
- std_values=[[128, 128, 128]], # 每个通道的像素标准差,每个通道除以该值
- optimization_level=3, # 优化级别
- quantized_method='layer',
- float_dtype="float16",
- target_platform = 'RK3568', #指定目标平台为rv1126
- # quantize_input_node=QUANTIZE_ON
- ) # 对时输入节点进行量化
- print('done')
-
- # 加载 ONNX 模型
- # print('--> Loading model')
- model = rknn.load_rknn(RKNN_MODEL)
- ret = rknn.init_runtime(target="rk3568")
- frame = cv2.imread('./test.jpg')
- frame =cv2.resize(frame,(128,128))
- npp = np.full_like(frame,2)
- # color_img = np.zeros([1,3,128,128]).astype(np.float16)
- pred = rknn.inference(inputs=[npp], data_format='nhwc',inputs_pass_through=[False])
- # ret = rknn.load_onnx(model=ONNX_MODEL)
- # rknn.inference(inputs=[])
- exit(1)
c++ 代码
- #include <android/log.h>
- #include <android/bitmap.h>
- #include "../rknn_api.h"
- #include "im2d_type.h"
- #include <sys/time.h>
- #include <string>
- #include <vector>
- #include <jni.h>
- #include "../rga/rga.h"
- #include "../rga/im2d.h"
- #include "../rga/im2d_version.h"
- #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "wuzhengsdkC++", ##__VA_ARGS__);
- #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "wuzhengsdkC++", ##__VA_ARGS__);
- uint32_t n_input = 1;
- uint32_t n_output = 2;
- int m_in_width = 0; // the width of the RKNN model input
- int m_in_height = 0; // the height of the RKNN model input
- int m_in_channel = 0; // the channel of the RKNN model input
- rknn_tensor_attr input_attrs[1];
- rknn_tensor_attr output_attrs[2];
- rknn_tensor_mem *output_mems[2];
- std::vector<float> out_scales;
- std::vector<int32_t> out_zps;
- bool created = false;
- rknn_context ctx = 0;
- //rga_buffer_t g_rga_dst;
- int g_inf_count = 0;
- char *jstringToChar(JNIEnv *env, jstring jstr) {
- char *rtn = NULL;
- jclass clsstring = env->FindClass("java/lang/String");
- jstring strencode = env->NewStringUTF("GB2312");
- jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
- jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
- jsize alen = env->GetArrayLength(barr);
- jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE);
- if (alen > 0) {
- rtn = (char *) malloc(alen + 1);
- memcpy(rtn, ba, alen);
- rtn[alen] = 0;
- }
- env->ReleaseByteArrayElements(barr, ba, 0);
- return rtn;
- }
- JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved) {
- LOGE("JNI_OnUnload");
- }
- extern "C"
- JNIEXPORT jint JNICALL Java_com_wuzhengai_examination_tfliterun_blazeface_rknn_BlazeFaceRknn_init(
- JNIEnv *env,
- jobject thiz,
- jstring jmodel_path) {
- char *model_path = jstringToChar(env, jmodel_path);
- rknn_sdk_version version;
- int ret1 = rknn_query(ctx, RKNN_QUERY_SDK_VERSION, &version,
- sizeof(rknn_sdk_version));
- // printf("api version : %s\n", version.api_version);
- // printf("driver version: %s\n", version.drv_version);
- LOGE("api version : %s\n", (char *) version.api_version);
- LOGE("driver version: %s\n", (char *) version.drv_version);
- LOGE("%s,%s", version.api_version, version.drv_version)
- // 1. Load model
- FILE *fp = fopen(model_path, "rb");
- if (fp == NULL) {
- LOGE("fopen %s fail!\n", model_path);
- return -1;
- }
- delete model_path;
- model_path = NULL;
- fseek(fp, 0, SEEK_END);
- uint32_t model_len = ftell(fp);
- void *model = malloc(model_len);
- fseek(fp, 0, SEEK_SET);
- if (model_len != fread(model, 1, model_len, fp)) {
- LOGE("fread %s fail!\n", model_path);
- free(model);
- fclose(fp);
- return -1;
- }
- fclose(fp);
- // 2. Init RKNN model
- int ret = rknn_init(&ctx, model, model_len, 0, nullptr);
- free(model);
- if (ret < 0) {
- LOGE("rknn_init fail! ret=%d\n", ret);
- return -1;
- }
- // 3. Query input/output attr.
- rknn_input_output_num io_num;
- rknn_query_cmd cmd = RKNN_QUERY_IN_OUT_NUM;
- // 3.1 Query input/output num.
- ret = rknn_query(ctx, cmd, &io_num, sizeof(io_num));
- if (ret != RKNN_SUCC) {
- LOGE("rknn_query io_num fail!ret=%d\n", ret);
- return -1;
- }
- n_input = io_num.n_input;
- n_output = io_num.n_output;
- // 3.2 Query input attributes
- memset(input_attrs, 0, n_input * sizeof(rknn_tensor_attr));
- for (int i = 0; i < n_input; ++i) {
- input_attrs[i].index = i;
- cmd = RKNN_QUERY_INPUT_ATTR;
- ret = rknn_query(ctx, cmd, &(input_attrs[i]), sizeof(rknn_tensor_attr));
- if (ret < 0) {
- LOGE("rknn_query input_attrs[%d] fail!ret=%d\n", i, ret);
- return -1;
- }
- }
- // 3.2.0 Update global model input shape.
- if (RKNN_TENSOR_NHWC == input_attrs[0].fmt) {
- m_in_height = input_attrs[0].dims[1];
- m_in_width = input_attrs[0].dims[2];
- m_in_channel = input_attrs[0].dims[3];
- } else if (RKNN_TENSOR_NCHW == input_attrs[0].fmt) {
- m_in_height = input_attrs[0].dims[2];
- m_in_width = input_attrs[0].dims[3];
- m_in_channel = input_attrs[0].dims[1];
- } else {
- LOGE("Unsupported model input layout: %d!\n", input_attrs[0].fmt);
- return -1;
- }
- // 3.3 Query output attributes
- memset(output_attrs, 0, n_output * sizeof(rknn_tensor_attr));
- for (int i = 0; i < n_output; ++i) {
- output_attrs[i].index = i;
- cmd = RKNN_QUERY_OUTPUT_ATTR;
- ret = rknn_query(ctx, cmd, &(output_attrs[i]), sizeof(rknn_tensor_attr));
- if (ret < 0) {
- LOGE("rknn_query output_attrs[%d] fail!ret=%d\n", i, ret);
- return -1;
- }
- // set out_scales/out_zps for post_process
- out_scales.push_back(output_attrs[i].scale);
- out_zps.push_back(output_attrs[i].zp);
- }
- void *in_data = malloc(m_in_width * m_in_height * m_in_channel);
- memset(in_data, 0, m_in_width * m_in_height * m_in_channel);
- // 4.1.2 Update input attrs
- input_attrs[0].index = 0;
- input_attrs[0].type = RKNN_TENSOR_UINT8;
- input_attrs[0].size = m_in_height * m_in_width * m_in_channel * sizeof(char);
- input_attrs[0].fmt = RKNN_TENSOR_NCHW;
- // TODO -- The efficiency of pass through will be higher, we need adjust the layout of input to
- // meet the use condition of pass through.
- input_attrs[0].pass_through = 0;
- // 4.1.3 Set input buffer
- // rknn_set_io_mem(ctx, input_mems[0], &(input_attrs[0]));
- created = true;
- return 0;
- }
- extern "C"
- JNIEXPORT void JNICALL
- Java_com_wuzhengai_examination_tfliterun_blazeface_rknn_BlazeFaceRknn_release(
- JNIEnv *env,
- jobject thiz) {
- LOGI("rknn_destroy!");
- // release io_mem resource
- // for (int i = 0; i < n_input; ++i) {
- // rknn_destroy_mem(ctx, input_mems[i]);
- // }
- for (int i = 0; i < n_output; ++i) {
- rknn_destroy_mem(ctx, output_mems[i]);
- }
- rknn_destroy(ctx);
- }
- extern "C"
- JNIEXPORT jboolean JNICALL
- Java_com_wuzhengai_examination_tfliterun_blazeface_rknn_BlazeFaceRknn_detect(
- JNIEnv *env,
- jobject thiz,
- jintArray input,
- jfloatArray output1,
- jfloatArray output2) {
- if (!created) {
- LOGE("run_yolo: init yolo hasn't successful!");
- return false;
- }
- jboolean inputCopy = JNI_FALSE;
- jint *const inData = env->GetIntArrayElements(input, &inputCopy);
- // 获取数组长度
- jsize length = env->GetArrayLength(input);
- // 创建一个int8_t数组
- uint8_t *inputData = new uint8_t[length];
- // inputData
- for (int i = 0; i < length; i++) {
- inputData[i] = static_cast<uint8_t>(inData[i]);
- }
- LOGE("test,%d,%d,%d", inData[126],static_cast<uint8_t>(inData[126]),inputData[126])
- jboolean outputCopy = JNI_FALSE;
- jfloat *const y0 = env->GetFloatArrayElements(output1, &outputCopy);
- jfloat *const y1 = env->GetFloatArrayElements(output2, &outputCopy);
- rknn_input inputs[1];
- memset(inputs, 0, sizeof(inputs));
- inputs[0].index = 0;
- inputs[0].type = RKNN_TENSOR_UINT8;
- // float 类型需要乘以2?不清楚
- inputs[0].size = m_in_height * m_in_width * m_in_channel ;
- // inputs[0].size =75264;
- inputs[0].fmt = RKNN_TENSOR_NHWC;
- inputs[0].pass_through = 0;
- inputs[0].buf = inData;
- int ret = rknn_inputs_set(ctx, 1, inputs);
- rknn_output outputs[2];
- memset(outputs, 0, sizeof(outputs));
- for (int i = 0; i < 2; ++i) {
- outputs[i].want_float = 1;
- }
- if (ret < 0) {
- LOGE("rknn_set fail! ret=%d\n", ret);
- return false;
- }
- // LOGE("rknn set %d",ret)
- ret = rknn_run(ctx, nullptr);
- if (ret < 0) {
- LOGE("rknn_run fail! ret=%d\n", ret);
- return false;
- }
- rknn_outputs_get(ctx, 2, outputs, NULL);
- memcpy(y0, outputs[0].buf, output_attrs[0].n_elems * sizeof(char));
- memcpy(y1, outputs[1].buf, output_attrs[1].n_elems * sizeof(char));
- //
- env->ReleaseIntArrayElements(input, inData, JNI_ABORT);
- env->ReleaseFloatArrayElements(output1, y0, 0);
- env->ReleaseFloatArrayElements(output2, y1, 0);
- rknn_outputs_release(ctx, 2, outputs);
- return JNI_TRUE;
- }
|
|