main.c_cursor_0202

/*

*

* 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_labels1001256;

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_pathAPP_MAX_FILE_PATH;

char tidl_network_file_pathAPP_MAX_FILE_PATH;

char input_file_pathAPP_MAX_FILE_PATH;

char input_file_listAPP_MAX_FILE_PATH;

char output_file_pathAPP_MAX_FILE_PATH;

char ti_logo_file_pathAPP_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_tensorsAPP_MAX_TENSORS;

vx_tensor output_tensorsAPP_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_typeAPP_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", argv0);

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.scalei = obj->ioBufDesc.outTensorScalei;

}

}

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_path0, &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_path0);

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_fileAPP_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.bufPitch0 = DISPLAY_WIDTH * 2;

sBufInfo.dataFormat = DRAW2D_DF_BGR16_565;

sBufInfo.transperentColor = 0;

sBufInfo.transperentColorFormat = DRAW2D_DF_BGR16_565;

sBufInfo.bufAddr0 = (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_tensorsid);

}

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

{

vxReleaseTensor(&obj->output_tensorsid);

}

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", argv0);

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_str1024;

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)

{

tokenstrlen(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)

{

tokenstrlen(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)

{

tokenstrlen(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)

{

tokenstrlen(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)

{

tokenstrlen(token)-1=0;

strcpy(obj->input_file_list, token);

}

}

else

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

{

token = strtok(NULL, s);

if(token != NULL)

{

tokenstrlen(token)-1=0;

strcpy(obj->output_file_path, token);

}

}

else

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

{

token = strtok(NULL, s);

if(token != NULL)

{

tokenstrlen(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)

{

tokenstrlen(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)

{

tokenstrlen(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)

{

tokenstrlen(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)

{

tokenstrlen(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(argvi, "--cfg")==0)

{

i++;

if(i>=argc)

{

app_show_usage(argc, argv);

}

app_parse_cfg_file(obj, argvi);

}

else

if(strcmp(argvi, "--help")==0)

{

app_show_usage(argc, argv);

return -1;

}

else

if(strcmp(argvi, "--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);

paramsnum_params = obj;

num_params++;

}

static vx_status app_create_graph(AppObj *obj)

{

vx_status status = VX_SUCCESS;

vx_reference paramsAPP_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_name64;

snprintf(ref_name, 64, "%s%s", tensor_name, tensor_num_stri);

vxSetReferenceName((vx_reference)obj->input_tensorsi, ref_name);

}

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

char tensor_name\[\] = "OutputTensor_";

char ref_name64;

snprintf(ref_name, 64, "%s%s", tensor_name, tensor_num_stri);

vxSetReferenceName((vx_reference)obj->output_tensorsi, 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_arr1;

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_arr0 = &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 color143={{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_sizesAPP_MAX_TENSOR_DIMS, input_sizesAPP_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_fileAPP_MAX_FILE_PATH;

char file_name_tempAPP_MAX_FILE_PATH;

char file_name_gmaskAPP_MAX_FILE_PATH;

char file_name_cmaskAPP_MAX_FILE_PATH;

char file_name_imaskAPP_MAX_FILE_PATH;

strcpy(file_name_temp, fileName);

file_name_tempstrlen(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.buffer0;

// ttevxYoloV5BBox num1 = obj->detections.buffer1;

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

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

// vx_char new_name256;

// 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.bufferi;

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

// }

// fclose(fp);

// }

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

if (1) {

initMult_yolov5params(&obj->yolov5params);

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

obj->yolov5params.inWidth0 = obj->ioBufDesc.inWidth0;

obj->yolov5params.inHeight0 = obj->ioBufDesc.inHeight0;

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

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

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

// {

// vx_size tensor_dims;

// vx_size tensor_sizesAPP_MAX_TENSOR_DIMS;

// vxQueryTensor(output_tensorszh_idx, VX_TENSOR_NUMBER_OF_DIMS, &tensor_dims, sizeof(vx_size));

// vxQueryTensor(output_tensorszh_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.outWidthzh_idx, obj->ioBufDesc.outHeightzh_idx, obj->ioBufDesc.outNumChannelszh_idx);

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

// zh_idx, tensor_dims, tensor_sizes0, tensor_sizes1, tensor_sizes2, tensor_sizes3);

// }

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

// return;

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

vx_map_id map_id_output_arrAPP_MAX_TENSOR_DIMS = {0};

int output_mappedAPP_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.scaledst_idx = obj->out_args.scalezh_idx;

obj->yolov5params.outWidthdst_idx = obj->ioBufDesc.outWidthzh_idx;

obj->yolov5params.outHeightdst_idx = obj->ioBufDesc.outHeightzh_idx;

/* 输入尺寸始终取输入张量0的实际尺寸,避免读取到未定义值 */

obj->yolov5params.inWidthdst_idx = obj->ioBufDesc.inWidth0;

obj->yolov5params.inHeightdst_idx = obj->ioBufDesc.inHeight0;

obj->yolov5params.outNumChannelsdst_idx = obj->ioBufDesc.outNumChannelszh_idx;

obj->yolov5params.outChannelPitchdst_idx = obj->ioBufDesc.outChannelPitchzh_idx;

obj->yolov5params.outPadLdst_idx = obj->ioBufDesc.outPadLzh_idx;

obj->yolov5params.outPadTdst_idx = obj->ioBufDesc.outPadTzh_idx;

obj->yolov5params.outPadRdst_idx = obj->ioBufDesc.outPadRzh_idx;

obj->yolov5params.outPadBdst_idx = obj->ioBufDesc.outPadBzh_idx;

obj->yolov5params.outDataTypeVXdst_idx = (int)getTensorDataType(obj->ioBufDesc.outElementTypezh_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.outDataTypeVXdst_idx,

obj->yolov5params.scaledst_idx,

obj->yolov5params.outWidthdst_idx,

obj->yolov5params.outHeightdst_idx,

obj->yolov5params.outNumChannelsdst_idx,

obj->yolov5params.outChannelPitchdst_idx);

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

zh_idx, dst_idx,

obj->ioBufDesc.outElementTypezh_idx,

vxTypeToStr((vx_enum)obj->yolov5params.outDataTypeVXdst_idx));

void *output_buffer;

vx_map_id map_id_output;

vx_size output_stridesAPP_MAX_TENSOR_DIMS;

vx_size output_startAPP_MAX_TENSOR_DIMS;

output_start0 = output_start1 = output_start2 = output_start3 = 0;

output_sizes0 = ioBufDesc->outWidthzh_idx + ioBufDesc->outPadLzh_idx + ioBufDesc->outPadRzh_idx;

output_sizes1 = ioBufDesc->outHeightzh_idx + ioBufDesc->outPadTzh_idx + ioBufDesc->outPadBzh_idx;

output_sizes2 = ioBufDesc->outNumChannelszh_idx;

vx_size out_elem_size = vxTypeSize((vx_enum)obj->yolov5params.outDataTypeVXdst_idx);

output_strides0 = out_elem_size;

output_strides1 = output_sizes0 * output_strides0;

output_strides2 = output_sizes1 * output_strides1;

vx_size tensor_dims;

vxQueryTensor(output_tensorszh_idx, VX_TENSOR_NUMBER_OF_DIMS, &tensor_dims, sizeof(vx_size));

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

tivxMapTensorPatch(output_tensorszh_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_tensorszh_idx);

if(VX_SUCCESS == status)

{

obj->yolov5params.output_tensorsdst_idx = output_buffer;

map_id_output_arrdst_idx = map_id_output;

output_mappeddst_idx = 1;

}

}

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

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

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

{

if(output_mappeddst_idx)

{

tivxUnmapTensorPatch(output_tensorsdst_idx + 1, map_id_output_arrdst_idx);

}

}

cur_time = tivxPlatformGetTimeInUsecs() - cur_time;

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

int num = obj->detections.num_bbox;

ttevxYoloV5BBox num0 = obj->detections.buffer0;

ttevxYoloV5BBox num1 = obj->detections.buffer1;

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

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

vx_char new_name256;

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.bufferi;

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_processidx;

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_sizes0 = ioBufDesc->outWidthid + obj->ioBufDesc.outPadLid + obj->ioBufDesc.outPadRid;

output_sizes1 = ioBufDesc->outHeightid + obj->ioBufDesc.outPadTid + obj->ioBufDesc.outPadBid;

output_sizes2 = 1;//ioBufDesc->outNumChannelsid;

input_sizes0 = ioBufDesc->inWidth0 + obj->ioBufDesc.inPadL0 + obj->ioBufDesc.inPadR0;

input_sizes1 = ioBufDesc->inHeight0 + obj->ioBufDesc.inPadT0 + obj->ioBufDesc.inPadB0;

input_sizes2 = ioBufDesc->inNumChannels0;

width = ioBufDesc->outWidthid;

height = ioBufDesc->outHeightid;

outPadL = obj->ioBufDesc.outPadLid;

outPadT = obj->ioBufDesc.outPadTid;

inPadL = obj->ioBufDesc.inPadL0;

inPadT = obj->ioBufDesc.inPadT0;

status = vxGetStatus((vx_reference)output_tensorsid);

if(VX_SUCCESS == status)

{

void *output_buffer, *input_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_stridesAPP_MAX_TENSOR_DIMS, input_stridesAPP_MAX_TENSOR_DIMS;

vx_size output_startAPP_MAX_TENSOR_DIMS, input_startAPP_MAX_TENSOR_DIMS;

output_start0 = output_start1 = output_start2 = output_start3 = 0;

input_start0 = input_start1 = input_start2 = input_start3 = 0;

output_strides0 = 1;

output_strides1 = output_sizes0;

output_strides2 = output_sizes1 * output_strides1;

input_strides0 = 1;

input_strides1 = input_sizes0;

input_strides2 = input_sizes1 * input_strides1;

tivxMapTensorPatch(output_tensorsid, 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

tivxMapTensorPatch(input_tensors0, 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 = pOutoutput_sizes\[0*(outPadT + i) + outPadL + j];

// if(seg_type>15)

// {

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

// }

uint8_t img_value_R = pIn0 \* input_strides\[2 + input_strides1*(inPadT + i) + inPadL + j];

uint8_t img_value_G = pIn1 \* input_strides\[2 + input_strides1*(inPadT + i) + inPadL + j];

uint8_t img_value_B = pIn2 \* input_strides\[2 + input_strides1*(inPadT + i) + inPadL + j];

int32_t color_chosen = seg_type < 14 ? seg_type : 13;

color_maskwidth \* 3 \* i + j \* 3 + 0 = colorcolor_chosen0;

color_maskwidth \* 3 \* i + j \* 3 + 1 = colorcolor_chosen1;

color_maskwidth \* 3 \* i + j \* 3 + 2 = colorcolor_chosen2;

gray_maskwidth \* 3 \* i + j \* 3 + 0 = seg_type;

gray_maskwidth \* 3 \* i + j \* 3 + 1 = seg_type;

gray_maskwidth \* 3 \* i + j \* 3 + 2 = seg_type;

if(seg_type > 0){

image_maskwidth \* 3 \* i + j \* 3 + 0 = img_value_R/2 + colorcolor_chosen0/2;

image_maskwidth \* 3 \* i + j \* 3 + 1 = img_value_G/2 + colorcolor_chosen1/2;

image_maskwidth \* 3 \* i + j \* 3 + 2 = img_value_B/2 + colorcolor_chosen2/2;

}else{

image_maskwidth \* 3 \* i + j \* 3 + 0 = img_value_R;

image_maskwidth \* 3 \* i + j \* 3 + 1 = img_value_G;

image_maskwidth \* 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_tensorsid, map_id_output);

tivxUnmapTensorPatch(input_tensors0, 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_sizesAPP_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_fileAPP_MAX_FILE_PATH;

char file_name_tempAPP_MAX_FILE_PATH;

char file_name_tensorAPP_MAX_FILE_PATH;

// char file_name_cmaskAPP_MAX_FILE_PATH;

// char file_name_imaskAPP_MAX_FILE_PATH;

strcpy(file_name_temp, fileName);

file_name_tempstrlen(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_processidx;

// 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_sizes0 = ioBufDesc->outWidthid + obj->ioBufDesc.outPadLid + obj->ioBufDesc.outPadRid;

output_sizes1 = ioBufDesc->outHeightid + obj->ioBufDesc.outPadTid + obj->ioBufDesc.outPadBid;

output_sizes2 = 1;//ioBufDesc->outNumChannelsid;

// input_sizes0 = ioBufDesc->inWidth0 + obj->ioBufDesc.inPadL0 + obj->ioBufDesc.inPadR0;

// input_sizes1 = ioBufDesc->inHeight0 + obj->ioBufDesc.inPadT0 + obj->ioBufDesc.inPadB0;

// input_sizes2 = ioBufDesc->inNumChannels0;

width = ioBufDesc->outWidthid;

height = ioBufDesc->outHeightid;

outPadL = obj->ioBufDesc.outPadLid;

outPadT = obj->ioBufDesc.outPadTid;

// inPadL = obj->ioBufDesc.inPadL0;

// inPadT = obj->ioBufDesc.inPadT0;

status = vxGetStatus((vx_reference)output_tensorsid);

if(VX_SUCCESS == status)

{

void *output_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_stridesAPP_MAX_TENSOR_DIMS;

vx_size output_startAPP_MAX_TENSOR_DIMS;

output_start0 = output_start1 = output_start2 = output_start3 = 0;

// input_start0 = input_start1 = input_start2 = input_start3 = 0;

output_strides0 = 1;

output_strides1 = output_sizes0;

output_strides2 = output_sizes1 * output_strides1;

// input_strides0 = 1;

// input_strides1 = input_sizes0;

// input_strides2 = input_sizes1 * input_strides1;

vx_char new_name256;

// 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_tensorsid, 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// tivxMapTensorPatch(input_tensors0, 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->outNumChannelsid; c++){

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

uint8_t *pOut_1 = pOut + c * output_sizes0 * output_sizes1 + output_sizes0*(outPadT + i) + outPadL;

uint8_t zh = pOutc \* output_sizes\[0 * output_sizes1 + output_sizes0*(outPadT + i) + outPadL];

fwrite(pOut_1, 1, ioBufDesc->outWidthid, fp);

}

}

fclose(fp);

}

tivxUnmapTensorPatch(output_tensorsid, map_id_output);

// tivxUnmapTensorPatch(input_tensors0, map_id_input);

}

}

}

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

{

uint8_t color143={{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_sizesAPP_MAX_TENSOR_DIMS, input_sizesAPP_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_fileAPP_MAX_FILE_PATH;

char file_name_tempAPP_MAX_FILE_PATH;

char file_name_gmaskAPP_MAX_FILE_PATH;

char file_name_cmaskAPP_MAX_FILE_PATH;

char file_name_imaskAPP_MAX_FILE_PATH;

strcpy(file_name_temp, fileName);

file_name_tempstrlen(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->scalei = obj->ioBufDesc.outTensorScalei;

}

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->anchorsijk = ANCHORSijk;

}

}

}

}

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

// {

// output_sizes0 = ioBufDesc->outWidthhead_idx + obj->ioBufDesc.outPadLhead_idx + obj->ioBufDesc.outPadRhead_idx;

// output_sizes1 = ioBufDesc->outHeighthead_idx + obj->ioBufDesc.outPadThead_idx + obj->ioBufDesc.outPadBhead_idx;

// output_sizes2 = 1;//ioBufDesc->outNumChannelsid;

// input_sizes0 = ioBufDesc->inWidth0 + obj->ioBufDesc.inPadL0 + obj->ioBufDesc.inPadR0;

// input_sizes1 = ioBufDesc->inHeight0 + obj->ioBufDesc.inPadT0 + obj->ioBufDesc.inPadB0;

// input_sizes2 = ioBufDesc->inNumChannels0;

// width = ioBufDesc->outWidthhead_idx;

// height = ioBufDesc->outHeighthead_idx;

// outPadL = obj->ioBufDesc.outPadLhead_idx;

// outPadT = obj->ioBufDesc.outPadThead_idx;

// inPadL = obj->ioBufDesc.inPadL0;

// inPadT = obj->ioBufDesc.inPadT0;

// //获取内存块

// void *output_buffer, *input_buffer;

// vx_map_id map_id_output, map_id_input;

// vx_size output_stridesAPP_MAX_TENSOR_DIMS, input_stridesAPP_MAX_TENSOR_DIMS;

// vx_size output_startAPP_MAX_TENSOR_DIMS, input_startAPP_MAX_TENSOR_DIMS;

// output_start0 = output_start1 = output_start2 = output_start3 = 0;

// input_start0 = input_start1 = input_start2 = input_start3 = 0;

// output_strides0 = 1;

// output_strides1 = output_sizes0;

// output_strides2 = output_sizes1 * output_strides1;

// input_strides0 = 1;

// input_strides1 = input_sizes0;

// input_strides2 = input_sizes1 * input_strides1;

// tivxMapTensorPatch(output_tensorshead_idx, 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// tivxMapTensorPatch(input_tensors0, 3, input_start, input_sizes, &map_id_input, input_strides, &input_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// //

// status = vxGetStatus((vx_reference)output_tensorshead_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_sizes0 * outPadT + outPadL);

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

// for (h_idx = 0; h_idx < ioBufDesc->outHeighthead_idx; ++h_idx) {

// for (w_idx = 0; w_idx < ioBufDesc->outWidthhead_idx; ++w_idx) {

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

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

// int32_t obj_hw_idx = h_idx * output_sizes0 + w_idx;

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

// int32_t obj_conf_idx = (anchor_idx * yolov5_class_stride + 4) * ioBufDesc->outChannelPitchhead_idx + obj_hw_idx;

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

// float conf = (float)raw_dataobj_conf_idx / out_args->scalehead_idx;

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

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

// int32_t obj_x_idx = (anchor_idx * yolov5_class_stride + 0) * ioBufDesc->outChannelPitchhead_idx + obj_hw_idx;

// int32_t obj_y_idx = (anchor_idx * yolov5_class_stride + 1) * ioBufDesc->outChannelPitchhead_idx + obj_hw_idx;

// int32_t obj_w_idx = (anchor_idx * yolov5_class_stride + 2) * ioBufDesc->outChannelPitchhead_idx + obj_hw_idx;

// int32_t obj_h_idx = (anchor_idx * yolov5_class_stride + 3) * ioBufDesc->outChannelPitchhead_idx + obj_hw_idx;

// float x = (float)raw_dataobj_x_idx / out_args->scalehead_idx;

// x = (x * 2.0 - 0.5 + w_idx) * (float)(ioBufDesc->inWidth0) / (float)(ioBufDesc->outWidthhead_idx);

// float y = (float)raw_dataobj_y_idx / out_args->scalehead_idx;

// y = (y * 2.0 - 0.5 + h_idx) * (float)(ioBufDesc->inHeight0) / (float)(ioBufDesc->outHeighthead_idx);

// float w = (float)raw_dataobj_w_idx / out_args->scalehead_idx;

// w = (w * 2.0) * (w * 2.0) * yolov5params->anchorshead_idxanchor_idx0;

// float h = (float)raw_dataobj_h_idx / out_args->scalehead_idx;

// h = (h * 2.0) * (h * 2.0) * yolov5params->anchorshead_idxanchor_idx1;

// 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->outChannelPitchhead_idx + obj_hw_idx;

// p = (float)raw_dataobj_cls_idx / out_args->scalehead_idx;

// if (p > cls_prob) {

// cls_prob = p;

// cls = max_prob_idx;

// }

// }

// }

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

// bbox_obj_arrbbox_num.confidence = conf * cls_prob;

// if (bbox_obj_arrbbox_num.confidence >= yolov5params->conf_thresh) {

// bbox_obj_arrbbox_num.x1 = (int)(x - w / 2 + 0.5);

// bbox_obj_arrbbox_num.y1 = (int)(y - h / 2 + 0.5);

// bbox_obj_arrbbox_num.x2 = (int)(x + w / 2 + 0.5);

// bbox_obj_arrbbox_num.y2 = (int)(y + h / 2 + 0.5);

// bbox_obj_arrbbox_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_sizes0 = ioBufDesc->outWidthid + obj->ioBufDesc.outPadLid + obj->ioBufDesc.outPadRid;

output_sizes1 = ioBufDesc->outHeightid + obj->ioBufDesc.outPadTid + obj->ioBufDesc.outPadBid;

output_sizes2 = 1;//ioBufDesc->outNumChannelsid;

input_sizes0 = ioBufDesc->inWidth0 + obj->ioBufDesc.inPadL0 + obj->ioBufDesc.inPadR0;

input_sizes1 = ioBufDesc->inHeight0 + obj->ioBufDesc.inPadT0 + obj->ioBufDesc.inPadB0;

input_sizes2 = ioBufDesc->inNumChannels0;

width = ioBufDesc->outWidthid;

height = ioBufDesc->outHeightid;

outPadL = obj->ioBufDesc.outPadLid;

outPadT = obj->ioBufDesc.outPadTid;

inPadL = obj->ioBufDesc.inPadL0;

inPadT = obj->ioBufDesc.inPadT0;

status = vxGetStatus((vx_reference)output_tensorsid);

if(VX_SUCCESS == status)

{

void *output_buffer, *input_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_stridesAPP_MAX_TENSOR_DIMS, input_stridesAPP_MAX_TENSOR_DIMS;

vx_size output_startAPP_MAX_TENSOR_DIMS, input_startAPP_MAX_TENSOR_DIMS;

output_start0 = output_start1 = output_start2 = output_start3 = 0;

input_start0 = input_start1 = input_start2 = input_start3 = 0;

output_strides0 = 1;

output_strides1 = output_sizes0;

output_strides2 = output_sizes1 * output_strides1;

input_strides0 = 1;

input_strides1 = input_sizes0;

input_strides2 = input_sizes1 * input_strides1;

tivxMapTensorPatch(output_tensorsid, 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

tivxMapTensorPatch(input_tensors0, 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)pOutoutput_sizes\[0*(outPadT + i) + outPadL + j]);

// if(seg_type>15)

// {

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

// }

uint8_t img_value_R = pIn0 \* input_strides\[2 + input_strides1*(inPadT + i) + inPadL + j];

uint8_t img_value_G = pIn1 \* input_strides\[2 + input_strides1*(inPadT + i) + inPadL + j];

uint8_t img_value_B = pIn2 \* input_strides\[2 + input_strides1*(inPadT + i) + inPadL + j];

int32_t color_chosen = seg_type < 14 ? seg_type : 13;

color_maskwidth \* 3 \* i + j \* 3 + 0 = colorcolor_chosen0;

color_maskwidth \* 3 \* i + j \* 3 + 1 = colorcolor_chosen1;

color_maskwidth \* 3 \* i + j \* 3 + 2 = colorcolor_chosen2;

gray_maskwidth \* 3 \* i + j \* 3 + 0 = seg_type;

gray_maskwidth \* 3 \* i + j \* 3 + 1 = seg_type;

gray_maskwidth \* 3 \* i + j \* 3 + 2 = seg_type;

if(seg_type > 0){

image_maskwidth \* 3 \* i + j \* 3 + 0 = img_value_R/2 + colorcolor_chosen0/2;

image_maskwidth \* 3 \* i + j \* 3 + 1 = img_value_G/2 + colorcolor_chosen1/2;

image_maskwidth \* 3 \* i + j \* 3 + 2 = img_value_B/2 + colorcolor_chosen2/2;

}else{

image_maskwidth \* 3 \* i + j \* 3 + 0 = img_value_R;

image_maskwidth \* 3 \* i + j \* 3 + 1 = img_value_G;

image_maskwidth \* 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_tensorsid, map_id_output);

tivxUnmapTensorPatch(input_tensors0, 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_sizesAPP_MAX_TENSOR_DIMS;

sTIDL_IOBufDesc_t *ioBufDesc;

ioBufDesc = &obj->ioBufDesc;

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

char output_fileAPP_MAX_FILE_PATH;

char file_name_tempAPP_MAX_FILE_PATH;

char file_name_tensorAPP_MAX_FILE_PATH;

// char file_name_cmaskAPP_MAX_FILE_PATH;

// char file_name_imaskAPP_MAX_FILE_PATH;

strcpy(file_name_temp, fileName);

file_name_tempstrlen(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_sizes0 = ioBufDesc->outWidthid + obj->ioBufDesc.outPadLid + obj->ioBufDesc.outPadRid;

output_sizes1 = ioBufDesc->outHeightid + obj->ioBufDesc.outPadTid + obj->ioBufDesc.outPadBid;

output_sizes2 = 1;//ioBufDesc->outNumChannelsid;

// input_sizes0 = ioBufDesc->inWidth0 + obj->ioBufDesc.inPadL0 + obj->ioBufDesc.inPadR0;

// input_sizes1 = ioBufDesc->inHeight0 + obj->ioBufDesc.inPadT0 + obj->ioBufDesc.inPadB0;

// input_sizes2 = ioBufDesc->inNumChannels0;

width = ioBufDesc->outWidthid;

height = ioBufDesc->outHeightid;

outPadL = obj->ioBufDesc.outPadLid;

outPadT = obj->ioBufDesc.outPadTid;

// inPadL = obj->ioBufDesc.inPadL0;

// inPadT = obj->ioBufDesc.inPadT0;

status = vxGetStatus((vx_reference)output_tensorsid);

if(VX_SUCCESS == status)

{

void *output_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_stridesAPP_MAX_TENSOR_DIMS;

vx_size output_startAPP_MAX_TENSOR_DIMS;

output_start0 = output_start1 = output_start2 = output_start3 = 0;

// input_start0 = input_start1 = input_start2 = input_start3 = 0;

output_strides0 = 1;

output_strides1 = output_sizes0;

output_strides2 = output_sizes1 * output_strides1;

// input_strides0 = 1;

// input_strides1 = input_sizes0;

// input_strides2 = input_sizes1 * input_strides1;

vx_char new_name256;

// 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_tensorsid, 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// tivxMapTensorPatch(input_tensors0, 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->outNumChannelsid; c++){

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

uint16_t *pOut_1 = pOut + c * output_sizes0 * output_sizes1 + output_sizes0*(outPadT + i) + outPadL;

uint16_t zh = pOutc \* output_sizes\[0 * output_sizes1 + output_sizes0*(outPadT + i) + outPadL];

fwrite(pOut_1, 2, ioBufDesc->outWidthid, fp);

}

}

fclose(fp);

}

tivxUnmapTensorPatch(output_tensorsid, map_id_output);

// tivxUnmapTensorPatch(input_tensors0, 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_sizesAPP_MAX_TENSOR_DIMS;

sTIDL_IOBufDesc_t *ioBufDesc;

ioBufDesc = &obj->ioBufDesc;

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

char output_fileAPP_MAX_FILE_PATH;

char file_name_tempAPP_MAX_FILE_PATH;

char file_name_tensorAPP_MAX_FILE_PATH;

// char file_name_cmaskAPP_MAX_FILE_PATH;

// char file_name_imaskAPP_MAX_FILE_PATH;

strcpy(file_name_temp, fileName);

file_name_tempstrlen(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_sizes0 = ioBufDesc->outWidthid + obj->ioBufDesc.outPadLid + obj->ioBufDesc.outPadRid;

output_sizes1 = ioBufDesc->outHeightid + obj->ioBufDesc.outPadTid + obj->ioBufDesc.outPadBid;

output_sizes2 = 1;//ioBufDesc->outNumChannelsid;

// input_sizes0 = ioBufDesc->inWidth0 + obj->ioBufDesc.inPadL0 + obj->ioBufDesc.inPadR0;

// input_sizes1 = ioBufDesc->inHeight0 + obj->ioBufDesc.inPadT0 + obj->ioBufDesc.inPadB0;

// input_sizes2 = ioBufDesc->inNumChannels0;

width = ioBufDesc->outWidthid;

height = ioBufDesc->outHeightid;

outPadL = obj->ioBufDesc.outPadLid;

outPadT = obj->ioBufDesc.outPadTid;

// inPadL = obj->ioBufDesc.inPadL0;

// inPadT = obj->ioBufDesc.inPadT0;

status = vxGetStatus((vx_reference)output_tensorsid);

if(VX_SUCCESS == status)

{

void *output_buffer;

vx_map_id map_id_output, map_id_input;

vx_size output_stridesAPP_MAX_TENSOR_DIMS;

vx_size output_startAPP_MAX_TENSOR_DIMS;

output_start0 = output_start1 = output_start2 = output_start3 = 0;

// input_start0 = input_start1 = input_start2 = input_start3 = 0;

output_strides0 = 1;

output_strides1 = output_sizes0;

output_strides2 = output_sizes1 * output_strides1;

// input_strides0 = 1;

// input_strides1 = input_sizes0;

// input_strides2 = input_sizes1 * input_strides1;

vx_char new_name256;

// 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_tensorsid, 3, output_start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

// tivxMapTensorPatch(input_tensors0, 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->outNumChannelsid; c++){

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

vx_float32 *pOut_1 = pOut + c * output_sizes0 * output_sizes1 + output_sizes0*(outPadT + i) + outPadL;

vx_float32 zh = pOutc \* output_sizes\[0 * output_sizes1 + output_sizes0*(outPadT + i) + outPadL];

fwrite(pOut_1, 4, ioBufDesc->outWidthid, fp);

}

}

fclose(fp);

}

tivxUnmapTensorPatch(output_tensorsid, map_id_output);

// tivxUnmapTensorPatch(input_tensors0, 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_nameAPP_MAX_FILE_PATH;

vx_char output_file_nameAPP_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_name0);

}

appPerfPointEnd(&obj->fileio_perf);

APP_PRINTF("Done!\n");

#ifdef APP_WRITE_PRE_PROC_OUTPUT

vx_char pre_proc_file_nameAPP_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_tensors0);

#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_name0);

// 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_expected0)/sizeof(checksums_expected00))-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_tensors0,

// getTensorDataType(obj->ioBufDesc.outElementType0),

// obj->ioBufDesc.outWidth0, obj->ioBufDesc.outPadL0,

// obj->ioBufDesc.outPadR0, obj->ioBufDesc.outHeight0,

// obj->ioBufDesc.outPadT0, obj->ioBufDesc.outPadB0,

// obj->ioBufDesc.outNumChannels0, checksums_expectedobj-\>test_case\*2counter,

// &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_expected1+(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 curFileNameAPP_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_expected0)/sizeof(checksums_expected00)) + 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))

{

curFileNamestrlen(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_sizesAPP_MAX_TENSOR_DIMS;

uint32_t id;

sTIDL_IOBufDesc_t *ioBufDesc = &obj->ioBufDesc;

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

input_sizes0 = ioBufDesc->inWidthid + ioBufDesc->inPadLid + ioBufDesc->inPadRid;

input_sizes1 = ioBufDesc->inHeightid + ioBufDesc->inPadTid + ioBufDesc->inPadBid;

input_sizes2 = ioBufDesc->inNumChannelsid;

vx_size data_type = getTensorDataType(ioBufDesc->inElementTypeid);

if(data_type != VX_TYPE_INVALID)

input_tensorsid = 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_sizesAPP_MAX_TENSOR_DIMS;

uint32_t id;

sTIDL_IOBufDesc_t *ioBufDesc = &obj->ioBufDesc;

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

output_sizes0 = ioBufDesc->outWidthid + ioBufDesc->outPadLid + ioBufDesc->outPadRid;

output_sizes1 = ioBufDesc->outHeightid + ioBufDesc->outPadTid + ioBufDesc->outPadBid;

output_sizes2 = ioBufDesc->outNumChannelsid;

vx_size data_type = getTensorDataType(ioBufDesc->outElementTypeid);

if(data_type != VX_TYPE_INVALID)

{

output_tensorsid = 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 a4;

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;

a0 = (1.0f - dx) * (1.0f - dy);

a1 = (1.0f - dx) * (dy);

a2 = (dx)* (1.0f - dy);

a3 = (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)(a0*tl + a2*tr + a1*bl + a3*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 startAPP_MAX_TENSOR_DIMS;

vx_size input_stridesAPP_MAX_TENSOR_DIMS;

vx_size input_sizesAPP_MAX_TENSOR_DIMS;

sTIDL_IOBufDesc_t *ioBufDesc = &obj->ioBufDesc;

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

{

vx_size data_type = getTensorDataType(ioBufDesc->inElementTypeid);

input_sizes0 = ioBufDesc->inWidthid + ioBufDesc->inPadLid + ioBufDesc->inPadRid;

input_sizes1 = ioBufDesc->inHeightid + ioBufDesc->inPadTid + ioBufDesc->inPadBid;

input_sizes2 = ioBufDesc->inNumChannelsid;

capacity = input_sizes0 * input_sizes1 * input_sizes2;

start0 = start1 = start2 = 0;

input_strides0 = sizeof(vx_int8);

if((data_type == VX_TYPE_INT8) ||

(data_type == VX_TYPE_UINT8))

{

input_strides0 = sizeof(vx_int8);

}

else if((data_type == VX_TYPE_INT16) ||

(data_type == VX_TYPE_UINT16))

{

input_strides0 = sizeof(vx_int16);

}

input_strides1 = input_sizes0 * input_strides0;

input_strides2 = input_sizes1 * input_strides1;

APP_PRINTF(" input_sizes0 = %d, dim = %d padL = %d padR = %d\n", (uint32_t)input_sizes0, ioBufDesc->inWidthid, ioBufDesc->inPadLid, ioBufDesc->inPadRid);

APP_PRINTF(" input_sizes1 = %d, dim = %d padT = %d padB = %d\n", (uint32_t)input_sizes1, ioBufDesc->inHeightid, ioBufDesc->inPadTid, ioBufDesc->inPadBid);

APP_PRINTF(" input_sizes2 = %d, dim = %d \n", (uint32_t)input_sizes2, ioBufDesc->inNumChannelsid);

if(status == VX_SUCCESS)

{

status = tivxMapTensorPatch(input_tensorsid, 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->inWidthid, ioBufDesc->inHeightid, ioBufDesc->inWidthid);

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->inDataFormatid == 1) /* RGB */

{

start_offset = (0 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

pR = (vx_uint8 *)input_buffer + start_offset;

start_offset = (1 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

pG = (vx_uint8 *)input_buffer + start_offset;

start_offset = (2 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

pB = (vx_uint8 *)input_buffer + start_offset;

}

else if(ioBufDesc->inDataFormatid == 0) /* BGR */

{

start_offset = (0 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

pB = (vx_uint8 *)input_buffer + start_offset;

start_offset = (1 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

pG = (vx_uint8 *)input_buffer + start_offset;

start_offset = (2 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

pR = (vx_uint8 *)input_buffer + start_offset;

}

//chOffset = 256*256;

chOffset = ioBufDesc->inWidthid*ioBufDesc->inHeightid;

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

{

/* Write image in network required format */

for(i = 0; i < ioBufDesc->inHeightid; i++)

{

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

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

uint32_t offset = i * ioBufDesc->inWidthid;

for(j = 0; j < ioBufDesc->inWidthid; j++)

{

pRj = pOutPlanes(0 \* chOffset) + offset + j;

pGj = pOutPlanes(1 \* chOffset) + offset + j;

pBj = pOutPlanes(2 \* chOffset) + offset + j;

}

pR += input_sizes0;

pG += input_sizes0;

pB += input_sizes0;

}

}

}

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->inDataFormatid == 1) /* RGB */

{

start_offset = (0 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

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

start_offset = (1 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

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

start_offset = (2 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

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

}

else if(ioBufDesc->inDataFormatid == 0) /* BGR */

{

start_offset = (0 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

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

start_offset = (1 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

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

start_offset = (2 * input_strides2) + (ioBufDesc->inPadTid * input_strides1) + (ioBufDesc->inPadLid * input_strides0);

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

}

chOffset = 256*256;

chOffset = ioBufDesc->inWidthid*ioBufDesc->inHeightid;

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

{

/* Write image in network required format */

for(i = 0; i < ioBufDesc->inHeightid; i++)

{

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

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

uint32_t offset = i * ioBufDesc->inWidthid;

for(j = 0; j < ioBufDesc->inWidthid; j++)

{

pRj = pOutPlanes(0 \* chOffset) + offset + j;

pGj = pOutPlanes(1 \* chOffset) + offset + j;

pBj = pOutPlanes(2 \* chOffset) + offset + j;

}

pR += input_sizes0;

pG += input_sizes0;

pB += input_sizes0;

}

}

}

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

}

tivxUnmapTensorPatch(input_tensorsid, 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_sizesAPP_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->outElementTypeid);

output_sizes0 = ioBufDesc->outWidthid + ioBufDesc->outPadLid + ioBufDesc->outPadRid;

output_sizes1 = ioBufDesc->outHeightid + ioBufDesc->outPadTid + ioBufDesc->outPadBid;

output_sizes2 = ioBufDesc->outNumChannelsid;

if(status == VX_SUCCESS)

{

status = vxGetStatus((vx_reference)output_tensorsid);

}

if (VX_SUCCESS == status)

{

void *output_buffer;

vx_map_id map_id_output;

vx_size output_stridesAPP_MAX_TENSOR_DIMS;

vx_size startAPP_MAX_TENSOR_DIMS;

start0 = start1 = start2 = start3 = 0;

output_strides0 = sizeof(vx_int8);

if((data_type == VX_TYPE_INT8) ||

(data_type == VX_TYPE_UINT8))

{

output_strides0 = sizeof(vx_int8);

}

else if((data_type == VX_TYPE_INT16) ||

(data_type == VX_TYPE_UINT16))

{

output_strides0 = sizeof(vx_int16);

}

else if(data_type == VX_TYPE_FLOAT32)

{

output_strides0 = sizeof(vx_float32);

}

output_strides1 = output_sizes0 * output_strides0;

output_strides2 = output_sizes1 * output_strides1;

status = tivxMapTensorPatch(output_tensorsid, 3, start, output_sizes, &map_id_output, output_strides, &output_buffer, VX_READ_ONLY, VX_MEMORY_TYPE_HOST);

if(status == VX_SUCCESS)

{

vx_uint32 classid5 = {0};

vx_uint32 label_offset;

label_offset = 0;

if(ioBufDesc->outWidthid == 1001)

{

label_offset = 0;

}

else if(ioBufDesc->outWidthid == 1000)

{

label_offset = 1;

}

APP_PRINTF("app_tidl: Finding top-5 ... \n");

if(data_type == VX_TYPE_FLOAT32)

{

float *pOut;

float score5;

pOut = (float *)output_buffer + (ioBufDesc->outPadTid * output_sizes0) + ioBufDesc->outPadLid;

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

{

scorei = FLT_MIN;

classidi = (vx_uint32)-1;

for(j = 0; j < ioBufDesc->outWidthid; j++)

{

if(pOutj > scorei)

{

scorei = pOutj;

classidi = j;

}

}

if(classidi < ioBufDesc->outWidthid )

{

pOutclassid\[i] = FLT_MIN;

}

else

{

classidi = 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_labelsclassid\[i + label_offset], classidi, scorei);

}

#endif

}

else if(data_type == VX_TYPE_INT16)

{

vx_int16 *pOut;

vx_int16 score5;

pOut = (vx_int16 *)output_buffer + (ioBufDesc->outPadTid * output_sizes0) + ioBufDesc->outPadLid;

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

{

scorei = INT16_MIN;

classidi = (vx_uint32)-1;

for(j = 0; j < ioBufDesc->outWidthid; j++)

{

if(pOutj > scorei)

{

scorei = pOutj;

classidi = j;

}

}

if(classidi < ioBufDesc->outWidthid )

{

pOutclassid\[i] = INT16_MIN;

}

else

{

classidi = 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_labelsclassid\[i + label_offset], classidi, scorei);

}

#endif

}

else if(data_type == VX_TYPE_INT8)

{

vx_int8 *pOut;

vx_int8 score5;

pOut = (vx_int8 *)output_buffer + (ioBufDesc->outPadTid * output_sizes0) + ioBufDesc->outPadLid;

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

{

scorei = INT8_MIN;

classidi = (vx_uint32)-1;

for(j = 0; j < ioBufDesc->outWidthid; j++)

{

if(pOutj > scorei)

{

scorei = pOutj;

classidi = j;

}

}

if(classidi < ioBufDesc->outWidthid )

{

pOutclassid\[i] = INT8_MIN;

}

else

{

classidi = 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_labelsclassid\[i + label_offset], classidi, scorei);

}

#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_labelsclassid\[i + label_offset], &sClassPrm);

}

}

tivxUnmapTensorPatch(output_tensorsid, 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->pDisplayBuf565i;

obj->pDisplayBuf888j + 0 = (RGB_565_val & 0x1F) << 3;

obj->pDisplayBuf888j + 1 = ((RGB_565_val >> 5) & 0x3F) << 2;

obj->pDisplayBuf888j + 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 startAPP_MAX_TENSOR_DIMS;

vx_size tensor_stridesAPP_MAX_TENSOR_DIMS;

vx_size tensor_sizesAPP_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));

start0 = start1 = start2 = 0;

tensor_strides0 = sizeof(vx_int8);

if((data_type == VX_TYPE_INT8) ||

(data_type == VX_TYPE_UINT8))

{

tensor_strides0 = sizeof(vx_int8);

}

else if((data_type == VX_TYPE_INT16) ||

(data_type == VX_TYPE_UINT16))

{

tensor_strides0 = sizeof(vx_int16);

}

else if((data_type == VX_TYPE_FLOAT32))

{

tensor_strides0 = sizeof(vx_float32);

}

tensor_strides1 = tensor_strides0 * tensor_strides0;

tensor_strides2 = tensor_strides1 * tensor_strides1;

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_nameAPP_MAX_FILE_PATH;

snprintf(new_name, APP_MAX_FILE_PATH, "%s_%dx%d.rgb", file_name, (uint32_t)tensor_sizes0, (uint32_t)tensor_sizes1);

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_strides2, fp);

fclose(fp);

tivxUnmapTensorPatch(output, map_id);

}

return(status);

}

#endif

相关推荐
2401_894915532 小时前
GEO 优化源码全解析:从搜索引擎到 AI 引擎的底层改写逻辑
java·服务器·前端·数据库·人工智能·分布式·搜索引擎
1000世界小札4 小时前
《大话数据结构》第9章精读:归并排序与快速排序完整 C++ 实现
数据结构·c++·算法
2601_956121976 小时前
背包基础篇(01、完全、分组、多重、混合)
c++·算法·动态规划
兴通物联科技7 小时前
SMT PCB 微小 DataMatrix 码扫不动问题分析 兴通 XT8601B 600 万像素工业读码器落地实践
大数据·人工智能·单片机·嵌入式硬件·算法·计算机视觉
Profile排查笔记8 小时前
指纹浏览器哪个好?从 Profile、代理、权限和自动化能力判断是否适合
前端·人工智能·后端·自动化
我是乌鸦的空间8 小时前
什么是网络安全中的电子数据取证与响应?
网络·网络安全
跨境旺仔小拳头8 小时前
如何使用Crawl4AI进行网页爬虫?从0搭建教程与代理配置指南
网络·人工智能·爬虫·chatgpt·aigc
沫儿笙8 小时前
焊接机器人氩弧焊省气装置
网络·机器人
lzhdim8 小时前
12、JavaScript常见的内存泄露问题 - JavaScript学习系列文章
开发语言·前端·javascript·学习·ecmascript