结果精筛SvpSampleWKYoloV3BoxPostProcess()
1. 获取基本的设置信息
如上,获取nms_thresh阈值、max bboxes number数目、图像width、图像height。具体设置位置在SvpSampleYolo.h文件中:
这些都是在仿真开始之前就需要根据自己算法和图像的实际情况设置好的。
2. 获得像素点的数目
调用了函数SvpSampleWkYoloV3GetBoxTotleNum()函数利用了上面三个层的索引,得到每个层的size,并得到对应的每个层的像素数目。
3. 计算总的内存
SVP_SAMPLE_STACK_S 结构体如下:
4. 排序
将目前的检测结果按照score从大到小排序
NonRecursiveArgQuickSortWithBox 介绍
HI_S32 NonRecursiveArgQuickSortWithBox(SVP_SAMPLE_BOX_S* pstBoxs, HI_S32 s32Low, HI_S32 s32High, SVP_SAMPLE_STACK_S *pstStack)
{
HI_S32 i = s32Low;//声明变量,检测结果的索引,从0开始
HI_S32 j = s32High;//声明变量,检测结果的最大索引,最大数目-1
HI_S32 s32Top = 0;//声明变量,初始化
pstStack[s32Top].s32Min = s32Low;
pstStack[s32Top].s32Max = s32High;
HI_FLOAT f32KeyConfidence = pstBoxs[s32Low].f32ClsScore;
while (s32Top > -1)//依次处理
{
s32Low = pstStack[s32Top].s32Min;
s32High = pstStack[s32Top].s32Max;
i = s32Low;
j = s32High;
s32Top--;
f32KeyConfidence = pstBoxs[s32Low].f32ClsScore;//score
while (i < j)
{
while ((i < j) && (f32KeyConfidence > pstBoxs[j].f32ClsScore))
{
j--;
}
if (i < j)
{
BoxArgswap(&pstBoxs[i], &pstBoxs[j]);//交换
i++;
}
while ((i < j) && (f32KeyConfidence < pstBoxs[i].f32ClsScore))
{
i++;
}
if (i < j)
{
BoxArgswap(&pstBoxs[i], &pstBoxs[j]);
j--;
}
}
if (s32Low < i - 1)
{
s32Top++;
pstStack[s32Top].s32Min = s32Low;
pstStack[s32Top].s32Max = i - 1;
}
if (s32High > i + 1)
{
s32Top++;
pstStack[s32Top].s32Min = i + 1;
pstStack[s32Top].s32Max = s32High;
}
}
return HI_SUCCESS;
}
5. NMS非极大值抑制
对排序后的结果进行非极大值抑制。
HI_S32 SvpDetYoloNonMaxSuppression(SVP_SAMPLE_BOX_S* pstBoxs, HI_U32 u32BoxNum, HI_FLOAT f32NmsThresh, HI_U32 u32MaxRoiNum)
{
//对于剩下的每个结果,依次与其余结果比较
for (HI_U32 i = 0, u32Num = 0; i < u32BoxNum && u32Num < u32MaxRoiNum; i++)
{
if (0 == pstBoxs[i].u32Mask)
{
//mask =0 则说明此处为前景,则表示检测成功一个,故检测个数+1
u32Num++;
for (HI_U32 j = i + 1; j < u32BoxNum; j++)
{
//将剩余的依次与其求IOU
if (0 == pstBoxs[j].u32Mask)
{
HI_DOUBLE f64Iou = SvpDetYoloCalIou(&pstBoxs[i], &pstBoxs[j]);
if (f64Iou >= (HI_DOUBLE)f32NmsThresh)
{
//如果满足阈值则说明是同一个物体,则mask为1
pstBoxs[j].u32Mask = 1;
}
}
}
}
}
return HI_SUCCESS;
}
6. 最终结果