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

重磅干货,第一时间送达

语义分割是计算机视觉中的关键概念之一,语义分割允许计算机通过按类型对图像中的对象进行颜色编码。GAN建立在基于真实内容的基础上复制和生成原始内容的概念上,这使它们适合于在街景图像上进行语义分割的任务,不同部分的分割使在环境中导航的代理能够适当地发挥作用。

数据预处理

我们从一个kaggle数据集获取数据,街景和分割的图像被配对在一起。这意味着为了构建数据集,必须将每个图像分成两部分,以分割每个实例的语义图像和街景图像。

from PIL import Image
from IPython.display import clear_output
import numpy as np
semantic = []
real = []
semantic_imgs = []
real_imgs = []
counter = 0
for img in img_paths:if 'jpg' in img:im = Image.open(img)left = 0top = 0right = 256bottom = 256real_img = im.crop((left, top, right, bottom)) real_imgs.append(real_img)real.append(np.array(real_img.getdata()).reshape(256,256,3))left = 256top = 0right = 512bottom = 256semantic_img = im.crop((left, top, right, bottom)) semantic_imgs.append(semantic_img)semantic.append(np.array(semantic_img.getdata()).reshape(256,256,3))counter += 1print(counter)if counter % 10 == 0:clear_output()else:print(img)

该脚本将每个图像裁剪为两个,并记录像素值和原始图像。原始图像也被记录下来,因此以后无需再进行显示。

import numpy as np
semantic = np.array(semantic)
real = np.array(real)
X = real
y = semantic

将两个列表都转换为numpy数组后,可以直接定义x和y值。实际上,根据目标,你们可以切换x和y值以控制模型的输出。在这种情况下,我们想将真实图像转换为语义图像。但是,稍后我们将尝试训练GAN将语义数据转换为真实数据。

构建GAN

from numpy import expand_dims
from numpy import zeros
from numpy import ones
from numpy import vstack
from numpy.random import randn
from numpy.random import randint
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D,Conv2DTranspose
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
from keras.initializers import RandomNormal
from keras.layers import LeakyReLU
from keras.layers import BatchNormalization
from keras.layers import Activation,Reshape
from keras.optimizers import Adam
from keras.models import Sequential
from keras.layers import Dropout
from IPython.display import clear_output
from keras.layers import Concatenate

当我们使用keras框架构造生成器和鉴别器时,我们需要导入所有必需的图层类型以构造模型。这包括主要的卷积和卷积转置层,以及批处理归一化层和泄漏的relu层。串联层用于构建U-net体系结构,因为它可以将某些层链接在一起。

def define_discriminator(image_shape=(256,256,3)):init = RandomNormal(stddev=0.02)in_src_image = Input(shape=image_shape)in_target_image = Input(shape=image_shape)merged = Concatenate()([in_src_image, in_target_image])d = Conv2D(64, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(merged)d = LeakyReLU(alpha=0.2)(d)d = Conv2D(128, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(d)d = BatchNormalization()(d)d = LeakyReLU(alpha=0.2)(d)d = Conv2D(256, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(d)d = BatchNormalization()(d)d = LeakyReLU(alpha=0.2)(d)d = Conv2D(512, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(d)d = BatchNormalization()(d)d = LeakyReLU(alpha=0.2)(d)d = Conv2D(512, (4,4), padding='same', kernel_initializer=init)(d)d = BatchNormalization()(d)d = LeakyReLU(alpha=0.2)(d)d = Conv2D(1, (4,4), padding='same', kernel_initializer=init)(d)patch_out = Activation('sigmoid')(d)model = Model([in_src_image, in_target_image], patch_out)opt = Adam(lr=0.0002, beta_1=0.5)model.compile(loss='binary_crossentropy', optimizer=opt, loss_weights=[0.5])return model

该判别器是pix2pix GAN论文使用的模型的keras实现。使用泄漏的Relu而不是正常的Relu是为了使负值仍然被考虑在内。这增加了收敛速度。鉴别器执行二进制分类,因此在最后一层使用S形,并使用二进制交叉熵作为损失函数。

def define_encoder_block(layer_in, n_filters, batchnorm=True):init = RandomNormal(stddev=0.02)g = Conv2D(n_filters, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(layer_in)if batchnorm:g = BatchNormalization()(g, training=True)g = LeakyReLU(alpha=0.2)(g)return gdef decoder_block(layer_in, skip_in, n_filters, dropout=True):init = RandomNormal(stddev=0.02)g = Conv2DTranspose(n_filters, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(layer_in)g = BatchNormalization()(g, training=True)if dropout:g = Dropout(0.5)(g, training=True)g = Concatenate()([g, skip_in])g = Activation('relu')(g)return g

生成器包括多次对初始数据进行编码,直到获得原始图像的特征图为止。然后将此特征图像解码,直到获得完整分辨率的图像为止。这意味着生成器中的大多数层只是编码器和解码器块。在对编码器解码器块进行了精心设计之后,为了构建生成器,没有更多的工作要做。

def define_generator(image_shape=(256,256,3)):init = RandomNormal(stddev=0.02)in_image = Input(shape=image_shape)e1 = define_encoder_block(in_image, 64, batchnorm=False)e2 = define_encoder_block(e1, 128)e3 = define_encoder_block(e2, 256)e4 = define_encoder_block(e3, 512)e5 = define_encoder_block(e4, 512)e6 = define_encoder_block(e5, 512)e7 = define_encoder_block(e6, 512)b = Conv2D(512, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(e7)b = Activation('relu')(b)d1 = decoder_block(b, e7, 512)d2 = decoder_block(d1, e6, 512)d3 = decoder_block(d2, e5, 512)d4 = decoder_block(d3, e4, 512, dropout=False)d5 = decoder_block(d4, e3, 256, dropout=False)d6 = decoder_block(d5, e2, 128, dropout=False)d7 = decoder_block(d6, e1, 64, dropout=False)g = Conv2DTranspose(3, (4,4), strides=(2,2), padding='same', kernel_initializer=init)(d7)out_image = Activation('tanh')(g)model = Model(in_image, out_image)return model

使用多个编码器和解码器,我们得到了这个生成器。使用双曲正切可对数据进行归一化,范围从(0,255)到(-1,1)。我们必须记住将数据编码为范围(-1,1),这样才能正确评估生成器的输出和y值。

def define_gan(g_model, d_model, image_shape):d_model.trainable = Falsein_src = Input(shape=image_shape)gen_out = g_model(in_src)dis_out = d_model([in_src, gen_out])model = Model(in_src, [dis_out, gen_out])opt = Adam(lr=0.0002, beta_1=0.5)model.compile(loss=['binary_crossentropy', 'mse'], optimizer=opt)return model

将两个模型连接在一起即可得到完整的GAN。发生器的输出直接馈入鉴别器。

生成样本

def generate_real_samples(dataset, n_samples, patch_shape):trainA, trainB = datasetix = randint(0, trainA.shape[0], n_samples)X1, X2 = trainA[ix], trainB[ix]y = ones((n_samples, patch_shape, patch_shape, 1))X1 = (X1 - 127.5) / 127.5X2 = (X2 - 127.5) / 127.5return [X1, X2], ydef generate_fake_samples(g_model, samples, patch_shape):X = g_model.predict(samples)y = zeros((len(X), patch_shape, patch_shape, 1))return X, y

为了使鉴别器起作用,必须同时提供真实样本和计算机生成的样本。但是,该过程并不是那么简单,需要对这些值进行标准化。由于像素值的范围介于0到255之间,因此通过使用等式X1 =(X1–127.5)/ 127.5,所有值都将在(-1,1)范围内进行归一化。

执行程序

def train(d_model, g_model, gan_model, dataset, n_epochs=100, n_batch=10):n_patch = d_model.output_shape[1]trainA, trainB = datasetbat_per_epo = int(len(trainA) / n_batch)n_steps = bat_per_epo * n_epochsfor i in range(n_steps):[X_realA, X_realB], y_real = generate_real_samples(dataset, n_batch, n_patch)X_fakeB, y_fake = generate_fake_samples(g_model, X_realA, n_patch)d_loss1 = d_model.train_on_batch([X_realA, X_realB], y_real)d_loss2 = d_model.train_on_batch([X_realA, X_fakeB], y_fake)g_loss, _, _ = gan_model.train_on_batch(X_realA, [y_real, X_realB])print('>%d, d1[%.3f] d2[%.3f] g[%.3f]' % (i+1, d_loss1, d_loss2, g_loss))if (i+1) % 100 == 0:clear_output()

此功能训练GAN。这里要注意的关键是批次大小。该论文建议使用迷你们批处理(n_batch = 1),但经过一些测试,我们发现批处理大小为10会产生更好的结果。

image_shape = (256,256,3)
d_model = define_discriminator()
g_model = define_generator()
gan_model = define_gan(g_model, d_model, image_shape)
train(d_model, g_model, gan_model, [X,y])

该脚本定义图像形状,并调用函数来构造GAN的不同部分。然后,它调用训练功能来训练模型。

结果

真实到语义:

尽管计算机生成的图像模糊,但可以正确对图像中的所有内容进行颜色编码。请记住,计算机无法看到真实图像的实际语义表示!我们认为图像是模糊的,因为真正的256 x 256图像不是很复杂,而且有许多可能使机器掉色的颜色。右边的图像(计算机生成)可以分割成正方形。如果计算这些平方,它将与卷积层的过滤器数量匹配!

语义到真实:

将语义数据转换为真实的街景图像时,我们担心这是不可能的,因为当转换为语义数据时,会丢失大量数据。例如,红色汽车和绿色汽车都变成蓝色,因为汽车是按蓝色像素分类的。这是一个明显的问题。可能具有不同颜色的对象根本没有出现,从而导致图像看起来只有一点点相似。看一下下面的图片:

结论

考虑到该网络仅训练了10个纪元,我们认为该项目是成功的,并且结果似乎很有希望。我们希望人们可以玩弄模型架构和超参数,以提高GAN创建的图像的质量。

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

基于GAN的自动驾驶汽车语义分割相关推荐

  1. 基于RGB和LiDAR融合的自动驾驶3D语义分割

    基于RGB和LiDAR融合的自动驾驶3D语义分割 论文 RGB and LiDAR fusion based 3D Semantic Segmentationfor Autonomous Drivin ...

  2. 标注案例分享:自动驾驶图像语义分割丨曼孚科技

    目前,自动驾驶主流算法模型主要以有监督的深度学习方式为主,是基于已知变量和因变量推导函数关系的算法模型,需要大量的结构化标注数据对模型进行训练与调优. 自动驾驶领域常见的标注类型通常包括2D框.3D立 ...

  3. 自动驾驶汽车的规划与控制

    1. 概念与意义 自动驾驶汽车作为一个复杂的软硬件结合系统,其安全,可靠地运行需要车载硬件,传感器集成.感知.预测以及规划控制等多个模块的协同配合工作.感知预测和规划控制的紧密配合非常重要.这里的规划 ...

  4. 自动驾驶 l5 ai_强AI和弱AI的真实故事以及适用于自动驾驶汽车的信息

    自动驾驶 l5 ai Dr. Lance Eliot, AI Insider AI Insider博士Lance Eliot博士 [Ed. Note: For reader's interested ...

  5. hana迁移可行性评估_评估``有益的AI''的可行性以及如何将其应用于自动驾驶汽车

    hana迁移可行性评估 Dr. Lance Eliot, AI Insider AI Insider的Lance Eliot博士 [Ed. Note: For reader's interested ...

  6. MFNet——向具有多光谱场景的自动驾驶汽车的实时语义分割

    Overview Title:MFNet: Towards real-time semantic segmentation for autonomous vehicles with multi-spe ...

  7. CV:无人驾驶/自动驾驶汽车中涉及的软硬件技术(摄像头、雷达、激光雷达)、计算机视觉技术(检测、分类、跟踪、语义分割)的简介

    CV:无人驾驶/自动驾驶汽车中涉及的软硬件技术(摄像头.雷达.激光雷达).计算机视觉技术(检测.分类.跟踪.语义分割)的简介 目录 无人驾驶汽车中涉及的软硬件结合相关的技术 摄像头.雷达.激光雷达 影 ...

  8. 3D点云的快速分割:自动驾驶汽车应用的LiDAR处理实例

    点云PCL免费知识星球,点云论文速读. 文章:Fast Segmentation of 3D Point Clouds: A Paradigm on LiDAR Data for Autonomous ...

  9. 【智能驾驶】基于计算机视觉的自动驾驶算法研究综述

    近年来,随着人工智能技术的迅速发展,传统汽车行业与信息技术结合,在汽车自动驾驶技术方面的研究取得了长足进步,业内很多大公司都在此领域投入巨资进行研发,如国外的谷歌.丰田,国内的百度.比亚迪等公司都推出 ...

最新文章

  1. C - Catch That Cow(BFS)
  2. BizTalk Server 2010新功能介绍(六):BizTalk Mapper (下)
  3. 使用Canal实现redis和mysql的同步
  4. 开始→运行→输入的命令集锦( 菜鸟必读)
  5. android 获取cpu使用率_超详细的zabbix监控windows磁盘IO及cpu使用率教程
  6. Linux crontab 定时任务没执行,没收到错误信息邮件
  7. 如何看待现在一些年轻人秉持「简单是福、平淡是真」的随遇而安的生活态度?...
  8. 计算机与管理科学的交叉与融合,计算机信息管理学科交叉融合研究论文
  9. zynq以太网官网例子调试
  10. 2003-2019年全国30省市分地区能源消费结构数据集(煤炭占比)
  11. B2C商城系统源码 单商户B2C商城系统源码
  12. Log4j2 0day漏洞项目级紧急修复方法
  13. SIP入门(一):建立SIP软电话环境
  14. echarts离线地图
  15. 建模大神是如何制作出可爱戴着眼镜的卡通女孩角色呢
  16. 三菱fx5u plc项目模板程序(含触摸屏程序) 程序注释全面,用的三菱fx5u系列plc和威纶触摸屏
  17. android 12.0 wifi开关控制功能实现
  18. 可惜知乎没有注销账号的选项
  19. pacemaker+nginx+iscsi实现的nginx服务远程储存高可用
  20. ios swift收起键盘

热门文章

  1. 强化学习大规模应用还远吗?Youtube推荐已强势上线
  2. 推荐系统遇上深度学习,9篇阿里推荐论文汇总!
  3. TIOBE 5 月编程语言排行榜:Python、C++竞争白热化,Objective-C已沦为小众语言
  4. 《周志华机器学习详细公式推导版》发布,Datawhale开源项目pumpkin-book
  5. 800万中文词,腾讯AI Lab开源大规模NLP数据集
  6. 如何保证世界杯直播不卡顿?腾讯云要用AI解决这个问题
  7. MySql批量插入时,如何不插入重复的数据
  8. GET 和 POST请求的本质区别是什么?原来我一直理解错了
  9. MyBatis 如何兼容所有日志框架?
  10. CMS垃圾收集器小实验之CMSInitiatingOccupancyFraction参数