main.c_cursor_0130

/*

*

* Copyright (c) 2017 Texas Instruments Incorporated

*

* All rights reserved not granted herein.

*

* Limited License.

*

* Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive

* license under copyrights and patents it now or hereafter owns or controls to make,

* have made, use, import, offer to sell and sell ("Utilize") this software subject to the

* terms herein. With respect to the foregoing patent license, such license is granted

* solely to the extent that any such patent is necessary to Utilize the software alone.

* The patent license shall not apply to any combinations which include this software,

* other than combinations with devices manufactured by or for TI ("TI Devices").

* No hardware patent is licensed hereunder.

*

* Redistributions must preserve existing copyright notices and reproduce this license

* (including the above copyright notice and the disclaimer and (if applicable) source

* code license limitations below) in the documentation and/or other materials provided

* with the distribution

*

* Redistribution and use in binary form, without modification, are permitted provided

* that the following conditions are met:

*

* * No reverse engineering, decompilation, or disassembly of this software is

* permitted with respect to any software provided in binary form.

*

* * any redistribution and use are licensed by TI for use only with TI Devices.

*

* * Nothing shall obligate TI to provide you with source code for the software

* licensed and provided to you in object code.

*

* If software source code is provided to you, modification and redistribution of the

* source code are permitted provided that the following conditions are met:

*

* * any redistribution and use of the source code, including any resulting derivative

* works, are licensed by TI for use only with TI Devices.

*

* * any redistribution and use of any object code compiled from the source code

* and any resulting derivative works, are licensed by TI for use only with TI Devices.

*

* Neither the name of Texas Instruments Incorporated nor the names of its suppliers

*

* may be used to endorse or promote products derived from this software without

* specific prior written permission.

*

* DISCLAIMER.

*

* THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS

* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.

* IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT,

* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,

* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,

* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY

* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE

* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

* OF THE POSSIBILITY OF SUCH DAMAGE.

*

*/

#include <utils/draw2d/include/draw2d.h>

#include <utils/perf_stats/include/app_perf_stats.h>

#include "itidl_ti.h"

#include "app_common.h"

#include "app_test.h"

#include "mult_yolov5_post_copy.h"

#include "math.h"

/*

* define this macro to enable TIDL intermediate layer traces on target

*/

#undef APP_TIDL_TRACE_DUMP

/*

* This is the size of trace buffer allocated in host memory and

* shared with target.

*/

#define TIVX_TIDL_TRACE_DATA_SIZE (128 * 1024 * 1024)

extern const char imgnet_labels[1001][256];

static const char *tensor_num_str[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"};

#define APP_DEBUG

#ifdef APP_DEBUG

#define APP_PRINTF(f_, ...) printf((f_), ##VA_ARGS)

#else

#define APP_PRINTF(f_, ...)

#endif

typedef struct {

/* config options */

char tidl_config_file_path[APP_MAX_FILE_PATH];

char tidl_network_file_path[APP_MAX_FILE_PATH];

char input_file_path[APP_MAX_FILE_PATH];

char input_file_list[APP_MAX_FILE_PATH];

char output_file_path[APP_MAX_FILE_PATH];

char ti_logo_file_path[APP_MAX_FILE_PATH];

uint32_t num_input_tensors;

uint32_t num_output_tensors;

/* Input image params */

vx_df_image df_image;

void *data_ptr;

tivx_utils_bmp_image_params_t imgParams;

vx_uint32 img_width;

vx_uint32 img_height;

vx_uint32 img_stride;

sTIDL_IOBufDesc_t ioBufDesc;

uint8_t *pInPlanes;

uint8_t *pOutPlanes;

uint8_t *temp;

char save_type;

uint8_t *pDisplayBuf888;

uint16_t *pDisplayBuf565;

/* OpenVX references */

vx_context context;

vx_graph graph;

vx_kernel kernel;

vx_node tidl_node;

vx_user_data_object config;

vx_user_data_object network;

vx_user_data_object createParams;

vx_user_data_object inArgs;

vx_user_data_object outArgs;

vx_user_data_object traceData;

vx_tensor input_tensors[APP_MAX_TENSORS];

vx_tensor output_tensors[APP_MAX_TENSORS];

vx_graph disp_graph;

vx_node disp_node;

vx_image disp_image;

vx_user_data_object disp_params_obj;

tivx_display_params_t disp_params;

vx_rectangle_t disp_rect;

vx_imagepatch_addressing_t image_addr;

vx_size in_tensor_data_type[APP_MAX_TENSORS];

vx_uint32 display_option;

vx_uint32 delay_in_msecs;

vx_uint32 num_iterations;

Draw2D_Handle pHndl;

uint32_t is_interactive;

vx_int32 test_mode;

vx_int32 test_case;

tivx_task task;

uint32_t stop_task;

uint32_t stop_task_done;

app_perf_point_t total_perf;

app_perf_point_t fileio_perf;

app_perf_point_t draw_perf;

ttevxYoloV5PostProcParams yolov5params;

ttevxYoloV5Detections detections;

TIDL_outArgs out_args;

} AppObj;

AppObj gAppObj;

static int app_parse_cmd_line_args(AppObj *obj, int argc, char *argv[]);

static vx_status app_init(AppObj *obj);

static void app_deinit(AppObj *obj);

static vx_status app_create_graph(AppObj *obj);

static vx_status app_verify_graph(AppObj *obj);

static vx_status app_run_graph(AppObj *obj);

static vx_status app_run_graph_interactive(AppObj *obj);

static void app_delete_graph(AppObj *obj);

static vx_user_data_object readConfig(AppObj *obj, vx_context context, char *config_file, uint32_t *num_input_tensors, uint32_t *num_output_tensors);

static vx_user_data_object readNetwork(vx_context context, char *network_file);

static vx_user_data_object setCreateParams(vx_context context);

static vx_user_data_object setInArgs(vx_context context);

static vx_user_data_object setOutArgs(vx_context context);

static void createInputTensors(AppObj *obj, vx_context context, vx_user_data_object config, vx_tensor *input_tensors);

static void createOutputTensors(AppObj *obj, vx_context context, vx_user_data_object config, vx_tensor *output_tensors);

static vx_status readInput(AppObj *obj, vx_context context, vx_user_data_object config, vx_tensor *input_tensors, char *input_file);

static void displayOutput(AppObj *obj, vx_user_data_object config, vx_tensor *output_tensors, char *output_file);

static vx_size getTensorDataType(vx_int32 tidl_type);

static const char* vxTypeToStr(vx_enum type);

static vx_size vxTypeSize(vx_enum type);

// #define APP_WRITE_PRE_PROC_OUTPUT;

#ifdef APP_WRITE_PRE_PROC_OUTPUT

static vx_status writePreProcOutput(char* file_name, vx_tensor output);

#endif

static uint32_t num_params;

static uint32_t max_params;

static const char* vxTypeToStr(vx_enum type)

{

switch(type)

{

case VX_TYPE_INT8: return "VX_TYPE_INT8";

case VX_TYPE_UINT8: return "VX_TYPE_UINT8";

case VX_TYPE_INT16: return "VX_TYPE_INT16";

case VX_TYPE_UINT16: return "VX_TYPE_UINT16";

default: return "VX_TYPE_UNKNOWN";

}

}

static vx_size vxTypeSize(vx_enum type)

{

switch(type)

{

case VX_TYPE_INT8:

case VX_TYPE_UINT8:

return sizeof(vx_uint8);

case VX_TYPE_INT16:

case VX_TYPE_UINT16:

return sizeof(vx_uint16);

default:

return 1;

}

}

int app_tidl_main(int argc, char* argv[])

{

int status = 0;

AppObj *obj = &gAppObj;

printf("hello: %s\n", argv[0]);

gAppObj.save_type = '0';

status = app_parse_cmd_line_args(obj, argc, argv);

if(status == VX_SUCCESS)

{

status = app_init(obj);

for(int i = 0;i<5;i++)

{

obj->out_args.scale[i] = obj->ioBufDesc.outTensorScale[i];

}

}

if(status == VX_SUCCESS)

{

status = app_create_graph(obj);

}

if(status == VX_SUCCESS)

{

status = app_verify_graph(obj);

}

if(status == VX_SUCCESS)

{

if(obj->is_interactive)

{

status = app_run_graph_interactive(obj);

}

else

{

status = app_run_graph(obj);

if(status == VX_FAILURE)

{

printf("Error processing graph!\n");

}

}

}

app_delete_graph(obj);

app_deinit(obj);

if(obj->test_mode == 1)

{

if((test_result == vx_false_e) || (status != VX_SUCCESS))

{

printf("\n\nTEST FAILED\n\n");

print_new_checksum_structs();

status = (status == VX_SUCCESS) ? VX_FAILURE : status;

}

else

{

printf("\n\nTEST PASSED\n\n");

}

}

return status;

}

static int app_init(AppObj *obj)

{

int status = 0;

uint32_t num_input_tensors = 0;

uint32_t num_output_tensors = 0;

APP_PRINTF("app_tidl: Init ... \n");

obj->context = vxCreateContext();

APP_ASSERT_VALID_REF(obj->context);

/* Create a vx_array object and read the config data*/

obj->config = readConfig(obj, obj->context, &obj->tidl_config_file_path[0], &num_input_tensors, &num_output_tensors);

APP_ASSERT_VALID_REF(obj->config)

/* Save a copy of number of input/output tensors required as per config */

obj->num_input_tensors = num_input_tensors;

obj->num_output_tensors = num_output_tensors;

/* Create a vx_tensor object and read the network data */

obj->network = readNetwork(obj->context, &obj->tidl_network_file_path[0]);

APP_ASSERT_VALID_REF(obj->network)

obj->createParams = setCreateParams(obj->context);

APP_ASSERT_VALID_REF(obj->createParams)

obj->inArgs = setInArgs(obj->context);

APP_ASSERT_VALID_REF(obj->inArgs)

obj->outArgs = setOutArgs(obj->context);

APP_ASSERT_VALID_REF(obj->outArgs)

#ifdef APP_TIDL_TRACE_DUMP

obj->traceData = vxCreateUserDataObject(obj->context, "TIDL_traceData", TIVX_TIDL_TRACE_DATA_SIZE, NULL);

APP_ASSERT_VALID_REF(obj->traceData)

#endif

obj->kernel = tivxAddKernelTIDL(obj->context, num_input_tensors, num_output_tensors);

APP_ASSERT_VALID_REF(obj->kernel)

if ((vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_DISPLAY1)) && (obj->display_option == 1))

{

obj->disp_image = vxCreateImage(obj->context, DISPLAY_WIDTH, DISPLAY_HEIGHT, VX_DF_IMAGE_RGB);

APP_ASSERT_VALID_REF(obj->disp_image)

obj->image_addr.dim_x = DISPLAY_WIDTH;

obj->image_addr.dim_y = DISPLAY_HEIGHT;

obj->image_addr.stride_x = 3; /* RGB */

obj->image_addr.stride_y = DISPLAY_WIDTH * 3;

obj->image_addr.scale_x = VX_SCALE_UNITY;

obj->image_addr.scale_y = VX_SCALE_UNITY;

obj->image_addr.step_x = 1;

obj->image_addr.step_y = 1;

obj->disp_rect.start_x = 0;

obj->disp_rect.start_y = 0;

obj->disp_rect.end_x = DISPLAY_WIDTH;

obj->disp_rect.end_y = DISPLAY_HEIGHT;

memset(&obj->disp_params, 0, sizeof(tivx_display_params_t));

obj->disp_params.opMode = TIVX_KERNEL_DISPLAY_BUFFER_COPY_MODE;

obj->disp_params.pipeId = 0;

obj->disp_params.outWidth = DISPLAY_WIDTH;

obj->disp_params.outHeight = DISPLAY_HEIGHT;

obj->disp_params.posX = (1920-DISPLAY_WIDTH)/2;

obj->disp_params.posY = (1080-DISPLAY_HEIGHT)/2;

obj->disp_params_obj = vxCreateUserDataObject(obj->context, "tivx_display_params_t", sizeof(tivx_display_params_t), &obj->disp_params);

APP_ASSERT_VALID_REF(obj->disp_params_obj)

tivxHwaLoadKernels(obj->context);

}

tivxTIDLLoadKernels(obj->context);

obj->temp = tivxMemAlloc(MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3 * 3, TIVX_MEM_EXTERNAL);

obj->pInPlanes = tivxMemAlloc(MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3, TIVX_MEM_EXTERNAL);

if(obj->pInPlanes == NULL) {

printf("app_tidl: ERROR: Unable to allocate memory for inPlanes, size = %d\n", MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3);

status = -1;

}

obj->pOutPlanes = tivxMemAlloc(MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3, TIVX_MEM_EXTERNAL);

if(obj->pOutPlanes == NULL) {

printf("app_tidl: ERROR: Unable to allocate memory for outPlanes, size = %d\n", MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3);

status = -1;

}

obj->pDisplayBuf888 = tivxMemAlloc(DISPLAY_WIDTH * DISPLAY_HEIGHT * 3, TIVX_MEM_EXTERNAL);

if(obj->pDisplayBuf888 == NULL) {

printf("app_tidl: ERROR: Unable to allocate memory for displayBuf888, size = %d\n", DISPLAY_WIDTH * DISPLAY_HEIGHT * 3);

status = -1;

}

obj->pDisplayBuf565 = tivxMemAlloc(DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t), TIVX_MEM_EXTERNAL);

if(obj->pDisplayBuf565 == NULL) {

printf("app_tidl: ERROR: Unable to allocate memory for displayBuf565, size = %ld\n", DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t));

status = -1;

}

{

Draw2D_BufInfo sBufInfo;

Draw2D_LinePrm sLinePrm;

Draw2D_FontPrm sTop5Prm;

char banner_file[APP_MAX_FILE_PATH];

snprintf(banner_file, APP_MAX_FILE_PATH, "%s/ti_logo.bmp", obj->ti_logo_file_path);

Draw2D_create(&obj->pHndl);

if(obj->pHndl != NULL)

{

sBufInfo.bufWidth = DISPLAY_WIDTH;

sBufInfo.bufHeight = DISPLAY_HEIGHT;

sBufInfo.bufPitch[0] = DISPLAY_WIDTH * 2;

sBufInfo.dataFormat = DRAW2D_DF_BGR16_565;

sBufInfo.transperentColor = 0;

sBufInfo.transperentColorFormat = DRAW2D_DF_BGR16_565;

sBufInfo.bufAddr[0] = (uint8_t *)obj->pDisplayBuf565;

Draw2D_setBufInfo(obj->pHndl, &sBufInfo);

Draw2D_clearBuf(obj->pHndl);

Draw2D_insertBmp(obj->pHndl, banner_file, 0, 0);

sLinePrm.lineColor = RGB888_TO_RGB565(255, 255, 255);

sLinePrm.lineSize = 3;

sLinePrm.lineColorFormat = DRAW2D_DF_BGR16_565;

/* Draw a vertial line */

Draw2D_drawLine(obj->pHndl, DISPLAY_WIDTH/2, 0, DISPLAY_WIDTH/2, DISPLAY_HEIGHT, &sLinePrm);

/* green color heading */

Draw2D_setFontColor(RGB888_TO_RGB565(0, 255, 0), RGB888_TO_RGB565(0, 0, 0), RGB888_TO_RGB565(0, 0, 0));

sTop5Prm.fontIdx = 0;

Draw2D_drawString(obj->pHndl, (DISPLAY_WIDTH/2) + 40, 140, "Top 5 classes", &sTop5Prm);

Draw2D_resetFontColor();

}

}

appPerfPointSetName(&obj->total_perf , "TOTAL");

appPerfPointSetName(&obj->draw_perf , "DRAW");

appPerfPointSetName(&obj->fileio_perf, "FILEIO");

APP_PRINTF("app_tidl: Init ... Done.\n");

return status;

}

static void app_deinit(AppObj *obj)

{

APP_PRINTF("app_tidl: De-init ... \n");

tivxTIDLUnLoadKernels(obj->context);

if (vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_DISPLAY1) && (obj->display_option == 1))

{

tivxHwaUnLoadKernels(obj->context);

}

vxRemoveKernel(obj->kernel);

vxReleaseContext(&obj->context);

tivxMemFree(obj->temp, MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3 * 3, TIVX_MEM_EXTERNAL);

tivxMemFree(obj->pInPlanes, MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3, TIVX_MEM_EXTERNAL);

tivxMemFree(obj->pOutPlanes, MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3, TIVX_MEM_EXTERNAL);

tivxMemFree(obj->pDisplayBuf888, DISPLAY_WIDTH * DISPLAY_HEIGHT * 3, TIVX_MEM_EXTERNAL);

tivxMemFree(obj->pDisplayBuf565 , DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t), TIVX_MEM_EXTERNAL);

{

Draw2D_delete(obj->pHndl);

}

APP_PRINTF("app_tidl: De-init ... Done.\n");

}

static void app_delete_graph(AppObj *obj)

{

uint32_t id;

APP_PRINTF("app_tidl: Delete ... \n");

if (vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_DISPLAY1) && (obj->display_option == 1))

{

vxReleaseNode(&obj->disp_node);

vxReleaseGraph(&obj->disp_graph);

}

#ifdef APP_TIVX_LOG_RT_ENABLE

tivxLogRtTraceExportToFile("app_tidl.bin");

tivxLogRtTraceDisable(obj->graph);

#endif

vxReleaseNode(&obj->tidl_node);

vxReleaseGraph(&obj->graph);

vxReleaseUserDataObject(&obj->config);

vxReleaseUserDataObject(&obj->network);

vxReleaseUserDataObject(&obj->createParams);

vxReleaseUserDataObject(&obj->inArgs);

vxReleaseUserDataObject(&obj->outArgs);

#ifdef APP_TIDL_TRACE_DUMP

vxReleaseUserDataObject(&obj->traceData);

#endif

for(id = 0; id < obj->num_input_tensors; id++)

{

vxReleaseTensor(&obj->input_tensors[id]);

}

for(id = 0; id < obj->num_output_tensors; id++)

{

vxReleaseTensor(&obj->output_tensors[id]);

}

if ((vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_DISPLAY1)) && (obj->display_option == 1))

{

vxReleaseImage(&obj->disp_image);

vxReleaseUserDataObject(&obj->disp_params_obj);

}

APP_PRINTF("app_tidl: Delete ... Done.\n");

}

static void app_show_usage(int argc, char* argv[])

{

printf("\n");

printf(" TIDL Demo - (c) Texas Instruments 2018\n");

printf(" ========================================================\n");

printf("\n");

printf(" Usage,\n");

printf(" %s --cfg <config file>\n", argv[0]);

printf("\n");

}

static void app_set_cfg_default(AppObj *obj)

{

snprintf(obj->tidl_config_file_path,APP_MAX_FILE_PATH, "test_data/tivx/tidl_models/mobilenetv1/config.bin");

snprintf(obj->tidl_network_file_path,APP_MAX_FILE_PATH, "test_data/tivx/tidl_models/mobilenetv1/network.bin");

snprintf(obj->input_file_path,APP_MAX_FILE_PATH, "test_data/psdkra/app_tidl");

snprintf(obj->input_file_list,APP_MAX_FILE_PATH, "test_data/psdkra/app_tidl/names.txt");

snprintf(obj->output_file_path,APP_MAX_FILE_PATH, "app_tidl_out");

snprintf(obj->ti_logo_file_path,APP_MAX_FILE_PATH, "test_data/tivx/tidl_models/");

obj->display_option = 1;

obj->delay_in_msecs = 0;

obj->num_iterations = 1;

obj->is_interactive = 0;

obj->test_mode = 0;

}

static int app_parse_cfg_file(AppObj *obj, char *cfg_file_name)

{

FILE *fp = fopen(cfg_file_name, "r");

char line_str[1024];

char *token;

if(fp==NULL)

{

printf("app_tidl: ERROR: Unable to open config file [%s]\n", cfg_file_name);

return -1;

}

while(fgets(line_str, sizeof(line_str), fp)!=NULL)

{

char s[]=" \t";

if (strchr(line_str, '#'))

{

continue;

}

/* get the first token */

token = strtok(line_str, s);

if(token != NULL)

{

if(strcmp(token, "tidl_config_file_path")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

strcpy(obj->tidl_config_file_path, token);

}

}

else

if(strcmp(token, "tidl_network_file_path")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

strcpy(obj->tidl_network_file_path, token);

/* for testing if relevant */

if(strstr(obj->tidl_network_file_path, "u16") != NULL)

{

obj->test_case = 1;

}

else

{

obj->test_case = 0;

}

}

}

else

if(strcmp(token, "input_file_path")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

strcpy(obj->input_file_path, token);

}

}

else

if(strcmp(token, "ti_logo_file_path")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

strcpy(obj->ti_logo_file_path, token);

}

}

else

if(strcmp(token, "input_file_list")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

strcpy(obj->input_file_list, token);

}

}

else

if(strcmp(token, "output_file_path")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

strcpy(obj->output_file_path, token);

}

}

else

if(strcmp(token, "display_option")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

obj->display_option = atoi(token);

if(obj->display_option > 1)

obj->display_option = 1;

}

}

else

if(strcmp(token, "delay")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

obj->delay_in_msecs = atoi(token);

if(obj->delay_in_msecs > 2000)

obj->delay_in_msecs = 2000;

}

}

else

if(strcmp(token, "num_iterations")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

obj->num_iterations = atoi(token);

if(obj->num_iterations == 0)

obj->num_iterations = 1;

}

}

else

if(strcmp(token, "is_interactive")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

obj->is_interactive = atoi(token);

if(obj->is_interactive > 1)

obj->is_interactive = 1;

}

}

else

if(strcmp(token, "test_mode")==0)

{

token = strtok(NULL, s);

if(token != NULL)

{

token[strlen(token)-1]=0;

obj->test_mode = atoi(token);

}

}

}

if (obj->test_mode == 1)

{

obj->is_interactive = 0;

/* display_option must be set to 1 in order for the checksums

to come out correctly */

#ifndef x86_64

printf("Turning display option on ... \n");

obj->display_option = 1;

#else

printf("Turning display option off ... \n");

obj->display_option = 0;

#endif

}

}

fclose(fp);

return 0;

}

static int app_parse_cmd_line_args(AppObj *obj, int argc, char *argv[])

{

int i;

vx_bool set_test_mode = vx_false_e;

app_set_cfg_default(obj);

if(argc==1)

{

app_show_usage(argc, argv);

return -1;

}

for(i=0; i<argc; i++)

{

if(strcmp(argv[i], "--cfg")==0)

{

i++;

if(i>=argc)

{

app_show_usage(argc, argv);

}

app_parse_cfg_file(obj, argv[i]);

}

else

if(strcmp(argv[i], "--help")==0)

{

app_show_usage(argc, argv);

return -1;

}

else

if(strcmp(argv[i], "--test")==0)

{

set_test_mode = vx_true_e;

}

}

if (set_test_mode == vx_true_e)

{

obj->test_mode = 1;

obj->is_interactive = 0;

obj->display_option = 1;

obj->delay_in_msecs = 100;

}

#ifdef x86_64

printf("Turning display option off ... \n");

obj->display_option = 0;

obj->is_interactive = 0;

#endif

return 0;

}

static void initParam(vx_reference params[], uint32_t _max_params)

{

num_params = 0;

max_params = _max_params;

}

static void addParam(vx_reference params[], vx_reference obj)

{

APP_ASSERT(num_params <= max_params);

params[num_params] = obj;

num_params++;

}

static vx_status app_create_graph(AppObj *obj)

{

vx_status status = VX_SUCCESS;

vx_reference params[APP_TIDL_MAX_PARAMS];

uint32_t i;

APP_PRINTF("app_tidl: Creating graph ... \n");

/* Create OpenVx Graph */

obj->graph = vxCreateGraph(obj->context);

APP_ASSERT_VALID_REF(obj->graph)

vxSetReferenceName((vx_reference)obj->graph, "app_tidl_graph");

/* Create array of input tensors */

createInputTensors(obj, obj->context, obj->config, obj->input_tensors);

/* Create array of output tensors */

createOutputTensors(obj, obj->context, obj->config, obj->output_tensors);

/* Initialize param array */

initParam(params, APP_TIDL_MAX_PARAMS);

/* The 1st param MUST be config */

addParam(params, (vx_reference)obj->config);

/* The 2nd param MUST be network */

addParam(params, (vx_reference)obj->network);

/* The 3rd param MUST be create params */

addParam(params, (vx_reference)obj->createParams);

/* The 4th param MUST be inArgs */

addParam(params, (vx_reference)obj->inArgs);

/* The 5th param MUST be outArgs */

addParam(params, (vx_reference)obj->outArgs);

#ifdef APP_TIDL_TRACE_DUMP

addParam(params, (vx_reference)obj->traceData);

#else

/* The 6th param MUST be NULL if trace data dump is not enabled */

addParam(params, (vx_reference)NULL);

#endif

/* Create TIDL Node */

obj->tidl_node = tivxTIDLNode(obj->graph, obj->kernel, params, obj->input_tensors, obj->output_tensors);

APP_ASSERT_VALID_REF(obj->tidl_node)

vxSetNodeTarget(obj->tidl_node, VX_TARGET_STRING, TIVX_TARGET_DSP_C7_1);

if ((vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_DISPLAY1)) && (obj->display_option == 1))

{

/* Create OpenVx Graph */

obj->disp_graph = vxCreateGraph(obj->context);

APP_ASSERT_VALID_REF(obj->disp_graph)

vxSetReferenceName((vx_reference)obj->disp_graph, "Display");

obj->disp_node = tivxDisplayNode(obj->disp_graph, obj->disp_params_obj, obj->disp_image);

APP_ASSERT_VALID_REF(obj->disp_node)

vxSetNodeTarget(obj->disp_node, VX_TARGET_STRING, TIVX_TARGET_DISPLAY1);

}

/* Set names for diferent OpenVX objects */

vxSetReferenceName((vx_reference)obj->config, "Config");

vxSetReferenceName((vx_reference)obj->network, "Network");

vxSetReferenceName((vx_reference)obj->createParams, "CreateParams");

vxSetReferenceName((vx_reference)obj->inArgs, "InArgs");

vxSetReferenceName((vx_reference)obj->outArgs, "OutArgs");

for(i = 0; i < obj->num_input_tensors; i++) {

char tensor_name[] = "InputTensor_";

char ref_name[64];

snprintf(ref_name, 64, "%s%s", tensor_name, tensor_num_str[i]);

vxSetReferenceName((vx_reference)obj->input_tensors[i], ref_name);

}

for(i = 0; i < obj->num_output_tensors; i++) {

char tensor_name[] = "OutputTensor_";

char ref_name[64];

snprintf(ref_name, 64, "%s%s", tensor_name, tensor_num_str[i]);

vxSetReferenceName((vx_reference)obj->output_tensors[i], ref_name);

}

vxSetReferenceName((vx_reference)obj->kernel, "TIDLKernel");

vxSetReferenceName((vx_reference)obj->tidl_node, "TIDLNode");

if (vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_DISPLAY1) && (obj->display_option == 1))

{

vxSetReferenceName((vx_reference)obj->disp_params_obj, "DisplayParams");

vxSetReferenceName((vx_reference)obj->disp_node, "DisplayNode");

}

APP_PRINTF("app_tidl: Creating graph ... Done.\n");

return status;

}

static void app_run_task(void *app_var)

{

AppObj *obj = (AppObj *)app_var;

vx_status status = VX_SUCCESS;

appPerfStatsCpuLoadResetAll();

while(!obj->stop_task)

{

status = app_run_graph(obj);

if(status == VX_FAILURE)

{

printf("Error processing graph!\n");

obj->stop_task = 1;

}

}

obj->stop_task_done = 1;

}

static int32_t app_run_task_create(AppObj *obj)

{

tivx_task_create_params_t params;

int32_t status;

tivxTaskSetDefaultCreateParams(¶ms);

params.task_main = app_run_task;

params.app_var = obj;

obj->stop_task_done = 0;

obj->stop_task = 0;

status = tivxTaskCreate(&obj->task, ¶ms);

return status;

}

static void app_run_task_delete(AppObj *obj)

{

while(obj->stop_task_done==0)

{

tivxTaskWaitMsecs(100);

}

tivxTaskDelete(&obj->task);

}

static char menu[] = {

"\n"

"\n ================================="

"\n Demo : TIDL Object Classification"

"\n ================================="

"\n"

"\n p: Print performance statistics"

"\n"

"\n x: Exit"

"\n"

"\n Enter Choice: "

};

static vx_status app_run_graph_interactive(AppObj *obj)

{

vx_status status = VX_SUCCESS;

uint32_t done = 0;

char ch;

FILE *fp;

app_perf_point_t *perf_arr[1];

status = app_run_task_create(obj);

if(status != VX_SUCCESS)

{

printf("app_tidl: ERROR: Unable to create task\n");

}

else

{

appPerfStatsResetAll();

while((!done) && (status == VX_SUCCESS))

{

printf(menu);

ch = getchar();

printf("\n");

switch(ch)

{

case 'p':

appPerfStatsPrintAll();

if(status == VX_SUCCESS)

{

status = tivx_utils_graph_perf_print(obj->graph);

}

if(status == VX_SUCCESS)

{

status = tivx_utils_graph_perf_print(obj->disp_graph);

}

appPerfPointPrint(&obj->fileio_perf);

appPerfPointPrint(&obj->draw_perf);

appPerfPointPrint(&obj->total_perf);

printf("\n");

appPerfPointPrintFPS(&obj->total_perf);

printf("\n");

break;

case 'e':

perf_arr[0] = &obj->total_perf;

fp = appPerfStatsExportOpenFile(".", "dl_demos_app_tidl");

if((NULL != fp) && (status == VX_SUCCESS))

{

appPerfStatsExportAll(fp, perf_arr, 1);

status = tivx_utils_graph_perf_export(fp, obj->graph);

appPerfStatsExportCloseFile(fp);

appPerfStatsResetAll();

}

else

{

printf("fp is null\n");

}

break;

case 'x':

obj->stop_task = 1;

done = 1;

break;

}

}

app_run_task_delete(obj);

}

return status;

}

static vx_status app_verify_graph(AppObj *obj)

{

vx_status status = VX_SUCCESS;

APP_PRINTF("app_tidl: Verifying graph ... \n");

/* Verify the TIDL Graph */

status = vxVerifyGraph(obj->graph);

if(status != VX_SUCCESS)

{

printf("app_tidl: ERROR: Verifying graph ... Failed !!!\n");

return status;

}

APP_PRINTF("app_tidl: Verifying graph ... Done.\n");

if ((vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_DISPLAY1)) && (obj->display_option == 1))

{

APP_PRINTF("app_tidl: Verifying display graph ... \n");

/* Verify the TIDL Graph */

status = vxVerifyGraph(obj->disp_graph);

if(status != VX_SUCCESS)

{

printf("app_tidl: ERROR: Verifying display graph ... Failed !!!\n");

return status;

}

APP_PRINTF("app_tidl: Verifying display graph ... Done.\n");

}

/* wait a while for prints to flush */

tivxTaskWaitMsecs(100);

#if 1

if(status == VX_SUCCESS)

{

status = tivxExportGraphToDot(obj->graph,".", "vx_app_tidl");

APP_ASSERT(status==VX_SUCCESS);

}

#endif

#ifdef APP_TIVX_LOG_RT_ENABLE

tivxLogRtTraceEnable(obj->graph);

#endif

return status;

}

static void saveOutput(AppObj *obj, vx_tensor *output_tensors, vx_tensor *input_tensors, char *fileName)

{

uint8_t color[14][3]={{0,0,0},{255,0,0},{0,255,0},{0,0,255},{255,255,0},

{255,0,255},{0,255,255},{127,0,0},{0,127,0},{0,0,127},

{127,127,0},{127,0,127},{0,127,127},{255,255,255},};

vx_status status = VX_SUCCESS;

vx_size output_sizes[APP_MAX_TENSOR_DIMS], input_sizes[APP_MAX_TENSOR_DIMS];

sTIDL_IOBufDesc_t *ioBufDesc;

ioBufDesc = &obj->ioBufDesc;

uint8_t *color_mask = obj->temp;

uint8_t *gray_mask = obj->temp + MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3;

uint8_t *image_mask= obj->temp + MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3 * 2;

int32_t width, height, outPadL, outPadT, inPadL, inPadT;//, padB, padR

char output_file[APP_MAX_FILE_PATH];

char file_name_temp[APP_MAX_FILE_PATH];

char file_name_gmask[APP_MAX_FILE_PATH];

char file_name_cmask[APP_MAX_FILE_PATH];

char file_name_imask[APP_MAX_FILE_PATH];

strcpy(file_name_temp, fileName);

file_name_temp[strlen(fileName)-4] = '\0';

//yolov5参数

vx_int32 head_idx, h_idx, w_idx, anchor_idx;

vx_int32 yolov5_class_stride = 3 + 5 + 8 + 6; //cls confxywh points slot

vx_int32 bbox_num = 0;

{

uint64_t cur_time;

cur_time = tivxPlatformGetTimeInUsecs();

/*测试端到端解码接口_依赖tda4结构体*/

// if (0) {

// getMult_yolov5e2eResult(&obj->ioBufDesc, obj->output_tensors, &obj->out_args, &obj->yolov5params, &obj->detections);

// cur_time = tivxPlatformGetTimeInUsecs() - cur_time;

// printf("端到端车位解码耗时: %d us \n", (int)cur_time);

// int num = obj->detections.num_bbox;

// ttevxYoloV5BBox num0 = obj->detections.buffer[0];

// ttevxYoloV5BBox num1 = obj->detections.buffer[1];

// printf("检测到%d车位 \n",(int)num);

// //将车位检测结果保存成二进制文件

// vx_char new_name[256];

// snprintf(new_name, APP_MAX_FILE_PATH-1, "%s%s%s%s%s%s", obj->output_file_path,"/psd/",file_name_temp,"_", "psd", ".bin");

// FILE *fp = fopen(new_name, "wb");

// if(NULL == fp)

// {

// printf("Unable to open file %s for writing!\n", new_name);

// }

// for(int i = 0; i< num ; i++)

// {

// ttevxYoloV5BBox num0 = obj->detections.buffer[i];

// fwrite(&num0, 4, 20, fp);

// }

// fclose(fp);

// }

/*测试端到端解码接口_不依赖tda4结构体*/

if (1) {

initMult_yolov5params(&obj->yolov5params);

/* 兜底:确保解码使用的输入尺寸有效 */

obj->yolov5params.inWidth[0] = obj->ioBufDesc.inWidth[0];

obj->yolov5params.inHeight[0] = obj->ioBufDesc.inHeight[0];

// 添加调试:打印所有输出张量的维度信息

// printf("=== 开始处理YOLOv5检测头 ===\n");

// for(int zh_idx = 0; zh_idx < 5; zh_idx++) // 查看所有5个输出张量

// {

// vx_size tensor_dims;

// vx_size tensor_sizes[APP_MAX_TENSOR_DIMS];

// vxQueryTensor(output_tensors[zh_idx], VX_TENSOR_NUMBER_OF_DIMS, &tensor_dims, sizeof(vx_size));

// vxQueryTensor(output_tensors[zh_idx], (vx_enum)VX_TENSOR_DIMS, tensor_sizes, APP_MAX_TENSOR_DIMS * sizeof(vx_size));

// printf("输出张量[%d] - ioBufDesc维度: outWidth=%d, outHeight=%d, outNumChannels=%d\n",

// zh_idx, obj->ioBufDesc.outWidth[zh_idx], obj->ioBufDesc.outHeight[zh_idx], obj->ioBufDesc.outNumChannels[zh_idx]);

// printf("输出张量[%d] - tensor维度: num_dims=%zu, sizes=[%zu, %zu, %zu, %zu]\n",

// zh_idx, tensor_dims, tensor_sizes[0], tensor_sizes[1], tensor_sizes[2], tensor_sizes[3]);

// }

// printf("=== 结束维度信息输出 ===\n\n");

// return;

// for(int zh_idx = 0; zh_idx < 3; zh_idx++)//lyp

vx_map_id map_id_output_arr[APP_MAX_TENSOR_DIMS] = {0};

int output_mapped[APP_MAX_TENSOR_DIMS] = {0};

for(int zh_idx = 1; zh_idx < 4; zh_idx++)

{

int dst_idx = zh_idx - 1; /* 将检测头1,2,3映射到0,1,2 */

obj->yolov5params.scale[dst_idx] = obj->out_args.scale[zh_idx];

obj->yolov5params.outWidth[dst_idx] = obj->ioBufDesc.outWidth[zh_idx];

obj->yolov5params.outHeight[dst_idx] = obj->ioBufDesc.outHeight[zh_idx];

obj->yolov5params.inWidth[dst_idx] = obj->ioBufDesc.inWidth[zh_idx];

obj->yolov5params.inHeight[dst_idx] = obj->ioBufDesc.inHeight[zh_idx];

obj->yolov5params.outNumChannels[dst_idx] = obj->ioBufDesc.outNumChannels[zh_idx];

obj->yolov5params.outChannelPitch[dst_idx] = obj->ioBufDesc.outChannelPitch[zh_idx];

obj->yolov5params.outPadL[dst_idx] = obj->ioBufDesc.outPadL[zh_idx];

obj->yolov5params.outPadT[dst_idx] = obj->ioBufDesc.outPadT[zh_idx];

obj->yolov5params.outPadR[dst_idx] = obj->ioBufDesc.outPadR[zh_idx];

obj->yolov5params.outPadB[dst_idx] = obj->ioBufDesc.outPadB[zh_idx];

obj->yolov5params.outDataTypeVX[dst_idx] = (int)getTensorDataType(obj->ioBufDesc.outElementType[zh_idx]);

printf("det_head[%d->%d] type(VX)=%d scale=%f outW=%d outH=%d outC=%d pitch=%d\n",

zh_idx, dst_idx,

obj->yolov5params.outDataTypeVX[dst_idx],

obj->yolov5params.scale[dst_idx],

obj->yolov5params.outWidth[dst_idx],

obj->yolov5params.outHeight[dst_idx],

obj->yolov5params.outNumChannels[dst_idx],

obj->yolov5params.outChannelPitch[dst_idx]);

printf("det_head[%d->%d] outElementType(TIDL)=%d vxType=%s\n",

zh_idx, dst_idx,

obj->ioBufDesc.outElementType[zh_idx],

vxTypeToStr((vx_enum)obj->yolov5params.outDataTypeVX[dst_idx]));

void *output_buffer;

vx_map_id map_id_output;

vx_size output_strides[APP_MAX_TENSOR_DIMS];

vx_size output_start[APP_MAX_TENSOR_DIMS];

output_start[0] = output_start[1] = output_start[2] = output_start[3] = 0;

output_sizes[0] = ioBufDesc->outWidth[zh_idx] + ioBufDesc->outPadL[zh_idx] + ioBufDesc->outPadR[zh_idx];

output_sizes[1] = ioBufDesc->outHeight[zh_idx] + ioBufDesc->outPadT[zh_idx] + ioBufDesc->outPadB[zh_idx];

output_sizes[2] = ioBufDesc->outNumChannels[zh_idx];

vx_size out_elem_size = vxTypeSize((vx_enum)obj->yolov5params.outDataTypeVX[dst_idx]);

output_strides[0] = out_elem_size;

output_strides[1] = output_sizes[0] * output_strides[0];

output_strides[2] = output_sizes[1] * output_strides[1];

vx_size tensor_dims;

vxQueryTensor(output_tensors[zh_idx], VX_TENSOR_NUMBER_OF_DIMS, &tensor_dims, sizeof(vx_size));

/* 获取tensor不同dim占用的内存大小 */

tivxMapTensorPatch(output_tensors[zh_idx], tensor_dims, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

status = vxGetStatus((vx_reference)output_tensors[zh_idx]);

if(VX_SUCCESS == status)

{

obj->yolov5params.output_tensors[dst_idx] = output_buffer;

map_id_output_arr[dst_idx] = map_id_output;

output_mapped[dst_idx] = 1;

}

}

printf("端到端车位解码耗时 \n");

getMult_yolov5e2eResult(&obj->yolov5params, &obj->detections);

for(int dst_idx = 0; dst_idx < 3; dst_idx++)

{

if(output_mapped[dst_idx])

{

tivxUnmapTensorPatch(output_tensors[dst_idx + 1], map_id_output_arr[dst_idx]);

}

}

cur_time = tivxPlatformGetTimeInUsecs() - cur_time;

printf("端到端车位解码耗时: %d us \n", (int)cur_time);

int num = obj->detections.num_bbox;

ttevxYoloV5BBox num0 = obj->detections.buffer[0];

ttevxYoloV5BBox num1 = obj->detections.buffer[1];

printf("检测到%d车位 \n",(int)num);

//将车位检测结果保存成二进制文件

vx_char new_name[256];

snprintf(new_name, APP_MAX_FILE_PATH-1, "%s%s%s%s%s%s", obj->output_file_path,"/psd/",file_name_temp,"_", "psd", ".bin");

FILE *fp = fopen(new_name, "wb");

if(NULL == fp)

{

printf("Unable to open file %s for writing!\n", new_name);

}

for(int i = 0; i< num ; i++)

{

ttevxYoloV5BBox num0 = obj->detections.buffer[i];

fwrite(&num0, 4, 20, fp);

}

fclose(fp);

}

}

//处理分割分支

// for(int32_t id = 3; id < 5; id++) //for mulTask_yolov5_seg lyp

// {

int32_t ids_to_process[] = {0, 4};

int32_t num_ids = 2;

for(int32_t idx = 0; idx < num_ids; idx++)

{

int32_t id = ids_to_process[idx];

snprintf(file_name_cmask, APP_MAX_FILE_PATH-1, "%s%s%s%d%s", "/img/", file_name_temp, "_cmask", id, ".bmp");

snprintf(file_name_imask, APP_MAX_FILE_PATH-1, "%s%s%s%d%s", "/img/",file_name_temp, "_imask", id, ".bmp");

snprintf(file_name_gmask, APP_MAX_FILE_PATH-1, "%s%s%s%d%s", "/img/", file_name_temp, "_gmask", id, ".bmp");

output_sizes[0] = ioBufDesc->outWidth[id] + obj->ioBufDesc.outPadL[id] + obj->ioBufDesc.outPadR[id];

output_sizes[1] = ioBufDesc->outHeight[id] + obj->ioBufDesc.outPadT[id] + obj->ioBufDesc.outPadB[id];

output_sizes[2] = 1;//ioBufDesc->outNumChannels[id];

input_sizes[0] = ioBufDesc->inWidth[0] + obj->ioBufDesc.inPadL[0] + obj->ioBufDesc.inPadR[0];

input_sizes[1] = ioBufDesc->inHeight[0] + obj->ioBufDesc.inPadT[0] + obj->ioBufDesc.inPadB[0];

input_sizes[2] = ioBufDesc->inNumChannels[0];

width = ioBufDesc->outWidth[id];

height = ioBufDesc->outHeight[id];

outPadL = obj->ioBufDesc.outPadL[id];

outPadT = obj->ioBufDesc.outPadT[id];

inPadL = obj->ioBufDesc.inPadL[0];

inPadT = obj->ioBufDesc.inPadT[0];

status = vxGetStatus((vx_reference)output_tensors[id]);

if(VX_SUCCESS == status)

{

void *output_buffer, *input_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_strides[APP_MAX_TENSOR_DIMS], input_strides[APP_MAX_TENSOR_DIMS];

vx_size output_start[APP_MAX_TENSOR_DIMS], input_start[APP_MAX_TENSOR_DIMS];

output_start[0] = output_start[1] = output_start[2] = output_start[3] = 0;

input_start[0] = input_start[1] = input_start[2] = input_start[3] = 0;

output_strides[0] = 1;

output_strides[1] = output_sizes[0];

output_strides[2] = output_sizes[1] * output_strides[1];

input_strides[0] = 1;

input_strides[1] = input_sizes[0];

input_strides[2] = input_sizes[1] * input_strides[1];

tivxMapTensorPatch(output_tensors[id], 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

tivxMapTensorPatch(input_tensors[0], 3, input_start, input_sizes, &map_id_input, input_strides, &input_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

{

uint8_t *pOut;

uint8_t *pIn;

pOut = (uint8_t *)output_buffer;

pIn = (uint8_t *)input_buffer;

// printf("模型没加argmax \n");

for(int32_t i = 0; i < height; i++){

for(int32_t j = 0; j < width; j++){

uint8_t seg_type = pOut[output_sizes[0]*(outPadT + i) + outPadL + j];

// if(seg_type>15)

// {

// printf("seg_type 大于15,出错");

// }

uint8_t img_value_R = pIn[0 * input_strides[2] + input_strides[1]*(inPadT + i) + inPadL + j];

uint8_t img_value_G = pIn[1 * input_strides[2] + input_strides[1]*(inPadT + i) + inPadL + j];

uint8_t img_value_B = pIn[2 * input_strides[2] + input_strides[1]*(inPadT + i) + inPadL + j];

int32_t color_chosen = seg_type < 14 ? seg_type : 13;

color_mask[width * 3 * i + j * 3 + 0] = color[color_chosen][0];

color_mask[width * 3 * i + j * 3 + 1] = color[color_chosen][1];

color_mask[width * 3 * i + j * 3 + 2] = color[color_chosen][2];

gray_mask[width * 3 * i + j * 3 + 0] = seg_type;

gray_mask[width * 3 * i + j * 3 + 1] = seg_type;

gray_mask[width * 3 * i + j * 3 + 2] = seg_type;

if(seg_type > 0){

image_mask[width * 3 * i + j * 3 + 0] = img_value_R/2 + color[color_chosen][0]/2;

image_mask[width * 3 * i + j * 3 + 1] = img_value_G/2 + color[color_chosen][1]/2;

image_mask[width * 3 * i + j * 3 + 2] = img_value_B/2 + color[color_chosen][2]/2;

}else{

image_mask[width * 3 * i + j * 3 + 0] = img_value_R;

image_mask[width * 3 * i + j * 3 + 1] = img_value_G;

image_mask[width * 3 * i + j * 3 + 2] = img_value_B;

}

}

}

// if(obj->save_type == '0' || obj->save_type == '1'){

// snprintf(output_file, APP_MAX_FILE_PATH-1, "%s/%s", obj->output_file_path, file_name_cmask);

// printf("save to %s!!!\n", output_file);

// tivx_utils_bmp_write(output_file, color_mask, width, height, (width * 3), obj->df_image);

// }

if(obj->save_type == '0' || obj->save_type == '3'){

snprintf(output_file, APP_MAX_FILE_PATH-1, "%s/%s", obj->output_file_path, file_name_gmask);

printf("save to %s!!!\n", output_file);

tivx_utils_bmp_write(output_file, gray_mask, width, height, (width * 3), obj->df_image);

}

if(obj->save_type == '0' || obj->save_type == '3'){

snprintf(output_file, APP_MAX_FILE_PATH-1, "%s/%s", obj->output_file_path, file_name_imask);

printf("save to %s!!!\n", output_file);

tivx_utils_bmp_write(output_file, image_mask, width, height, (width * 3), obj->df_image);

}

}

tivxUnmapTensorPatch(output_tensors[id], map_id_output);

tivxUnmapTensorPatch(input_tensors[0], map_id_input);

}

}

}

static void saveOutput_tensor(AppObj *obj, vx_tensor *output_tensors, vx_tensor *input_tensors, char *fileName)

{

vx_status status = VX_SUCCESS;

vx_size output_sizes[APP_MAX_TENSOR_DIMS];

sTIDL_IOBufDesc_t *ioBufDesc;

ioBufDesc = &obj->ioBufDesc;

uint8_t *color_mask = obj->temp;

uint8_t *gray_mask = obj->temp + MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3;

uint8_t *image_mask= obj->temp + MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3 * 2;

int32_t width, height, outPadL, outPadT, inPadL, inPadT;//, padB, padR

char output_file[APP_MAX_FILE_PATH];

char file_name_temp[APP_MAX_FILE_PATH];

char file_name_tensor[APP_MAX_FILE_PATH];

// char file_name_cmask[APP_MAX_FILE_PATH];

// char file_name_imask[APP_MAX_FILE_PATH];

strcpy(file_name_temp, fileName);

file_name_temp[strlen(fileName)-4] = '\0';

//处理分割分支 lyp

for(int32_t id = 4; id < 5; id++) //for mulTask_yolov5_seg

{

// int32_t ids_to_process[] = {0, 4};

// int32_t num_ids = 2;

// for(int32_t idx = 0; idx < num_ids; idx++)

// {

// int32_t id = ids_to_process[idx];

// snprintf(file_name_tensor, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_tensor", id, ".bmp");

// snprintf(file_name_imask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_imask", id, ".bmp");

// snprintf(file_name_gmask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_gmask", id, ".bmp");

output_sizes[0] = ioBufDesc->outWidth[id] + obj->ioBufDesc.outPadL[id] + obj->ioBufDesc.outPadR[id];

output_sizes[1] = ioBufDesc->outHeight[id] + obj->ioBufDesc.outPadT[id] + obj->ioBufDesc.outPadB[id];

output_sizes[2] = 1;//ioBufDesc->outNumChannels[id];

// input_sizes[0] = ioBufDesc->inWidth[0] + obj->ioBufDesc.inPadL[0] + obj->ioBufDesc.inPadR[0];

// input_sizes[1] = ioBufDesc->inHeight[0] + obj->ioBufDesc.inPadT[0] + obj->ioBufDesc.inPadB[0];

// input_sizes[2] = ioBufDesc->inNumChannels[0];

width = ioBufDesc->outWidth[id];

height = ioBufDesc->outHeight[id];

outPadL = obj->ioBufDesc.outPadL[id];

outPadT = obj->ioBufDesc.outPadT[id];

// inPadL = obj->ioBufDesc.inPadL[0];

// inPadT = obj->ioBufDesc.inPadT[0];

status = vxGetStatus((vx_reference)output_tensors[id]);

if(VX_SUCCESS == status)

{

void *output_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_strides[APP_MAX_TENSOR_DIMS];

vx_size output_start[APP_MAX_TENSOR_DIMS];

output_start[0] = output_start[1] = output_start[2] = output_start[3] = 0;

// input_start[0] = input_start[1] = input_start[2] = input_start[3] = 0;

output_strides[0] = 1;

output_strides[1] = output_sizes[0];

output_strides[2] = output_sizes[1] * output_strides[1];

// input_strides[0] = 1;

// input_strides[1] = input_sizes[0];

// input_strides[2] = input_sizes[1] * input_strides[1];

vx_char new_name[256];

// snprintf(new_name, APP_MAX_FILE_PATH-1, "%s%s%d%s", obj->output_file_path, "/_tensor", id, ".bin");

snprintf(new_name, APP_MAX_FILE_PATH-1, "%s%s%s%s%d%s", obj->output_file_path,"/bin/",file_name_temp,"_", id, ".bin");

FILE *fp = fopen(new_name, "wb");

if(NULL == fp)

{

printf("Unable to open file %s for writing!\n", new_name);

break;

}

tivxMapTensorPatch(output_tensors[id], 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// tivxMapTensorPatch(input_tensors[0], 3, input_start, input_sizes, &map_id_input, input_strides, &input_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

{

uint8_t *pOut, *pIn;

pOut = (uint8_t *)output_buffer;

// pIn = (uint8_t *)input_buffer;

// printf("模型没加argmax \n");

for(int32_t c = 0; c < ioBufDesc->outNumChannels[id]; c++){

for(int32_t i = 0; i < height; i++){

uint8_t *pOut_1 = pOut + c * output_sizes[0] * output_sizes[1] + output_sizes[0]*(outPadT + i) + outPadL;

uint8_t zh = pOut[c * output_sizes[0] * output_sizes[1] + output_sizes[0]*(outPadT + i) + outPadL];

fwrite(pOut_1, 1, ioBufDesc->outWidth[id], fp);

}

}

fclose(fp);

}

tivxUnmapTensorPatch(output_tensors[id], map_id_output);

// tivxUnmapTensorPatch(input_tensors[0], map_id_input);

}

}

}

static void saveOutput_16bit(AppObj *obj, vx_tensor *output_tensors, vx_tensor *input_tensors, char *fileName)

{

uint8_t color[14][3]={{0,0,0},{255,0,0},{0,255,0},{0,0,255},{255,255,0},

{255,0,255},{0,255,255},{127,0,0},{0,127,0},{0,0,127},

{127,127,0},{127,0,127},{0,127,127},{127,127,127},};

vx_status status = VX_SUCCESS;

vx_size output_sizes[APP_MAX_TENSOR_DIMS], input_sizes[APP_MAX_TENSOR_DIMS];

sTIDL_IOBufDesc_t *ioBufDesc;

ioBufDesc = &obj->ioBufDesc;

uint8_t *color_mask = obj->temp;

uint8_t *gray_mask = obj->temp + MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3;

uint8_t *image_mask= obj->temp + MAX_IMG_WIDTH * MAX_IMG_HEIGHT * 3 * 2;

int32_t width, height, outPadL, outPadT, inPadL, inPadT;//, padB, padR

char output_file[APP_MAX_FILE_PATH];

char file_name_temp[APP_MAX_FILE_PATH];

char file_name_gmask[APP_MAX_FILE_PATH];

char file_name_cmask[APP_MAX_FILE_PATH];

char file_name_imask[APP_MAX_FILE_PATH];

strcpy(file_name_temp, fileName);

file_name_temp[strlen(fileName)-4] = '\0';

//yolov5参数

vx_int32 head_idx, h_idx, w_idx, anchor_idx;

vx_int32 yolov5_class_stride = 3 + 5 + 8 + 6; //cls confxywh points slot

ttevxYoloV5BBox *bbox_obj_arr = vxCreateUserDataObject(obj->context, "", sizeof(ttevxYoloV5BBox), NULL);

ttevxYoloV5PostProcParams *yolov5params = vxCreateUserDataObject(obj->context, "", sizeof(ttevxYoloV5PostProcParams), NULL);

vx_int32 bbox_num = 0;

TIDL_outArgs* out_args = obj->outArgs;

ttevxYoloV5Detections *detections = vxCreateUserDataObject(obj->context, "", sizeof(ttevxYoloV5Detections), NULL);

//init

{

for(int i = 0;i<5;i++)

{

out_args->scale[i] = obj->ioBufDesc.outTensorScale[i];

}

yolov5params->num_anchors = TTE_YOLOV5_NUM_ANCHOR;

yolov5params->num_classes = TTE_YOLOV5_NUM_CLASSES;

yolov5params->conf_thresh = 0.45;

yolov5params->nms_thresh = 0.25;

int i, j, k;

for (i = 0; i < TTE_YOLOV5_NUM_HEAD; ++i) {

for (j = 0; j < TTE_YOLOV5_NUM_ANCHOR; ++j) {

for (k = 0; k < 2; ++k) {

yolov5params->anchors[i][j][k] = ANCHORS[i][j][k];

}

}

}

}

// for(int32_t head_idx = 2; head_idx < obj->num_output_tensors; head_idx++) // for mulTask_yolov5_det

// {

// output_sizes[0] = ioBufDesc->outWidth[head_idx] + obj->ioBufDesc.outPadL[head_idx] + obj->ioBufDesc.outPadR[head_idx];

// output_sizes[1] = ioBufDesc->outHeight[head_idx] + obj->ioBufDesc.outPadT[head_idx] + obj->ioBufDesc.outPadB[head_idx];

// output_sizes[2] = 1;//ioBufDesc->outNumChannels[id];

// input_sizes[0] = ioBufDesc->inWidth[0] + obj->ioBufDesc.inPadL[0] + obj->ioBufDesc.inPadR[0];

// input_sizes[1] = ioBufDesc->inHeight[0] + obj->ioBufDesc.inPadT[0] + obj->ioBufDesc.inPadB[0];

// input_sizes[2] = ioBufDesc->inNumChannels[0];

// width = ioBufDesc->outWidth[head_idx];

// height = ioBufDesc->outHeight[head_idx];

// outPadL = obj->ioBufDesc.outPadL[head_idx];

// outPadT = obj->ioBufDesc.outPadT[head_idx];

// inPadL = obj->ioBufDesc.inPadL[0];

// inPadT = obj->ioBufDesc.inPadT[0];

// //获取内存块

// void *output_buffer, *input_buffer;

// vx_map_id map_id_output, map_id_input;

// vx_size output_strides[APP_MAX_TENSOR_DIMS], input_strides[APP_MAX_TENSOR_DIMS];

// vx_size output_start[APP_MAX_TENSOR_DIMS], input_start[APP_MAX_TENSOR_DIMS];

// output_start[0] = output_start[1] = output_start[2] = output_start[3] = 0;

// input_start[0] = input_start[1] = input_start[2] = input_start[3] = 0;

// output_strides[0] = 1;

// output_strides[1] = output_sizes[0];

// output_strides[2] = output_sizes[1] * output_strides[1];

// input_strides[0] = 1;

// input_strides[1] = input_sizes[0];

// input_strides[2] = input_sizes[1] * input_strides[1];

// tivxMapTensorPatch(output_tensors[head_idx], 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// tivxMapTensorPatch(input_tensors[0], 3, input_start, input_sizes, &map_id_input, input_strides, &input_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// //

// status = vxGetStatus((vx_reference)output_tensors[head_idx]);

// if(VX_SUCCESS == status)

// {

// /* 初始时将指针定位到第一个有效内存位置 */

// uint8_t *pOut, *pIn;

// pOut = (uint8_t *)output_buffer;

// pIn = (uint8_t *)input_buffer;

// vx_uint8 *raw_data = (vx_uint8*)(pOut) + (output_sizes[0] * outPadT + outPadL);

// /* TIDL中内存实际是CHW排布,但是以WHC记录,所以查找内存时首先定位正确的通道,再进行WH的偏移 */

// for (h_idx = 0; h_idx < ioBufDesc->outHeight[head_idx]; ++h_idx) {

// for (w_idx = 0; w_idx < ioBufDesc->outWidth[head_idx]; ++w_idx) {

// for (anchor_idx = 0; anchor_idx < yolov5params->num_anchors; ++anchor_idx) {

// /* 在内存片中对应[h,w]的线性位置 */

// int32_t obj_hw_idx = h_idx * output_sizes[0] + w_idx;

// /* 找到正确conf内存通道位置,并做hw偏移 */

// int32_t obj_conf_idx = (anchor_idx * yolov5_class_stride + 4) * ioBufDesc->outChannelPitch[head_idx] + obj_hw_idx;

// /* 获得conf并将conf缩放回输入尺度 */

// float conf = (float)raw_data[obj_conf_idx] / out_args->scale[head_idx];

// if (conf >= yolov5params->conf_thresh) {

// /* 计算xywh和cls内存位置并转化为输出值 */

// int32_t obj_x_idx = (anchor_idx * yolov5_class_stride + 0) * ioBufDesc->outChannelPitch[head_idx] + obj_hw_idx;

// int32_t obj_y_idx = (anchor_idx * yolov5_class_stride + 1) * ioBufDesc->outChannelPitch[head_idx] + obj_hw_idx;

// int32_t obj_w_idx = (anchor_idx * yolov5_class_stride + 2) * ioBufDesc->outChannelPitch[head_idx] + obj_hw_idx;

// int32_t obj_h_idx = (anchor_idx * yolov5_class_stride + 3) * ioBufDesc->outChannelPitch[head_idx] + obj_hw_idx;

// float x = (float)raw_data[obj_x_idx] / out_args->scale[head_idx];

// x = (x * 2.0 - 0.5 + w_idx) * (float)(ioBufDesc->inWidth[0]) / (float)(ioBufDesc->outWidth[head_idx]);

// float y = (float)raw_data[obj_y_idx] / out_args->scale[head_idx];

// y = (y * 2.0 - 0.5 + h_idx) * (float)(ioBufDesc->inHeight[0]) / (float)(ioBufDesc->outHeight[head_idx]);

// float w = (float)raw_data[obj_w_idx] / out_args->scale[head_idx];

// w = (w * 2.0) * (w * 2.0) * yolov5params->anchors[head_idx][anchor_idx][0];

// float h = (float)raw_data[obj_h_idx] / out_args->scale[head_idx];

// h = (h * 2.0) * (h * 2.0) * yolov5params->anchors[head_idx][anchor_idx][1];

// int32_t cls = 0;

// float cls_prob = 0.0;

// /* 遍历查找类别内存,找到最大的置信度进行赋值 */

// {

// int32_t obj_cls_idx;

// int32_t max_prob_idx;

// float p;

// for (max_prob_idx = 0; max_prob_idx < yolov5params->num_classes; ++max_prob_idx) {

// obj_cls_idx = (anchor_idx * yolov5_class_stride + 5 + 8 + 5 + max_prob_idx) * ioBufDesc->outChannelPitch[head_idx] + obj_hw_idx;

// p = (float)raw_data[obj_cls_idx] / out_args->scale[head_idx];

// if (p > cls_prob) {

// cls_prob = p;

// cls = max_prob_idx;

// }

// }

// }

// /* 输出概率 = 存在目标概率 * 类别置信概率 */

// bbox_obj_arr[bbox_num].confidence = conf * cls_prob;

// if (bbox_obj_arr[bbox_num].confidence >= yolov5params->conf_thresh) {

// bbox_obj_arr[bbox_num].x1 = (int)(x - w / 2 + 0.5);

// bbox_obj_arr[bbox_num].y1 = (int)(y - h / 2 + 0.5);

// bbox_obj_arr[bbox_num].x2 = (int)(x + w / 2 + 0.5);

// bbox_obj_arr[bbox_num].y2 = (int)(y + h / 2 + 0.5);

// bbox_obj_arr[bbox_num].cls = cls;

// bbox_num++;

// }

// }

// }

// }

// }

// }

// }

// //NMS

// bbox_num = NMS(bbox_obj_arr, bbox_num, yolov5params->nms_thresh);

// detections->num_bbox = bbox_num;

//处理分割分支

for(int32_t id = 4; id < 5; id++) //for mulTask_yolov5_seg

{

snprintf(file_name_cmask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_cmask", id, ".bmp");

snprintf(file_name_imask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_imask", id, ".bmp");

snprintf(file_name_gmask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_gmask", id, ".bmp");

output_sizes[0] = ioBufDesc->outWidth[id] + obj->ioBufDesc.outPadL[id] + obj->ioBufDesc.outPadR[id];

output_sizes[1] = ioBufDesc->outHeight[id] + obj->ioBufDesc.outPadT[id] + obj->ioBufDesc.outPadB[id];

output_sizes[2] = 1;//ioBufDesc->outNumChannels[id];

input_sizes[0] = ioBufDesc->inWidth[0] + obj->ioBufDesc.inPadL[0] + obj->ioBufDesc.inPadR[0];

input_sizes[1] = ioBufDesc->inHeight[0] + obj->ioBufDesc.inPadT[0] + obj->ioBufDesc.inPadB[0];

input_sizes[2] = ioBufDesc->inNumChannels[0];

width = ioBufDesc->outWidth[id];

height = ioBufDesc->outHeight[id];

outPadL = obj->ioBufDesc.outPadL[id];

outPadT = obj->ioBufDesc.outPadT[id];

inPadL = obj->ioBufDesc.inPadL[0];

inPadT = obj->ioBufDesc.inPadT[0];

status = vxGetStatus((vx_reference)output_tensors[id]);

if(VX_SUCCESS == status)

{

void *output_buffer, *input_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_strides[APP_MAX_TENSOR_DIMS], input_strides[APP_MAX_TENSOR_DIMS];

vx_size output_start[APP_MAX_TENSOR_DIMS], input_start[APP_MAX_TENSOR_DIMS];

output_start[0] = output_start[1] = output_start[2] = output_start[3] = 0;

input_start[0] = input_start[1] = input_start[2] = input_start[3] = 0;

output_strides[0] = 1;

output_strides[1] = output_sizes[0];

output_strides[2] = output_sizes[1] * output_strides[1];

input_strides[0] = 1;

input_strides[1] = input_sizes[0];

input_strides[2] = input_sizes[1] * input_strides[1];

tivxMapTensorPatch(output_tensors[id], 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

tivxMapTensorPatch(input_tensors[0], 3, input_start, input_sizes, &map_id_input, input_strides, &input_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

{

uint8_t *pOut, *pIn;

pOut = (uint16_t *)output_buffer;

pIn = (uint8_t *)input_buffer;

// printf("模型没加argmax \n");

for(int32_t i = 0; i < height; i++){

for(int32_t j = 0; j < width; j++){

uint8_t seg_type = (uint8_t)((uint16_t)pOut[output_sizes[0]*(outPadT + i) + outPadL + j]);

// if(seg_type>15)

// {

// printf("seg_type 大于15,出错");

// }

uint8_t img_value_R = pIn[0 * input_strides[2] + input_strides[1]*(inPadT + i) + inPadL + j];

uint8_t img_value_G = pIn[1 * input_strides[2] + input_strides[1]*(inPadT + i) + inPadL + j];

uint8_t img_value_B = pIn[2 * input_strides[2] + input_strides[1]*(inPadT + i) + inPadL + j];

int32_t color_chosen = seg_type < 14 ? seg_type : 13;

color_mask[width * 3 * i + j * 3 + 0] = color[color_chosen][0];

color_mask[width * 3 * i + j * 3 + 1] = color[color_chosen][1];

color_mask[width * 3 * i + j * 3 + 2] = color[color_chosen][2];

gray_mask[width * 3 * i + j * 3 + 0] = seg_type;

gray_mask[width * 3 * i + j * 3 + 1] = seg_type;

gray_mask[width * 3 * i + j * 3 + 2] = seg_type;

if(seg_type > 0){

image_mask[width * 3 * i + j * 3 + 0] = img_value_R/2 + color[color_chosen][0]/2;

image_mask[width * 3 * i + j * 3 + 1] = img_value_G/2 + color[color_chosen][1]/2;

image_mask[width * 3 * i + j * 3 + 2] = img_value_B/2 + color[color_chosen][2]/2;

}else{

image_mask[width * 3 * i + j * 3 + 0] = img_value_R;

image_mask[width * 3 * i + j * 3 + 1] = img_value_G;

image_mask[width * 3 * i + j * 3 + 2] = img_value_B;

}

}

}

// if(obj->save_type == '0' || obj->save_type == '1'){

// snprintf(output_file, APP_MAX_FILE_PATH-1, "%s/%s", obj->output_file_path, file_name_cmask);

// printf("save to %s!!!\n", output_file);

// tivx_utils_bmp_write(output_file, color_mask, width, height, (width * 3), obj->df_image);

// }

// if(obj->save_type == '0' || obj->save_type == '2'){

// snprintf(output_file, APP_MAX_FILE_PATH-1, "%s/%s", obj->output_file_path, file_name_gmask);

// printf("save to %s!!!\n", output_file);

// tivx_utils_bmp_write(output_file, gray_mask, width, height, (width * 3), obj->df_image);

// }

// if(obj->save_type == '0' || obj->save_type == '3'){

// snprintf(output_file, APP_MAX_FILE_PATH-1, "%s/%s", obj->output_file_path, file_name_imask);

// printf("save to %s!!!\n", output_file);

// tivx_utils_bmp_write(output_file, image_mask, width, height, (width * 3), obj->df_image);

// }

}

tivxUnmapTensorPatch(output_tensors[id], map_id_output);

tivxUnmapTensorPatch(input_tensors[0], map_id_input);

}

}

}

static void saveOutput_tensor_16bit(AppObj *obj, vx_tensor *output_tensors, vx_tensor *input_tensors, char *fileName)

{

vx_status status = VX_SUCCESS;

vx_size output_sizes[APP_MAX_TENSOR_DIMS];

sTIDL_IOBufDesc_t *ioBufDesc;

ioBufDesc = &obj->ioBufDesc;

int32_t width, height, outPadL, outPadT, inPadL, inPadT;//, padB, padR

char output_file[APP_MAX_FILE_PATH];

char file_name_temp[APP_MAX_FILE_PATH];

char file_name_tensor[APP_MAX_FILE_PATH];

// char file_name_cmask[APP_MAX_FILE_PATH];

// char file_name_imask[APP_MAX_FILE_PATH];

strcpy(file_name_temp, fileName);

file_name_temp[strlen(fileName)-4] = '\0';

//处理分割分支

for(int32_t id = 4; id < 5; id++) //for mulTask_yolov5_seg

{

// snprintf(file_name_tensor, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_tensor", id, ".bmp");

// snprintf(file_name_imask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_imask", id, ".bmp");

// snprintf(file_name_gmask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_gmask", id, ".bmp");

output_sizes[0] = ioBufDesc->outWidth[id] + obj->ioBufDesc.outPadL[id] + obj->ioBufDesc.outPadR[id];

output_sizes[1] = ioBufDesc->outHeight[id] + obj->ioBufDesc.outPadT[id] + obj->ioBufDesc.outPadB[id];

output_sizes[2] = 1;//ioBufDesc->outNumChannels[id];

// input_sizes[0] = ioBufDesc->inWidth[0] + obj->ioBufDesc.inPadL[0] + obj->ioBufDesc.inPadR[0];

// input_sizes[1] = ioBufDesc->inHeight[0] + obj->ioBufDesc.inPadT[0] + obj->ioBufDesc.inPadB[0];

// input_sizes[2] = ioBufDesc->inNumChannels[0];

width = ioBufDesc->outWidth[id];

height = ioBufDesc->outHeight[id];

outPadL = obj->ioBufDesc.outPadL[id];

outPadT = obj->ioBufDesc.outPadT[id];

// inPadL = obj->ioBufDesc.inPadL[0];

// inPadT = obj->ioBufDesc.inPadT[0];

status = vxGetStatus((vx_reference)output_tensors[id]);

if(VX_SUCCESS == status)

{

void *output_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_strides[APP_MAX_TENSOR_DIMS];

vx_size output_start[APP_MAX_TENSOR_DIMS];

output_start[0] = output_start[1] = output_start[2] = output_start[3] = 0;

// input_start[0] = input_start[1] = input_start[2] = input_start[3] = 0;

output_strides[0] = 1;

output_strides[1] = output_sizes[0];

output_strides[2] = output_sizes[1] * output_strides[1];

// input_strides[0] = 1;

// input_strides[1] = input_sizes[0];

// input_strides[2] = input_sizes[1] * input_strides[1];

vx_char new_name[256];

// snprintf(new_name, APP_MAX_FILE_PATH-1, "%s%s%d%s", obj->output_file_path, "/_tensor", id, ".bin");

snprintf(new_name, APP_MAX_FILE_PATH-1, "%s%s%s%s%d%s", obj->output_file_path,"/bin/",file_name_temp,"_", id, ".bin");

FILE *fp = fopen(new_name, "wb");

if(NULL == fp)

{

printf("Unable to open file %s for writing!\n", new_name);

break;

}

tivxMapTensorPatch(output_tensors[id], 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// tivxMapTensorPatch(input_tensors[0], 3, input_start, input_sizes, &map_id_input, input_strides, &input_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

{

uint16_t *pOut;

pOut = (uint16_t *)output_buffer;

// pIn = (uint8_t *)input_buffer;

// printf("模型没加argmax \n");

for(int32_t c = 0; c < ioBufDesc->outNumChannels[id]; c++){

for(int32_t i = 0; i < height; i++){

uint16_t *pOut_1 = pOut + c * output_sizes[0] * output_sizes[1] + output_sizes[0]*(outPadT + i) + outPadL;

uint16_t zh = pOut[c * output_sizes[0] * output_sizes[1] + output_sizes[0]*(outPadT + i) + outPadL];

fwrite(pOut_1, 2, ioBufDesc->outWidth[id], fp);

}

}

fclose(fp);

}

tivxUnmapTensorPatch(output_tensors[id], map_id_output);

// tivxUnmapTensorPatch(input_tensors[0], map_id_input);

}

}

}

static void saveOutput_tensor_32bit(AppObj *obj, vx_tensor *output_tensors, vx_tensor *input_tensors, char *fileName)

{

vx_status status = VX_SUCCESS;

vx_size output_sizes[APP_MAX_TENSOR_DIMS];

sTIDL_IOBufDesc_t *ioBufDesc;

ioBufDesc = &obj->ioBufDesc;

int32_t width, height, outPadL, outPadT, inPadL, inPadT;//, padB, padR

char output_file[APP_MAX_FILE_PATH];

char file_name_temp[APP_MAX_FILE_PATH];

char file_name_tensor[APP_MAX_FILE_PATH];

// char file_name_cmask[APP_MAX_FILE_PATH];

// char file_name_imask[APP_MAX_FILE_PATH];

strcpy(file_name_temp, fileName);

file_name_temp[strlen(fileName)-4] = '\0';

//处理分割分支

for(int32_t id = 4; id < 5; id++) //for mulTask_yolov5_seg

{

// snprintf(file_name_tensor, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_tensor", id, ".bmp");

// snprintf(file_name_imask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_imask", id, ".bmp");

// snprintf(file_name_gmask, APP_MAX_FILE_PATH-1, "%s%s%d%s", file_name_temp, "_gmask", id, ".bmp");

output_sizes[0] = ioBufDesc->outWidth[id] + obj->ioBufDesc.outPadL[id] + obj->ioBufDesc.outPadR[id];

output_sizes[1] = ioBufDesc->outHeight[id] + obj->ioBufDesc.outPadT[id] + obj->ioBufDesc.outPadB[id];

output_sizes[2] = 1;//ioBufDesc->outNumChannels[id];

// input_sizes[0] = ioBufDesc->inWidth[0] + obj->ioBufDesc.inPadL[0] + obj->ioBufDesc.inPadR[0];

// input_sizes[1] = ioBufDesc->inHeight[0] + obj->ioBufDesc.inPadT[0] + obj->ioBufDesc.inPadB[0];

// input_sizes[2] = ioBufDesc->inNumChannels[0];

width = ioBufDesc->outWidth[id];

height = ioBufDesc->outHeight[id];

outPadL = obj->ioBufDesc.outPadL[id];

outPadT = obj->ioBufDesc.outPadT[id];

// inPadL = obj->ioBufDesc.inPadL[0];

// inPadT = obj->ioBufDesc.inPadT[0];

status = vxGetStatus((vx_reference)output_tensors[id]);

if(VX_SUCCESS == status)

{

void *output_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_strides[APP_MAX_TENSOR_DIMS];

vx_size output_start[APP_MAX_TENSOR_DIMS];

output_start[0] = output_start[1] = output_start[2] = output_start[3] = 0;

// input_start[0] = input_start[1] = input_start[2] = input_start[3] = 0;

output_strides[0] = 1;

output_strides[1] = output_sizes[0];

output_strides[2] = output_sizes[1] * output_strides[1];

// input_strides[0] = 1;

// input_strides[1] = input_sizes[0];

// input_strides[2] = input_sizes[1] * input_strides[1];

vx_char new_name[256];

// snprintf(new_name, APP_MAX_FILE_PATH-1, "%s%s%d%s", obj->output_file_path, "/_tensor", id, ".bin");

snprintf(new_name, APP_MAX_FILE_PATH-1, "%s%s%s%s%d%s", obj->output_file_path,"/bin/",file_name_temp,"_", id, ".bin");

FILE *fp = fopen(new_name, "wb");

if(NULL == fp)

{

printf("Unable to open file %s for writing!\n", new_name);

break;

}

tivxMapTensorPatch(output_tensors[id], 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// tivxMapTensorPatch(input_tensors[0], 3, input_start, input_sizes, &map_id_input, input_strides, &input_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

{

vx_float32 *pOut;

pOut = (vx_float32 *)output_buffer;

// pIn = (uint8_t *)input_buffer;

// printf("模型没加argmax \n");

for(int32_t c = 0; c < ioBufDesc->outNumChannels[id]; c++){

for(int32_t i = 0; i < height; i++){

vx_float32 *pOut_1 = pOut + c * output_sizes[0] * output_sizes[1] + output_sizes[0]*(outPadT + i) + outPadL;

vx_float32 zh = pOut[c * output_sizes[0] * output_sizes[1] + output_sizes[0]*(outPadT + i) + outPadL];

fwrite(pOut_1, 4, ioBufDesc->outWidth[id], fp);

}

}

fclose(fp);

}

tivxUnmapTensorPatch(output_tensors[id], map_id_output);

// tivxUnmapTensorPatch(input_tensors[0], map_id_input);

}

}

}

static vx_status app_run_graph_for_one_frame(AppObj *obj, char *curFileName, vx_uint32 counter)

{

vx_status status = VX_SUCCESS;

vx_char input_file_name[APP_MAX_FILE_PATH];

vx_char output_file_name[APP_MAX_FILE_PATH];

vx_uint32 tensor_actual_checksum = 0, display_actual_checksum = 0;

appPerfPointBegin(&obj->total_perf);

snprintf(input_file_name, APP_MAX_FILE_PATH-1, "%s/%s",

obj->input_file_path,

curFileName

);

APP_PRINTF("app_tidl: Reading input file %s ... ", input_file_name);

appPerfPointBegin(&obj->fileio_perf);

/* Read input from file and poplulate the input tensors */

if(status == VX_SUCCESS)

{

status = readInput(obj, obj->context, obj->config, obj->input_tensors, &input_file_name[0]);

}

appPerfPointEnd(&obj->fileio_perf);

APP_PRINTF("Done!\n");

#ifdef APP_WRITE_PRE_PROC_OUTPUT

vx_char pre_proc_file_name[APP_MAX_FILE_PATH];

snprintf(pre_proc_file_name, APP_MAX_FILE_PATH-1, "%s/%s",

obj->output_file_path,

"pre_proc_out"

);

writePreProcOutput(pre_proc_file_name, obj->input_tensors[0]);

#endif

uint64_t cur_time;

APP_PRINTF("app_tidl: Running Graph ... ");

/* Execute the network */

if(status == VX_SUCCESS)

{

cur_time = tivxPlatformGetTimeInUsecs();

status = vxProcessGraph(obj->graph);

cur_time = tivxPlatformGetTimeInUsecs() - cur_time;

}

APP_PRINTF("Done!\n");

APP_PRINTF("20260122==============!\n");

printf("time of rmfsd: %d us \n", (int)cur_time);

if(status == VX_SUCCESS)

{

saveOutput_tensor(obj, obj->output_tensors, obj->input_tensors,curFileName);

// saveOutput_tensor_16bit(obj, obj->output_tensors, obj->input_tensors,curFileName);

}

if(status == VX_SUCCESS)

{

saveOutput(obj, obj->output_tensors, obj->input_tensors,curFileName);

appPerfPointBegin(&obj->draw_perf);

appPerfPointEnd(&obj->draw_perf);

}

tivx_utils_bmp_read_release(&obj->imgParams);

// if(status == VX_SUCCESS)

// {

// snprintf(output_file_name, APP_MAX_FILE_PATH-1, "%s/%s",

// obj->output_file_path,

// curFileName

// );

//

// saveOutput(obj, obj->output_tensors, obj->input_tensors,curFileName);

// appPerfPointBegin(&obj->draw_perf);

// /* Display the output */

// displayOutput(obj, obj->config, obj->output_tensors, &output_file_name[0]);

// appPerfPointEnd(&obj->draw_perf);

// if ((vx_true_e == tivxIsTargetEnabled(TIVX_TARGET_DISPLAY1)) && (obj->display_option == 1)) {

// /* At this point, the output is ready to copy the updated buffer */

// if(status == VX_SUCCESS)

// {

// status = vxCopyImagePatch(obj->disp_image,

// &obj->disp_rect,

// 0,

// &obj->image_addr,

// (void *)obj->pDisplayBuf888,

// VX_WRITE_ONLY,

// VX_MEMORY_TYPE_HOST

// );

// }

// APP_PRINTF("app_tidl: Running display graph ... \n");

// /* Execute the display graph */

// if(status == VX_SUCCESS)

// {

// status = vxProcessGraph(obj->disp_graph);

// }

// APP_PRINTF("app_tidl: Running display graph ... Done.\n");

// }

// /* Check that you are within the first n frames, where n is the number

// of samples in the checksums_expected */

// if ((obj->test_mode == 1) &&

// (counter < ((sizeof(checksums_expected[0])/sizeof(checksums_expected[0][0]))-1)))

// {

// /* numOutputbuf is 1 here, but for the sake of generalizing

// in the future, the loop will remain */

// if(vx_false_e == app_test_check_tensor(obj->output_tensors[0],

// getTensorDataType(obj->ioBufDesc.outElementType[0]),

// obj->ioBufDesc.outWidth[0], obj->ioBufDesc.outPadL[0],

// obj->ioBufDesc.outPadR[0], obj->ioBufDesc.outHeight[0],

// obj->ioBufDesc.outPadT[0], obj->ioBufDesc.outPadB[0],

// obj->ioBufDesc.outNumChannels[0], checksums_expected[obj->test_case*2][counter],

// &tensor_actual_checksum))

// {

// test_result = vx_false_e;

// }

// /* in case test fails and needs to change */

// populate_gatherer(0 + (obj->test_case*2), counter, tensor_actual_checksum);

//#ifndef x86_64

// if(vx_false_e == app_test_check_image(obj->disp_image, checksums_expected[1+(2*obj->test_case)][counter],

// &display_actual_checksum))

// {

// test_result = vx_false_e;

// }

// populate_gatherer(1 + (obj->test_case*2), counter, display_actual_checksum);

//#endif

// }

// }

appPerfPointEnd(&obj->total_perf);

#ifdef APP_TIDL_TRACE_DUMP

tivx_utils_tidl_trace_write(obj->traceData, curFileName);

#endif

// printf("exit_begin\n");

// exit(0);

// printf("exit_end\n");

return status;

}

static vx_status app_run_graph(AppObj *obj)

{

vx_status status = VX_SUCCESS;

vx_char curFileName[APP_MAX_FILE_PATH];

uint64_t cur_time;

uint64_t max_frames = INT64_MAX;

vx_uint32 counter = 0;

FILE* test_case_file;

uint32_t cur_iteration;

printf("network file: %s\n", obj->tidl_network_file_path);

printf("config file: %s\n", obj->tidl_config_file_path);

if (obj->test_mode == 1)

{

/* This way if the application failed at any point up to here

the test mode would return a failure */

test_result = vx_true_e;

obj->num_iterations = 1;

max_frames = (sizeof(checksums_expected[0])/sizeof(checksums_expected[0][0])) + TEST_BUFFER;

}

for(cur_iteration=0; cur_iteration<obj->num_iterations; cur_iteration++)

{

printf("Iteration %d of %d ... \n", cur_iteration, obj->num_iterations);

test_case_file = fopen(obj->input_file_list,"r");

if(test_case_file==NULL)

{

break;

}

int zh = 0;

while (fgets(curFileName, sizeof(curFileName), test_case_file) && (counter < max_frames))

{

curFileName[strlen(curFileName) - 1] = 0;

zh ++;

cur_time = tivxPlatformGetTimeInUsecs();

APP_PRINTF("Classifying input %s ...\n", curFileName);

if(status == VX_SUCCESS)

{

status = app_run_graph_for_one_frame(obj, curFileName, counter++);

}

printf("完成图像张数: %d\n", zh);

APP_PRINTF("Classifying input %s ...Done!\n", curFileName);

cur_time = tivxPlatformGetTimeInUsecs() - cur_time;

/* convert to msecs */

cur_time = cur_time;

printf("cur_time:==%ld\n",cur_time);

if(cur_time < obj->delay_in_msecs)

{

tivxTaskWaitMsecs(obj->delay_in_msecs - cur_time);

}

/* user asked to stop processing */

if(obj->stop_task || (status != VX_SUCCESS))

{

break;

}

}

fclose(test_case_file);

if(obj->stop_task || (status != VX_SUCCESS))

{

break;

}

}

printf("exit_begin\n");

exit(0);

printf("exit_end\n");

return status;

}

static vx_user_data_object readConfig(AppObj *obj, vx_context context, char *config_file, uint32_t *num_input_tensors, uint32_t *num_output_tensors)

{

vx_status status = VX_SUCCESS;

tivxTIDLJ7Params *tidlParams = NULL;

sTIDL_IOBufDesc_t *ioBufDesc = NULL;

vx_user_data_object config = NULL;

vx_uint32 capacity;

vx_map_id map_id;

FILE *fp_config;

vx_size read_count;

APP_PRINTF("app_tidl: Reading config file %s ...\n", config_file);

fp_config = fopen(config_file, "rb");

if(fp_config == NULL)

{

printf("app_tidl: ERROR: Unable to open IO config file %s \n", config_file);

return NULL;

}

fseek(fp_config, 0, SEEK_END);

capacity = ftell(fp_config);

fseek(fp_config, 0, SEEK_SET);

if( capacity != sizeof(sTIDL_IOBufDesc_t) )

{

printf("app_tidl: ERROR: Config file size (%d bytes) does not match size of sTIDL_IOBufDesc_t (%d bytes)\n", capacity, (vx_uint32)sizeof(sTIDL_IOBufDesc_t));

fclose(fp_config);

return NULL;

}

/* Create a user struct type for handling config data*/

config = vxCreateUserDataObject(context, "tivxTIDLJ7Params", sizeof(tivxTIDLJ7Params), NULL );

status = vxGetStatus((vx_reference)config);

if (VX_SUCCESS == status)

{

status = vxMapUserDataObject(config, 0, sizeof(tivxTIDLJ7Params), &map_id,

(void **)&tidlParams, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, 0);

if (VX_SUCCESS == status)

{

if(tidlParams == NULL)

{

printf("app_tidl: ERROR: Map of config object failed\n");

fclose(fp_config);

return NULL;

}

tivx_tidl_j7_params_init(tidlParams);

ioBufDesc = (sTIDL_IOBufDesc_t *)&tidlParams->ioBufDesc;

read_count = fread(ioBufDesc, capacity, 1, fp_config);

if(read_count != 1)

{

printf("app_tidl: ERROR: Unable to read config file\n");

}

fclose(fp_config);

memcpy(&obj->ioBufDesc, ioBufDesc, capacity);

*num_input_tensors = ioBufDesc->numInputBuf;

*num_output_tensors = ioBufDesc->numOutputBuf;

if(status == VX_SUCCESS)

{

status = vxUnmapUserDataObject(config, map_id);

}

}

else

{

fclose(fp_config);

}

}

else

{

fclose(fp_config);

}

APP_PRINTF("app_tidl: Reading config file %s ... Done. %d bytes\n", config_file, (uint32_t)capacity);

APP_PRINTF("app_tidl: Tensors, input = %d, output = %d\n", *num_input_tensors, *num_output_tensors);

return config;

}

static vx_user_data_object readNetwork(vx_context context, char *network_file)

{

vx_status status;

vx_user_data_object network;

vx_map_id map_id;

vx_uint32 capacity;

void *network_buffer = NULL;

vx_size read_count;

FILE *fp_network;

APP_PRINTF("app_tidl: Reading network file %s ... \n", network_file);

fp_network = fopen(network_file, "rb");

if(fp_network == NULL)

{

printf("app_tidl: ERROR: Unable to open network file %s \n", network_file);

return NULL;

}

fseek(fp_network, 0, SEEK_END);

capacity = ftell(fp_network);

fseek(fp_network, 0, SEEK_SET);

network = vxCreateUserDataObject(context, "TIDL_network", capacity, NULL );

status = vxGetStatus((vx_reference)network);

if (VX_SUCCESS == status)

{

status = vxMapUserDataObject(network, 0, capacity, &map_id,

(void **)&network_buffer, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, 0);

if (VX_SUCCESS == status)

{

if(network_buffer)

{

read_count = fread(network_buffer, capacity, 1, fp_network);

if(read_count != 1)

{

printf("app_tidl: ERROR: Unable to read network file\n");

}

fclose(fp_network);

}

else

{

printf("app_tidl: ERROR: Unable to allocate memory for reading network file of %d bytes\n", capacity);

fclose(fp_network);

}

if(status == VX_SUCCESS)

{

status = vxUnmapUserDataObject(network, map_id);

}

}

else

{

fclose(fp_network);

}

}

else

{

fclose(fp_network);

}

APP_PRINTF("app_tidl: Reading network file %s ... Done. %d bytes\n", network_file, (uint32_t)capacity);

return network;

}

static vx_user_data_object setCreateParams(vx_context context)

{

vx_status status;

vx_user_data_object createParams;

vx_map_id map_id;

vx_uint32 capacity;

void *createParams_buffer = NULL;

capacity = sizeof(TIDL_CreateParams);

createParams = vxCreateUserDataObject(context, "TIDL_CreateParams", capacity, NULL );

status = vxGetStatus((vx_reference)createParams);

if (VX_SUCCESS == status)

{

status = vxMapUserDataObject(createParams, 0, capacity, &map_id,

(void **)&createParams_buffer, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, 0);

if (VX_SUCCESS == status)

{

if(createParams_buffer)

{

TIDL_CreateParams *prms = createParams_buffer;

TIDL_createParamsInit(prms);

prms->isInbufsPaded = 1;

prms->quantRangeExpansionFactor = 1.0;

prms->quantRangeUpdateFactor = 0.0;

#ifdef x86_64

prms->flowCtrl = 1;

#endif

#ifdef APP_TIDL_TRACE_DUMP

prms->traceLogLevel = 1;

prms->traceWriteLevel = 1;

#else

prms->traceLogLevel = 0;

prms->traceWriteLevel = 0;

#endif

}

else

{

printf("app_tidl: ERROR: Unable to allocate memory for create time params! %d bytes\n", capacity);

}

vxUnmapUserDataObject(createParams, map_id);

}

}

return createParams;

}

static vx_user_data_object setInArgs(vx_context context)

{

vx_status status;

vx_user_data_object inArgs;

vx_map_id map_id;

vx_uint32 capacity;

void *inArgs_buffer = NULL;

capacity = sizeof(TIDL_InArgs);

inArgs = vxCreateUserDataObject(context, "TIDL_InArgs", capacity, NULL );

status = vxGetStatus((vx_reference)inArgs);

if (VX_SUCCESS == status)

{

status = vxMapUserDataObject(inArgs, 0, capacity, &map_id,

(void **)&inArgs_buffer, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, 0);

if (VX_SUCCESS == status)

{

if(inArgs_buffer)

{

TIDL_InArgs *prms = inArgs_buffer;

prms->iVisionInArgs.size = sizeof(TIDL_InArgs);

prms->iVisionInArgs.subFrameInfo = 0;

}

else

{

printf("app_tidl: Unable to allocate memory for inArgs! %d bytes\n", capacity);

}

vxUnmapUserDataObject(inArgs, map_id);

}

}

return inArgs;

}

static vx_user_data_object setOutArgs(vx_context context)

{

vx_status status;

vx_user_data_object outArgs;

vx_map_id map_id;

vx_uint32 capacity;

void *outArgs_buffer = NULL;

capacity = sizeof(TIDL_outArgs);

outArgs = vxCreateUserDataObject(context, "TIDL_outArgs", capacity, NULL );

status = vxGetStatus((vx_reference)outArgs);

if (VX_SUCCESS == status)

{

status = vxMapUserDataObject(outArgs, 0, capacity, &map_id,

(void **)&outArgs_buffer, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, 0);

if (VX_SUCCESS == status)

{

if(outArgs_buffer)

{

TIDL_outArgs *prms = outArgs_buffer;

prms->iVisionOutArgs.size = sizeof(TIDL_outArgs);

}

else

{

printf("app_tidl: Unable to allocate memory for outArgs! %d bytes\n", capacity);

}

vxUnmapUserDataObject(outArgs, map_id);

}

}

return outArgs;

}

static void createInputTensors(AppObj *obj, vx_context context, vx_user_data_object config, vx_tensor *input_tensors)

{

vx_size input_sizes[APP_MAX_TENSOR_DIMS];

uint32_t id;

sTIDL_IOBufDesc_t *ioBufDesc = &obj->ioBufDesc;

for(id = 0; id < ioBufDesc->numInputBuf; id++) {

input_sizes[0] = ioBufDesc->inWidth[id] + ioBufDesc->inPadL[id] + ioBufDesc->inPadR[id];

input_sizes[1] = ioBufDesc->inHeight[id] + ioBufDesc->inPadT[id] + ioBufDesc->inPadB[id];

input_sizes[2] = ioBufDesc->inNumChannels[id];

vx_size data_type = getTensorDataType(ioBufDesc->inElementType[id]);

if(data_type != VX_TYPE_INVALID)

input_tensors[id] = vxCreateTensor(context, 3, input_sizes, data_type, 0);

}

return;

}

static void createOutputTensors(AppObj *obj, vx_context context, vx_user_data_object config, vx_tensor *output_tensors)

{

vx_size output_sizes[APP_MAX_TENSOR_DIMS];

uint32_t id;

sTIDL_IOBufDesc_t *ioBufDesc = &obj->ioBufDesc;

for(id = 0; id < ioBufDesc->numOutputBuf; id++) {

output_sizes[0] = ioBufDesc->outWidth[id] + ioBufDesc->outPadL[id] + ioBufDesc->outPadR[id];

output_sizes[1] = ioBufDesc->outHeight[id] + ioBufDesc->outPadT[id] + ioBufDesc->outPadB[id];

output_sizes[2] = ioBufDesc->outNumChannels[id];

vx_size data_type = getTensorDataType(ioBufDesc->outElementType[id]);

if(data_type != VX_TYPE_INVALID)

{

output_tensors[id] = vxCreateTensor(context, 3, output_sizes, data_type, 0);

}

}

return;

}

static void resizeImage(uint8_t *inImg, uint8_t *outImg, uint32_t inWidth, uint32_t inHeight, uint32_t inStride, uint32_t outWidth, uint32_t outHeight, uint32_t outStride)

{

float xScale = (inWidth * 1.0f) / (outWidth * 1.0f);

float yScale = (inHeight * 1.0f) / (outHeight * 1.0f);

uint8_t border_constant_value = 128;

int32_t srcOffsetX = 0;

int32_t srcOffsetY = 0;

int32_t dstOffsetX = 0;

int32_t dstOffsetY = 0;

int32_t x, y, ch;

for( ch = 0; ch < 3; ch++) {

uint8_t *pIn = inImg + (ch * inStride * inHeight);

uint8_t *pOut = outImg + (ch * outStride * outHeight);

for( y = 0; y < outHeight; y++ ) {

for( x = 0; x < outWidth; x++ ) {

/* Apply scale factors to find input pixel for each output pixel */

float src_x_f = ((float)(x+dstOffsetX) + 0.5f)*xScale - 0.5f;

float src_y_f = ((float)(y+dstOffsetY) + 0.5f)*yScale - 0.5f;

float xf = floorf(src_x_f);

float yf = floorf(src_y_f);

float dx = src_x_f - xf;

float dy = src_y_f - yf;

float a[4];

int32_t src_x = (int32_t)(xf) - srcOffsetX;

int32_t src_y = (int32_t)(yf) - srcOffsetY;

uint8_t tl = 0;

uint8_t tr = 0;

uint8_t bl = 0;

uint8_t br = 0;

a[0] = (1.0f - dx) * (1.0f - dy);

a[1] = (1.0f - dx) * (dy);

a[2] = (dx)* (1.0f - dy);

a[3] = (dx)* (dy);

tl = (src_x < 0 || src_y < 0 || src_x > (inWidth-1) || src_y > (inHeight-1) ) ?

border_constant_value :

pIn[(src_y*inStride) + src_x];

tr = ((src_x+1) < 0 || src_y < 0 || (src_x+1) > (inWidth-1) || src_y > (inHeight-1) ) ?

border_constant_value :

pIn[(src_y*inStride) + src_x + 1];

bl = (src_x < 0 || (src_y+1) < 0 || src_x > (inWidth-1) || (src_y+1) > (inHeight-1) ) ?

border_constant_value :

pIn[((src_y+1)*inStride) + src_x];

br = ((src_x+1) < 0 || (src_y+1) < 0 || (src_x+1) > (inWidth-1) || (src_y+1) > (inHeight-1) ) ?

border_constant_value :

pIn[((src_y+1)*inStride) + src_x + 1];

pOut[(y*outStride) + x] = (uint8_t)(a[0]*tl + a[2]*tr + a[1]*bl + a[3]*br + 0.5f);

}

}

}

return;

}

static vx_status readInput(AppObj *obj, vx_context context, vx_user_data_object config, vx_tensor *input_tensors, char *input_file)

{

vx_status status = VX_SUCCESS;

tivx_utils_bmp_image_params_t *imgParams;

void *input_buffer = NULL;

int32_t capacity;

uint32_t id;

vx_map_id map_id_input;

vx_size start[APP_MAX_TENSOR_DIMS];

vx_size input_strides[APP_MAX_TENSOR_DIMS];

vx_size input_sizes[APP_MAX_TENSOR_DIMS];

sTIDL_IOBufDesc_t *ioBufDesc = &obj->ioBufDesc;

for(id = 0; id < ioBufDesc->numInputBuf; id++)

{

vx_size data_type = getTensorDataType(ioBufDesc->inElementType[id]);

input_sizes[0] = ioBufDesc->inWidth[id] + ioBufDesc->inPadL[id] + ioBufDesc->inPadR[id];

input_sizes[1] = ioBufDesc->inHeight[id] + ioBufDesc->inPadT[id] + ioBufDesc->inPadB[id];

input_sizes[2] = ioBufDesc->inNumChannels[id];

capacity = input_sizes[0] * input_sizes[1] * input_sizes[2];

start[0] = start[1] = start[2] = 0;

input_strides[0] = sizeof(vx_int8);

if((data_type == VX_TYPE_INT8) ||

(data_type == VX_TYPE_UINT8))

{

input_strides[0] = sizeof(vx_int8);

}

else if((data_type == VX_TYPE_INT16) ||

(data_type == VX_TYPE_UINT16))

{

input_strides[0] = sizeof(vx_int16);

}

input_strides[1] = input_sizes[0] * input_strides[0];

input_strides[2] = input_sizes[1] * input_strides[1];

APP_PRINTF(" input_sizes[0] = %d, dim = %d padL = %d padR = %d\n", (uint32_t)input_sizes[0], ioBufDesc->inWidth[id], ioBufDesc->inPadL[id], ioBufDesc->inPadR[id]);

APP_PRINTF(" input_sizes[1] = %d, dim = %d padT = %d padB = %d\n", (uint32_t)input_sizes[1], ioBufDesc->inHeight[id], ioBufDesc->inPadT[id], ioBufDesc->inPadB[id]);

APP_PRINTF(" input_sizes[2] = %d, dim = %d \n", (uint32_t)input_sizes[2], ioBufDesc->inNumChannels[id]);

if(status == VX_SUCCESS)

{

status = tivxMapTensorPatch(input_tensors[id], 3, start, input_sizes, &map_id_input, input_strides, &input_buffer, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST);

}

if (VX_SUCCESS == status)

{

vx_df_image df_image;

void *data_ptr = NULL;

vx_uint32 img_width;

vx_uint32 img_height;

vx_uint32 img_stride;

vx_int32 start_offset;

vx_uint8 *pData;

vx_uint8 *pInPlanes;

vx_uint8 *pOutPlanes;

vx_int32 i, j;

APP_PRINTF("app_tidl: Reading bmp file ...\n" );

imgParams = &obj->imgParams;

status = tivx_utils_bmp_file_read(

input_file,

vx_false_e,

imgParams);

if(status != VX_SUCCESS)

{

printf("app_tidl: Reading bmp file ... Failed !!!\n" );

}

else

{

img_width = imgParams->width;

img_height = imgParams->height;

img_stride = imgParams->stride_y;

df_image = imgParams->format;

data_ptr = imgParams->data;

APP_PRINTF("app_tidl: Reading bmp file ... Done.\n" );

APP_PRINTF("app_tidl: Image Pre processing for image of size %d x %d (pitch = %d bytes)...\n", img_width, img_height, img_stride);

APP_PRINTF("app_tidl: Deinterleaving data ...\n");

/* Save image params which are used in displayOutput function */

obj->img_width = img_width;

obj->img_height = img_height;

obj->img_stride = img_stride;

obj->data_ptr = data_ptr;

obj->df_image = df_image;

pInPlanes = (vx_uint8 *)obj->pInPlanes;

pOutPlanes = (vx_uint8 *)obj->pOutPlanes;

/* Deinterleave RGB to planar */

uint32_t chOffset = img_width * img_height;

for(i = 0; i < img_height; i ++)

{

pData = (vx_uint8 *)data_ptr + (i * img_stride);

for(j = 0; j < img_width; j ++)

{

pInPlanes[(0 * chOffset) + (i * img_width) + j] = *pData++;

pInPlanes[(1 * chOffset) + (i * img_width) + j] = *pData++;

pInPlanes[(2 * chOffset) + (i * img_width) + j] = *pData++;

}

}

APP_PRINTF("app_tidl: Resizing image ...\n");

/* Resize image to network input resolution */

//resizeImage(pInPlanes, pOutPlanes, img_width, img_height, img_width, 256, 256, 256);

resizeImage(pInPlanes, pOutPlanes, img_width, img_height, img_width, ioBufDesc->inWidth[id], ioBufDesc->inHeight[id], ioBufDesc->inWidth[id]);

APP_PRINTF("app_tidl: Rearranging data ...\n");

if((data_type == VX_TYPE_INT8) ||

(data_type == VX_TYPE_UINT8))

{

vx_uint8 *pR = NULL;

vx_uint8 *pG = NULL;

vx_uint8 *pB = NULL;

/* Reset the input buffer, this will take care of padding requirement for TIDL */

memset(input_buffer, 0, capacity);

if(ioBufDesc->inDataFormat[id] == 1) /* RGB */

{

start_offset = (0 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pR = (vx_uint8 *)input_buffer + start_offset;

start_offset = (1 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pG = (vx_uint8 *)input_buffer + start_offset;

start_offset = (2 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pB = (vx_uint8 *)input_buffer + start_offset;

}

else if(ioBufDesc->inDataFormat[id] == 0) /* BGR */

{

start_offset = (0 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pB = (vx_uint8 *)input_buffer + start_offset;

start_offset = (1 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pG = (vx_uint8 *)input_buffer + start_offset;

start_offset = (2 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pR = (vx_uint8 *)input_buffer + start_offset;

}

//chOffset = 256*256;

chOffset = ioBufDesc->inWidth[id]*ioBufDesc->inHeight[id];

if ( (NULL != pR) && (NULL != pG) && (NULL != pB) )

{

/* Write image in network required format */

for(i = 0; i < ioBufDesc->inHeight[id]; i++)

{

//Center crop 224x224 image from 256x256 resized input

//uint32_t offset = ((16 + i) * 256) + 16;

uint32_t offset = i * ioBufDesc->inWidth[id];

for(j = 0; j < ioBufDesc->inWidth[id]; j++)

{

pR[j] = pOutPlanes[(0 * chOffset) + offset + j];

pG[j] = pOutPlanes[(1 * chOffset) + offset + j];

pB[j] = pOutPlanes[(2 * chOffset) + offset + j];

}

pR += input_sizes[0];

pG += input_sizes[0];

pB += input_sizes[0];

}

}

}

else if((data_type == VX_TYPE_INT16) ||

(data_type == VX_TYPE_UINT16))

{

vx_uint16 *pR = NULL;

vx_uint16 *pG = NULL;

vx_uint16 *pB = NULL;

/* Reset the input buffer, this will take care of padding requirement for TIDL */

memset(input_buffer, 0, capacity);

if(ioBufDesc->inDataFormat[id] == 1) /* RGB */

{

start_offset = (0 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pR = (vx_uint16 *)((vx_uint8 *)input_buffer + start_offset);

start_offset = (1 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pG = (vx_uint16 *)((vx_uint8 *)input_buffer + start_offset);

start_offset = (2 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pB = (vx_uint16 *)((vx_uint8 *)input_buffer + start_offset);

}

else if(ioBufDesc->inDataFormat[id] == 0) /* BGR */

{

start_offset = (0 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pB = (vx_uint16 *)((vx_uint8 *)input_buffer + start_offset);

start_offset = (1 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pG = (vx_uint16 *)((vx_uint8 *)input_buffer + start_offset);

start_offset = (2 * input_strides[2]) + (ioBufDesc->inPadT[id] * input_strides[1]) + (ioBufDesc->inPadL[id] * input_strides[0]);

pR = (vx_uint16 *)((vx_uint8 *)input_buffer + start_offset);

}

chOffset = 256*256;

chOffset = ioBufDesc->inWidth[id]*ioBufDesc->inHeight[id];

if ( (NULL != pR) && (NULL != pG) && (NULL != pB) )

{

/* Write image in network required format */

for(i = 0; i < ioBufDesc->inHeight[id]; i++)

{

//Center crop 224x224 image from 256x256 resized input

//uint32_t offset = ((16 + i) * 256) + 16;

uint32_t offset = i * ioBufDesc->inWidth[id];

for(j = 0; j < ioBufDesc->inWidth[id]; j++)

{

pR[j] = pOutPlanes[(0 * chOffset) + offset + j];

pG[j] = pOutPlanes[(1 * chOffset) + offset + j];

pB[j] = pOutPlanes[(2 * chOffset) + offset + j];

}

pR += input_sizes[0];

pG += input_sizes[0];

pB += input_sizes[0];

}

}

}

APP_PRINTF("app_tidl: Image Pre processing ... Done.\n");

}

tivxUnmapTensorPatch(input_tensors[id], map_id_input);

}

}

return status;

}

static void displayOutput(AppObj *obj, vx_user_data_object config, vx_tensor *output_tensors, char *output_file)

{

vx_status status = VX_SUCCESS;

vx_size output_sizes[APP_MAX_TENSOR_DIMS];

int32_t id, i, j;

sTIDL_IOBufDesc_t *ioBufDesc;

Draw2D_FontPrm sClassPrm;

ioBufDesc = &obj->ioBufDesc;

for(id = 0; id < ioBufDesc->numOutputBuf; id++)

{

vx_size data_type = getTensorDataType(ioBufDesc->outElementType[id]);

output_sizes[0] = ioBufDesc->outWidth[id] + ioBufDesc->outPadL[id] + ioBufDesc->outPadR[id];

output_sizes[1] = ioBufDesc->outHeight[id] + ioBufDesc->outPadT[id] + ioBufDesc->outPadB[id];

output_sizes[2] = ioBufDesc->outNumChannels[id];

if(status == VX_SUCCESS)

{

status = vxGetStatus((vx_reference)output_tensors[id]);

}

if (VX_SUCCESS == status)

{

void *output_buffer;

vx_map_id map_id_output;

vx_size output_strides[APP_MAX_TENSOR_DIMS];

vx_size start[APP_MAX_TENSOR_DIMS];

start[0] = start[1] = start[2] = start[3] = 0;

output_strides[0] = sizeof(vx_int8);

if((data_type == VX_TYPE_INT8) ||

(data_type == VX_TYPE_UINT8))

{

output_strides[0] = sizeof(vx_int8);

}

else if((data_type == VX_TYPE_INT16) ||

(data_type == VX_TYPE_UINT16))

{

output_strides[0] = sizeof(vx_int16);

}

else if(data_type == VX_TYPE_FLOAT32)

{

output_strides[0] = sizeof(vx_float32);

}

output_strides[1] = output_sizes[0] * output_strides[0];

output_strides[2] = output_sizes[1] * output_strides[1];

status = tivxMapTensorPatch(output_tensors[id], 3, start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

if(status == VX_SUCCESS)

{

vx_uint32 classid[5] = {0};

vx_uint32 label_offset;

label_offset = 0;

if(ioBufDesc->outWidth[id] == 1001)

{

label_offset = 0;

}

else if(ioBufDesc->outWidth[id] == 1000)

{

label_offset = 1;

}

APP_PRINTF("app_tidl: Finding top-5 ... \n");

if(data_type == VX_TYPE_FLOAT32)

{

float *pOut;

float score[5];

pOut = (float *)output_buffer + (ioBufDesc->outPadT[id] * output_sizes[0]) + ioBufDesc->outPadL[id];

for(i = 0; i < 5; i++)

{

score[i] = FLT_MIN;

classid[i] = (vx_uint32)-1;

for(j = 0; j < ioBufDesc->outWidth[id]; j++)

{

if(pOut[j] > score[i])

{

score[i] = pOut[j];

classid[i] = j;

}

}

if(classid[i] < ioBufDesc->outWidth[id] )

{

pOut[classid[i]] = FLT_MIN;

}

else

{

classid[i] = 0; /* invalid class ID, ideally it should not reach here */

}

}

#ifdef APP_DEBUG

APP_PRINTF("app_tidl: Image classification Top-5 results: \n");

for(i = 0; i < 5; i++)

{

APP_PRINTF("app_tidl: %s, class-id: %d, score: %f \n", (char *)&imgnet_labels[classid[i] + label_offset], classid[i], score[i]);

}

#endif

}

else if(data_type == VX_TYPE_INT16)

{

vx_int16 *pOut;

vx_int16 score[5];

pOut = (vx_int16 *)output_buffer + (ioBufDesc->outPadT[id] * output_sizes[0]) + ioBufDesc->outPadL[id];

for(i = 0; i < 5; i++)

{

score[i] = INT16_MIN;

classid[i] = (vx_uint32)-1;

for(j = 0; j < ioBufDesc->outWidth[id]; j++)

{

if(pOut[j] > score[i])

{

score[i] = pOut[j];

classid[i] = j;

}

}

if(classid[i] < ioBufDesc->outWidth[id] )

{

pOut[classid[i]] = INT16_MIN;

}

else

{

classid[i] = 0; /* invalid class ID, ideally it should not reach here */

}

}

#ifdef APP_DEBUG

APP_PRINTF("app_tidl: Image classification Top-5 results: \n");

for(i = 0; i < 5; i++)

{

APP_PRINTF("app_tidl: %s, class-id: %d, score: %d \n", (char *)&imgnet_labels[classid[i] + label_offset], classid[i], score[i]);

}

#endif

}

else if(data_type == VX_TYPE_INT8)

{

vx_int8 *pOut;

vx_int8 score[5];

pOut = (vx_int8 *)output_buffer + (ioBufDesc->outPadT[id] * output_sizes[0]) + ioBufDesc->outPadL[id];

for(i = 0; i < 5; i++)

{

score[i] = INT8_MIN;

classid[i] = (vx_uint32)-1;

for(j = 0; j < ioBufDesc->outWidth[id]; j++)

{

if(pOut[j] > score[i])

{

score[i] = pOut[j];

classid[i] = j;

}

}

if(classid[i] < ioBufDesc->outWidth[id] )

{

pOut[classid[i]] = INT8_MIN;

}

else

{

classid[i] = 0; /* invalid class ID, ideally it should not reach here */

}

}

#ifdef APP_DEBUG

APP_PRINTF("app_tidl: Image classification Top-5 results: \n");

for(i = 0; i < 5; i++)

{

APP_PRINTF("app_tidl: %s, class-id: %d, score: %d \n", (char *)&imgnet_labels[classid[i] + label_offset], classid[i], score[i]);

}

#endif

}

APP_PRINTF("app_tidl: Finding top-5 ... Done \n");

Draw2D_clearRegion(obj->pHndl, (DISPLAY_WIDTH/2) + 40, 200, 600, 300);

sClassPrm.fontIdx = 1;

for(i = 0; i < 5; i++)

{

Draw2D_drawString(obj->pHndl, (DISPLAY_WIDTH/2) + 40, 200 + (i * 40), (char *)&imgnet_labels[classid[i] + label_offset], &sClassPrm);

}

}

tivxUnmapTensorPatch(output_tensors[id], map_id_output);

}

}

{

/* Convert RGB565 to RGB888 before writing output */

for(i = 0, j = 0; i < (DISPLAY_WIDTH * DISPLAY_HEIGHT); i++)

{

uint16_t RGB_565_val = obj->pDisplayBuf565[i];

obj->pDisplayBuf888[j + 0] = (RGB_565_val & 0x1F) << 3;

obj->pDisplayBuf888[j + 1] = ((RGB_565_val >> 5) & 0x3F) << 2;

obj->pDisplayBuf888[j + 2] = ((RGB_565_val >> 11) & 0x1F) << 3;

j += 3;

}

if((obj->img_width <= (DISPLAY_WIDTH/2)) && (obj->img_height <= (DISPLAY_HEIGHT - 200)))

{

uint32_t startX = ((DISPLAY_WIDTH/2) / 2) - (obj->img_width / 2);

uint32_t startY = ((DISPLAY_HEIGHT/2) / 2) - (obj->img_height / 2);

uint32_t imgOffset = 200;

for(i = 0; i < obj->img_height; i++)

{

uint8_t *pOut = &obj->pDisplayBuf888[((imgOffset + startY + i) * DISPLAY_WIDTH * 3) + (startX * 3)];

uint8_t *pIn = obj->data_ptr + (i * obj->img_stride);

for(j = 0; j < obj->img_width; j++)

{

*pOut++ = *pIn++;

*pOut++ = *pIn++;

*pOut++ = *pIn++;

}

}

}

}

if (obj->display_option == 0)

{

tivx_utils_bmp_write(output_file, obj->pDisplayBuf888, DISPLAY_WIDTH, DISPLAY_HEIGHT, (DISPLAY_WIDTH * 3), obj->df_image);

}

/* Release the bmp buffer created in readInput() */

tivx_utils_bmp_read_release(&obj->imgParams);

APP_PRINTF("app_tidl: Showing output ... Done.\n");

}

static vx_size getTensorDataType(vx_int32 tidl_type)

{

vx_size openvx_type = VX_TYPE_INVALID;

if (tidl_type == TIDL_UnsignedChar)

{

openvx_type = VX_TYPE_UINT8;

}

else if(tidl_type == TIDL_SignedChar)

{

openvx_type = VX_TYPE_INT8;

}

else if(tidl_type == TIDL_UnsignedShort)

{

openvx_type = VX_TYPE_UINT16;

}

else if(tidl_type == TIDL_SignedShort)

{

openvx_type = VX_TYPE_INT16;

}

else if(tidl_type == TIDL_UnsignedWord)

{

openvx_type = VX_TYPE_UINT32;

}

else if(tidl_type == TIDL_SignedWord)

{

openvx_type = VX_TYPE_INT32;

}

else if(tidl_type == TIDL_SinglePrecFloat)

{

openvx_type = VX_TYPE_FLOAT32;

}

return openvx_type;

}

#ifdef APP_WRITE_PRE_PROC_OUTPUT

static vx_status writePreProcOutput(char* file_name, vx_tensor output)

{

vx_status status = VX_SUCCESS;

vx_size num_dims;

vx_enum data_type;

void *data_ptr;

vx_map_id map_id;

vx_size start[APP_MAX_TENSOR_DIMS];

vx_size tensor_strides[APP_MAX_TENSOR_DIMS];

vx_size tensor_sizes[APP_MAX_TENSOR_DIMS];

vxQueryTensor(output, VX_TENSOR_NUMBER_OF_DIMS, &num_dims, sizeof(vx_size));

if(num_dims != 3)

{

printf("Number of dims are != 3! exiting.. \n");

return VX_FAILURE;

}

vxQueryTensor(output, (vx_enum)VX_TENSOR_DIMS, tensor_sizes, 3 * sizeof(vx_size));

vxQueryTensor(output, (vx_enum)VX_TENSOR_DATA_TYPE, &data_type, sizeof(data_type));

start[0] = start[1] = start[2] = 0;

tensor_strides[0] = sizeof(vx_int8);

if((data_type == VX_TYPE_INT8) ||

(data_type == VX_TYPE_UINT8))

{

tensor_strides[0] = sizeof(vx_int8);

}

else if((data_type == VX_TYPE_INT16) ||

(data_type == VX_TYPE_UINT16))

{

tensor_strides[0] = sizeof(vx_int16);

}

else if((data_type == VX_TYPE_FLOAT32))

{

tensor_strides[0] = sizeof(vx_float32);

}

tensor_strides[1] = tensor_strides[0] * tensor_strides[0];

tensor_strides[2] = tensor_strides[1] * tensor_strides[1];

status = tivxMapTensorPatch(output, num_dims, start, tensor_sizes, &map_id, tensor_strides, &data_ptr, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

if(VX_SUCCESS == status)

{

vx_char new_name[APP_MAX_FILE_PATH];

snprintf(new_name, APP_MAX_FILE_PATH, "%s_%dx%d.rgb", file_name, (uint32_t)tensor_sizes[0], (uint32_t)tensor_sizes[1]);

FILE *fp = fopen(new_name, "wb");

if(NULL == fp)

{

printf("Unable to open file %s for writing!\n", new_name);

return VX_FAILURE;

}

fwrite(data_ptr, 1, num_dims * tensor_strides[2], fp);

fclose(fp);

tivxUnmapTensorPatch(output, map_id);

}

return(status);

}

#endif

===============

我看完 0130 日志后,确定还有一个更关键的结构性问题,这能解释为什么修了 stride 和 map/unmap 仍没改善。


⚠ 根因:检测头索引错位(最关键)

当前模型输出中:

  • 检测头是 output[1], output[2], output[3]
  • 但 getMult_yolov5e2eResult() 内部固定用 head_idx=0..2

你在 main.c 里把检测头参数写入 index=1..3,

但解码函数只读 index=0..2。

这会导致:

  1. head_idx=0 的数据未初始化
  1. head_idx=1/2 读取的是错 head 的 anchors / params
  1. 结果就是坐标错位、整体几何错误

这也是为什么图像一直"差不多错",不会随机炸掉,但永远不对。


✅ 我已经帮你把索引统一了

在 main.c 中做了 检测头索引重映射:

  • 将 zh_idx=1..3 对应到 dst_idx=0..2
  • 这样 getMult_yolov5e2eResult() 就会按 正确顺序 解码

同时日志也会打印:

det_head[1->0]

det_head[2->1]

det_head[3->2]


✅ 你明天只要做这几步(最快验证)

  1. 重新编译下位机程序
  1. 运行推理
  1. 看日志里是否出现 det_head[1->0]
  1. 再跑 draw_tensor2psd.py
  1. 看 _model.bmp 是否正常

为什么我确认这是关键问题?

  • 模型输出 head 的尺寸完全对应 P5/P4/P3:

19×23、38×46、76×92

  • 这些应该对应 head_idx=0/1/2
  • 但你实际把它们放在 index=1/2/3
  • 结果就是 anchors 与 head 对不上

这会导致框位置整体错误,但不会崩溃------非常符合你的现象。


如果这次改完仍不对,我会再帮你继续定位,但这个问题必须先修正。

明天你跑完日志和 _model.bmp 发给我,我们就能迅速确认是否闭环。

相关推荐
C澒2 小时前
SGW 接入层运维实战:配置查看 + 监控分析 + 日志排查
前端·安全·运维开发
半壶清水2 小时前
[软考网规考点笔记]-操作系统核心知识及历年真题解析
网络·网络协议·算法
德育处主任Pro2 小时前
『NAS』在群晖部署一款太空策略游戏-ogame-vue-ts
前端·vue.js·游戏
Tansmjs2 小时前
实时数据可视化库
开发语言·c++·算法
WBluuue2 小时前
Codeforces 1075 Div2(ABC1C2D1D2)
c++·算法
犀思云3 小时前
如何借助总部融合业务专线服务提升企业运作效率?
网络·智能仓储·fusionwan·专线·naas
emma羊羊3 小时前
【AI技术安全】
网络·人工智能·安全
2401_838472513 小时前
C++模拟器开发实践
开发语言·c++·算法
凌寒113 小时前
minio预签名访问地址经过Nginx代理后返回403问题
服务器·网络·nginx