目录 (Table of Contents)
[TOCM]
[TOC]
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。
关于对 Width 和 Stride 的理解,请参考 yuv 图像里的stride和plane的解释 2 代码实现根据上一小节的分析,我们知道 Width 是小于等于 Stride 的。当输入的图片格式是 U8C1 时,图片的 Width 等于 Stride。当然下面的代码也可以进一步简化。
这里的代码是想参考 opencv 的 countNonZero 函数,返回值是灰度值不为0的像素数。同时也打印出各个像素点的灰度值。
但是此方法耗时过长,对720×576的图像处理一次时间为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 生成一张 64×64 的图像,其中 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结果
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);
计算公式:
在使用前需要声明和初始化数组 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);免责声明:文章内容来自互联网,本站不对其真实性负责,也不承担任何法律责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:在海思平台上实现统计图像像素非零点个数 https://www.yhzz.com.cn/a/17125.html