在海思平台上实现统计图像像素非零点个数

merz 2019-12-31 16:23:45 2489

目录 (Table of Contents)

[TOCM]

1 对 IVE_IMAGE_S 的分析

这部分内容来自海思文档 HiIVE API 参考 ,文档中有更多图像类型的说明内容。

说明

定义二维广义图像信息。

定义

typedef struct hiIVE_IMAGE_S
{
HI_U64 au64PhyAddr[3]; /* RW;The physical address of the image */
HI_U64 au64VirAddr[3]; /* RW;The virtual address of the image */
HI_U32 au32Stride[3]; /* RW;The stride of the image */
HI_U32 u32Width; /* RW;The width of the image */
HI_U32 u32Height; /* RW;The height of the image */
IVE_IMAGE_TYPE_E enType; /* RW;The type of the image */
}IVE_IMAGE_S;

成员

成员名称 描述
au64PhyAddr[3] 广义图像的物理地址数组
au64VirAddr[3] 广义图像的虚拟地址数组
au32Stride[3] 广义图像的跨度
u32Width 广义图像的宽度
u32Height 广义图像的高度
enType 广义图像的图像类型

二维广义图像类型表

类型 图像描述 内存地址 跨度
IVE_IMAGE_TYPE_U8C1 8bit 无符号单通道图像 仅用到 IVE_IMAGE_S 中的 au64PhyAddr[0]、au64VirAddr[0] 仅用到 u32Stride[0]

图像描述

如果图片类型为 IVE_IMAGE_TYPE_U8C1 时,n 取 8。 1 关于对 Width 和 Stride 的理解,请参考 yuv 图像里的stride和plane的解释

2 代码实现

根据上一小节的分析,我们知道 Width 是小于等于 Stride 的。当输入的图片格式是 U8C1 时,图片的 Width 等于 Stride。当然下面的代码也可以进一步简化。 这里的代码是想参考 opencv 的 countNonZero 函数,返回值是灰度值不为0的像素数。同时也打印出各个像素点的灰度值。 但是此方法耗时过长,对720x576的图像处理一次时间为0.28s,推荐使用3 使用海思 IVE 实现 countNonZero

代码


/*
As we all know, au32Stride[0] greater than u32Width
*/
static HI_U32 CountNonZero(IVE_IMAGE_S *pstImg)
{
HI_U16 u16Row;
HI_U16 u16List;
HI_U8* u8copy;      //read
HI_U8* u8origin;    //change line
HI_U16 height;
HI_U16 width;
HI_U16 NonZeroCount = 0;

height = pstImg->u32Height;
width  = pstImg->u32Width;    

u8copy   = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0];
u8origin = (HI_U8 *)(HI_UL)pstImg->au64VirAddr[0];

for (u16Row = 0; u16Row < height; ++u16Row)
{
    for(u16List = 0; u16List < width; ++u16List)
    {
        printf("%d ", *u8copy);
        if(*u8copy != 0)
        {
            NonZeroCount++;
        }
        u8copy += 1;
    }
    printf("\n");
    u8origin += pstImg->au32Stride[0]; //switch to the next line
    u8copy = u8origin;
}

return NonZeroCount;

}

## 效果
* 先使用 CV 生成一张 64x64 的图像,其中 10~19 行是黑色部分。
```cpp
#include <iostream>
#include <stdio.h>
#include <opencv2/highgui.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>

using namespace cv;
using namespace std;

int main()
{       
    Mat image(64, 64, CV_8UC1);

    for (int i = 0; i < image.rows; i++)    
    {
        uchar* p = image.ptr<uchar>(i);
        for (int j = 0; j < image.cols; j++)
        {
            if (i < 20 && i>=10)     
            {
                p[j] = 0;
            }
            else
            {
                p[j] = 255;
            }
        }
    }

    imwrite("demo.jpg", image);

    return 0;
}
  • 转化为 yuv 格式图像 ffmpeg -i demo.jpg -pix_fmt gray demo.yuv
  • 结果 1

    3 使用海思 IVE 实现 countNonZero

    阅读文档后发现,海思已经提供了类似的统计函数(我哭了) HI_S32 HI_MPI_IVE_Hist(IVE_HANDLE *pIveHandle, IVE_SRC_IMAGE_S *pstSrc, IVE_DST_MEM_INFO_S *pstDst, HI_BOOL bInstant); 计算公式: 1 2 在使用前需要声明和初始化数组 IVE_DST_MEM_INFO_S stCount,使用完需要释放 在程序中的具体位置可以参阅海思Hi3519A开发(11.海思IVE使用模板总结(FILE->IVE->FILE))

    //在 hiSAMPLE_IVE_SFD_S 结构体里里声明
    IVE_DST_MEM_INFO_S stCount;
    //在 SAMPLE_IVE_Sfd_Uninit 函数里释放
    IVE_MMZ_FREE(pstSfd->stCount.u64PhyAddr, pstSfd->stCount.u64VirAddr);
    //在 SAMPLE_IVE_Sfd_Init 函数里初始化 
    HI_U32 u32Size = IVE_HIST_NUM * sizeof(HI_U32);
    s32Ret = SAMPLE_COMM_IVE_CreateMemInfo(&(pstSfd->stCount), u32Size);
    SAMPLE_CHECK_EXPR_GOTO(HI_SUCCESS != s32Ret, SFD_INIT_FAIL, "Error(%#x),Create Count mem info failed!\n", s32Ret);

    HI_MPI_IVE_Hist 的具体使用,输入为统计用的数组 stCount 和待测试图片 pstImg,返回值为灰度值为255的像素个数。

    static HI_U32 SAMPLE_IVE_Count(IVE_DST_MEM_INFO_S stCount, IVE_SRC_IMAGE_S *pstImg)
    {
    HI_S32 s32Ret;
    HI_U32 Num;
    HI_U32* pu32Count;
    IVE_HANDLE IveHandle;
    HI_BOOL bBlock = HI_TRUE;
    HI_BOOL bFinish = HI_FALSE;
    
    s32Ret = HI_MPI_IVE_Hist(&IveHandle, pstImg, &stCount, HI_TRUE);
    SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,"Error(%#x),HI_MPI_IVE_Hist failed!\n",s32Ret); 
    
    s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
    while (HI_ERR_IVE_QUERY_TIMEOUT == s32Ret)
    {
        s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);
    }
    SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret,s32Ret,"Error(%#x),HI_MPI_IVE_Query failed!\n",s32Ret);
    
    pu32Count = SAMPLE_COMM_IVE_CONVERT_64BIT_ADDR(HI_U32, stCount.u64VirAddr);
    Num = *(pu32Count + 255);
    
    return Num; 
    }

    使用举例

HI_U32 CntNonZero;
CntNonZero = SAMPLE_IVE_Count(pstSfd->stCount, &pstSfd->FgImg);
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
merz
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
merz
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

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

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区