一个 c++版本的 yolo 部署 (二)

yolo模型简介

作为一个从业时间1个月的ai相关开发人员,我确实对yolo模型谈不上多了解。但是好在作为一个从业10多年的游戏开发人员,我对“引擎”的理解还是比较深刻的。在我看来yolo模型就是一个引擎,按照规范输入信息,就能获取想要的结果。所以想要使用一个引擎,最关键的是准确理解输入结构输出结构。而模型部署的主要任务:

  • 前处理Preprocess – 就是准备输入数据
  • 推理Inference – 这个不需要操心
  • 后处理Postprocess–就是从输出数据中取得自己需要的信息

既然绕不开,我就尝试按照自己的理解大致介绍一下这个模型的输入数据和输出数据。如果有错误,也希望不吝赐教。

我司目前用到的yolo模型主要有3种任务:分类Classify检测Detect分割Segment。除此之外还有一种任务,似乎是和动作分析有关,但我司业务中用不到,就愉快的略过吧。

ok,假设我有一张图:
这是一张参考图
然后训练了针对猫狗的3种模型,那么当输入这张图后,各自会得到什么信息呢?

分类Classify

分类是最简单的一种任务,输出是各个分类的概率所有分类的概率总和为1。经过推理,上图获得的信息如下:
分类模型输出各个分类的概率

检测Detect

很多时候,我希望知道狗狗到底在图中哪里,所以只有一个分类概率是不够的。我们希望知道图中的什么地方什么东西。所以目标检测是由一批矩形框,以及每个矩形框在每个类别的概率组成的。一个典型的输出结果如图:
目标检测的结果

分割Segment

目标检测给出的通常是目标物体的外接矩形框。如果我们希望获得更加准确的轮廓,就需要用到分割任务。分割任务的输出分为两块:

  • 检测头Predict:在Detect基础上,增加32个权重Weights,对应32个掩码维度
  • 掩码头Mask:将图片分为32个维度,并生成32个掩码图。通常会下采样2次,假如输入图为640 x 640,则mask图为160 x 160。

通过weight和mask,可以更精细的知道每一格(mask一格对应到原图其实就是一块区域)是目标物体的概率,可以更精细的提取物体轮廓:
Segment可以更准确的提取物体轮廓

前处理Preprocess

一个典型的 640 x 640的3通道图片其实就是一组字节数组组成的。每3个字节对应一个像素的rgb3个通道(opencv::Mat是bgr)。每3 x 640个字节(640 个像素)是一行,一共有3 x 640 x 640个字节(640列)。用3维数组表示:

uint8_t image[640][640][3];

在这里插入图片描述

我们通常不会在c++中这样定义图片,但理解这个3维数组定义,对我们理解各种切片至关重要!
我们仔细看这3个维度,按照顺序分别是:

  • 第一个640:高度Height
  • 第二个640:宽度Weight
  • 3:通道Channel

所以作为模型的输入数据,我们通常说这个格式叫HWC。但是模型需要的格式是CHW,从逻辑上说我们需要进行通道转换,或者说需要进行变形(想象这是一个3维立方体,其实转换结果就是这个立方体进行了翻转)。
翻转后还有一步归一化,其实就是将原来0-255之间的颜色值,除以256,使其变为0~1之间的浮点数。归一化在模型中非常常见。

预处理后的数据如图:
在这里插入图片描述

下一篇开始讲解基于opencv的前处理和分割后处理代码。基于上面的介绍,可知分割是3种任务中最复杂的,所以理解了分割后处理流程,另两个自然就都明白了。

to be continue…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值