当前位置:   article > 正文

Rk3588开发板,deeplabv3+_mobilenetv2部署代码,脚本代码,c++代码_deeplabv3+模型部署到rv1126开发板上

deeplabv3+模型部署到rv1126开发板上

Rk3588开发板,deeplabv3+_mobilenetv2部署代码,脚本代码,c++代码

前提说明:

代码是经过RKNPU2-MASTER的example中的rknn_yolov5_demo修改完成的。可以不管其他文件,将main.cc、build-android_RK3588.sh、CMakeList.txt直接进行修改就行。其他操作需要自己在开发文档中进行。

build-android_RK3588.sh文件

下面展示build-android_RK3588.sh脚本文件。

#!/bin/bash

set -e

if [ -z ${ANDROID_NDK_PATH} ]
then
  ANDROID_NDK_PATH=~/下载/android-ndk-r17c
fi

BUILD_TYPE=Release

TARGET_SOC="rk3588"

ROOT_PWD=$( cd "$( dirname $0 )" && cd -P "$( dirname "$SOURCE" )" && pwd )

BUILD_DIR=${ROOT_PWD}/build/build_android_v8a

if [[ ! -d "${BUILD_DIR}" ]]; then
  mkdir -p ${BUILD_DIR}
fi

cd ${BUILD_DIR}
cmake ../.. \
        -DANDROID_TOOLCHAIN=clang \
        -DTARGET_SOC=${TARGET_SOC} \
       	-DCMAKE_SYSTEM_NAME=Android \
        -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_PATH/build/cmake/android.toolchain.cmake \
        -DANDROID_ABI="arm64-v8a" \
        -DANDROID_STL=c++_static \
        -DANDROID_PLATFORM=android-24 \
        -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
make -j4
make install
cd ..
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

CMakeList.txt文件

下面展示CMakeList.txt文件代码。

cmake_minimum_required(VERSION 3.4.1)

project(rknn_deeplab_demo)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# skip 3rd-party lib dependencies
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined")

# install target and libraries
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install/rknn_deeplab_demo_${CMAKE_SYSTEM_NAME})

set(CMAKE_SKIP_INSTALL_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

if (CMAKE_C_COMPILER MATCHES "aarch64")
  set(LIB_ARCH aarch64)
else()
  set(LIB_ARCH armhf)
endif()

include_directories(${CMAKE_SOURCE_DIR})

# rknn api
if(TARGET_SOC STREQUAL "rk356x")
  set(RKNN_API_PATH ${CMAKE_SOURCE_DIR}/../../runtime/RK356X/${CMAKE_SYSTEM_NAME}/librknn_api)
elseif(TARGET_SOC STREQUAL "rk3588")
  set(RKNN_API_PATH ${CMAKE_SOURCE_DIR}/../../runtime/RK3588/${CMAKE_SYSTEM_NAME}/librknn_api)
else()
  message(FATAL_ERROR "TARGET_SOC is not set, ref value: rk356x or rk3588 or rv110x")
endif()

if (CMAKE_SYSTEM_NAME STREQUAL "Android")
  set(RKNN_RT_LIB ${RKNN_API_PATH}/${CMAKE_ANDROID_ARCH_ABI}/librknnrt.so)
else()
  set(RKNN_RT_LIB ${RKNN_API_PATH}/${LIB_ARCH}/librknnrt.so)
endif()
include_directories(${RKNN_API_PATH}/include)
include_directories(${CMAKE_SOURCE_DIR}/../3rdparty)

# opencv
if (CMAKE_SYSTEM_NAME STREQUAL "Android")
    set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/../3rdparty/opencv/OpenCV-android-sdk/sdk/native/jni/abi-${CMAKE_ANDROID_ARCH_ABI})
else()
  if(LIB_ARCH STREQUAL "armhf")
    set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/../3rdparty/opencv/opencv-linux-armhf/share/OpenCV)
  else()
    set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/../3rdparty/opencv/opencv-linux-aarch64/share/OpenCV)
  endif()
endif()
find_package(OpenCV REQUIRED)

#rga
if(TARGET_SOC STREQUAL "rk356x")
  set(RGA_PATH ${CMAKE_SOURCE_DIR}/../3rdparty/rga/RK356X)
elseif(TARGET_SOC STREQUAL "rk3588")
  set(RGA_PATH ${CMAKE_SOURCE_DIR}/../3rdparty/rga/RK3588)
else()
  message(FATAL_ERROR "TARGET_SOC is not set, ref value: rk356x or rk3588")
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Android")
  set(RGA_LIB ${RGA_PATH}/lib/Android/${CMAKE_ANDROID_ARCH_ABI}/librga.so)
else()
  set(RGA_LIB ${RGA_PATH}/lib/Linux//${LIB_ARCH}/librga.so)
endif()
include_directories( ${RGA_PATH}/include)

# mpp
set(MPP_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/mpp)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
  set(MPP_LIBS ${MPP_PATH}/${CMAKE_SYSTEM_NAME}/${LIB_ARCH}/librockchip_mpp.so)
elseif (CMAKE_SYSTEM_NAME STREQUAL "Android")
  set(MPP_LIBS ${MPP_PATH}/${CMAKE_SYSTEM_NAME}/${CMAKE_ANDROID_ARCH_ABI}/libmpp.so)
endif()
include_directories(${MPP_PATH}/include)

# zlmediakit
set(ZLMEDIAKIT_PATH ${CMAKE_SOURCE_DIR}/../3rdparty/zlmediakit)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
include_directories(${ZLMEDIAKIT_PATH}/include)
set(ZLMEDIAKIT_LIBS ${ZLMEDIAKIT_PATH}/${LIB_ARCH}/libmk_api.so)
endif()

if (ZLMEDIAKIT_LIBS)
    add_definitions(-DBUILD_VIDEO_RTSP)
endif()

set(CMAKE_INSTALL_RPATH "lib")

# rknn_deeplab_demo
include_directories( ${CMAKE_SOURCE_DIR}/include)

add_executable(rknn_deeplab_demo
        src/main.cc
)

target_link_libraries(rknn_deeplab_demo
  ${RKNN_RT_LIB}
  ${RGA_LIB}
  ${OpenCV_LIBS}
)

if (MPP_LIBS)
add_executable(rknn_deeplab_video_demo
        src/main_video.cc
        src/postprocess.cc
        utils/mpp_decoder.cpp
        utils/mpp_encoder.cpp
        utils/drawing.cpp
)
target_link_libraries(rknn_deeplab_video_demo
  ${RKNN_RT_LIB}
  ${RGA_LIB}
  ${OpenCV_LIBS}
  ${MPP_LIBS}
  ${ZLMEDIAKIT_LIBS}
)
endif()

# install target and libraries
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install/rknn_deeplab_demo_${CMAKE_SYSTEM_NAME})
install(TARGETS rknn_deeplab_demo DESTINATION ./)

install(PROGRAMS ${RKNN_RT_LIB} DESTINATION lib)
install(PROGRAMS ${RGA_LIB} DESTINATION lib)
install(DIRECTORY model DESTINATION ./)

if (MPP_LIBS)
install(TARGETS rknn_deeplab_video_demo DESTINATION ./)
install(PROGRAMS ${MPP_LIBS} DESTINATION lib)
endif()

if (ZLMEDIAKIT_LIBS)
install(PROGRAMS ${ZLMEDIAKIT_LIBS} DESTINATION lib)
endif()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137

main.cc文件

下面展示build-android_RK3588.sh脚本文件。

// Copyright (c) 2021 by Rockchip Electronics Co., Ltd. All Rights Reserved.
//
// 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.

/*-------------------------------------------
                Includes
-------------------------------------------*/
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <iostream>
#include <cmath>
#include <vector>
#include <fstream>
#include <cstring>
#include <dirent.h>
#define _BASETSD_H

#include "RgaUtils.h"
#include "im2d.h"
#include "opencv2/core/core.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "rga.h"
#include "rknn_api.h"

#define PERF_WITH_POST 1
/*-------------------------------------------
                  Functions
-------------------------------------------*/

int colors[22][3] = {{0, 0, 0}, {128, 0, 0}, {0, 128, 0}, {128, 128, 0}, {0, 0, 128}, {128, 0, 128}, {0, 128, 128},
                   {128, 128, 128}, {64, 0, 0}, {192, 0, 0}, {64, 128, 0}, {192, 128, 0}, {64, 0, 128}, {192, 0, 128},
                   {64, 128, 128}, {192, 128, 128}, {0, 64, 0}, {128, 64, 0}, {0, 192, 0}, {128, 192, 0}, {0, 64, 128}, {128, 64, 12}};

static void dump_tensor_attr(rknn_tensor_attr* attr)
{
  std::string shape_str = attr->n_dims < 1 ? "" : std::to_string(attr->dims[0]);
  for (int i = 1; i < attr->n_dims; ++i) {
    shape_str += ", " + std::to_string(attr->dims[i]);
  }

  printf("  index=%d, name=%s, n_dims=%d, dims=[%s], n_elems=%d, size=%d, w_stride = %d, size_with_stride=%d, fmt=%s, "
         "type=%s, qnt_type=%s, "
         "zp=%d, scale=%f\n",
         attr->index, attr->name, attr->n_dims, shape_str.c_str(), attr->n_elems, attr->size, attr->w_stride,
         attr->size_with_stride, get_format_string(attr->fmt), get_type_string(attr->type),
         get_qnt_type_string(attr->qnt_type), attr->zp, attr->scale);
}

double __get_us(struct timeval t) { return (t.tv_sec * 1000000 + t.tv_usec); }

static unsigned char* load_data(FILE* fp, size_t ofst, size_t sz)
{
  unsigned char* data;
  int            ret;

  data = NULL;

  if (NULL == fp) {
    return NULL;
  }

  ret = fseek(fp, ofst, SEEK_SET);
  if (ret != 0) {
    printf("blob seek failure.\n");
    return NULL;
  }

  data = (unsigned char*)malloc(sz);
  if (data == NULL) {
    printf("buffer malloc failure.\n");
    return NULL;
  }
  ret = fread(data, 1, sz, fp);
  return data;
}

static unsigned char* load_model(const char* filename, int* model_size)
{
  FILE*          fp;
  unsigned char* data;

  fp = fopen(filename, "rb");
  if (NULL == fp) {
    printf("Open file %s failed.\n", filename);
    return NULL;
  }

  fseek(fp, 0, SEEK_END);
  int size = ftell(fp);

  data = load_data(fp, 0, size);

  fclose(fp);

  *model_size = size;
  return data;
}

static int saveFloat(const char* file_name, float* output, int element_size)
{
  FILE* fp;
  fp = fopen(file_name, "w");
  for (int i = 0; i < element_size; i++) {
    fprintf(fp, "%.6f\n", output[i]);
  }
  fclose(fp);
  return 0;
}
int nw = 0;
int nh = 0;

cv::Mat resizeImage(cv::Mat image, cv::Size size) {
    int iw = image.cols;
    int ih = image.rows;
    int w = size.width;
    int h = size.height;

    double scale = std::min(static_cast<double>(w) / iw, static_cast<double>(h) / ih);
    nw = static_cast<int>(iw * scale);
    nh = static_cast<int>(ih * scale);

    cv::resize(image, image, cv::Size(nw, nh), cv::INTER_CUBIC);

    cv::Mat newImage(size, CV_8UC3, cv::Scalar(128, 128, 128));
    image.copyTo(newImage(cv::Rect((w - nw) / 2, (h - nh) / 2, nw, nh)));

    return newImage;
}

// std::vector<int> argmax_indices; // 存储 argmax 结果
void softmax(float* data, int channels, int height, int width) {
    for (int h = 0; h < height; ++h) {
        for (int w = 0; w < width; ++w) {
            int max_index = 0;
            // 计算最大值以增加稳定性
            float max_val = data[h * w];
            for (int c = 1; c < channels; ++c) {
              // if(max_val<data[c*width*height+h*width+w]){
              //   max_val = data[c*width*height+h*width+w];
              //   max_index = c;
              // }
                max_val = std::max(max_val, data[c*width*height+h*width+w]);
            }
            // argmax_indices.push_back(max_index);

            // 计算指数并计算 softmax 时的总和
            float sum = 0.0f;
            for (int c = 0; c < channels; ++c) {
                data[c*width*height+h*width+w] -= max_val;
                data[c*width*height+h*width+w] = std::exp(data[c*width*height+h*width+w]);
                sum += data[c*width*height+h*width+w];
            }
            
            // 使用总和进行归一化
            for (int c = 0; c < channels; ++c) {
                data[c*width*height+h*width+w] /= sum;
                // printf("%d,          %f\n",c*width*height+h*width+w,data[c*width*height+h*width+w]);
            }
        }
    }
}

void clearFileContent(const std::string& filePath) {
    std::ofstream file(filePath, std::ofstream::out | std::ofstream::trunc);
    if (!file.is_open()) {
        std::cerr << "Unable to clear file content." << std::endl;
        return;
    }
    file.close();
}

void listFilesInDirectory(const std::string& directoryPath, const std::string& outputFile) {
    clearFileContent(outputFile); 
    
    std::ofstream output(outputFile);

    if (!output.is_open()) {
        std::cerr << "不能打开输出文件." << std::endl;
        return;
    }

    DIR* dir = opendir(directoryPath.c_str());
    if (!dir) {
        std::cerr << "不能打开文件夹." << std::endl;
        output.close();
        return;
    }

    dirent* entry;
    while ((entry = readdir(dir)) != nullptr) {
        if (entry->d_type == DT_REG) {
            output << entry->d_name << std::endl;
        }
    }

    closedir(dir);
    output.close();
}

/*-------------------------------------------
                  Main Functions
-------------------------------------------*/
int main()
{
  int            status     = 0;
  char*          model_name = NULL;
  rknn_context   ctx;
  size_t         actual_size        = 0;
  int            img_width          = 0;
  int            img_height         = 0;
  int            img_channel        = 0;
  struct timeval start_time, stop_time;
  int            ret;

  // init rga context
  // rga_buffer_t src;
  // rga_buffer_t dst;
  // im_rect      src_rect;
  // im_rect      dst_rect;
  // memset(&src_rect, 0, sizeof(src_rect));
  // memset(&dst_rect, 0, sizeof(dst_rect));
  // memset(&src, 0, sizeof(src));
  // memset(&dst, 0, sizeof(dst));


  //脚本工具,将文件夹中的文件名,全部都保存在dataset.txt文件。
  std::string directoryPath = "./dataset";
  std::string outputFile = "./dataset.txt";
  listFilesInDirectory(directoryPath,outputFile);
  std::cout<<"文件名已保存"<<outputFile <<std::endl;

  model_name = "./model/RK3588/deeplab_mobilenetv2.rknn";

  /* Create the neural network */
  printf("Loading mode...\n");
  int            model_data_size = 0;
  unsigned char* model_data      = load_model(model_name, &model_data_size);
  ret                            = rknn_init(&ctx, model_data, model_data_size, RKNN_FLAG_COLLECT_PERF_MASK, NULL);
  if (ret < 0) {
    printf("rknn_init error ret=%d\n", ret);
    return -1;
  }

  rknn_sdk_version version;
  ret = rknn_query(ctx, RKNN_QUERY_SDK_VERSION, &version, sizeof(rknn_sdk_version));
  if (ret < 0) {
    printf("rknn_init error ret=%d\n", ret);
    return -1;
  }
  printf("sdk version: %s driver version: %s\n", version.api_version, version.drv_version);

  rknn_input_output_num io_num;
  ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
  if (ret < 0) {
    printf("rknn_init error ret=%d\n", ret);
    return -1;
  }
  printf("model input num: %d, output num: %d\n", io_num.n_input, io_num.n_output);

  rknn_tensor_attr input_attrs[io_num.n_input];
  memset(input_attrs, 0, sizeof(input_attrs));
  for (int i = 0; i < io_num.n_input; i++) {
    input_attrs[i].index = i;
    ret                  = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]), sizeof(rknn_tensor_attr));
    if (ret < 0) {
      printf("rknn_init error ret=%d\n", ret);
      return -1;
    }
    dump_tensor_attr(&(input_attrs[i]));
  }

  rknn_tensor_attr output_attrs[io_num.n_output];
  memset(output_attrs, 0, sizeof(output_attrs));
  for (int i = 0; i < io_num.n_output; i++) {
    output_attrs[i].index = i;
    ret                   = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]), sizeof(rknn_tensor_attr));
    dump_tensor_attr(&(output_attrs[i]));
  }

  int channel = 3;
  int width   = 0;
  int height  = 0;
  if (input_attrs[0].fmt == RKNN_TENSOR_NCHW) {
    printf("model is NCHW input fmt\n");
    channel = input_attrs[0].dims[1];
    height  = input_attrs[0].dims[2];
    width   = input_attrs[0].dims[3];
  } else {
    printf("model is NHWC input fmt\n");
    height  = input_attrs[0].dims[1];
    width   = input_attrs[0].dims[2];
    channel = input_attrs[0].dims[3];
  }

  printf("model input height=%d, width=%d, channel=%d\n", height, width, channel);

  rknn_input inputs[1];
  memset(inputs, 0, sizeof(inputs));
  inputs[0].index        = 0;
  inputs[0].type         = RKNN_TENSOR_UINT8;
  inputs[0].size         = width * height * channel;
  inputs[0].fmt          = RKNN_TENSOR_NHWC;
  inputs[0].pass_through = 0;

  // You may not need resize when src resulotion equals to dst resulotion

  // 开始循环
  std::ifstream file("dataset.txt");
  std::string line;
  while (std::getline(file,line)){
    std::string input_path = "./dataset/" +line;
    std::string save_path = "./output/" +line;

    char* image_name = strdup(input_path.c_str());
    printf("Read %s ...\n", image_name);
    cv::Mat orig_img = cv::imread(image_name, 1);
    if (!orig_img.data) {
      printf("cv::imread %s fail!\n", image_name);
      return -1;
    }
    cv::Mat img;
    cv::cvtColor(orig_img, img, cv::COLOR_BGR2RGB);
    img_width  = img.cols;
    img_height = img.rows;
    printf("img width = %d, img height = %d\n", img_width, img_height);



    gettimeofday(&start_time, NULL);
    // 新的ressize方式
    img= resizeImage(img,cv::Size(width,height));
    // cv::imwrite("xiao.jpg",img);
    inputs[0].buf = img.data;

    gettimeofday(&stop_time, NULL);
    printf("resize时间once run use %f ms\n", (__get_us(stop_time) - __get_us(start_time)) / 1000);

    gettimeofday(&start_time, NULL);

    rknn_inputs_set(ctx, io_num.n_input, inputs);

    rknn_output outputs[io_num.n_output];
    memset(outputs, 0, sizeof(outputs));
    for (int i = 0; i < io_num.n_output; i++) {
      outputs[i].want_float = 1;
    }

    gettimeofday(&stop_time, NULL);
    printf("input和output时间once run use %f ms\n", (__get_us(stop_time) - __get_us(start_time)) / 1000);
    gettimeofday(&start_time, NULL); 


    ret = rknn_run(ctx, NULL);

    rknn_perf_detail perf_detail;
    ret = rknn_query(ctx,RKNN_QUERY_PERF_DETAIL,&perf_detail,sizeof(perf_detail));
    ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);


    // 根据获取的属性,判断数据类型
    // if (output_attrs[0].type == RKNN_TENSOR_FLOAT32) {
    //     printf("第一个输出数据类型为:RKNN_TENSOR_FLOAT32\n");
    // } else if (output_attrs[0].type == RKNN_TENSOR_UINT8) {
    //     printf("第一个输出数据类型为:RKNN_TENSOR_UINT8\n");
    // } else if (output_attrs[0].type == RKNN_TENSOR_INT8) {
    //     printf("第一个输出数据类型为:RKNN_TENSOR_INT8\n");
    // } else {
    //     printf("第一个输出数据类型未知\n");
    // }


    // printf("张量的数量::%d\n",io_num.n_output);
    // for (int i = 0; i < io_num.n_output; ++i) {
    //   printf("Output %d dimensions:", i);
    //   for (int j = 0; j < output_attrs[i].n_dims; ++j) {
    //       printf(" %d", output_attrs[i].dims[j]);
    //   }
    //   printf("\n");
    //   printf("\n");
    //   printf("\n");
    //   printf("\n");
    //   printf("\n");
    //   printf("\n");
    // }

    gettimeofday(&stop_time, NULL);
    printf("推理数据once run use %f ms\n", (__get_us(stop_time) - __get_us(start_time)) / 1000);
    
    // 打印每一层的运行时间。
    printf("每一层运行时间::\n\n %s \n\n",perf_detail.perf_data);


    gettimeofday(&start_time, NULL);

    // 提取有关输出张量的相关信息
    int output_index = 0; // 要复制的输出张量的索引
    int output_channel = output_attrs[output_index].dims[1];
    int output_height = output_attrs[output_index].dims[2];
    int output_width = output_attrs[output_index].dims[3];
    printf("输出通道:%d,输出高度:%d,输出宽度:%d\n", output_channel, output_height, output_width);
    // for (int i=0; i <344064;i++){
    //     printf("aaaaaaa  %d  The fifth element of pr is: %f\n",i, pr[i]);

    // }

    int output_size = outputs[output_index].size;
    printf("output_size的大小:::::%d\n",output_size);

    
    // 获取模型输出数据的指针
    // unsigned char* output_data = reinterpret_cast<unsigned char*>(outputs[output_index].buf);
    float* output_data = reinterpret_cast<float*>(outputs[0].buf);
    // 创建一个新的整数数组来存储解释后的数据
    std::vector<float> interpreted_data(output_size);

    for (int i = 0; i < output_size/4; ++i) {
        
        interpreted_data[i] = output_data[i];
        // printf("%d,          %f\n",i,interpreted_data[i]);
    }

    int mini_h = nh/4;
    int mini_w = nw/4;

    float* pr = interpreted_data.data();
    // printf("interpreted_data的大小:::::%d\n",interpreted_data.size());

    int slice_start_h = (output_height - mini_h) / 2;
    int slice_end_h = (output_height - mini_h) / 2 + mini_h;
    int slice_start_w = (output_width - mini_w) / 2;
    int slice_end_w = (output_width - mini_w) / 2 + mini_w;

    // 计算切片后的数据大小
    int sliced_height = slice_end_h - slice_start_h;
    int sliced_width = slice_end_w - slice_start_w;
    int sliced_channel = output_channel;
    int sliced_size = sliced_height * sliced_width*sliced_channel;


    // 创建一个新的数组来存储切片后的数据
    std::vector<float> sliced_data(sliced_size);
    // 复制数据到新数组
    for (int k = 0;k<sliced_channel;k++){
      for (int i = slice_start_h; i < slice_end_h; i++) {
        for (int j = slice_start_w; j < slice_end_w; j++) {
            int src_index =k*output_height*output_width+ i * output_width + j;
            int dst_index = k*sliced_height*sliced_width + (i - slice_start_h) * sliced_width + (j - slice_start_w);
            sliced_data[dst_index] = pr[src_index];
        }
      }
    }
    pr = sliced_data.data();
    
    // softmax操作
    softmax(pr, sliced_channel, sliced_height,sliced_width);


    cv::Mat segmented_img = cv::Mat(mini_h, mini_w, CV_8UC3);
    std::vector<int> argmax_indices; // 存储 argmax 结果
    for (int h = 0; h < sliced_height; ++h) {
        for (int w = 0; w < sliced_width; ++w) {
            int max_index = 0;
            float max_value = pr[h * sliced_width + w];

            for (int c = 1; c < output_channel; ++c) {
                float current_value = pr[c*sliced_height*sliced_width+ h * sliced_width + w];
                if (current_value > max_value) {
                    max_value = current_value;
                    max_index = c;
                }
            }

            argmax_indices.push_back(max_index);
            // printf("%d ",max_index);

            segmented_img.at<cv::Vec3b>(h, w) = cv::Vec3b(colors[max_index][2], colors[max_index][1], colors[max_index][0]);
        }
        // printf("\n");
    }
    printf("argmax_indices大小::%d\n",argmax_indices.size());
    
    

    
    // cv::Mat segmented_img = cv::Mat(mini_h, mini_w, CV_8UC3);
    // // Map argmax_indices to colors and fill the segmented image(可优化可以直接生成mat数据)
    // for (int h = 0; h < mini_h; ++h) {
    //     for (int w = 0; w < mini_w; ++w) {
    //         int index = argmax_indices[h * mini_w + w];
    //         segmented_img.at<cv::Vec3b>(h, w) = cv::Vec3b(colors[index][2], colors[index][1], colors[index][0]);
    //     }
    // }
    
    

    
    gettimeofday(&stop_time, NULL);
    printf("后处理时间::once run use %f ms\n", (__get_us(stop_time) - __get_us(start_time)) / 1000);

    bool saved = cv::imwrite(save_path, segmented_img);
    if(saved){
      std::cout<<"图片已存为:"<<save_path<<"\n\n\n\n"<<std::endl;
  }


}
  // release
  ret = rknn_destroy(ctx);

  if (model_data) {
    free(model_data);
  }
  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528

.rknn模型文件放在model中的RK3588中。

提示:

需要文档,或者其他文件的,可以评论区找我。希望对大家有用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/229574
推荐阅读
  

闽ICP备14008679号