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