语义分割:基于openCV和深度学习(二)

Semantic segmentation in images with OpenCV

开始吧-打开segment.py归档并插入以下代码:

Semantic segmentation with OpenCV and deep learning

# import the necessary packages

import numpy as np

import argparse

import imutils

import time

import cv2

从输入必要的依赖包开始。对于这个脚本,推荐OpenCV 3.4.1或更高版本。可以按照一个安装教程进行操作—只要确保在执行步骤时指定要下载和安装的OpenCV版本。还需要安装OpenCV便利功能包imutils-只需使用pip安装该包:

Semantic segmentation with OpenCV and deep learning

$ pip install --upgrade imutils

如果使用的是Python虚拟环境,不要忘记在使用pip安装imutils之前使用work-on命令!              接下来,分析一下命令行参数:

Semantic segmentation with OpenCV and deep learning

# construct the argument parse and parse the arguments

ap = argparse.ArgumentParser()

ap.add_argument("-m", "--model", required=True,

help="path to deep learning segmentation model")

ap.add_argument("-c", "--classes", required=True,

help="path to .txt file containing class labels")

ap.add_argument("-i", "--image", required=True,

help="path to input image")

ap.add_argument("-l", "--colors", type=str,

help="path to .txt file containing colors for labels")

ap.add_argument("-w", "--width", type=int, default=500,

help="desired width (in pixels) of input image")

args = vars(ap.parse_args())

此脚本有五个命令行参数,其中两个是可选的:             

--模型:深入学习语义分割模型的途径。             

--类:包含类标签的文本文件的路径。             

--图像:的输入图像文件路径。              -

-颜色:颜色文本文件的可选路径。如果没有指定文件,则将为每个类分配随机颜色。             

--宽度:可选的所需图像宽度。默认情况下,该值为500像素。             

如果不熟悉argparse和命令行参数的概念,一定要阅读这篇深入介绍命令行参数的博客文章。              接下来,来分析类标签文件和颜色:

Semantic segmentation with OpenCV and deep learning

# load the class label names

CLASSES = open(args["classes"]).read().strip().split("\n")

# if a colors file was supplied, load it from disk

if args["colors"]:

COLORS = open(args["colors"]).read().strip().split("\n")

COLORS = [np.array(c.split(",")).astype("int") for c in COLORS]

COLORS = np.array(COLORS, dtype="uint8")

# otherwise, we need to randomly generate RGB colors for each class

# label

else:

# initialize a list of colors to represent each class label in

# the mask (starting with 'black' for the background/unlabeled

# regions)

np.random.seed(42)

COLORS = np.random.randint(0, 255, size=(len(CLASSES) - 1, 3),

dtype="uint8")

COLORS = np.vstack([[0, 0, 0], COLORS]).astype("uint8")

从提供的文本文件中将类加载到内存中,该文件的路径包含在命令行args字典(第23行)中。

如果文本文件中为每个类标签提供了一组预先指定的颜色(每行一个),将它们加载到内存中(第26-29行)。否则,为每个标签随机生成颜色(第33-40行)。

出于测试目的(并且由于有20个类),使用OpenCV绘图函数创建一个漂亮的颜色查找图例:

Semantic segmentation with OpenCV and deep learning

# initialize the legend visualization

legend = np.zeros(((len(CLASSES) * 25) + 25, 300, 3), dtype="uint8")

# loop over the class names + colors

for (i, (className, color)) in enumerate(zip(CLASSES, COLORS)):

# draw the class name + color on the legend

color = [int(c) for c in color]

cv2.putText(legend, className, (5, (i * 25) + 17),

cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

cv2.rectangle(legend, (100, (i * 25)), (300, (i * 25) + 25),

tuple(color), -1)

生成一个图例可视化,就可以很容易地可视化地将类标签与颜色关联起来。图例由类标签及其旁边的彩色矩形组成。这是通过创建画布(第43行)和使用循环动态构建图例(第46-52行)快速创建的。本文中介绍了绘画基础知识。

结果如下:

Figure 2: Our deep learning semantic segmentation class color legend generated with OpenCV.

下一个区块将进行深度学习细分:

Semantic segmentation with OpenCV and deep learning

# load our serialized model from disk

print("[INFO] loading model...")

net = cv2.dnn.readNet(args["model"])

# load the input image, resize it, and construct a blob from it,

# but keeping mind mind that the original input image dimensions

# ENet was trained on was 1024x512

image = cv2.imread(args["image"])

image = imutils.resize(image, width=args["width"])

blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (1024, 512), 0,

swapRB=True, crop=False)

# perform a forward pass using the segmentation model

net.setInput(blob)

start = time.time()

output = net.forward()

end = time.time()

# show the amount of time inference took

print("[INFO] inference took {:.4f} seconds".format(end - start))

为了使用Python和OpenCV对图像进行深入的语义分割:

加载模型(第56行)。构造一个blob(第61-64行),在这篇博客文章中使用的ENet模型是在1024×512分辨率的输入图像上训练的,将在这里使用相同的方法。可以在这里了解更多关于OpenCV的blob是如何工作的。将blob设置为网络的输入(第67行),并执行神经网络的前向传递(第69行)。用时间戳将forward pass语句括起来。将经过的时间打印到第73行的终端。

在脚本的其余行中,将生成一个颜色映射,覆盖在原始图像上。每个像素都有一个对应的类标签索引,能够在屏幕上看到语义分割的结果。

首先,需要从输出中提取卷维度信息,然后计算类图和颜色掩码:

Semantic segmentation with OpenCV and deep learning

# infer the total number of classes along with the spatial dimensions

# of the mask image via the shape of the output array

(numClasses, height, width) = output.shape[1:4]

# our output class ID map will be num_classes x height x width in

# size, so we take the argmax to find the class label with the

# largest probability for each and every (x, y)-coordinate in the

# image

classMap = np.argmax(output[0], axis=0)

# given the class ID map, we can map each of the class IDs to its

# corresponding color

mask = COLORS[classMap]

在第77行确定输出体积的空间维度。接下来,让找到输出卷的每个(x,y)-坐标的概率最大的类标签索引(第83行)。这就是现在所知道的类映射,它包含每个像素的类索引。 给定类ID索引,可以使用NumPy数组索引“神奇地”(更不用说超级高效地)查找每个像素(第87行)对应的可视化颜色。彩色mask版将透明地覆盖在原始图像上。让完成脚本:

Semantic segmentation with OpenCV and deep learning

# resize the mask and class map such that its dimensions match the

# original size of the input image (we're not using the class map

# here for anything else but this is how you would resize it just in

# case you wanted to extract specific pixels/classes)

mask = cv2.resize(mask, (image.shape[1], image.shape[0]),

interpolation=cv2.INTER_NEAREST)

classMap = cv2.resize(classMap, (image.shape[1], image.shape[0]),

interpolation=cv2.INTER_NEAREST)

# perform a weighted combination of the input image with the mask to

# form an output visualization

output = ((0.4 * image) + (0.6 * mask)).astype("uint8")

# show the input and output images

cv2.imshow("Legend", legend)

cv2.imshow("Input", image)

cv2.imshow("Output", output)

cv2.waitKey(0)

调整掩码和类映射的大小,使它们与输入图像(第93-96行)具有完全相同的维度。为了保持原始的类id/mask值,使用最近邻插值而不是三次、二次等插值是非常重要的。现在大小是正确的,创建了一个“透明的颜色覆盖”,通过覆盖的原始图像(第100行)的遮罩。这使能够轻松地可视化分割的输出。关于透明覆盖层以及如何构建它们的更多信息,可以在本文中找到。最后,图例和原始+输出图像显示在第103-105行的屏幕上。

单图像分割结果

在使用本节中的命令之前,请确保获取此博客文章的“下载”。为了方便起见,在zip文件中提供了模型+相关文件、图像和Python脚本。在终端中提供的命令行参数对于复制结果很重要。如果不熟悉命令行参数,请在此处了解它们。准备好后,打开一个终端并导航到项目,然后执行以下命令:

Semantic segmentation with OpenCV and deep learning

$ python segment.py --model enet-cityscapes/enet-model.net \

--classes enet-cityscapes/enet-classes.txt \

--colors enet-cityscapes/enet-colors.txt \

--image images/example_01.png

[INFO] loading model...

[INFO] inference took 0.2100 seconds

图3: OpenCV的语义分割显示了道路、人行道、人、自行车、交通标志等等!

注意分割的精确程度-它清楚地分割类并准确地识别人和自行车(自动驾驶汽车的安全问题)。道路,人行道,汽车,甚至树叶都被识别出来了。

尝试另一个示例,只需将--image命令行参数更改为不同的图像:

Semantic segmentation with OpenCV and deep learning

$ python segment.py --model enet-cityscapes/enet-model.net \

--classes enet-cityscapes/enet-classes.txt \

--colors enet-cityscapes/enet-colors.txt \

--image images/example_02.jpg

[INFO] loading model...

[INFO] inference took 0.1989 seconds

图4中的结果展示了这个语义分割模型的准确性和清晰性。汽车、道路、树木和天空都有清晰的标记。下面是另一个例子:

Semantic segmentation with OpenCV and deep learning

$ python segment.py --model enet-cityscapes/enet-model.net \

--classes enet-cityscapes/enet-classes.txt \

--colors enet-cityscapes/enet-colors.txt \

--image images/example_03.png

[INFO] loading model...

[INFO] inference took 0.1992 seconds

上图是一个更复杂的场景,但ENet仍然可以分割走在车前的人。不幸的是,该模型错误地将道路分类为人行道,但可能是因为人们在人行道上行走。最后一个例子:

Semantic segmentation with OpenCV and deep learning

$ python segment.py --model enet-cityscapes/enet-model.net \

--classes enet-cityscapes/enet-classes.txt \

--colors enet-cityscapes/enet-colors.txt \

--image images/example_04.png

[INFO] loading model...

[INFO] inference took 0.1916 seconds

通过ENet发送的最终图像显示了模型如何在道路、人行道、树叶、人物等其他场景类别中清晰地分割卡车与汽车。

语义分割:基于openCV和深度学习(二)的更多相关文章

  1. 语义分割:基于openCV和深度学习(一)

    语义分割:基于openCV和深度学习(一) Semantic segmentation with OpenCV and deep learning 介绍如何使用OpenCV.深度学习和ENet架构执行 ...

  2. 人工智能之基于Opencv与深度学习的计算机视觉实战课程

    https://www.bilibili.com/video/av66375362 imagewatch:https://blog.csdn.net/iracer/article/details/83 ...

  3. Opencv调用深度学习模型

    https://blog.csdn.net/lovelyaiq/article/details/79929393 https://blog.csdn.net/qq_29462849/article/d ...

  4. 基于OpenCL的深度学习工具:AMD MLP及其使用详解

    基于OpenCL的深度学习工具:AMD MLP及其使用详解 http://www.csdn.net/article/2015-08-05/2825390 发表于2015-08-05 16:33| 59 ...

  5. 从Theano到Lasagne:基于Python的深度学习的框架和库

    从Theano到Lasagne:基于Python的深度学习的框架和库 摘要:最近,深度神经网络以“Deep Dreams”形式在网站中如雨后春笋般出现,或是像谷歌研究原创论文中描述的那样:Incept ...

  6. (转) 基于Theano的深度学习(Deep Learning)框架Keras学习随笔-01-FAQ

    特别棒的一篇文章,仍不住转一下,留着以后需要时阅读 基于Theano的深度学习(Deep Learning)框架Keras学习随笔-01-FAQ

  7. 基于TensorFlow的深度学习系列教程 2——常量Constant

    前面介绍过了Tensorflow的基本概念,比如如何使用tensorboard查看计算图.本篇则着重介绍和整理下Constant相关的内容. 基于TensorFlow的深度学习系列教程 1--Hell ...

  8. 基于 Keras 用深度学习预测时间序列

    目录 基于 Keras 用深度学习预测时间序列 问题描述 多层感知机回归 多层感知机回归结合"窗口法" 改进方向 扩展阅读 本文主要参考了 Jason Brownlee 的博文 T ...

  9. 基于pythpn的深度学习 - 记录

    [基于pythpn的深度学习] 环境:    windows/linux-ubuntu    Tensorflow (基于anaconda)        *安装 (python3.5以上不支持)   ...

随机推荐

  1. hdu2067 简单dp或者记忆化搜索

    题意: 小兔的棋盘 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  2. 路由器逆向分析------QEMU的基本使用方法(MIPS)

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/69258334 一.QEMU的运行模式 直接摘抄自己<揭秘家用路由器0day漏 ...

  3. POJ3322滚箱子游戏(不错)

    题意:       讲的是一个游戏,就是在一个平面上滚动一个1*1*2的长方体的游戏,在本题里面的游戏规则是这样的: (1)      一开始给你箱子的状态,可能是横着也可能是竖着. (2)     ...

  4. 学习Canvas绘图与动画基础 canvas入门(一)

    一.创建canvas 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta char ...

  5. Day004 Scanner进阶

    Scanner进阶 例1 Scanner scanner = new Scanner(System.in); //从键盘接收数据 int i = 0; float f = 0.0f; System.o ...

  6. Mybatis-Plus01 快速开始

    Mybatis-Plus虽然官网上有一个快速开始,但是实际操作有点问题,所以,自己写了一个. 版本说明 如果用其他软件版本可能会有部分差异 mybatis-plus:3.4.0 之前我是使用的是3.0 ...

  7. Maven不扫描java文件夹下的配置文件解决办法

    <build> <resources> <resource> <directory>src/main/java</directory> &l ...

  8. SpringBoot JPA + 分页 + 单元测试SpringBoot JPA条件查询

    application.properties 新增数据库链接必须的参数 spring.jpa.properties.hibernate.hbm2ddl.auto=update 表示会自动更新表结构,所 ...

  9. Windows反调试技术(下)

    OD的DBGHELP模块 检测DBGHELP模块,此模块是用来加载调试符号的,所以一般加载此模块的进程的进程就是调试器.绕过方法也很简单,将DBGHELP.DLL改名. #include <Wi ...

  10. 看雪加密解密第一个traceme程序破解

    工具:ollydbg(吾爱破解2.10版) 工具设置:因为traceme是一个win32图形用户程序,所以其程序入口点在WinMain()函数处,设置ollydbg的调试设置的事件选项,选中在WinM ...