点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

前言

OpenCV DNN模块支持的图像语义分割网络FCN是基于VGG16作为基础网络,运行速度很慢,无法做到实时语义分割。2016年提出的ENet实时语义分割网络基于编码与解码的网络语义分割方式,类似UNet网络,通过构建自定义Block块,在Cityscapes, CamVid, SUN数据集上实现了性能与实时双提高。

ENet网络结构

作者从ResNet网络结构设计中收到启发,定义两个新的Block结构,如下:

其中a是初始Block,非重叠2x2最大池化,左侧卷积步长为2,然后13个filters之连接合并,该结构注意是收到了Inception改进模型的启发。B是ENet的bottleneck模块,其中卷积可能是正常卷积、空洞卷积、反卷积,使用3x3或者5x5的filters,最终合并在一起是按空间位置相加。两个1x1的卷积分别用来降低维度与扩展,使用BN/Dropout正则化,PReLU非线性激活。最终的ENet网络模型结构如下:

其中stage2跟stage3结构相同,stage4跟stage5属于解码部分。

设计考量

常见的深度学习语义分割模型在下采样操作上的两个缺点:一是降低Feature Map的分辨率会导致图像空间信息损失,特别是图像边缘信息,这个对语义分割精度有明显影响;二是像素级别的语义分割网络要求输入跟输出的分辨率保持一致,这个就要求强的下采样跟强的上采样必须对称,这个增加了模型的计算与参数量。其中第一个问题在FCN与SegNet网络中通过在编码阶段叠加Feature Map与在解码阶段通过稀疏上采样来抑制,但是强的下采样依然对整个语义分割精度有伤害,要在设计时候适当的加以限制。

但是下采样同样可以帮助获得较大的感受野,区分不同的类别,作者发现空洞卷积在这个方面特别有帮助,ENet为了获得实时性能,采用了早期下采样策略来降低计算SegNet跟UNet都是对称的网络结构,ENet采用大的编码网络,小的解码网络实现的不对称结构,编码网络实现分类任务,解码网络主要是优化细节,更好的输出结果。

此外作者在设计过程中还考虑了非线性激活、空洞卷积、正则化方式的影响。

数据对比实验

最终模型与SegNet的对比实验结果如下:

速度性能

参数总量与模型大小

精度对比

OpenCV DNN使用ENet道路分割

OpenCV DNN模块从OpenCV4.0版本开始支持ENet网络模型加载与解析,其中的道路分割模型可以从下面的地址下载:

https://github.com/e-lab/ENet-training

在OpenCV DNN使用该模型时转换Blob输入相关参数信息如下:

  • mean: [0, 0, 0]

  • scale: 0.00392

  • width: 512

  • height: 256

  • rgb: true

  • classes: "enet-classes.txt"

其中分类文件enet-classes.txt可以从OpenCV的sample/data/dnn中发现。输出的数据格式为:Nx20xHxW,其中N=1表示每次输入的一张图像,20是基于Cityscapes数据集训练的20个类别标签,H跟W是输入时图像分辨率(512x256)。

01

最初版本代码实现

该代码实现是来自C++版本的翻译,完整的演示代码如下:

# load CNN model
bin_model = "D:/projects/models/enet/model-best.net";
net = cv.dnn.readNetFromTorch(bin_model)
# read input data
frame = cv.imread("D:/images/software.jpg");
blob = cv.dnn.blobFromImage(frame, 0.00392, (512, 256), (0, 0, 0), True, False);
cv.imshow("input", frame)# Run a model
net.setInput(blob)
score = net.forward()
# Put efficiency information.
t, _ = net.getPerfProfile()
label = 'Inference time: %.2f ms' % (t * 1000.0 / cv.getTickFrequency())
print(score.shape)# generate color table
color_lut = []
n, con, h, w = score.shape
for i in range(con):b = np.random.randint(0, 256)g = np.random.randint(0, 256)r = np.random.randint(0, 256)color_lut.append((b, g, r))maxCl = np.zeros((h, w), dtype=np.int32);
maxVal = np.zeros((h, w), dtype=np.float32);# find max score for 20 channels on pixel-wise
for i in range(con):for row in range(h):for col in range(w):t = maxVal[row, col]s = score[0, i, row, col]if s > t:maxVal[row, col] = smaxCl[row, col] = i# colorful the segmentation image
segm = np.zeros((h, w, 3), dtype=np.uint8)
for row in range(h):for col in range(w):index = maxCl[row, col]segm[row, col] = color_lut[index]h, w = frame.shape[:2]
segm = cv.resize(segm, (w, h), None, 0, 0, cv.INTER_NEAREST)
print(segm.shape, frame.shape)
frame = cv.addWeighted(frame, 0.2, segm, 0.8, 0.0)
cv.putText(frame, label, (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0))
cv.imshow("ENet-Demo", frame)
cv.imwrite("D:/result.png", frame)
cv.waitKey(0)
cv.destroyAllWindows()

总的来说比较啰嗦!

02

修改后代码熟实现

上面是我在2019年3月份时候在 OpenCV研习社 的代码分享,当时主要是把C++代码直接翻译过来,并没有太多考虑,今天又重新看了一下感觉自己写了点垃圾代码,所以重新整理了一下,把输出解析的部分基于Numpy跟OpenCV-Python函数做了简化,最终得到的代码如下:

1# load CNN model2bin_model = "D:/projects/models/enet/model-best.net";3net = cv.dnn.readNetFromTorch(bin_model)4# read input data5frame = cv.imread("D:/images/spacecity.png");6blob = cv.dnn.blobFromImage(frame, 0.00392, (512, 256), (0, 0, 0), True, False);7cv.imshow("input", frame)8h, w, c = frame.shape9
10# Run a model
11net.setInput(blob)
12score = net.forward()
13# Put efficiency information.
14t, _ = net.getPerfProfile()
15label = 'Inference time: %.2f ms' % (t * 1000.0 / cv.getTickFrequency())
16score = np.squeeze(score)
17score = score.transpose((1, 2, 0))
18score = np.argmax(score, 2)
19mask = np.uint8(score)
20mask = cv.cvtColor(mask, cv.COLOR_GRAY2BGR)
21cv.normalize(mask, mask, 0, 255, cv.NORM_MINMAX)
22cmask = cv.applyColorMap(mask, cv.COLORMAP_JET)
23cmask = cv.resize(cmask, (w, h))
24dst = cv.addWeighted(frame, 0.7, cmask, 0.3, 0)
25cv.putText(dst, label, (50, 50), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
26cv.imshow("dst", dst)
27cv.waitKey(0)

运行结果如下:

总的执行时间也大大减少,主要去除了一些无谓的循环解析输出数据部分。CPU上10+FPS 应该没问题!实时get!

好消息!

小白学视觉知识星球

开始面向外开放啦

详解ENet | CPU可以实时的道路分割网络相关推荐

  1. 详解从redis,memcached到nginx,网络底层io

    从redis,memcached到nginx,网络底层io的哪些事 1. redis的单线程模型 2. memcached的多线程模型 3. nginx的多进程模型 4. 10种网络模型的应用场景 视 ...

  2. RGPNET: 复杂环境下实时通用语义分割网络

    作者:Tom Hardy Date:2020-02-09 来源:RGPNET: 复杂环境下实时通用语义分割网络

  3. 详解服务器CPU和GPU技术区别和联系

    CPU (Central Processing Unit,中央处理器)就是机器的"大脑",是完成布局谋略.发号施令.控制行动的"总司令官".CPU的结构主要包括 ...

  4. FFmpeg入门详解之124:Qt5 FFmpeg单路网络摄像头采集预览

    Qt5+FFmpeg单路网络摄像头采集预览 源码工程:S26_Test4 RTSP协议简介 RTSP(Real Time Streaming Protocol),RFC2326 RTSP(Real T ...

  5. 【详解】CPU执行算术运算或逻辑运算时,常将源操作数和结果暂存在()中

    CPU执行算术运算或逻辑运算时,常将源操作数和结果暂存在()中   A.程序计数器(PC)   B.累加寄存器(AC)   C.指令寄存器(IR)   D.地址寄存器(AR) 解析: 程序计数器:存放 ...

  6. kvm架构详解--理解CPU、内存、IO虚拟化技术、处理器硬件支持

    1. 简介 当前的主流虚拟化实现技术分为两种: VMM(虚拟化监控器)运行在硬件平台上,控制所有硬件并管理guest os.guest os运行在比VMM更高的级别.例如xen. VMM运行在宿主操作 ...

  7. 计算机cpu最高温度,详解电脑cpu温度过高几种常用处理方法

    大夏天可能您正在high游戏或者电影,突然电脑蓝屏死机了,然后大多数人直接会想到是不是系统的问题,接着就重装系统,如果是系统的问题,重装完系统后问题就会解决.如果还是经常出现蓝屏,便认为不是软件的问题 ...

  8. ADI Blackfin DSP处理器-BF533的开发详解21:RTC实时时钟的原理及应用(含源码)

    硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 硬件设计原理图 功能介绍 ADSP-BF53x ...

  9. 24核超级计算机,从CPU内部详解电脑CPU的性能:24核CPU什么样?

    现如今的CPU技术已经相当成熟,每隔几年,生产技术上来说会有新的制程商用,生产技术更是几乎每两三个季度就会更新.目前电脑CPU市场几乎是被Intel和AMD霸占.国产龙芯CPU和麒麟系统虽然已经面世有 ...

最新文章

  1. 从jQuery的缓存到事件监听
  2. ubuntu下修改文件夹权限
  3. BOOST使用 proto 转换进行任意类型操作的简单示例
  4. 红橙Darren视频笔记 从AIDL Demo分析Android源码走向
  5. McAfee安全管理器允许任何用户绕过管理器的安全机制
  6. 在Ubuntu 18.04中更改时区
  7. 【0702作业】输出九九乘法表
  8. 前端面试instanceof_【面试准备】每日前端面试题 45 (前端校招字节跳动面试4)...
  9. CTP: 各种错误的测试(补充和修改中)
  10. mysql inner 连接多表_MySQL数据库之多表查询inner join内连接
  11. 单链表的实现 (C语言版 数据结构 严蔚敏)
  12. c语言输出成绩与排名,C语言算成绩 要求输完两个分数后 同时输出两个分数换算出来的成绩...
  13. 拔丝芋头的Java学习日记--Day6
  14. echarts饼图制作
  15. 信道容量、码率、带宽、频谱利用率
  16. 我的年假2016-2017
  17. JMETER解决测试结果乱码问题
  18. 本笔记为阿里云天池龙珠计划SQL训练营的学习内容,链接为:https://tianchi.aliyun.com/specials/promotion/aicampsql;Task4:集合运算-JOIN
  19. c51查表法 c语言表达式,单片机c语言教程第六章--C51运算符和表达式
  20. Xubuntu虚拟机系统终端下载速度太慢解决方法

热门文章

  1. qpython3手机版turtle_Python的画图模块turtle使用详解
  2. 解决choice金融终端Excel/Wps插件修复visual basic异常
  3. 论文阅读_对比学习_SimCSE
  4. Redhat_rhel_linux镜像下载,持续更新......
  5. python实验结论_Python基础(上)实验报告
  6. 基于fpga的FlexRay总线设计
  7. AM335x uboot 移植
  8. NFA到DFA的转化
  9. 国际菜鸟网络露头 阿里2.49亿美元投资新加坡邮政
  10. STM32驱动AD7366-5/AD7367-5芯片