zhuifengsn

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn  发布于  2015-05-16 14:44:08
采纳率 0%
7个问答
13362

yuv转RGB,生成图片仍然为黑白。

 
本帖最后由 zhuifengsn 于 2015-5-16 15:04 编辑

我的开发板是HI3520D,我通过getframe函数获取一帧,然后从网上找了YUV转RGB的公式进行转换成RGB24,通过opencv的函数将图片保存下来。发现保存的图片仍然为黑白色。我尝试过修改YUV2RGB转换的公式系数,但始终没有获得彩色图片。想问下有没有朋友有过类似的经历,如果有测试代码共享下就更好了!

我的思路:
1,获取一帧YUV图像数据;
2,通过HI_MPI_SYS_Mmap函数将物理地址映射到内存;
3,根据semiplanar420存储YUV的特点(Y连续,UV交叉存储),依次取出YUV数据;
4,通过公式来进行像素值转换;
5,将数据存入iplimage中;
6,保存RGB图像到本地。

以下为我的部分代码:
[code]/* get video frame from vi chn */
s32ret = HI_MPI_VI_GetFrame(ViChn, &stFrame) ;
                 if (HI_SUCCESS != s32ret)
                 {
                  printf("get vi frame err:0x%x\n", s32ret);
                  return s32ret;
                 }
         /* deal with video frame ... */
         int height=stFrame.stVFrame.u32Height;
         int width=stFrame.stVFrame.u32Width;
         unsigned char *Ybuf= (unsigned char *) malloc(sizeof(unsigned char)*height*width);
         unsigned  char *UVbuf=(unsigned char *) malloc(sizeof(unsigned char)*height*width/2);
         int R,G,B,Y,U,V;
         Ybuf = (unsigned char *) HI_MPI_SYS_Mmap(stFrame.stVFrame.u32PhyAddr[0], height*width);
         UVbuf = (unsigned char *) HI_MPI_SYS_Mmap(stFrame.stVFrame.u32PhyAddr[1], height*width/2);
         /*        yuv转RGB单通道        */
        for(i=0;i         {
                for(j=0;j                 {
                        (gryimg->imageData+i*IMG_WIDTH)[j*gryimg->nChannels]=
                                *(Ybuf+i*IMG_WIDTH+j);
                        //灰度图片为单通道,故nchannels=1
                }       
        }
         /*        yuv转RGB        */
        for(i=0;i         {
                for(j=0;j                 {//存储顺序为:BGR
                Y=max(Ybuf[i*IMG_WIDTH+j],0);
                U=max(UVbuf[((i*IMG_WIDTH+j)/4)*2]-128,0);
                V=max(UVbuf[((i*IMG_WIDTH+j)/4)*2+1]-128,0);
                //cout<<"u="<                        B = Y + 1.779 *U;
                G = Y-0.3455 *U-0.7169 *V;      
                R = Y + 1.0475 *V;
               
                B = min(255, max(0, B));
                G = min(255, max(0, G));        
                R = min(255, max(0, R));

                img->imageData[i*IMG_WIDTH*3+3*j]= B;//B' = Y' + 2.032*U'
                img->imageData[i*IMG_WIDTH*3+3*j+1]= G;//G' = Y' - 0.394*U' - 0.581*V'       
                img->imageData[i*IMG_WIDTH*3+3*j+2]= R;//R' = Y' + 1.140*V'                       
                }       
        } [/code]
实际处理得到的图片如下:
(1)直接保存灰度图

(2)RGB24图

我来回答
回答20个
时间排序
认可量排序

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2015-05-17 05:12:03
认可0
根据我做过得经验是...转法公式的不同
Hisi 目前转出来对的公式为

ColorYCbCrtoRGB
R = 1.164 * (Y - 16) + 1.596 * (Cr - 128)
G = 1.164 * (Y - 16) - 0.813 * (Cr - 128) - 0.392 * (Cb - 128)
B = 1.164 * (Y - 16) + 2.017 * (Cb - 128)

ColorRGBtoYCbCr
Y = ( 0.257f * r + 0.504f * g + 0.098f * b) + 16.
U = (-0.148f * r - 0.291f * g + 0.439f * b) + 128.
V = ( 0.439f * r - 0.368f * g - 0.071f * b) + 128.

这种查表转法是非常快的, 缺点是转换后跟原图差异比较大

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn 2015-05-17 09:43:49
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=16103&ptid=7600]LinJoy 发表于 2015-5-17 05:12[/url]
根据我做过得经验是...转法公式的不同
Hisi 目前转出来对的公式为

[/quote]

谢谢,我试试

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn 2015-05-17 09:49:11
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=16103&ptid=7600]LinJoy 发表于 2015-5-17 05:12[/url]
根据我做过得经验是...转法公式的不同
Hisi 目前转出来对的公式为

[/quote]

得到的仍然是黑白图,没有色彩。跟我上面的效果基本一样

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2015-05-17 17:19:45
认可0
那你的 NTSC 和 PAL 制設定是否正確, 就是 Camera 為 PAL 那 VO 就要設定 PAL
一般來說 VO 看到是 VI 直接輸出過來的, 這時候要為彩色 (VI->VPSS->VO 要 ntsc/pal 一致性)
這樣轉換過來來會彩色, 當看到彩色的畫面再去做 GetImage 轉換

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn 2015-05-17 20:31:49
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=16114&ptid=7600]LinJoy 发表于 2015-5-17 17:19[/url]
那你的 NTSC 和 PAL 制設定是否正確, 就是 Camera 為 PAL 那 VO 就要設定 PAL
一般來說 VO 看到是 VI 直接 ...[/quote]

全部都是PAL格式,统一的。另外,我做过实验,如果只是把视频流存到本地,可以看到是彩色图像的。

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2015-05-17 21:06:21
认可0
本帖最后由 LinJoy 于 2015-5-17 21:08 编辑

原因可能出錯再這邊
                Y=max(Ybuf[i*IMG_WIDTH+j],0);
                U=max(UVbuf[((i*IMG_WIDTH+j)/4)*2]-128,0);
                V=max(UVbuf[((i*IMG_WIDTH+j)/4)*2+1]-128,0);
正確應該是
                Y=max(Ybuf[i*IMG_WIDTH+j],0);
                V=max(UVbuf[((i*IMG_WIDTH+j)/4)*2]-128,0);
                U=max(UVbuf[((i*IMG_WIDTH+j)/4)*2+1]-128,0);

Hisi 420 之排列為
        Yptr ==> Y Y
       uvptr ==> V U
        取出 2 點 Y 都對 1 次 V U (先V 在 U) 做計算
        這樣應該就對了

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2015-05-17 21:14:23
认可0
等正確後再去最佳化吧, 目前你的碼一整個 慢, 且記憶體配置也應該不需要

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn 2015-05-17 22:06:41
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=16117&ptid=7600]LinJoy 发表于 2015-5-17 21:06[/url]
原因可能出錯再這邊
                Y=max(Ybuf,0);
                U=max(UVbuf[((i*IMG_WIDTH+j)/4)* ...[/quote]

将UV调换之后,图片效果还是老样子,没有太大变化。是否可以加q向您请教?

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2015-05-18 09:45:13
认可0
  Y=max(Ybuf[i*IMG_WIDTH+j],0);
                U=max(UVbuf[((i*IMG_WIDTH+j)/4)*2]-128,0);    ==> 這樣做誰說可以的, 直接減去 Interger 128, 這樣似乎不行
                V=max(UVbuf[((i*IMG_WIDTH+j)/4)*2+1]-128,0);
                //cout<<"u="<                 B = Y + 1.779 *U;
                G = Y-0.3455 *U-0.7169 *V;      
                R = Y + 1.0475 *V;
                B = min(255, max(0, B));   ==> Max 裁剪, 好像也沒有這樣用的
                G = min(255, max(0, G));        
                R = min(255, max(0, R));
----------------------------------------------------------------------------------
我這邊有轉換一點程式
u32 ColorYCbCrtoRGB (u32 tYCbCr)
{
    u8 r, g, b, y, cb, cr;

    y  = (tYCbCr & 0xFF);
    cb = (tYCbCr >> 8) & 0xFF;      // U
    cr = (tYCbCr >> 16) & 0xFF;     // V
    //  R =  1.164 * (Y - 16) + 1.596 * (Cr - 128)
    //  G =  1.164 * (Y - 16) - 0.813 * (Cr - 128) - 0.392 * (Cb - 128)
    //  B =  1.164 * (Y - 16) + 2.017 * (Cb - 128)
    r = (u8)(1.164f * (y - 16.) + 1.596f * (cr - 128.));
    g = (u8)(1.164f * (y - 16.) - 0.813f * (cr - 128.) - 0.392f * (cb - 128.));
    b = (u8)(1.164f * (y - 16.) + 2.017f * (cb - 128.));
    return (dMakeColorRGB (r, g, b));
}

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn 2015-05-18 16:33:07
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=16129&ptid=7600]LinJoy 发表于 2015-5-18 09:45[/url]
Y=max(Ybuf,0);
                U=max(UVbuf[((i*IMG_WIDTH+j)/4)*2]-128,0);    ==> 這樣做誰說可以的 ...[/quote]

我那些转换公式都是从网上找的,结果发现都用不了。
我试了下你的,也不行,色彩是乱的

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2015-05-18 18:04:27
认可0
可能你流程那部份有問題,
我這邊是將圖片抓出後 直接 jpeg 編碼再寫出去
一般要直接轉 RGB 通常是拿來計算用的,

867241432

0个粉丝

9

问答

0

专栏

0

资料

867241432 2015-05-18 19:24:58
认可0
void YUV2RGB(unsigned char **yuvData, unsigned char *pRGB, int width, int height)
{
        int y_width = width;
        int y_height = height;
        int uv_width = width / 2;
        int y_index = 0;
        int uv_index = 0;
        int i = 0;
        int j = 0;
        int uTemp;
        int vTemp;
        unsigned char *rgbData = (unsigned char *)malloc(width * height * 3);
        unsigned char *rData = rgbData;
        unsigned char *gData = rgbData + width * height;
        unsigned char *bData = gData + width * height;
        int temp = 0;
        for(i = 0; i < y_height; i++)
        {
                for(j = 0; j < y_width; j++)
                {
                        y_index = i * y_width + j;
                        uv_index = (i >> 1) * uv_width + (j >> 1);
                        uTemp = (int)yuvData[1][uv_index] - 128;
                        vTemp = (int)yuvData[2][uv_index] - 128;
                        //R
                        temp = (int)yuvData[0][y_index] + vTemp + ((vTemp * 103) >> 8);
                        rData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
                        //G
                        temp = (int)yuvData[0][y_index] - ((uTemp * 88) >> 8) - ((vTemp * 183) >> 8);
                        gData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
                        //B
                        temp = (int)yuvData[0][y_index] + uTemp + ((uTemp * 198) >> 8);
                        bData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
                        /*
                        //R
                        temp = (int)yuvData[0][y_index] + ((int)yuvData[2][uv_index] - 128) * 1.4022;
                        rData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
                       
                        //G
                        temp = (int)yuvData[0][y_index] - 0.7145 * ((int)yuvData[2][uv_index] - 128) -
                                                                                0.3456 * ((int)yuvData[1][uv_index] - 128);

                        gData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));

                        //B
                        temp = (int)yuvData[0][y_index] + ((int)yuvData[1][uv_index] - 128) * 1.771;
                        bData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
                        */

                }
        }
        for(i = 0; i < height; i++)
        {
                for(j = 0; j < width; j++)
                {
                        pRGB[i * width * 3 + j * 3 + 0] = bData[i * width + j];
                        pRGB[i * width * 3 + j * 3 + 1] = gData[i * width + j];
                        pRGB[i * width * 3 + j * 3 + 2] = rData[i * width + j];
                }
        }
        free(rgbData);
}

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn 2015-05-18 21:28:35
认可0
本帖最后由 zhuifengsn 于 2015-5-18 21:41 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=16156&ptid=7600]867241432 发表于 2015-5-18 19:24[/url]
void YUV2RGB(unsigned char **yuvData, unsigned char *pRGB, int width, int height)
{
        int y_width = ...[/quote]

semiplanar存储方式为UV交叉存储。那你要使得U和V各自连续存储,就要先将值复制到一个二维数组咯?另外,是否有可用的例程?求分享可用代码

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn 2015-05-18 21:33:08
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=16151&ptid=7600]LinJoy 发表于 2015-5-18 18:04[/url]
可能你流程那部份有問題,
我這邊是將圖片抓出後 直接 jpeg 編碼再寫出去
一般要直接轉 RGB 通常是拿來計 ...[/quote]

我是要获取像素数据来做识别的用途。能否帮看下代码?我是基于venc例程修改的。
[code]#include"opencv/cv.h"
#include"opencv/highgui.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include "sample_comm.h"
#include "hi_type.h"

#define IMG_WIDTH       960
#define IMG_HEIGTH                576
#define RGB_SIZE        (IMG_WIDTH * IMG_HEIGTH * 3)
#define Y_SIZE          (IMG_WIDTH * IMG_HEIGTH)
#define UV_SIZE         (IMG_WIDTH * IMG_HEIGTH/ 4)
#define COLOR_CHN       3
#pragma pack(push)

#ifndef max
#define max(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
#define min(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
#endif

#pragma pack(4)
#pragma pack(pop)

using namespace std;
using namespace cv;

/******************for time mesurement*************************/
struct timeval tpstart,tpend;
unsigned long timeuses;
void timeRec()
{
    gettimeofday(&tpstart,0);
}
int timeRep()
{
    gettimeofday(&tpend,0);
    timeuses=(tpend.tv_sec-tpstart.tv_sec)*1000000+tpend.tv_usec-tpstart.tv_usec;
    printf("use time: %uus\n",timeuses);
    return timeuses;
}
/********************end**************************************/

/******************************************************************************
* function : to process abnormal case                                         
******************************************************************************/
void SAMPLE_VENC_HandleSig(HI_S32 signo)
{
    if (SIGINT == signo || SIGTSTP == signo)
    {
        SAMPLE_COMM_SYS_Exit();
        printf("\033program termination abnormally!\033");
    }
    exit(-1);
}

/******************************************************************************
* function : to process abnormal case - the case of stream venc
******************************************************************************/
void SAMPLE_VENC_StreamHandleSig(HI_S32 signo)
{

    if (SIGINT == signo || SIGTSTP == signo)
    {
        SAMPLE_COMM_SYS_Exit();
        printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
    }

    exit(0);
}
HI_U32 InitVideoCam()
{
        VIDEO_NORM_E gs_enNorm = VIDEO_ENCODING_MODE_PAL;
        SAMPLE_VI_MODE_E enViMode= SAMPLE_VI_MODE_4_D1;
        HI_U32 viChnCnt=4;
        HI_U32 vpssGrpCnt=4;
        PAYLOAD_TYPE_E enPayLoad[2]= {PT_H264, PT_H264};
        PIC_SIZE_E enSize[2] = {PIC_960H, PIC_CIF};

    VB_CONF_S stVbConf;   //videobuffer
    VPSS_GRP VpssGrp;
    VPSS_GRP_ATTR_S stGrpAttr;
    VENC_GRP VencGrp;
    VENC_CHN VencChn;
    SAMPLE_RC_E enRcMode=SAMPLE_RC_VBR;
        HI_U32 i;
    HI_U32 s32Ret = HI_SUCCESS;
    HI_U32 u32BlkSize;
    SIZE_S stSize;       
    /******************************************
     step  1: init variable
    ******************************************/       
    memset(&stVbConf,0,sizeof(VB_CONF_S));
    u32BlkSize = SAMPLE_COMM_SYS_CalcPicVbBlkSize(gs_enNorm,\
                PIC_960H, SAMPLE_PIXEL_FORMAT, SAMPLE_SYS_ALIGN_WIDTH);
        cout<<"BlkSize="<     stVbConf.u32MaxPoolCnt = 128;
   
    stVbConf.astCommPool[0].u32BlkSize = u32BlkSize;
    stVbConf.astCommPool[0].u32BlkCnt = viChnCnt * 6;
    memset(stVbConf.astCommPool[0].acMmzName,0,
        sizeof(stVbConf.astCommPool[0].acMmzName));

    /* hist buf*/
    stVbConf.astCommPool[1].u32BlkSize = (196*4);
    stVbConf.astCommPool[1].u32BlkCnt = viChnCnt * 6;
    memset(stVbConf.astCommPool[1].acMmzName,0,
        sizeof(stVbConf.astCommPool[1].acMmzName));
    /******************************************
     step 2: mpp system init.
    ******************************************/
    s32Ret = SAMPLE_COMM_SYS_Init(&stVbConf);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("system init failed with %d!\n", s32Ret);
        return -1;
    }

    /******************************************
     step 3: start vi dev & chn to capture
    ******************************************/
    s32Ret = SAMPLE_COMM_VI_Start(enViMode, gs_enNorm);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("start vi failed!\n");
       return -1;
    }
   
    /******************************************
     step 4: start vpss and vi bind vpss
    ******************************************/
    s32Ret = SAMPLE_COMM_SYS_GetPicSize(gs_enNorm, PIC_960H, &stSize);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("SAMPLE_COMM_SYS_GetPicSize failed!\n");
        return -1;
    }
        cout<<"picsize="<     //VPSS group static attribute
    stGrpAttr.u32MaxW = stSize.u32Width;
    stGrpAttr.u32MaxH = stSize.u32Height;
    stGrpAttr.bDrEn = HI_FALSE;
    stGrpAttr.bDbEn = HI_FALSE;
    stGrpAttr.bIeEn = HI_TRUE;
    stGrpAttr.bNrEn = HI_TRUE;
    stGrpAttr.bHistEn = HI_TRUE;
    stGrpAttr.enDieMode = VPSS_DIE_MODE_AUTO;
    stGrpAttr.enPixFmt = SAMPLE_PIXEL_FORMAT;

    s32Ret = SAMPLE_COMM_VPSS_Start(vpssGrpCnt, &stSize, VPSS_MAX_CHN_NUM,NULL);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("Start Vpss failed!\n");
        return -1;
    }

    s32Ret = SAMPLE_COMM_VI_BindVpss(enViMode);
    if (HI_SUCCESS != s32Ret)
    {
        SAMPLE_PRT("Vi bind Vpss failed!\n");
        return -1;
    }
   
  /******************************************
     step 5: start stream venc (big + little)
    ******************************************/
    for (i=0; i     {
        /*** main stream **/
        VencGrp = i*2;
        VencChn = i*2;
        VpssGrp = i;
        s32Ret = SAMPLE_COMM_VENC_Start(VencGrp, VencChn, enPayLoad[0],\
                                       gs_enNorm, enSize[0], enRcMode);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
                        return -1;
        }

        s32Ret = SAMPLE_COMM_VENC_BindVpss(VencGrp, VpssGrp, VPSS_BSTR_CHN);//定义大码流通道号
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
                        return -1;
        }

        /*** Sub stream **/
        VencGrp ++;
        VencChn ++;
        s32Ret = SAMPLE_COMM_VENC_Start(VencGrp, VencChn, enPayLoad[1], \
                                        gs_enNorm, enSize[1], enRcMode);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
                        return -1;
        }

        s32Ret = SAMPLE_COMM_VENC_BindVpss(VencChn, VpssGrp, VPSS_PRE0_CHN);
        if (HI_SUCCESS != s32Ret)
        {
            SAMPLE_PRT("Start Venc failed!\n");
                        return -1;
        }
   }
                /* set max depth */
                s32Ret = HI_MPI_VI_SetFrameDepth(0, 5);
                if (HI_SUCCESS != s32Ret)
                {
                 printf("set max depth err:0x%x\n", s32Ret);
                 return s32Ret;
                 }                        
                return s32Ret;       
       
}
HI_U32 GetYUVStream(IplImage *gryimg,IplImage *img)
{
        HI_S32 s32ret=HI_SUCCESS;
        VI_CHN ViChn = 0;
        VIDEO_FRAME_INFO_S stFrame;
         /* get video frame from vi chn */
         s32ret = HI_MPI_VI_GetFrame(ViChn, &stFrame) ;
         if (HI_SUCCESS != s32ret)
         {
          printf("get vi frame err:0x%x\n", s32ret);
          return s32ret;
         }
               
         /* deal with video frame ... */
         unsigned char *Ybuf= (unsigned char *) malloc(sizeof(unsigned char)*IMG_HEIGTH*IMG_WIDTH);
         unsigned  char *UVbuf=(unsigned char *) malloc(sizeof(unsigned char)*IMG_HEIGTH*IMG_WIDTH/2);
         int R,G,B,Y,U,V;
         Ybuf = (unsigned char *) HI_MPI_SYS_Mmap(stFrame.stVFrame.u32PhyAddr[0], IMG_HEIGTH*IMG_WIDTH);
         UVbuf = (unsigned char *) HI_MPI_SYS_Mmap(stFrame.stVFrame.u32PhyAddr[1], IMG_HEIGTH*IMG_WIDTH/2);
         cout<<"phyaddr:"<          /*        yuv转RGB单通道        */
        for(int i=0;i         {
                for(int j=0;j                 {
                        (gryimg->imageData+i*IMG_WIDTH)[j*gryimg->nChannels]=
                                *(Ybuf+i*IMG_WIDTH+j);
                        //灰度图片为单通道,故nchannels=1
                }       
        }
         /*        yuv转RGB24        */
        for(int i=0;i         {
                for(int j=0;j                 {//存储顺序为:BGR
                /*
                Y=max(Ybuf[i*IMG_WIDTH+j]-16,0);
                U=UVbuf[((i*IMG_WIDTH+j)/4)*2]-128;
                V=UVbuf[((i*IMG_WIDTH+j)/4)*2+1]-128;

                Y*=1192;
               
        B = Y + 2066 *U;
                G = Y- 400 *U-833 *V;      
                R = Y + 2066 *V;
               
                B = min(262143, max(0, B));
                G = min(262143, max(0, G));        
                R = min(262143, max(0, R));
                B=B>>10;
                G=G>>10;
                R=R>>10;
                */
                Y=Ybuf[i*IMG_WIDTH+j];
                U=UVbuf[((i*IMG_WIDTH+j)/4)*2];
                V=UVbuf[((i*IMG_WIDTH+j)/4)*2+1];
                R=(HI_U8)(1.164f*(Y-16)+1.596f*(V-128));
                G=(HI_U8)(1.164f*(Y-16)-0.813f*(V-128)-0.392f*(U-128));
                B=(HI_U8)(1.164f*(Y-16)+2.017f*(U-128));
               
               
                int step=img->widthStep/sizeof(unsigned char);
                int channels=img->nChannels;
                img->imageData[i*step+channels*j]= B;//B' = Y' + 2.032*U'
                img->imageData[i*step+channels*j+1]= G;//G' = Y' - 0.394*U' - 0.581*V'       
                img->imageData[i*step+channels*j+2]= R;//R' = Y' + 1.140*V'                       
                }       
        }          
         /* release video frame */  
        (void)HI_MPI_VI_ReleaseFrame(ViChn, &stFrame);
        SAMPLE_COMM_SYS_Exit();;
}
void YUV2RGB(unsigned char **yuvData, unsigned char *pRGB, int width, int height)
{
        int y_width = width;
        int y_height = height;
        int uv_width = width / 2;
        int y_index = 0;
        int uv_index = 0;
        int i = 0;
        int j = 0;
        int uTemp;
        int vTemp;
        unsigned char *rgbData = (unsigned char *)malloc(width * height * 3);
        unsigned char *rData = rgbData;
        unsigned char *gData = rgbData + width * height;
        unsigned char *bData = gData + width * height;
        int temp = 0;
        for(i = 0; i < y_height; i++)
        {
                for(j = 0; j < y_width; j++)
                {
                        y_index = i * y_width + j;
                        uv_index = (i >> 1) * uv_width + (j >> 1);
                        uTemp = (int)yuvData[1][uv_index] - 128;
                        vTemp = (int)yuvData[2][uv_index] - 128;
                        //R
                        temp = (int)yuvData[0][y_index] + vTemp + ((vTemp * 103) >> 8);
                        rData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
                        //G
                        temp = (int)yuvData[0][y_index] - ((uTemp * 88) >> 8) - ((vTemp * 183) >> 8);
                        gData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
                        //B
                        temp = (int)yuvData[0][y_index] + uTemp + ((uTemp * 198) >> 8);
                        bData[y_index] = (unsigned char)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));


                }
        }
        for(i = 0; i < height; i++)
        {
                for(j = 0; j < width; j++)
                {
                        pRGB[i * width * 3 + j * 3 + 0] = bData[i * width + j];
                        pRGB[i * width * 3 + j * 3 + 1] = gData[i * width + j];
                        pRGB[i * width * 3 + j * 3 + 2] = rData[i * width + j];
                }
        }
        free(rgbData);
}

/******************************************************************************
* function    : main()
* Description : get video stream ,convert to rgb picture and save it
******************************************************************************/
int main(int argc, char *argv[])
{
            signal(SIGINT, SAMPLE_VENC_HandleSig);
            signal(SIGTERM, SAMPLE_VENC_HandleSig);       
                IplImage *gryimg=cvCreateImage(cvSize(IMG_WIDTH,IMG_HEIGTH),IPL_DEPTH_8U,1);
                IplImage *img=cvCreateImage(cvSize(IMG_WIDTH,IMG_HEIGTH),IPL_DEPTH_8U,3);
                HI_S32 s32Ret=InitVideoCam();
                if(s32Ret==HI_FAILURE)
                        {
                        cout<<"InitVideoCam failed!"<                         return -1;
                }                       
                s32Ret=GetYUVStream(gryimg,img);
                if(s32Ret==HI_FAILURE)
                {
                        cout<<"GetYUVStream failed!"<                         return -1;               
                }               
                        cvSaveImage("snapgry.jpg",gryimg);
                        cvSaveImage("snap.jpg",img);
                         timeRep();
                return 0;       
}


[/code]

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2015-05-20 02:54:06
认可0
好似奇怪, 既然最後都儲存為 jpeg , 就不需要轉為 RGB
Hisi 抓到 Frame 以後再送進去編碼為 jpeg
然後編碼資料出來就直接儲存就好

LinJoy

0个粉丝

1

问答

0

专栏

0

资料

LinJoy 2015-05-20 03:04:42
认可0
建議 最後轉為 RGB 就直接輸出 BMP 檔案吧
如果要輸出 JPG, 在 Hisi GetFrame 後 直接編碼 jpeg 就直接儲存即可

zhuifengsn

0个粉丝

7

问答

0

专栏

0

资料

zhuifengsn 2015-05-22 22:24:04
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=16187&ptid=7600]LinJoy 发表于 2015-5-20 03:04[/url]
建議 最後轉為 RGB 就直接輸出 BMP 檔案吧
如果要輸出 JPG, 在 Hisi GetFrame 後 直接編碼 jpeg 就直接儲 ...[/quote]

好的,我试试

猴子的救兵

0个粉丝

12

问答

0

专栏

0

资料

猴子的救兵 2016-02-23 09:28:38
认可0
楼主问题解决了吗,我遇到和你一样的问题,能分享一下代码吗

hero

0个粉丝

1

问答

0

专栏

0

资料

hero 2019-02-20 17:48:58
认可0
marking   :lol:lol:lol:lol:lol

zzf

0个粉丝

0

问答

0

专栏

0

资料

zzf 2024-02-17 20:19:06
认可0

解决了吗,我也有这个问题

或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区