语义分割:基于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. ZOJ3261并查集逆向处理

    题意:       给你一些点,还有一些边,每个点上都有一个权值,然后有一些询问,分为两种, query a 询问与a直接或者间接想连的点中最大权值的是那个点,输出那个点,如果那个点的权值小于等于a的 ...

  2. 写复杂的json方法

    <?php for($j=0; $j< 30; $j++) { $Axis[$j] = "a"; } $data['xAxis']= $Axis; for($i=0; ...

  3. 【python】Leetcode每日一题-丑数

    [python]Leetcode每日一题-丑数 [题目描述] 给你一个整数 n ,请你判断 n 是否为 丑数 .如果是,返回 true :否则,返回 false . 丑数 就是只包含质因数 2.3 和 ...

  4. php笔记之魔术方法、魔法常量和超全局变量

    一.魔术方法(13个)1.__construct()实例化对象时被调用, 当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用.2.__destru ...

  5. 四、postman关联、参数化

    一.postman关联 在实际接口测试中,后一个接口要用到前面接口返回的结果,从而让后面的接口能够正常运行,这个过程的实现成为关联 如上图通过新版本或者老版本的语法把获取的变量access_token ...

  6. JVM虚拟机 类加载过程与类加载器

    目录 前言 类的生命周期 类加载过程 加载 连接 验证 准备 解析 初始化 类加载器 三大类加载器 双亲委派模型 概念 为什么要使用双亲委派模型 源码分析 反双亲委派模型 参考 前言 类装载器子系统是 ...

  7. 记一次 .NET 某HIS系统后端服务 内存泄漏分析

    一:背景 1. 讲故事 前天那位 his 老哥又来找我了,上次因为CPU爆高的问题我给解决了,看样子对我挺信任的,这次另一个程序又遇到内存泄漏,希望我帮忙诊断下. 其实这位老哥技术还是很不错的,他既然 ...

  8. Java集合详解(三):LinkedList原理解析

    概述 本文是基于jdk8_271源码进行分析的. LinkedList底层是基于链表实现.链表没有长度限制,内存地址不需要固定长度,也不需要是连续的地址来进行存储,只需要通过引用来关联前后元素即可完成 ...

  9. Flink使用二次聚合实现TopN计算-乱序数据

    一.背景说明: 在上篇文章实现了TopN计算,但是碰到迟到数据则会无法在当前窗口计算,需要对其中的键控状态优化 Flink使用二次聚合实现TopN计算 本次需求是对数据进行统计,要求每隔5秒,输出最近 ...

  10. 攻防世界(五)Web_php_include

    攻防世界系列:Web_php_include 方法一:大小写绕过 strstr()函数对php我协议进行了过滤,但我们可以尝试大小写绕过 抓包POST传值让其执行我们输入的命令 ?page=Php:/ ...