nnie yuv bgr


原文链接: nnie yuv bgr

首先要看的sdk文档(HiIVE API 参考)
其中详细说明了 IVE_IMAGE_TYPE_YUV420SP,IVE_IMAGE_TYPE_YUV420P,IVE_IMAGE_TYPE_YUV422SP,IVE_IMAGE_TYPE_U8C3_PACKAGE,IVE_IMAGE_TYPE_U8C3_PLANAR等文件格式,而我们也需要使用IVE提供的 HI_MPI_IVE_CSC 进行图片格式的转换,那么我们来看看这个函数:

/*****************************************************************************

  • Prototype : HI_MPI_IVE_CSC
  • Description : YUV2RGB\YUV2HSV\YUV2LAB\RGB2YUV color space conversion are supported.
  • Parameters : IVE_HANDLE *pIveHandle Returned handle ID of a task
  • IVE_SRC_IMAGE_S *pstSrc Input source data:
  • 1. SP420\SP422 type for YUV2RGB\YUV2HSV\YUV2LAB;
  • 2. U8C3_PACKAGE\U8C3_PLANAR type for RGB2YUV;
  • IVE_DST_IMAGE_S *pstDst Output result:
  • 1. U8C3_PACKAGE\U8C3_PLANAR typed for YUV2RGB\YUV2HSV\YUV2LAB;
  • 2. SP420\SP422 type for RGB2YUV;
  • IVE_CSC_CTRL_S *pstCscCtrl Control parameters for CSC
  • HI_BOOL bInstant For details, see HI_MPI_IVE_DMA.
  • Return Value : HI_SUCCESS: Success;Error codes: Failure.
  • Spec : The size of the input data ranges from 64x64 pixels to 1920x1080 pixels.
  • The physical addresses of the input data and output data must be 16-byte-aligned.
  • The stride must be 16-pixel-aligned.

*****************************************************************************/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
由于我们模型使用的是 IVE_IMAGE_TYPE_U8C3_PLANAR 此种数据格式,因此只能使用YUV2RGB,也就是注释中的第一种情况中的 SP420 to U8C3_PLANAR

再来看看从摄像头出来的图片格式吧,将图片7yuv打开,发现是YUV420 planar I420,对应到ive里的图片格式为IVE_IMAGE_TYPE_YUV420P.

因此在使用 HI_MPI_IVE_CSC 之前要先进行图片转换,简单一点,我们先将IVE_IMAGE_TYPE_YUV420P转换为IVE_IMAGE_TYPE_YUV420SP,再使用.

具体demo代码如下:

typedef struct tag_csc_s
{
        HI_S32  sWidth;
        HI_S32  sHeight;
        IVE_SRC_IMAGE_S stSrc;
        IVE_DST_IMAGE_S stDst;
        IVE_CSC_CTRL_S stCtrl;
}CSC_S;

void CreateCSC(CSC_S* pstCSC, HI_S32 sWidth, HI_S32 sHeight)
{
        HI_S32 s32Ret;
        HI_U32 u32Size;

        pstCSC->sWidth = sWidth;
        pstCSC->sHeight = sHeight;

        // input image
        memset(&pstCSC->stSrc,0,sizeof(IVE_SRC_IMAGE_S));
        pstCSC->stSrc.enType        = IVE_IMAGE_TYPE_YUV420SP;

        s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstCSC->stSrc.au64PhyAddr[0], (HI_VOID **)&pstCSC->stSrc.au64VirAddr[0],
                                                                                 "InputImage", HI_NULL, sWidth * sHeight * 3 / 2);
        if(s32Ret != HI_SUCCESS)
        {
                printf("can't alloc InputImage memory for %x\n",s32Ret);
        }                        
        pstCSC->stSrc.u32Width      = sWidth;
        pstCSC->stSrc.u32Height     = sHeight;
        pstCSC->stSrc.au32Stride[0]  = sWidth;

        // SP420
        pstCSC->stSrc.au32Stride[1] = pstCSC->stSrc.au32Stride[0];
        pstCSC->stSrc.au64PhyAddr[1] = pstCSC->stSrc.au64PhyAddr[0] + pstCSC->stSrc.au32Stride[0] * pstCSC->stSrc.u32Height;
        pstCSC->stSrc.au64VirAddr[1] = pstCSC->stSrc.au64VirAddr[0] + pstCSC->stSrc.au32Stride[0] * pstCSC->stSrc.u32Height;

        // output image
        memset(&pstCSC->stDst,0,sizeof(IVE_DST_IMAGE_S));
        u32Size = sWidth * sHeight * 3;
        pstCSC->stDst.enType        = IVE_IMAGE_TYPE_U8C3_PLANAR;
        s32Ret = HI_MPI_SYS_MmzAlloc(&pstCSC->stDst.au64PhyAddr[0], (void**)&pstCSC->stDst.au64VirAddr[0],
                "OutputImage", HI_NULL, u32Size);
        if(s32Ret != HI_SUCCESS)
        {
                printf("can't alloc OutputImage memory for %x\n",s32Ret);
        }
        pstCSC->stDst.u32Width      = sWidth;
        pstCSC->stDst.u32Height     = sHeight;
        pstCSC->stDst.au32Stride[0]  = sWidth;

        pstCSC->stDst.au64VirAddr[1] = pstCSC->stDst.au64VirAddr[0] + pstCSC->stDst.u32Height * pstCSC->stDst.au32Stride[0];
        pstCSC->stDst.au64PhyAddr[1] = pstCSC->stDst.au64PhyAddr[0] + pstCSC->stDst.u32Height * pstCSC->stDst.au32Stride[0];
        pstCSC->stDst.au32Stride[1] = pstCSC->stDst.au32Stride[0];

        pstCSC->stDst.au64VirAddr[2] = pstCSC->stDst.au64VirAddr[1] + pstCSC->stDst.u32Height * pstCSC->stDst.au32Stride[1];       
        pstCSC->stDst.au64PhyAddr[2] = pstCSC->stDst.au64PhyAddr[1] + pstCSC->stDst.u32Height * pstCSC->stDst.au32Stride[1];
        
        pstCSC->stDst.au32Stride[2] = pstCSC->stDst.au32Stride[0];
       
        // ctrl
        memset(&pstCSC->stCtrl, 0, sizeof(IVE_CSC_CTRL_S));
        pstCSC->stCtrl.enMode = IVE_CSC_MODE_PIC_BT601_YUV2RGB;
}

void DestoryCSC(CSC_S* pstCSC)
{
        if (pstCSC->stSrc.au64PhyAddr[0] != NULL)
        {
                HI_MPI_SYS_MmzFree(pstCSC->stSrc.au64PhyAddr[0], pstCSC->stSrc.au64VirAddr[0]);
        }

        if (pstCSC->stDst.au64VirAddr[0] != NULL)
        {
                HI_MPI_SYS_MmzFree(pstCSC->stDst.au64PhyAddr[0], pstCSC->stDst.au64VirAddr[0]);
        }
}

void ReadYUV420pFile(IVE_IMAGE_S *pstImg, FILE *pFp)
{
        HI_U16 y;
        HI_U8 *pU8;
        HI_U16 height;
        HI_U16 width;
        HI_U8 *pUBuf;
        HI_U8 *pVBuf;
        HI_U16 x;
        int nShift;

        width = pstImg->u32Width;
        height = pstImg->u32Height;
        pU8 = pstImg->au64VirAddr[0];
        for (y = 0; y < height; y++)
        {
                if ( 1 != fread(pU8,width,1,pFp))
                {
                        printf("Read file fail\n");
                        return ;
                }

                pU8 += pstImg->au32Stride[0];
        }

        pUBuf = malloc(width * height / 4);
        pVBuf = malloc(width * height / 4);
        fread(pUBuf, 1, width * height / 4, pFp);
        fread(pVBuf, 1, width * height / 4, pFp);

        pU8 = pstImg->au64VirAddr[1];
        for (y = 0; y < height/2; y++)
        {
                nShift = y * width /2 ;
                for(x = 0; x < width/2; x++)
                {
                        pU8[2*x+0] = pVBuf[nShift + x];
                        pU8[2*x+1] = pUBuf[nShift + x];
                }
                pU8 += pstImg->au32Stride[1];
        }
        
        free(pUBuf);
        free(pVBuf);
}


void WriteYUV420spFile(IVE_IMAGE_S *pstImg, FILE *pFp)
{
        HI_U16 y;
        HI_U8 *pU8;
        HI_U16 height;
        HI_U16 width;

        width = pstImg->u32Width;
        height = pstImg->u32Height *3 /2;
        pU8 = pstImg->au64VirAddr[0];
        for (y = 0; y < height; y++)
        {
                if ( 1 != fwrite(pU8,width,1,pFp))
                {
                        printf("write file error, y = %d\n", y);
                        return ;
                }

                pU8 += pstImg->au32Stride[0];
        }
}

void WriteBGRPackFile(IVE_IMAGE_S *pstImg, FILE *pFp)
{
        HI_U16 y;
        HI_U8 *pU8;
        HI_U16 height;
        HI_U16 width;

        width = pstImg->u32Width;
        height = pstImg->u32Height*3;
        pU8 = pstImg->au64VirAddr[0];
        for (y = 0; y < height; y++)
        {
                if ( 1 != fwrite(pU8,width,1,pFp))
                {
                        printf("write file error, y = %d\n", y);
                        return ;
                }

                pU8 += pstImg->au32Stride[0];
        }
}

void TestCSC(HI_U8 * pu8VirAddr)
// void TestCSC()
{
    IVE_HANDLE hIveHandle;
    CSC_S stCSC;
    FILE *fIn;
    FILE *fOut;
    FILE *fMid;
    HI_CHAR *pchSrcFileName = "./pipe0_chn0_w1920_h1080_P420.yuv";
    HI_CHAR *pchDstFileName = "./pipe0_chn0_w1920_h1080_RGB.bgr";

    HI_CHAR *pchMidFileName = "./pipe0_chn0_w1920_h1080_SP420.yuv";


    fIn = fopen(pchSrcFileName,"rb");
    if(HI_NULL == fIn)
    {
        printf("Open in file %s fail\n",pchSrcFileName);
                return;
    }
    printf("aaaaaaaaaaaaaaaaaaaaa\n");
    fOut = fopen(pchDstFileName,"wb");
    if(HI_NULL == fOut)
    {
        printf("Open out file %s fail\n",pchDstFileName);
        fclose(fIn);
                return;
    }

    fMid = fopen(pchMidFileName,"wb");
    if(HI_NULL == fOut)
    {
        printf("Open out file %s fail\n",pchMidFileName);
        fclose(fIn);
                return;
    }



    int sWidth = 1920;
    int sHeight = 1080;

    printf("aaaaaaaaaaaaaaaaaaaaa\n");
    CreateCSC(&stCSC, sWidth,sHeight);
    ReadYUV420pFile(&stCSC.stSrc, fIn);

    WriteYUV420spFile(&stCSC.stSrc,fMid);
    HI_MPI_IVE_CSC(&hIveHandle, &stCSC.stSrc, &stCSC.stDst, &stCSC.stCtrl, HI_TRUE);

    //B
    memcpy(pu8VirAddr,stCSC.stDst.au64VirAddr[0],sWidth * sHeight);
    //G
    memcpy(pu8VirAddr+sWidth * sHeight,stCSC.stDst.au64VirAddr[1],sWidth * sHeight);
    //R
    memcpy(pu8VirAddr+sWidth * sHeight*2,stCSC.stDst.au64VirAddr[2],sWidth * sHeight);
    

    WriteBGRPackFile(&stCSC.stDst, fOut);
    DestoryCSC(&stCSC);

    fclose(fIn);
    fclose(fOut);
}

————————————————
版权声明:本文为CSDN博主「南有木兮木不知」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mhsszm/article/details/104946840

`