【好文转载】海思Hi3516cv500使用IVE实现yuv420sp转换rgb的opencv下Mat数据格式

原文连接

版权声明:本文为博主lishi_1991原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

感谢大佬lishi_1991 的无私分享

代码实现

#include "hi_ive.h"
#include "hi_comm_ive.h"
#include "mpi_ive.h"
typedef struct tagIPC_IMAGE{
	HI_U64      u64PhyAddr;
	HI_U64      u64VirAddr;
	HI_U32      u32Width;
	HI_U32      u32Height;
}IPC_IMAGE;
 
HI_S32 frame2Mat(VIDEO_FRAME_INFO_S *srcFrame,Mat &dstMat)
{
    HI_U32 w = srcFrame->stVFrame.u32Width;
    HI_U32 h = srcFrame->stVFrame.u32Height;
    int bufLen = w*h*3;
    HI_U8 *srcRGB = NULL;
    IPC_IMAGE dstImage;
    if(yuvFrame2rgb(srcFrame,&dstImage)!=HI_SUCC){
        LOG(ERROR)<<"yuvFrame2rgb Err ."<<endl;
        return HI_FAIL;
    }
    srcRGB = (HI_U8 *)dstImage.u64VirAddr;
    dstMat.create(h, w, CV_8UC3);
    memcpy(dstMat.data, srcRGB, bufLen*sizeof(HI_U8));
    HI_MPI_SYS_MmzFree(dstImage.u64PhyAddr, (void *)&(dstImage.u64VirAddr));
    return HI_SUCC;
}
 
HI_S32 yuvFrame2rgb(VIDEO_FRAME_INFO_S *srcFrame,IPC_IMAGE *dstImage)
{
    IVE_HANDLE hIveHandle;
    IVE_SRC_IMAGE_S pstSrc;
    IVE_DST_IMAGE_S pstDst;
    IVE_CSC_CTRL_S stCscCtrl;
    HI_S32 s32Ret = 0;
    stCscCtrl.enMode = IVE_CSC_MODE_PIC_BT709_YUV2RGB;//IVE_CSC_MODE_VIDEO_BT601_YUV2RGB;
    pstSrc.enType = IVE_IMAGE_TYPE_YUV420SP;
    pstSrc.au64VirAddr[0]=srcFrame->stVFrame.u64VirAddr[0];
    pstSrc.au64VirAddr[1]=srcFrame->stVFrame.u64VirAddr[1];
    pstSrc.au64VirAddr[2]=srcFrame->stVFrame.u64VirAddr[2];
 
    pstSrc.au64PhyAddr[0]=srcFrame->stVFrame.u64PhyAddr[0];
    pstSrc.au64PhyAddr[1]=srcFrame->stVFrame.u64PhyAddr[1];
    pstSrc.au64PhyAddr[2]=srcFrame->stVFrame.u64PhyAddr[2];
 
    pstSrc.au32Stride[0]=srcFrame->stVFrame.u32Stride[0];
    pstSrc.au32Stride[1]=srcFrame->stVFrame.u32Stride[1];
    pstSrc.au32Stride[2]=srcFrame->stVFrame.u32Stride[2];
 
    pstSrc.u32Width = srcFrame->stVFrame.u32Width;
    pstSrc.u32Height = srcFrame->stVFrame.u32Height;
 
    pstDst.enType = IVE_IMAGE_TYPE_U8C3_PACKAGE;
    pstDst.u32Width   = pstSrc.u32Width;
    pstDst.u32Height  = pstSrc.u32Height;
    pstDst.au32Stride[0]  = pstSrc.au32Stride[0];
    pstDst.au32Stride[1]  = 0;
    pstDst.au32Stride[2]  = 0;
    s32Ret = HI_MPI_SYS_MmzAlloc_Cached(&pstDst.au64PhyAddr[0], (void **)&pstDst.au64VirAddr[0], "User", HI_NULL, pstDst.u32Height*pstDst.au32Stride[0]*3);
    if(HI_SUCCESS != s32Ret)
    {       
        HI_MPI_SYS_MmzFree(pstDst.au64PhyAddr[0], (void *)pstDst.au64VirAddr[0]);
        LOG(ERROR)<<"HI_MPI_SYS_MmzAlloc_Cached Failed with 0x"<<hex<<s32Ret<<endl;
        return s32Ret;
    }
    s32Ret = HI_MPI_SYS_MmzFlushCache(pstDst.au64PhyAddr[0], (void *)pstDst.au64VirAddr[0], pstDst.u32Height*pstDst.au32Stride[0]*3);
    if(HI_SUCCESS != s32Ret)
    {       
        HI_MPI_SYS_MmzFree(pstDst.au64PhyAddr[0], (void *)pstDst.au64VirAddr[0]);
        LOG(ERROR)<<"HI_MPI_SYS_MmzFlushCache Failed with 0x"<<hex<<s32Ret<<endl;
        return s32Ret;
    }
    memset((void *)pstDst.au64VirAddr[0], 0, pstDst.u32Height*pstDst.au32Stride[0]*3);
    HI_BOOL bInstant = HI_TRUE;
    s32Ret = HI_MPI_IVE_CSC(&hIveHandle,&pstSrc,&pstDst,&stCscCtrl,bInstant);
    if(HI_SUCCESS != s32Ret)
    {       
        HI_MPI_SYS_MmzFree(pstDst.au64PhyAddr[0], (void *)pstDst.au64VirAddr[0]);
        LOG(ERROR)<<"HI_MPI_IVE_CSC Failed with 0x"<<hex<<s32Ret<<endl;
        return s32Ret;
    }
    if (HI_TRUE == bInstant)
    {
        HI_BOOL bFinish = HI_TRUE;
        HI_BOOL bBlock = HI_TRUE;
        s32Ret = HI_MPI_IVE_Query(hIveHandle,&bFinish,bBlock);
        while(HI_ERR_IVE_QUERY_TIMEOUT == s32Ret)
        {
            usleep(100);
            s32Ret = HI_MPI_IVE_Query(hIveHandle,&bFinish,bBlock);
        }
    }
    dstImage->u64PhyAddr = pstDst.au64PhyAddr[0];
    dstImage->u64VirAddr = pstDst.au64VirAddr[0];
    dstImage->u32Width = pstDst.u32Width;
    dstImage->u32Height = pstDst.u32Height;
    return HI_SUCC;
}

调用

{
    Mat frame;
    VIDEO_FRAME_INFO_S videoframeinfo;
	HI_MPI_VPSS_GetChnFrame(,,&videoframeinfo,);
	...;
	frame2Mat(&videoframeinfo,frame);
    imwrite("save.bmp", frame);
}

你可能感兴趣的:(opencv,c++,嵌入式硬件)