This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TDA4VM:如何使用 TIvxVpacMscScaleNode 进行裁剪

Guru**** 2539500 points
Other Parts Discussed in Thread: TDA4VM

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1185589/tda4vm-how-to-use-tivxvpacmscscalenode-for-cropping

器件型号:TDA4VM

您好、TI 专家!
我正在尝试使用 TIvxVpacMscScaleNode。
我想做一个简单的示例、以 NV12中的图像1920x1080为例、将器件裁剪为512x512。
我研究了示例 vision_apps/apps/dl_demos/app_tidl_AVP、并执行了从1920x1080扩展到512x512的项目。
但是、当我为裁剪做相同的事情时-它不起作用。
请告诉我如何找出根本原因。

两种情况的初始化节点:裁剪和使用系数

 static void scale_set_crop_params(tivx_vpac_msc_crop_params_t &params)
{
    params.crop_start_x = 0;
    params.crop_start_y = 0;
    params.crop_width = 512;
    params.crop_height = 512;
}


vx_status init_scaler(vx_context context, ScalerObj *scalerObj, vx_int32 bufq_depth)
{
    vx_status status = VX_SUCCESS;
    vx_int32 q;

    vx_image input     = vxCreateImage(context, scalerObj->input.width, scalerObj->input.height, VX_DF_IMAGE_NV12);
    vx_image output_1  = vxCreateImage(context, scalerObj->output_1.width, scalerObj->output_1.height, VX_DF_IMAGE_NV12);

    for(q = 0; q < bufq_depth; q++)
    {
        scalerObj->input.arr[q]     = vxCreateObjectArray(context, (vx_reference)input, 1);
        scalerObj->input_images[q]  = (vx_image)vxGetObjectArrayItem((vx_object_array)scalerObj->input.arr[q], 0);
    }
    scalerObj->output_1.arr[0]  = vxCreateObjectArray(context, (vx_reference)output_1, 1);

#if CROP
    tivx_vpac_msc_crop_params_t cropParams;
    scale_set_crop_params(cropParams);
    /* Set Coefficients */
    scalerObj->crop_params_obj = vxCreateUserDataObject(context,
                                                        "tivx_vpac_msc_crop_params_t",
                                                        sizeof(tivx_vpac_msc_crop_params_t),
                                                        NULL);

    vxCopyUserDataObject(scalerObj->crop_params_obj, 0,
                         sizeof(tivx_vpac_msc_crop_params_t),
                         &cropParams,
                         VX_WRITE_ONLY,
                         VX_MEMORY_TYPE_HOST);

#else
    tivx_vpac_msc_coefficients_t coeffs;
    scale_set_coeff(&coeffs, VX_INTERPOLATION_BILINEAR);

    /* Set Coefficients */
    scalerObj->coeff_obj = vxCreateUserDataObject(context,
                                                  "tivx_vpac_msc_coefficients_t",
                                                  sizeof(tivx_vpac_msc_coefficients_t),
                                                  NULL);

    vxCopyUserDataObject(scalerObj->coeff_obj, 0,
                         sizeof(tivx_vpac_msc_coefficients_t),
                         &coeffs,
                         VX_WRITE_ONLY,
                         VX_MEMORY_TYPE_HOST);
#endif

    vxReleaseImage(&input);
    vxReleaseImage(&output_1);
}

创建图和验证两种情况

vx_status create_graph_scaler(vx_context context, vx_graph graph, ScalerObj *scalerObj)
{
    vx_status status = VX_SUCCESS;

    vx_image input    = (vx_image)vxGetObjectArrayItem((vx_object_array)scalerObj->input.arr[0], 0);
    vx_image output_1 = (vx_image)vxGetObjectArrayItem((vx_object_array)scalerObj->output_1.arr[0], 0);

    scalerObj->node = tivxVpacMscScaleNode(graph, input, output_1, NULL, NULL, NULL, NULL);
    vxSetNodeTarget(scalerObj->node, VX_TARGET_STRING, TIVX_TARGET_VPAC_MSC1);
    vxSetReferenceName((vx_reference)scalerObj->node, "ScalerNode");

    vx_bool replicate[] = { vx_true_e, vx_true_e, vx_false_e, vx_false_e, vx_false_e, vx_false_e};
    vxReplicateNode(graph, scalerObj->node, replicate, 6);


    vxReleaseImage(&input);
    vxReleaseImage(&output_1);

    return status;
}

vx_status verify_graph(vx_graph *graph, ScalerObj *scalerObj)
{
    vx_status status = VX_SUCCESS;

    vx_reference refs[1];

    status = vxVerifyGraph(*graph);

    if(status == VX_SUCCESS)
    {
        status = tivxExportGraphToDot(*graph,".", "vx_app_tidl_avp");
    }

#if CROP
    refs[0] = (vx_reference)scalerObj->crop_params_obj;
#else
    refs[0] = (vx_reference)scalerObj->coeff_obj;
#endif

    if(status == VX_SUCCESS)
    {
#if CROP
        status = tivxNodeSendCommand(scalerObj->node, 0u, TIVX_VPAC_MSC_CMD_SET_CROP_PARAMS, refs, 1u);
#else
        status = tivxNodeSendCommand(scalerObj->node, 0u, TIVX_VPAC_MSC_CMD_SET_COEFF, refs, 1u);
#endif
        printf("App Send MSC Command Done!\n");
    }

    if(status != VX_SUCCESS)
    {
        printf("MSC: Node send command failed!\n");
    }

    /* wait a while for prints to flush */
    tivxTaskWaitMsecs(100);

    return status;
}

一项主要任务

void main_task(vx_context context)
{
    const std::string name_file = "xaa";
    const std::string name_file_output = "out_xaa";
    vx_status status = VX_SUCCESS;

    if(status == VX_SUCCESS)
    {
        tivxHwaLoadKernels(context);
        tivxImgProcLoadKernels(context);
        tivxTIDLLoadKernels(context);
    }

    ScalerObj scaler;
    scaler.input.width  = 1920;
    scaler.input.height = 1080;
    scaler.output_1.width = 512;
    scaler.output_1.height = 512;


    init_scaler(context, &scaler, 2);

    vx_graph graph = vxCreateGraph(context);

    status = vxGetStatus((vx_reference)graph);
    vxSetReferenceName((vx_reference)graph, "avp_graph");

    if(VX_SUCCESS == status)
    {
        printf("graph was created\n");
        status = create_graph_scaler(context, graph, &scaler);
        if (VX_SUCCESS == status)
        {
            printf("scaler was created\n");

            status = verify_graph(&graph, &scaler);
            if (VX_SUCCESS == status)
            {
                printf("graph was verified\n");
                status = readScalerInput(name_file.data(), scaler.input.arr[0], 0);
                if (VX_SUCCESS == status)
                {
                    status = vxProcessGraph(graph);
                    if (VX_SUCCESS == status)
                    {
                        printf("Graph is done!\n");
                        status = writeScalerOutput(name_file_output.data(), scaler.output_1.arr[0]);
                        if (VX_SUCCESS == status)
                        {
                            printf("file was written\n");
                        }
                    }
                }
            }
        }

    }

    printf("release Graph\n");
    vxReleaseGraph(&graph);

    deinit_scaler(&scaler, AVP_BUFFER_Q_DEPTH);
    delete_scaler(&scaler);

    tivxTIDLUnLoadKernels(context);
    tivxImgProcUnLoadKernels(context);
    tivxHwaUnLoadKernels(context);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    一个可能的原因可能是您仅为通道0设置此参数、因此如果您 为多个通道使用多标量、 则仅对通道0执行裁剪。  

    status = tivxNodeSendCommand (scalerObj->node、0U、TIVX_VPAC_MSC_CMD_SET_CROP_PARAMS、REFs、1U);

    您能否尝试将上述内容更改为 TIVX_CONTINL_CMD_SEND_TO_All_Replicated 节点、以便将其设置为多通道节点中的所有复制节点?  

    此致、

    Brijesh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Brijesh Jadav

    感谢您的回复!

    我是怎么做的、但没有什么变化。 是否可以帮助解决此问题,我在尝试释放节点时收到该消息?

    362668.634080 s:  VX_ZONE_ERROR:[ownReleaseReferenceInt:307] Invalid reference
    

    void deinit_scaler(ScalerObj *scalerObj, vx_int32 bufq_depth)
    {
        vx_int32 q;
        printf("deinit scaler\n");
        for(q = 0; q < bufq_depth; q++)
        {
            vxReleaseObjectArray(&scalerObj->input.arr[q]);
            vxReleaseImage(&scalerObj->input_images[q]);
        }
    
        vxReleaseObjectArray(&scalerObj->output_1.arr[0]);
    
        vxReleaseUserDataObject(&scalerObj->crop_params_obj);
    }
    
    void delete_scaler(ScalerObj *scalerObj)
    {
        printf("delete scaler\n");
        if(scalerObj->node != NULL)
        {
            printf("not null\n");
            vxReleaseNode(&scalerObj->node); //this place
        }
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    根据上述误差、标量节点对象本身不正确。 它看起来甚至不是正确创建的。  

    您可以共享完整代码进行审核吗? 您还看到 /获得来自标量的正确输出吗?

    此致、

    Brijesh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Brijesh Jadav

    我认为我的裁剪问题是"浮动错误"。 今天、我能够使用相同的代码裁剪图像、但在重新引导 TDA4VM 后 、裁剪停止工作。

    我用"无效引用"解决了这个问题。  我在释放一个更分频器节点之前释放了该图。

    main.cpp

    #include <iostream>
    #include <VX/vx.h>
    #include <VX/vx_api.h>
    #include <TI/tivx_img_proc_kernels.h>
    
    #include <app_init.h>
    
    #include "scaler_module.h"
    #include "image_wrapper.h"
    
    #define AVP_BUFFER_Q_DEPTH   (2)
    
    
    void crop_image(vx_context context)
    {
        const std::string name_file = "xaa";
        const std::string name_file_output = "xaa_crop";
        vx_status status = VX_SUCCESS;
    
        tivxHwaLoadKernels(context);
        tivxImgProcLoadKernels(context);
        tivxTIDLLoadKernels(context);
    
        ScalerObj scaler;
        scaler.input.width  = 1920;
        scaler.input.height = 1080;
        scaler.output_1.width = 512;
        scaler.output_1.height = 512;
    
        init_scaler(context, &scaler, AVP_BUFFER_Q_DEPTH);
    
        vx_graph graph = vxCreateGraph(context);
    
        status = vxGetStatus((vx_reference)graph);
        vxSetReferenceName((vx_reference)graph, "avp_graph");
    
        if(VX_SUCCESS == status)
        {
            printf("graph was created\n");
            status = create_graph_scaler(context, graph, &scaler);
            if (VX_SUCCESS == status)
            {
                printf("scaler was created\n");
    
                status = verify_graph(&graph, &scaler);
                if (VX_SUCCESS == status)
                {
                    printf("graph was verified\n");
                    status = readScalerInput(name_file.data(), scaler.input.arr[0], 0);
                    if (VX_SUCCESS == status)
                    {
                        status = vxProcessGraph(graph);
                        if (VX_SUCCESS == status)
                        {
                            printf("Graph is done!\n");
                            status = writeScalerOutput(name_file_output.data(), scaler.output_1.arr[0]);
                            if (VX_SUCCESS == status)
                            {
                                printf("file was written\n");
                            }
                        }
                    }
                }
            }
    
        }
    
    
        deinit_scaler(&scaler, AVP_BUFFER_Q_DEPTH);
        delete_scaler(&scaler);
    
        printf("release Graph\n");
        vxReleaseGraph(&graph);
    
        tivxTIDLUnLoadKernels(context);
        tivxImgProcUnLoadKernels(context);
        tivxHwaUnLoadKernels(context);
    }
    
    
    int main (void)
    {
        if ( VX_SUCCESS == appCommonInit())
        {
            tivxInit();
            tivxHostInit();
    
            vx_context context = vxCreateContext();
            crop_image(context);
            vxReleaseContext(&context);
    
            tivxHostDeInit();
            tivxDeInit();
            appCommonDeInit();
        }
    
        return 0;
    }

    scaler_module.cpp

    //
    // Created by log on 1/3/23.
    //
    
    #include "scaler_module.h"
    #include "image_wrapper.h"
    
    #define CROP 1
    
    static void scale_set_crop_params(tivx_vpac_msc_crop_params_t &params)
    {
        params.crop_start_x = 0;
        params.crop_start_y = 0;
        params.crop_width = 512;
        params.crop_height = 512;
    }
    
    static void scale_set_coeff(tivx_vpac_msc_coefficients_t *coeff, uint32_t interpolation)
    {
        uint32_t i;
        uint32_t idx;
        uint32_t weight;
    
        idx = 0;
        coeff->single_phase[0][idx ++] = 0;
        coeff->single_phase[0][idx ++] = 0;
        coeff->single_phase[0][idx ++] = 256;
        coeff->single_phase[0][idx ++] = 0;
        coeff->single_phase[0][idx ++] = 0;
        idx = 0;
        coeff->single_phase[1][idx ++] = 0;
        coeff->single_phase[1][idx ++] = 0;
        coeff->single_phase[1][idx ++] = 256;
        coeff->single_phase[1][idx ++] = 0;
        coeff->single_phase[1][idx ++] = 0;
    
        if (VX_INTERPOLATION_BILINEAR == interpolation)
        {
            idx = 0;
            for(i=0; i<32; i++)
            {
                weight = i<<2;
                coeff->multi_phase[0][idx ++] = 0;
                coeff->multi_phase[0][idx ++] = 0;
                coeff->multi_phase[0][idx ++] = 256-weight;
                coeff->multi_phase[0][idx ++] = weight;
                coeff->multi_phase[0][idx ++] = 0;
            }
            idx = 0;
            for(i=0; i<32; i++)
            {
                weight = (i+32)<<2;
                coeff->multi_phase[1][idx ++] = 0;
                coeff->multi_phase[1][idx ++] = 0;
                coeff->multi_phase[1][idx ++] = 256-weight;
                coeff->multi_phase[1][idx ++] = weight;
                coeff->multi_phase[1][idx ++] = 0;
            }
            idx = 0;
            for(i=0; i<32; i++)
            {
                weight = i<<2;
                coeff->multi_phase[2][idx ++] = 0;
                coeff->multi_phase[2][idx ++] = 0;
                coeff->multi_phase[2][idx ++] = 256-weight;
                coeff->multi_phase[2][idx ++] = weight;
                coeff->multi_phase[2][idx ++] = 0;
            }
            idx = 0;
            for(i=0; i<32; i++)
            {
                weight = (i+32)<<2;
                coeff->multi_phase[3][idx ++] = 0;
                coeff->multi_phase[3][idx ++] = 0;
                coeff->multi_phase[3][idx ++] = 256-weight;
                coeff->multi_phase[3][idx ++] = weight;
                coeff->multi_phase[3][idx ++] = 0;
            }
        }
        else /* STR_VX_INTERPOLATION_NEAREST_NEIGHBOR */
        {
            idx = 0;
            for(i=0; i<32; i++)
            {
                coeff->multi_phase[0][idx ++] = 0;
                coeff->multi_phase[0][idx ++] = 0;
                coeff->multi_phase[0][idx ++] = 256;
                coeff->multi_phase[0][idx ++] = 0;
                coeff->multi_phase[0][idx ++] = 0;
            }
            idx = 0;
            for(i=0; i<32; i++)
            {
                coeff->multi_phase[1][idx ++] = 0;
                coeff->multi_phase[1][idx ++] = 0;
                coeff->multi_phase[1][idx ++] = 0;
                coeff->multi_phase[1][idx ++] = 256;
                coeff->multi_phase[1][idx ++] = 0;
            }
            idx = 0;
            for(i=0; i<32; i++)
            {
                coeff->multi_phase[2][idx ++] = 0;
                coeff->multi_phase[2][idx ++] = 0;
                coeff->multi_phase[2][idx ++] = 256;
                coeff->multi_phase[2][idx ++] = 0;
                coeff->multi_phase[2][idx ++] = 0;
            }
            idx = 0;
            for(i=0; i<32; i++)
            {
                coeff->multi_phase[3][idx ++] = 0;
                coeff->multi_phase[3][idx ++] = 0;
                coeff->multi_phase[3][idx ++] = 0;
                coeff->multi_phase[3][idx ++] = 256;
                coeff->multi_phase[3][idx ++] = 0;
            }
        }
    }
    
    vx_status init_scaler(vx_context context, ScalerObj *scalerObj, vx_int32 bufq_depth)
    {
        vx_status status = VX_SUCCESS;
        vx_int32 q;
    
        vx_image input     = vxCreateImage(context, scalerObj->input.width, scalerObj->input.height, VX_DF_IMAGE_NV12);
        vx_image output_1  = vxCreateImage(context, scalerObj->output_1.width, scalerObj->output_1.height, VX_DF_IMAGE_NV12);
    
        for(q = 0; q < bufq_depth; q++)
        {
            scalerObj->input.arr[q]     = vxCreateObjectArray(context, (vx_reference)input, NUM_CH);
            scalerObj->input_images[q]  = (vx_image)vxGetObjectArrayItem((vx_object_array)scalerObj->input.arr[q], 0);
        }
        scalerObj->output_1.arr[0]  = vxCreateObjectArray(context, (vx_reference)output_1, NUM_CH);
    
    #if CROP
        tivx_vpac_msc_crop_params_t cropParams;
        scale_set_crop_params(cropParams);
        /* Set Coefficients */
        scalerObj->crop_params_obj = vxCreateUserDataObject(context,
                                                            "tivx_vpac_msc_crop_params_t",
                                                            sizeof(tivx_vpac_msc_crop_params_t),
                                                            NULL);
    
        printf("crop params %u %u %u %u\n", cropParams.crop_width, cropParams.crop_height, cropParams.crop_start_y, cropParams.crop_start_x);
        vxCopyUserDataObject(scalerObj->crop_params_obj, 0,
                             sizeof(tivx_vpac_msc_crop_params_t),
                             &cropParams,
                             VX_WRITE_ONLY,
                             VX_MEMORY_TYPE_HOST);
    
    #else
        tivx_vpac_msc_coefficients_t coeffs;
        scale_set_coeff(&coeffs, VX_INTERPOLATION_BILINEAR);
        /* Set Coefficients */
        scalerObj->coeff_obj = vxCreateUserDataObject(context,
                                                      "tivx_vpac_msc_coefficients_t",
                                                      sizeof(tivx_vpac_msc_coefficients_t),
                                                      NULL);
    
        vxCopyUserDataObject(scalerObj->coeff_obj, 0,
                             sizeof(tivx_vpac_msc_coefficients_t),
                             &coeffs,
                             VX_WRITE_ONLY,
                             VX_MEMORY_TYPE_HOST);
    #endif
    
        vxReleaseImage(&input);
        vxReleaseImage(&output_1);
    
        return status;
    }
    
    void deinit_scaler(ScalerObj *scalerObj, vx_int32 bufq_depth)
    {
        vx_int32 q;
        printf("deinit scaler\n");
        for(q = 0; q < bufq_depth; q++)
        {
            vxReleaseObjectArray(&scalerObj->input.arr[q]);
            vxReleaseImage(&scalerObj->input_images[q]);
        }
    
        vxReleaseObjectArray(&scalerObj->output_1.arr[0]);
    
        vxReleaseUserDataObject(&scalerObj->crop_params_obj);
    }
    
    void delete_scaler(ScalerObj *scalerObj)
    {
        printf("delete scaler\n");
        if(scalerObj->node != NULL)
        {
            vxReleaseNode(&scalerObj->node);
        }
    }
    
    vx_status create_graph_scaler(vx_context context, vx_graph graph, ScalerObj *scalerObj)
    {
        vx_status status = VX_SUCCESS;
    
        vx_image input    = (vx_image)vxGetObjectArrayItem((vx_object_array)scalerObj->input.arr[0], 0);
        vx_image output_1 = (vx_image)vxGetObjectArrayItem((vx_object_array)scalerObj->output_1.arr[0], 0);
    
        scalerObj->node = tivxVpacMscScaleNode(graph, input, output_1, NULL, NULL, NULL, NULL);
        vxSetNodeTarget(scalerObj->node, VX_TARGET_STRING, TIVX_TARGET_VPAC_MSC1);
        vxSetReferenceName((vx_reference)scalerObj->node, "ScalerNode");
    
        vx_bool replicate[] = { vx_true_e, vx_true_e, vx_false_e, vx_false_e, vx_false_e, vx_false_e};
        vxReplicateNode(graph, scalerObj->node, replicate, 6);
    
        vxReleaseImage(&input);
        vxReleaseImage(&output_1);
    
        return status;
    }
    
    vx_status readScalerInput(const char* file_name, vx_object_array img_arr, int32_t ch_num)
    {
        vx_status status;
        status = vxGetStatus((vx_reference)img_arr);
    
        if(status == VX_SUCCESS)
        {
            FILE * fp = fopen(file_name,"rb");
            vx_size arr_len;
    
            if(fp == NULL)
            {
                printf("File %s could not be opened \n", file_name);
                return (VX_FAILURE);
            }
    
            vxQueryObjectArray(img_arr, VX_OBJECT_ARRAY_NUMITEMS, &arr_len, sizeof(vx_size));
    
            for (vx_int32 i = 0; i < arr_len; i++)
            {
                ImageWrapper image((vx_image)vxGetObjectArrayItem(img_arr, i));
                image.LoadFromNV12File(fp);
            }
    
            fclose(fp);
        }
    
        return(status);
    }
    
    vx_status writeScalerOutput(const char* file_name, vx_object_array img_arr)
    {
        vx_status status;
        status = vxGetStatus((vx_reference)img_arr);
    
        if(status == VX_SUCCESS)
        {
            FILE * fp = fopen(file_name,"wb");
            vx_size arr_len;
    
            if(fp == NULL)
            {
                printf("File %s could not be opened \n", file_name);
                return (VX_FAILURE);
            }
    
            vxQueryObjectArray(img_arr, VX_OBJECT_ARRAY_NUMITEMS, &arr_len, sizeof(vx_size));
    
            for (vx_int32 i = 0; i < arr_len; i++)
            {
                ImageWrapper image((vx_image)vxGetObjectArrayItem(img_arr, i));
                image.SaveToNV12File(fp);
            }
    
            fclose(fp);
        }
    
        return(status);
    }
    
    vx_status verify_graph(vx_graph *graph, ScalerObj *scalerObj)
    {
        vx_status status = VX_SUCCESS;
    
        vx_reference refs[1];
    
        status = vxVerifyGraph(*graph);
    
        if(status == VX_SUCCESS)
        {
            status = tivxExportGraphToDot(*graph,".", "vx_app_tidl_avp");
        }
    
    #if CROP
        refs[0] = (vx_reference)scalerObj->crop_params_obj;
    #else
        refs[0] = (vx_reference)scalerObj->coeff_obj;
    #endif
    
        if(status == VX_SUCCESS)
        {
    #if CROP
            status = tivxNodeSendCommand(scalerObj->node, TIVX_CONTROL_CMD_SEND_TO_ALL_REPLICATED_NODES,
                                         TIVX_VPAC_MSC_CMD_SET_CROP_PARAMS,
                                         refs, 1u);
    #else
            status = tivxNodeSendCommand(scalerObj->node, TIVX_CONTROL_CMD_SEND_TO_ALL_REPLICATED_NODES,
                                         TIVX_VPAC_MSC_CMD_SET_COEFF,
                                         refs, 1u);
    #endif
            printf("App Send MSC Command Done!\n");
        }
    
        if(status != VX_SUCCESS)
        {
            printf("MSC: Node send command failed!\n");
        }
    
        /* wait a while for prints to flush */
        tivxTaskWaitMsecs(100);
    
        return status;
    }

    scaler_module.h

    //
    // Created by log on 1/3/23.
    //
    
    #ifndef MINI_PERCEPTION_SDK_SCALER_MODULE_H
    #define MINI_PERCEPTION_SDK_SCALER_MODULE_H
    
    #include <TI/tivx.h>
    #include <TI/tivx_task.h>
    #include <TI/tivx_target_kernel.h>
    #include <TI/j7_tidl.h>
    
    #include "tivx_kernels_host_utils.h"
    
    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <sys/stat.h>
    #include <float.h>
    #include <math.h>
    
    #define APP_MAX_FILE_PATH           (256u)
    
    #define NUM_CH    (1)
    #define APP_MAX_BUFQ_DEPTH (8)
    #define AVP_BUFFER_Q_DEPTH   (2)
    
    
    typedef struct {
        vx_object_array arr[APP_MAX_BUFQ_DEPTH];
    
        vx_int32 width;
        vx_int32 height;
    
        vx_char objName[APP_MAX_FILE_PATH];
    
    } ImgObj;
    
    typedef struct {
        vx_node    node;
    
        /* For AVP demo input is 1280x720 NV12 */
        ImgObj input;
        /* For AVP demo we require 1 outputs from MSC */
        ImgObj output_1; /* 512x512 - NV12 */
    
        vx_user_data_object crop_params_obj;
        vx_user_data_object coeff_obj;
    
        vx_int32 graph_parameter_index;
    
        /* Arrray of 0th index reference of input.arr */
        vx_image input_images[APP_MAX_BUFQ_DEPTH];
    
        vx_char objName[APP_MAX_FILE_PATH];
    
    } ScalerObj;
    
    
    vx_status init_scaler(vx_context context, ScalerObj *scalerObj, vx_int32 bufq_depth);
    void deinit_scaler(ScalerObj *scalerObj, vx_int32 bufq_depth);
    void delete_scaler(ScalerObj *scalerObj);
    
    vx_status readScalerInput(const char* file_name, vx_object_array img_arr, int32_t ch_num);
    vx_status writeScalerOutput(const char* file_name, vx_object_array img_arr);
    vx_status create_graph_scaler(vx_context context, vx_graph graph, ScalerObj *scalerObj);
    vx_status verify_graph(vx_graph *graph, ScalerObj *scalerObj);
    
    
    #endif  // MINI_PERCEPTION_SDK_SCALER_MODULE_H
    

    image_wrapper.h

    #ifndef MINI_PERCEPTION_SDK_IMAGE_WRAPPER_H
    #define MINI_PERCEPTION_SDK_IMAGE_WRAPPER_H
    
    #include <TI/tivx.h>
    #include <stdio.h>
    
    
    
    
    class ImageWrapper final {
    public:
        explicit  ImageWrapper (vx_image img);
        ~ImageWrapper();
        bool SaveToNV12File(FILE * fp);
        bool LoadFromNV12File(FILE * fp);
        vx_image GetImage(void);
        bool ReleaseImage(void);
    
    private:
        vx_image   img_;
    };
    
    #endif  // MINI_PERCEPTION_SDK_IMAGE_WRAPPER_H

    image_wrapper.cpp

    #include <iostream>
    
    #include "image_wrapper.h"
    
    ImageWrapper::ImageWrapper(vx_image img):img_(img) {}
    
    ImageWrapper::~ImageWrapper(void) {
        ReleaseImage();
    }
    
    bool ImageWrapper::ReleaseImage(void) {
        bool answer = true;
        if (img_)
            answer = VX_SUCCESS == vxReleaseImage(&img_);
        img_ = nullptr;
        return answer;
    }
    
    vx_image ImageWrapper::GetImage(void)
    {
        return img_;
    }
    
    bool ImageWrapper::SaveToNV12File(FILE *fp) {
        vx_int32 j;
        vx_status status;
        vx_rectangle_t rect;
        vx_imagepatch_addressing_t image_addr;
        vx_map_id map_id;
        void * data_ptr;
        vx_uint32  img_width;
        vx_uint32  img_height;
        vx_uint32  num_bytes = 0;
        vx_image   out_img = img_;
    
        vxQueryImage(out_img, VX_IMAGE_WIDTH, &img_width, sizeof(vx_uint32));
        vxQueryImage(out_img, VX_IMAGE_HEIGHT, &img_height, sizeof(vx_uint32));
    
        rect.start_x = 0;
        rect.start_y = 0;
        rect.end_x = img_width;
        rect.end_y = img_height;
        status = vxMapImagePatch(out_img,
                                 &rect,
                                 0,
                                 &map_id,
                                 &image_addr,
                                 &data_ptr,
                                 VX_READ_ONLY,
                                 VX_MEMORY_TYPE_HOST,
                                 VX_NOGAP_X);
    
        if (VX_SUCCESS != status)
        {
            std::cout << "The fail mapping image for saving the Luma. Status:" << status << std::endl;
            return false;
        }
        /* Copy Luma */
        for (j = 0; j < img_height; j++)
        {
    
            num_bytes += f_write(data_ptr, 1, img_width, fp);
            data_ptr = static_cast<void *>(static_cast<uint8_t*>(data_ptr) + image_addr.stride_y);
        }
    
        if(num_bytes != (img_width*img_height))
            std::cout <<"Luma bytes written = "<<num_bytes << ", expected = " << img_width*img_height << std::endl;
    
        vxUnmapImagePatch(out_img, map_id);
    
        rect.start_x = 0;
        rect.start_y = 0;
        rect.end_x = img_width;
        rect.end_y = img_height / 2;
        status = vxMapImagePatch(out_img,
                                 &rect,
                                 1,
                                 &map_id,
                                 &image_addr,
                                 &data_ptr,
                                 VX_READ_ONLY,
                                 VX_MEMORY_TYPE_HOST,
                                 VX_NOGAP_X);
    
        if (VX_SUCCESS != status) {
            std::cout << "The fail mapping image for saving the CbCr. Status:" << status << std::endl;
            return false;
        }
    
        /* Copy CbCr */
        num_bytes = 0;
        for (j = 0; j < img_height/2; j++)
        {
    
            num_bytes += f_write(data_ptr, 1, img_width, fp);
            data_ptr = static_cast<void *>(static_cast<uint8_t*>(data_ptr) + image_addr.stride_y);
        }
    
        if(num_bytes != (img_width*img_height/2))
            std::cout <<"CbCr bytes written = "<<num_bytes << ", expected = " << img_width*img_height/2 << std::endl;
    
        vxUnmapImagePatch(out_img, map_id);
        return true;
    }
    
    bool ImageWrapper::LoadFromNV12File(FILE *fp) {
        vx_int32 j;
        vx_status status;
        vx_rectangle_t rect;
        vx_imagepatch_addressing_t image_addr;
        vx_map_id map_id;
        void * data_ptr;
        vx_uint32  img_width;
        vx_uint32  img_height;
        vx_uint32  num_bytes = 0;
        vx_image   in_img = img_;
    
        vxQueryImage(in_img, VX_IMAGE_WIDTH, &img_width, sizeof(vx_uint32));
        vxQueryImage(in_img, VX_IMAGE_HEIGHT, &img_height, sizeof(vx_uint32));
    
        rect.start_x = 0;
        rect.start_y = 0;
        rect.end_x = img_width;
        rect.end_y = img_height;
        status = vxMapImagePatch(in_img,
                                 &rect,
                                 0,
                                 &map_id,
                                 &image_addr,
                                 &data_ptr,
                                 VX_WRITE_ONLY,
                                 VX_MEMORY_TYPE_HOST,
                                 VX_NOGAP_X);
    
        if (VX_SUCCESS != status)
        {
            std::cout << "The fail mapping image for loading the Luma. Status:" << status << std::endl;
            return false;
        }
    
        /* Copy Luma */
        for (j = 0; j < img_height; j++)
        {
            num_bytes += f_read(data_ptr, 1, img_width, fp);
            data_ptr = static_cast<void *>(static_cast<uint8_t*>(data_ptr) + image_addr.stride_y);
        }
    
        if(num_bytes != (img_width*img_height))
            std::cout << "Luma bytes read = " << num_bytes << ", expected = " << img_width*img_height << std::endl;
    
        vxUnmapImagePatch(in_img, map_id);
    
        rect.start_x = 0;
        rect.start_y = 0;
        rect.end_x = img_width;
        rect.end_y = img_height / 2;
        status = vxMapImagePatch(in_img,
                                 &rect,
                                 1,
                                 &map_id,
                                 &image_addr,
                                 &data_ptr,
                                 VX_WRITE_ONLY,
                                 VX_MEMORY_TYPE_HOST,
                                 VX_NOGAP_X);
    
        if (VX_SUCCESS != status) {
            std::cout << "The fail mapping image for loading the CbCr. Status:" << status << std::endl;
            return false;
        }
    
        /* Copy CbCr */
        num_bytes = 0;
        for (j = 0; j < img_height/2; j++)
        {
            num_bytes += f_
            read(data_ptr, 1, img_width, fp);
            data_ptr = static_cast<void *>(static_cast<uint8_t*>(data_ptr) + image_addr.stride_y);
        }
    
        if(num_bytes != (img_width*img_height/2))
            std::cout << "CbCr bytes read = " << num_bytes << ", expected = " << img_width*img_height/2 << std::endl;
    
        vxUnmapImagePatch(in_img, map_id);
    
        return true;
    }

    在 image_wrapper.cpp 中、文件名函数 fread 和 fwrite 已更改、因为 web-plagin 无法访问以放置它们

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Brijesh Jadav

    我明白为什么我能够裁剪图像。 因为我在进行裁剪之前调用了不带裁剪且仅具有缩放功能("#define CROP 0")的程序。 之后、在裁剪("#define CROP 1")上使用灯的程序运行良好。

    我将这两个命令组合到了 VpacMscScale Node 中、裁剪可与此更改配合使用。

    vx_status verify_graph(vx_graph *graph, ScalerObj *scalerObj)
    {
        vx_status status = VX_SUCCESS;
    
        vx_reference refs[1];
    
        status = vxVerifyGraph(*graph);
    
        if(status == VX_SUCCESS)
        {
            status = tivxExportGraphToDot(*graph,".", "vx_app_tidl_avp");
        }
    
    
        if(status == VX_SUCCESS)
        {
            refs[0] = (vx_reference)scalerObj->coeff_obj;
            status = tivxNodeSendCommand(scalerObj->node, TIVX_CONTROL_CMD_SEND_TO_ALL_REPLICATED_NODES,
                                         TIVX_VPAC_MSC_CMD_SET_COEFF,
                                         refs, 1u);
    
            printf("App Send Coef MSC Command Done!\n");
        }
    
    
        if(status == VX_SUCCESS)
        {
            refs[0] = (vx_reference)scalerObj->crop_params_obj;
            status = tivxNodeSendCommand(scalerObj->node, TIVX_CONTROL_CMD_SEND_TO_ALL_REPLICATED_NODES,
                                         TIVX_VPAC_MSC_CMD_SET_CROP_PARAMS,
                                         refs, 1u);
    
            printf("App Send Crop MSC Command Done!\n");
        }
    
        if(status != VX_SUCCESS)
        {
            printf("MSC: Node send command failed!\n");
        }
    
        /* wait a while for prints to flush */
        tivxTaskWaitMsecs(100);
    
        return status;
    }
    


    我有疑问。 这是否合法?

    e2e.ti.com/.../2438.code.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    是的、您可以调用控制命令来首先设置比例系数、然后设置裁剪参数。  这两个命令都是不同的控制命令、参考数组(ref[0])可在此处重复使用。  

    由于您的原始问题已解决、我将关闭此 TT。  

    此致、

    Brijesh