海思3559平台移植二维码解码库zbar

1. 下载并解压 zbar 源码包:

http://zbar.sourceforge.net/download.html
海思3559平台移植二维码解码库zbar_第1张图片
zbar-0.10.tar.bz2
解压缩:
tar -xvjf zbar-0.10.tar.bz2

2. 编译过程

./configure –prefix=/home/lie/3559_V30_KK_SY/references/thirdparty/zbar-0.10/lib_out/ –host=arm-hisiv600-linux –disable-video –without-imagemagick –without-gtk –without-qt –without-python –enable-static
make
make install

其中 /home/lie/3559_V30_KK_SY/references/thirdparty/zbar-0.10/lib_out/ 修改为要生成lib的绝对路径。
-host=arm-hisiv600-linux 指定编译链

3. 生成的库文件

在路径/home/lie/3559_V30_KK_SY/references/thirdparty/zbar-0.10/lib_out/lib下:
libzbar.a
include文件夹下面的头文件:
zbar.h

4. 应用程序添加库文件

将库加入到放库的路径
在Makefile中直接添加
VSS_LIB += -lzbar

5. 调用zbar算法 识别二维码

在代码包里,有个examples的文件夹,
嵌入式平台的调用可以参考scan_image.c

流程图如下
海思3559平台移植二维码解码库zbar_第2张图片

初始化以及参数配置:

zbar_image_scanner_t *scanner = NULL;
zbar_image_t *image= NULL;

int width = 1024, height = 576;
    /* create a reader */
    scanner = zbar_image_scanner_create();

    /* configure the reader */
    zbar_image_scanner_set_config(scanner, 0, ZBAR_CFG_ENABLE, 1);

     /* obtain image data */
     image = zbar_image_create();
    zbar_image_set_format(image, *(int*)"Y800");
    zbar_image_set_size(image, width, height);

上面设置的“Y800”的模式是只需要 YUV图像中的Y分量(灰阶)
从YUV420的数据中只取前面的Y数据即可。

载入图像以及识别的流程,我这里做了一个线程一直去处理,直到识别到二维码退出

static HI_S32 Service_Zbar_Start()
{
    void *raw = NULL;
    int width = 1024, height = 576; 
    pthread_detach(pthread_self());
    raw = (void*)malloc(width*height);
    if(NULL == raw)
    {
        printf("[Zbar_Start]:malloc memory failed \n");
        return -1;
    }

    while(Zbar_Thread_Start)
    {
        usleep(100*1000);
        if(s_video_valid == HI_FALSE)
            continue;

        pthread_mutex_lock(&s_video_mutex);
        //只复制Y分量的数据内容
        memcpy(raw, s_video_frame, width*height);
        s_video_valid = HI_FALSE;
        pthread_mutex_unlock(&s_video_mutex);


        zbar_image_set_data(image, raw, width * height, NULL);


        /* scan the image for barcodes */
        int n = zbar_scan_image(scanner, image);

        if(n==0)
            continue;

        /* extract results */
        const zbar_symbol_t *symbol = zbar_image_first_symbol(image);
        for(; symbol; symbol = zbar_symbol_next(symbol)) 
        {
            /* do something useful with results */
            zbar_symbol_type_t typ = zbar_symbol_get_type(symbol);
            const char *data = zbar_symbol_get_data(symbol);

            printf("decoded %s symbol \"%s\"\n",
                   zbar_get_symbol_name(typ), data);
        }

        break;

    }

    free(raw);

    return HI_SUCCESS;

}

6. 海思平台获取YUV420数据

hisi3559可以直接获取YUV420的数据,
获取到的是数据放在一个buffer中,供zbar的zbar_image_set_data函数使用。

HI_S32 VideoSaveFrame(HI_HANDLE VProcHdl, HI_HANDLE VPortHdl, HI_FRAME_DATA_S* pVPortYUV)
{   
    char* pFrame = s_video_frame;
    char* pVBufVirt_Y;
    HI_U32 u32FrameSize = 0;
    HI_U8* pUserPageAddr = NULL;
    HI_U32 phy_addr;
    HI_MPP_PIXEL_FORMAT_E  enPixelFormat = pVPortYUV->enPixelFormat;

    if(pVPortYUV->enCompressMode != HI_COMPRESS_MODE_NONE)
    {
        printf("Frame is compressed:%d\n", pVPortYUV->enCompressMode);
        return HI_FAILURE;
    }       
    if (HI_MPP_PIXEL_FORMAT_420 == enPixelFormat)
    {
        u32FrameSize = (pVPortYUV->u32Stride[0]) * (pVPortYUV->u32Height) * 3 / 2;
    }
    else if(HI_MPP_PIXEL_FORMAT_422 == enPixelFormat)
    {
        u32FrameSize = (pVPortYUV->u32Stride[0]) * (pVPortYUV->u32Height) * 2;
    }
    else
    {
        printf("enPixelFormat error.\n");
        return HI_FAILURE;
    }

    phy_addr = pVPortYUV->u32PhyAddr[0];        
    pUserPageAddr = (HI_U8*) Video_Mmap(phy_addr, u32FrameSize);
    if (HI_NULL == pUserPageAddr)
    {
        printf("mmap error.\n");
        return HI_FAILURE;
    }

    pVBufVirt_Y = (HI_CHAR*)pUserPageAddr;

    // save Y ----------------------------------------------------------------
    pthread_mutex_lock(&s_video_mutex);

    memcpy(pFrame, pVBufVirt_Y, u32FrameSize);
    s_video_valid = HI_TRUE;
    pthread_mutex_unlock(&s_video_mutex);

    Video_Munmap(pUserPageAddr, u32FrameSize);

    return HI_SUCCESS;
}

HI_S32 VideoStart_Color()
{
    HI_S32 s32Ret =0;
    HI_HANDLE VProcHdl =VPROC_HDL_COLOR;
    HI_HANDLE VPortHdl =VPORT_HDL_COLOR;
    HI_VPORT_ATTR_S  stVPortAttr;
    stVPortAttr.s32FrameRate = VPROC_FRAME_RATE;
    stVPortAttr.stResolution.u32Width = 1024;
    stVPortAttr.stResolution.u32Height = 576;
    stVPortAttr.enPixFormat = HI_MPP_PIXEL_FORMAT_420;
    stVPortAttr.enCompressMode = HI_COMPRESS_MODE_NONE;
    s32Ret = HI_MAPI_VProc_Port_SetAttr(VProcHdl, VPortHdl, &stVPortAttr);
    if(s32Ret != HI_SUCCESS) 

    {
        printf("HI_MAPI_VProc_Port_SetAttr( %d,%d) fail. error = %X\r\n", 
            VProcHdl, VPortHdl, s32Ret);
        return s32Ret;
    }

    //dump YUV
    s32Ret = HI_MAPI_VProc_EnableDumpYUV(VProcHdl, VPortHdl);
    if(s32Ret != HI_SUCCESS) 
    {
        printf("HI_MAPI_VProc_EnableDumpYUV( %d,%d) fail. error = %X\r\n", 
        VProcHdl, VPortHdl, s32Ret);
        return s32Ret;
    }    

    HI_MAPI_VProc_Port_Start(VProcHdl, VPortHdl);
    s32Ret = HI_MAPI_VProc_DumpYUV(VProcHdl, VPortHdl, 0, VideoSaveFrame);

    if(s32Ret != HI_SUCCESS) 

    {
        printf("HI_MAPI_VProc_EnableDumpYUV( %d,%d) fail. error = %X\r\n", 
        VProcHdl, VPortHdl, s32Ret);
    }   

    return s32Ret;
}

测试结果,

条码识别成功。
二维码QR code码识别成功。
识别速度还算可以。

你可能感兴趣的:(海思平台(hisi),开源移植)