[Cambrian (1)] Use of DSP libraries: scaling and splicing practice, based on CNVE_LIB (Vision Engine Library), developing IPM splicing of DSP

Article directory

  • MSP resources for Cambrian SD5223C
  • Prepare
  • Basic use
  • DSP development dependencies
  • 1 Look at the file “cn_dsp.h”
  • 2 Look at the file “sample_comm_dsp.h”
  • 3 Develop DSP resize
    • Look at the core file cnve.h file
  • 4 Develop IPM splicing of DSP
    • REMap method for IPM splicing
    • The following is the general usage of the `remap` function:
    • How are the sizes of the two mapping relationship arrays of remap determined? for example
    • For IPM splicing warpPerspective method
    • Then you can get remap
    • So, how to splice MPS-DSP?
  • 5 Currently supported operators include:

MSP resources for Cambrian SD5223C

Each single module may refer to a different computer program or system component, with the following specific meanings:

CVE: May refer to "Common Video Encoder", which is a computer program or hardware component used to encode raw video data into a specific format.
DSP: May refer to "Digital Signal Processor", which is a dedicated processor for processing digital signals.
VDEC: May refer to "Video Decoder", which is a computer program or hardware component used to decode compressed video data and restore it to original video data.
VENC: May refer to "Video Encoder", which is a computer program or hardware component used to encode raw video data into a specific format.
VGU: May refer to "Video Graphics Unit", which is a computer hardware component used to process video image data.

Practice using DSP resources today. Based on “CNVE-LIB Developer Manual”

Preparation

1. Configure the cross-compilation tool
2. Configure the NFS service and the NFS client connection on the board.
3. Check the rootfs file (this will be in the bsp/filesystem/rootfs directory after installing the EF2301 sdk)

Basic purposes

DSP can be used for: image scaling, color space conversion, filtering, preprocessing for artificial intelligence, etc.
The hardware involved is CPU and VPU, and the software includes SDK environment and supporting tools.

DSP development dependencies

1. cn_dsp.elf file, this should be some firmware of dsp
2. Under the /mps/ko path, execute the two scripts ./load_cnUDM_drv.sh and ./load_mps_drv.sh in sequence to install the driver.

1 Look at the file “cn_dsp.h”

This file defines

cnS32_t cnveDspPowerOn(cnveEnDspID_t enDspId);
cnS32_t cnveDspPowerOff(cnveEnDspID_t enDspId);
cnS32_t cnveDspLoadBin(const cnChar_t *pszBinFileName, cnveEnDspID_t enDspId);
cnS32_t cnveDspEnableCore(cnveEnDspID_t enDspId);
cnS32_t cnveDspDisableCore(cnveEnDspID_t enDspId);
cnS32_t cnveDspRPC(cnveDspHandle_t *phHandle, const cnveDspMessage_t *pstMsg, cnveEnDspID_t enDspId, cnveEnDspPri_t enPri);
cnS32_t cnveDspQuery(cnveEnDspID_t enDspId, cnveDspHandle_t hHandle, cnBool_t *pbFinish, cnBool_t bBlock);
cnS32_t cnveDspCoreStatStart(cnveEnDspID_t enDspId, const cnveDspStatCfgParam_t *pParams);
cnS32_t cnveDspCoreStatGet(cnveEnDspID_t enDspId, cnveDspStatExport_t *pParams);
cnS32_t cnveDspCoreStatStop(cnveEnDspID_t enDspId);

These functions appear to be part of a DSP (Digital Signal Processor) system. A DSP is a specialized microprocessor used to process digital signals, typically for tasks such as audio and video processing, data compression and decompression. The parameters and return types of these functions are specific to this DSP system.

The following is a speculative explanation of these functions:

  1. cnveDspPowerOn: This function may be used to turn on a specific DSP. enDspId may be an identifier specifying the DSP to be enabled. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  2. cnveDspPowerOff: This function may be used to turn off a specific DSP. enDspId may be an identifier specifying the DSP to be turned off. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  3. cnveDspLoadBin: This function may be used to load binary code to a DSP. pszBinFileName is the path to the binary file and enDspId may be an identifier specifying the DSP to load the code from. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  4. cnveDspEnableCore: This function may be used to enable the core of DSP. enDspId may be an identifier specifying the DSP to enable. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  5. cnveDspDisableCore: This function may be used to disable the DSP core. enDspId may be an identifier specifying the DSP to be disabled. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  6. cnveDspRPC: This function may be used to make a remote procedure call (RPC) to a DSP. phHandle may be the handle used to receive RPC requests, pstMsg may be the data structure containing the RPC message, enDspId may be an identifier, used To specify the DSP to be called, enPri may be the priority parameter. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  7. cnveDspQuery: This function may be used to query the status of a certain DSP. enDspId may be an identifier specifying the DSP to query, hHandle may be the handle used to query, pbFinish may be the Pointer to receive query completion flag, bBlock may be a flag indicating whether it should block waiting for query results. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  8. cnveDspCoreStatStart: This function may be used to start recording the core statistical information of a certain DSP. enDspId may be an identifier that specifies the DSP for which statistics are to be logged, and pParams may be a data structure containing statistics logging configuration. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  9. cnveDspCoreStatGet: This function may be used to obtain the core statistical information of a certain DSP. enDspId may be an identifier used to specify the DSP to obtain statistical information, and pParams may be a pointer to a structure used to receive statistical information. The return type cnS32_t may be an error code or status code indicating whether the operation was successful.
  10. cnveDspCoreStatStop: This function may be used to stop recording the core statistical information of a certain DSP.

2 Look at the file “sample_comm_dsp.h”

/*
*Malloc memory
*/
cnS32_t sampleCommDspMemAlloc(cnU64_t *pu64PhyAddr, cnVoid_t **ppu64VirAddr, cnU32_t u32Len);

Let’s see how Malloc memory works:
This is a C language function, the function name is sampleCommDspMemAlloc. The main purpose of this function is to allocate memory for the DSP (Digital Signal Processor).

There are three parameters in the function parameter list:

  1. cnU64_t *pu64PhyAddr: A pointer to a variable of type cnU64_t. This variable may be used to save the physical memory address.
  2. cnVoid_t **ppu64VirAddr: A pointer to a pointer of type cnVoid_t. This pointer may be used to save the virtual memory address.
  3. cnU32_t u32Len: A variable of type cnU32_t, indicating the length of memory that needs to be allocated.
cnS32_t sampleCommDspMemAlloc(cnU64_t *pu64PhyAddr, cnVoid_t **ppu64VirAddr, cnU32_t u32Len)
{<!-- -->
    cnS32_t s32Ret;
    cnMemInfo_t mem_info;
     mem_info.u32Size = u32Len;
     mem_info.enCmpMode = COMPRESS_MODE_NONE;
     snprintf(mem_info.acMmzName, MAX_MMZ_NAME_LEN, "zone_anon");
     snprintf(mem_info.acMmbName, MAX_MMB_NAME_LEN, "dspMem");
    s32Ret = cnsysMmzAlloc( & amp;mem_info, (cnU64_t *)pu64PhyAddr, (cnVoid_t **)ppu64VirAddr);
    SAMPLE_DSP_CHECK_EXPR_RET(CN_SUCCESS != s32Ret, CN_ERR_CNVE_DSP_NOMEM, SAMPLE_DSP_ERR_LEVEL_ERROR, "Error(%d):cnrtMallocExt failed!\
", s32Ret);
    return CN_SUCCESS;
}

In the function body, a variable s32Ret of type cnS32_t is first defined to save the function return value. Then a variable mem_info of type cnMemInfo_t is defined to save memory information.

Next, assign values to the member variables of the mem_info structure. Among them, mem_info.u32Size = u32Len; assigns the memory length to be allocated to mem_info.u32Size. mem_info.enCmpMode = COMPRESS_MODE_NONE; sets the compression mode to no compression mode. Through the snprintf function, assign “zone_anon” to mem_info.acMmzName and assign “dspMem” to mem_info.acMmbName.

Then, by calling the cnsysMmzAlloc function, allocate memory based on the information of mem_info, and save the physical memory address and virtual memory address to the corresponding parameters.

Then, by calling the SAMPLE_DSP_CHECK_EXPR_RET macro function, check whether s32Ret is equal to 0. If not, an error message is output and an error code is returned.

Finally, if everything is OK, the function returns CN_SUCCESS.

/*
*Create image memory
*/
cnS32_t sampleCommDspCreateImage(cnveImage_t *pstImg, cnveEnImageType_t enType, cnU32_t u32Width, cnU32_t u32Height);
/*
*Create Image memory
*/
cnS32_t sampleCommDspCreateImage(cnveImage_t *pstImg, cnveEnImageType_t enType, cnU32_t u32Width, cnU32_t u32Height)
{<!-- -->
    cnS32_t s32Ret;
    cnU32_t u32Size = 0;

    pstImg->enType = enType;
    pstImg->u32Width = u32Width;
    pstImg->u32Height = u32Height;
    pstImg->au32Stride[0] = sampleCommDspAlign(pstImg->u32Width, SAMPLE_DSP_ALIGN_32);
    switch(enType)
    {<!-- -->
        case CNVE_IMAGE_TYPE_RGB_PACKAGE:
        case CNVE_IMAGE_TYPE_BGR_PACKAGE:
        {<!-- -->
            u32Size = pstImg->au32Stride[0] * pstImg->u32Height * 3;
            s32Ret = sampleCommDspMemAlloc( & amp;pstImg->au64PhyAddr[0], (cnVoid_t**) & amp;pstImg->au64VirAddr[0], u32Size);
            SAMPLE_DSP_CHECK_EXPR_RET(CN_SUCCESS != s32Ret, s32Ret, SAMPLE_DSP_ERR_LEVEL_ERROR, "Error(%#x):sampleCommDspMemAlloc failed!\
", s32Ret);

            pstImg->au32Stride[1] = pstImg->au32Stride[0];
            pstImg->au32Stride[2] = pstImg->au32Stride[0];
            pstImg->au64VirAddr[1] = pstImg->au64VirAddr[0] + 1;
            pstImg->au64VirAddr[2] = pstImg->au64VirAddr[1] + 1;
            pstImg->au64PhyAddr[1] = pstImg->au64PhyAddr[0] + 1;
            pstImg->au64PhyAddr[2] = pstImg->au64PhyAddr[1] + 1;
            break;
        }
        default:
            break;
    }

return CN_SUCCESS;
}

This is a C language function named sampleCommDspCreateImage, which is used to create image objects.

There are three parameters in the function parameter list:

  1. cnveImage_t *pstImg: A pointer to a variable of type cnveImage_t. This variable may be used to save image information.
  2. cnveEnImageType_t enType: A variable of type cnveEnImageType_t, representing the image type.
  3. cnU32_t u32Width: A variable of type cnU32_t, indicating the width of the image.
  4. cnU32_t u32Height: A variable of type cnU32_t, representing the image height.

In the function body, a variable s32Ret of type cnS32_t is first defined to save the function return value. Then a variable u32Size of type cnU32_t is defined to save the size of the image.

Then, through assignment operations, the member variables of the pstImg structure are set, including image type, width, height and step size. Then depending on the image type, different operations are performed.

When the image type is CNVE_IMAGE_TYPE_RGB_PACKAGE or CNVE_IMAGE_TYPE_BGR_PACKAGE, calculate the size of the image and call the sampleCommDspMemAlloc function to allocate memory. Then based on the allocated memory size, set the virtual address and physical address of the image. At the same time, set other relevant information, such as the step size and the virtual address and physical address of the color channel.

If the image type is not CNVE_IMAGE_TYPE_RGB_PACKAGE or CNVE_IMAGE_TYPE_BGR_PACKAGE, no action is performed.

Finally, the function returns CN_SUCCESS, indicating that the image object was successfully created.

3 Develop DSP resize

static cnVoid_t cnveSampleResize(Sample_Image_table_t para, cnChar_t *rootdir)
{<!-- -->
     cnChar_t fname[128];
     cnveImage_t srcImage, dstImage;
     cnveResizeCtrl_t resizeCtrl;
     cnveEnErrCode_t ret;
     cnU32_t srcSize, dstSize;
     cnS32_t Ret;

     srcImage.u32Width = para.srcWidth;
     srcImage.u32Height = para.srcHeight;
     srcImage.au32Stride[0] = para.srcStride;
     srcImage.enType = para.srcType;
     dstImage.u32Width = para.dstWidth;
     dstImage.u32Height = para.dstHeight;
     dstImage.au32Stride[0] = para.dstStride;
     dstImage.enType = para.dstType;

     Ret = sampleCommDspCreateImage( & amp;srcImage, srcImage.enType, srcImage.u32Width, srcImage.u32Height);
     SAMPLE_DSP_CHECK(Ret);
     Ret = sampleCommDspCreateImage( & amp;dstImage, dstImage.enType, dstImage.u32Width, dstImage.u32Height);
     SAMPLE_DSP_CHECK(Ret);
     srcSize = get_image_size(srcImage.u32Width, srcImage.u32Height, srcImage.enType);
     dstSize = get_image_size(dstImage.u32Width, dstImage.u32Height, dstImage.enType);

     sprintf(fname, "%s", para.srcName);
     read_bin(fname, (cnChar_t *)srcImage.au64VirAddr[0], srcSize);

     resizeCtrl.alignCornerType = CNVE_ALIGN_CORNER_FALSE;
     resizeCtrl.resizeType = CNVE_RESIZE_NORMAL;
     resizeCtrl.interType = CNVE_INTER_BILINEAR;
     resizeCtrl.batchSize = 1;

     ret = cnveResize( & amp;srcImage, & amp;dstImage, & amp;resizeCtrl, g_enCoreId, g_enPri, g_bBlock);
     if(ret != CNVE_ERR_SUCCESS)
     {<!-- -->
          printf("cnveResize failed!\
");
          exit(-1);
     }
     memset(fname, 0, 128);
     sprintf(fname, "%s%s", rootdir, para.dstName);
     write_bin(fname, (cnChar_t *)dstImage.au64VirAddr[0], dstSize);

     sampleCommDspDestroyImage( & amp;srcImage);
     sampleCommDspDestroyImage( & amp;dstImage);
     printf("cnveResize success!\
");
}

This is a C language function, the function name is cnveSampleResize, which is used to scale the image.

The function has two parameters, one is para of type Sample_Image_table_t, and the other is rootdir of type cnChar_t.

In this function, some variables are first defined, including two variables of type cnveImage_t, srcImage and dstImage, which are used to save the source image and target image information. A variable resizeCtrl of type cnveResizeCtrl_t, used to save scaling control information. A variable ret of type cnveEnErrCode_t, used to save the function return value. Two variables of type cnU32_t, srcSize and dstSize, are used to save the size of the source image and the target image. A variable Ret of type cnS32_t, used to save the function return value. A character array fname used to save the file name.

Then, through assignment operations, information such as the width, height, step size, and type of the source image and the target image are set.

Next, the source and target images are created by calling the sampleCommDspCreateImage function. Then by calling the get_image_size function, the size of the source image and the target image is calculated.

Then, by calling the sprintf function, the source file name is assigned to fname. Then by calling the read_bin function, the content of the source file is read and saved to the virtual address of the source image.

Then, through the assignment operation, the scaling control information is set.

Then, by calling the cnveResize function, the source image is scaled and the result is saved to the target image. If scaling fails, an error message is output and the program exits.

Then, by calling the memset function, the fname array is cleared. Then by calling the sprintf function, the target file name is assigned to fname. Then by calling the write_bin function, the contents of the target image are written into the target file.

Finally, by calling the sampleCommDspDestroyImage function, the source and target images are destroyed and a success message is output.

Look at the core file cnve.h file

/*!
 *@brief
 *
 * This function performs the Resize operation.
 *
 * @param[in] pstSrc
 * Input. Pointer to the input cnveSrcImage_t struct.
 * @param[out] pstDst
 * Output. Pointer to the output cnveDstImage_t struct.
 * @param[in] pstResizeCtrl
 * Input. Pointer to the cnveResizeCtrl_t struct.
 * @param[in] enCoreId
 * Input. DSP ID.
 * @param[in] enPri
 * Input. DSP task priority.
 * @param[in] bBlock
 * Input. Specify whether to block until the result is returned.
 * @retval CNVE_ERR_SUCCESS
 * The function ends normally.
 * @par Requirements
 * - None.
 * @par Example
 * - None.
 *
 */
cnveEnErrCode_t cnveResize(cnveSrcImage_t *pstSrc,
                           cnveDstImage_t *pstDst,
                           cnveResizeCtrl_t *pstResizeCtrl,
                           cnveEnDspID_t enCoreId,
                           cnveEnDspPri_t enPri,
                           cnBool_t bBlock);

We cannot see the specific code implementation.

4 Develop DSP IPM splicing

For IPM splicing REMap method

Regarding the image stitching processing function, the main function is to stitch the images captured by the four cameras into a panoramic image.

Function parameter description:

  • src: Input parameters, the original image data captured by the four-channel camera, from top to bottom are “front left, back right”.
  • output: Output parameters, spliced panoramic image data.
  • drawCar: Whether to paste the vehicle model, true means pasting.

Code logic analysis:

  1. First check whether the size of the input image is 4x1280x2880. If so, copy the original image data directly to src_image.
  2. Use the remap function to remap src_image and obtain tmp[0] and tmp[1] respectively. images. Remapping is an image transformation technology that can achieve image transformation effects by changing the mapping relationship between pixels. Remapping may be used here to correct image distortion, resize the image, etc.
  3. Adjust the pixel values of tmp[0] and tmp[1], multiply by the corresponding alpha value, and divide by 255 for normalization.
  4. Splice the adjusted tmp[0] and tmp[1] to obtain the panoramic image output.

Summary: The main purpose of this function is to stitch the images captured by four cameras into a panoramic image, and you can choose whether to paste the vehicle model on the stitched image.

The remap function is an image processing function used to remap images. It can realize image transformation, distortion correction, resizing and other functions by changing the mapping relationship between pixels.

The following is the general usage of the remap function:

void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode, const Scalar & amp; borderColor);

The parameters are explained as follows:

  • src: Input image, which can be a color image or grayscale image.
  • dst: Output image, that is, the remapped image.
  • map1: Mapping relationship array 1, used to specify the first mapping relationship.
  • map2: Mapping relationship array 2, used to specify the second mapping relationship.
  • interpolation: Interpolation method, used to specify the calculation method of pixel values. Common interpolation methods include linear interpolation (INTER_LINEAR) and nearest neighbor interpolation (INTER_NEAREST).
  • borderMode: Border mode, used to specify the border processing method of pixel values. Common boundary modes include copy boundary (BORDER_CONSTANT) and mirror boundary (BORDER_REFLECT).
  • borderColor: Border color, used to specify the color when copying the border.

Precautions:

  1. The remap function needs to provide two mapping relationship arrays. The first array specifies the horizontal mapping relationship from the input image to the output image, and the second array specifies the vertical mapping relationship from the input image to the output image. Each element in the mapping relationship array represents the corresponding mapping relationship, usually bilinear interpolation or nearest neighbor interpolation.
  2. The length of the mapping array must be the same as the number of rows or columns of the input image, otherwise an error will result.
  3. The interpolation method and boundary mode can be selected according to needs. Common choices include linear interpolation and copy boundary.
  4. When using the remap function, you need to pay attention to the size and type of the image to ensure that the size and data type of the input image and the output image are consistent.
  5. If the input image and output image are of different sizes, you need to ensure that the size of the mapping array is the same as the size of the input image, otherwise an error will occur.
  6. There is a trade-off between processing speed and accuracy. Linear interpolation has higher accuracy but slower calculation speed than nearest neighbor interpolation; nearest neighbor interpolation has faster calculation speed but lower accuracy. Choose the appropriate interpolation method according to actual needs.

How are the sizes of the two mapping relationship arrays of remap determined? Give an example

The size of the two mapping relationship arrays of the remap function (ie, the number of rows and the number of columns) is determined based on the size of the input image. Specifically, the number of rows in the mapping array should be the same as the number of rows in the input image, and the number of columns in the mapping array should be the same as the number of columns in the input image.

For IPM splicing warpPerspective method

1. Calculate the image plane to world coords transfer matrix M through external parameters
2. Calculate the IPM homography matrix homographies
3. Use cv2.warpPerspective(img, IPM, (outputRes[1], outputRes[0]), flags=interpMode) for projection calculation.

Then you can get remap

Initialize and calculate a mapping of calibration and correction images based on the camera’s intrinsic parameters, distortion coefficients and other motion parameters. It then merges the processed map data into a complete map and returns it.

So, how to splice MPS-DSP?

/*!
 *@brief
 *
 * This function performs the Ipm operation.
 *
 * @param[in] pstSrcFront
 * Input. Pointer to the input cnveSrcImage_t struct.
 * @param[in] pstSrcLeft
 * Input. Pointer to the input cnveSrcImage_t struct.
 * @param[in] pstSrcRight
 * Input. Pointer to the input cnveSrcImage_t struct.
 * @param[in] pstSrcRear
 * Input. Pointer to the input cnveSrcImage_t struct.
 * @param[out] pstDst
 * Output. Pointer to the output cnveDstImage_t struct.
 * @param[in] pstIpmCtrl
 * Input. Pointer to the input cnveIpmCtrl_t struct.
 * @param[in] enCoreId
 * Input. DSP ID.
 * @param[in] enPri
 * Input. DSP task priority.
 * @param[in] bBlock
 * Input. Specify whether to block until the result is returned.
 * @retval CNVE_ERR_SUCCESS
 * The function ends normally.
 * @par Requirements
 * - None.
 * @par Example
 * - None.
 *
 */
cnveEnErrCode_t cnveIpm(cnveSrcImage_t *pstSrcFront, cnveSrcImage_t *pstSrcLeft,
                        cnveSrcImage_t *pstSrcRight, cnveSrcImage_t *pstSrcRear,
                        cnveSrcImage_t *pstParams, cnveDstImage_t *pstDst,
                        cnveIpmCtrl_t *pstIpmCtrl, cnveEnDspID_t enCoreId,
                        cnveEnDspPri_t enPri, cnBool_t bBlock);

Let’s take a look at the solution’s sample_alg_ipm.cpp

First initialize and read the pstParams file

cnS32_t sampleAlgIpmInit()
{<!-- -->
    cnS32_t s32Ret;

s32Ret = sampleCommDspCreateImage( & amp;g_stIpmParamsImage, CNVE_IMAGE_TYPE_U8C1, sampleCommSysStatFile((cnChar_t*)SAMPLE_IPM_PARAM_FILE), 1);
    SAMPLE_DSP_CHECK_EXPR_GOTO(CN_SUCCESS != s32Ret, ERR_EXIT, SAMPLE_DSP_ERR_LEVEL_ERROR, "Error(%#x):sampleCommDspCreateImage failed!\
", s32Ret);

s32Ret = sampleAlgIpmReadBin( & amp;g_stIpmParamsImage);
    SAMPLE_DSP_CHECK_EXPR_GOTO(CN_SUCCESS != s32Ret, IMAGE_EXIT, SAMPLE_DSP_ERR_LEVEL_ERROR, "Error(%#x):sampleAlgIpmReadBin failed!\
", s32Ret);

SAMPLE_TRACE("sampleAlgIpmInit success\
");
return CN_SUCCESS;
\t
}

Then perform splicing

cnS32_t sampleAlgIpmProcess(cncveImage_t astRGBInFrame[], cnS32_t s32ChnNum, cncveImage_t *pstRGBOutFrame)
{<!-- -->
static cnS32_t s32Cnt = 0;
cnveImage_t astSrcImage[4];
cnveImage_t astDstImage;
cnveIpmCtrl_t stCtrl;
\t\t
//0-front 1-left 2-right 3-rear
for (cnS32_t i = 0; i < 4; i + + )
{<!-- -->
sampleAlgBGRFrameConvert2Image( & amp;astRGBInFrame[i], & amp;astSrcImage[i]);
}
sampleAlgBGRFrameConvert2Image(pstRGBOutFrame, & amp;astDstImage);

    cnS32_t s32Ret = cnveIpm( & amp;astSrcImage[0], & amp;astSrcImage[1], & amp;astSrcImage[2], & amp;astSrcImage[3],
             & amp;g_stIpmParamsImage, & amp;astDstImage, & amp;stCtrl, CNVE_DSP_ID_0, CNVE_DSP_PRI_0, CN_FALSE);
...
//sampleCommSysWriteFile((cnChar_t*)"ipm_out.bgr", pstRGBOutFrame->au64VirtAddr[0], 3 * pstRGBOutFrame->u32Width * pstRGBOutFrame->u32Height);
...
}

5 Currently supported operators include:

1. Standardization
2. Connected domain labeling operation
3. Crop cutout
4. Image space conversion of Csc
5. Gaussian fuzzy calculation
6. IPM splicing
7. Generate the boundaries of the image
8. Complete multi-line segment fitting of ransac
9. Image scaling

(End of text)