结果解析SvpSampleDetOneSegGetResult
1. 变量初始化
HI_S32 SvpSampleDetOneSegGetResult(SVP_NNIE_ONE_SEG_DET_S *pstDetParam,
HI_U8 netType, HI_VOID *pExtraParam,
string& strResultFolderDir, vector<SVP_SAMPLE_FILE_NAME_PAIR>& imgNameRecoder)
{
HI_S32 s32Ret = HI_SUCCESS;//变量初始化
SVP_SAMPLE_BOX_S astBoxesResult[1024] = { 0 };//存储结果初始化,结构体下面介绍主要包括xmin,ymin,xmax,ymax,score,classid,mask
HI_U32* p32BoxNum = (HI_U32*)malloc(pstDetParam->astSrc->u32Num * sizeof(HI_U32));//结果初始化,eg:一张图像一个结果
//cout<<" pstDetParam->astSrc->u32Num : "<<pstDetParam->astSrc->u32Num<<endl;
CHECK_EXP_RET(p32BoxNum == NULL, HI_FAILURE, "malloc p32BoxNum failure!");
memset(p32BoxNum, 0, pstDetParam->astSrc->u32Num * sizeof(HI_U32));//结果,初始化为0
SVP_SAMPLE_BOX_RESULT_INFO_S stBoxesInfo = { 0 };//结果初始化,除包含astBoxesResult还包含图像的height和width
stBoxesInfo.pstBbox = astBoxesResult;//bbox信息
stBoxesInfo.u32OriImHeight = pstDetParam->astSrc[0].unShape.stWhc.u32Height;//图像的高度
stBoxesInfo.u32OriImWidth = pstDetParam->astSrc[0].unShape.stWhc.u32Width;//图像的宽度
(1)SVP_SAMPLE_BOX_S 结构体介绍
bbox 的基本信息
typedef struct hiSVP_SAMPLE_BOX_S
{
HI_FLOAT f32Xmin;//bbox 的 xmin
HI_FLOAT f32Xmax;//bbox's xmax
HI_FLOAT f32Ymin;//bbox's ymin
HI_FLOAT f32Ymax;//bbox's ymax
HI_FLOAT f32ClsScore;//bbox's obj score
HI_U32 u32MaxScoreIndex;//bbox's class score
HI_U32 u32Mask;//noobj mask
}SVP_SAMPLE_BOX_S;
(2) SVP_SAMPLE_BOX_RESULT_INFO_S 结构体介绍
图像信息:bbox 信息 + 自身宽高信息
typedef struct hiSVP_SAMPLE_BOX_RESULT_INFO_S
{
HI_U32 u32OriImHeight;
HI_U32 u32OriImWidth;
SVP_SAMPLE_BOX_S* pstBbox;
}SVP_SAMPLE_BOX_RESULT_INFO_S;
2. 根据网络类型选择处理方法
如上图所示,netType为YOLOv3,故处理方式选择SvpSampleWkYoloV3GetResult()函数。
SvpSampleWkYoloV3GetResult函数介绍
(1)参数核验
(2)变量初始化
(3)对Batch内图像依次处理
(4)YOLOV3有3个尺度的输出层,故对每个层依次进行处理
通过SvpSampleWkYoloV3GetResultForOneBlob函数进行处理。
SvpSampleWkYoloV3GetResultForOneBlob函数介绍
以输入图像为384*288为例
<1> 前期计算
<2> 数据类型转换
将网络得到的结果进行数据类型转换,
<3> 依次获取每个像素点位置的值
<4> 坐标修正和粗略过滤
可能会比较疑惑f32Width与f32Height为什么后面要除以SVP_SAMPLE_YOLOV3_SRC_WIDTH 和 SVP_SAMPLE_YOLOV3_SRC_HEIGHT?
这要看width与height的计算公式了:
width = exp(log(Wp/Wsa)) * Wsa;
height = exp(log(Hp/Hsa)) * Hsa
经过计算上面得到的width与height分别为相对于当前feature_map的size,而我们要遵循上面的x和y的计算方式,将w和h相对于原图进行归一化处理。
A:上面的Wsa、Hsa分别对应当前feature map下anchor的宽和高,而Wsa 与 Hsa 对通过当前feature map的缩放倍数计算出来的。
B: 而缩放倍数为 原图的 Width 除以当前 feature map的 Fwidth, 即scale = Width / Fwidth,即 Wsa = Wa /(Width / Fwidth) = Wa * Fwidth / Width.
C : 而相对于原图归于化需在除以当前feature map的Fwidth
D :故 归一化后为 exp(log(Wp/Wsa)) * Wa / Width
<5> 获得阶段性的检测结果
为什么是阶段性的检测结果?
因为这部分检测结果,只是在上面通过阈值过滤了依次,而必定还存在很大的冗余,即一个物体可能有N个检测结果(其score 都满足阈值,只是坐标有略微的偏差);故后面还会有NMS等操作,进行进一步的处理。
上面得到的结果中的坐标值都是相对于原图进行归一化之后的。
综合上面的<1><2><3><4><5>便对一个尺度的输出结果进行了处理操作,而三个尺度,则需要进行三次即可。如下图说是:
第二个尺度:(中等大小的物体)
第三个尺度:小尺度物体