sift线特征提取代码_车道线检测LaneNet

LanNetSegmentation branch完成语义分割,即判断出像素属于车道or背景Embedding branch完成像素的向量表示,用于后续聚类,以完成实例分割H-Net

Segmentation branch

解决样本分布不均衡

车道线像素远小于背景像素.loss函数的设计对不同像素赋给不同权重,降低背景权重.

该分支的输出为(w,h,2).

Embedding branch

loss的设计思路为使得属于同一条车道线的像素距离尽量小,属于不同车道线的像素距离尽可能大.即Discriminative loss.

该分支的输出为(w,h,n).n为表示像素的向量的维度.

实例分割

在Segmentation branch完成语义分割,Embedding branch完成像素的向量表示后,做聚类,完成实例分割.

9620ad73e29468f3d7089046b0009e01.png

H-net

透视变换

to do

车道线拟合

LaneNet的输出是每条车道线的像素集合,还需要根据这些像素点回归出一条车道线。传统的做法是将图片投影到鸟瞰图中,然后使用二次或三次多项式进行拟合。在这种方法中,转换矩阵H只被计算一次,所有的图片使用的是相同的转换矩阵,这会导致坡度变化下的误差。

为了解决这个问题,论文训练了一个可以预测变换矩阵H的神经网络HNet,网络的输入是图片,输出是转置矩阵H。之前移植过Opencv逆透视变换矩阵的源码,里面转换矩阵需要8个参数,这儿只给了6个参数的自由度,一开始有些疑惑,后来仔细阅读paper,发现作者已经给出了解释,是为了对转换矩阵在水平方向上的变换进行约束。

代码分析

binary_seg_image, instance_seg_image = sess.run(            [binary_seg_ret, instance_seg_ret],            feed_dict={input_tensor: [image]}        )

输入(1,256,512,3)输出binary_seg_image:(1, 256, 512) instance_seg_image:(1, 256, 512, 4)

完成像素级别的分类和向量表示

class LaneNet的inference分为两步.

第一步提取分割的特征,包括了用于语义分割的特征和用以实例分割的特征.

class LaneNet(cnn_basenet.CNNBaseModel):    def inference(self, input_tensor, name):        """        :param input_tensor:        :param name:        :return:        """        with tf.variable_scope(name_or_scope=name, reuse=self._reuse):            # first extract image features            extract_feats_result = self._frontend.build_model(                input_tensor=input_tensor,                name='{:s}_frontend'.format(self._net_flag),                reuse=self._reuse            )            #得到一个字典,包含了用于语义分割的feature map和用于实例分割的feature map.            #binary_segment_logits (1,256,512,2) 2是类别数目.即车道/背景.            #instance_segment_logits (1,256,512,64) 用以后面再做卷积为每个像素生成一个向量表示            print('features:',extract_feats_result)            # second apply backend process            binary_seg_prediction, instance_seg_prediction = self._backend.inference(                binary_seg_logits=extract_feats_result['binary_segment_logits']['data'],                instance_seg_logits=extract_feats_result['instance_segment_logits']['data'],                name='{:s}_backend'.format(self._net_flag),                reuse=self._reuse            )            if not self._reuse:                self._reuse = True        return binary_seg_prediction, instance_seg_prediction

第一步得到的features如下:

features : OrderedDict([('encode_stage_1_share', {'data': , 'shape': [1, 256, 512, 64]}), ('encode_stage_2_share', {'data': , 'shape': [1, 128, 256, 128]}), ('encode_stage_3_share', {'data': , 'shape': [1, 64, 128, 256]}), ('encode_stage_4_share', {'data': , 'shape': [1, 32, 64, 512]}), ('encode_stage_5_binary', {'data': , 'shape': [1, 16, 32, 512]}), ('encode_stage_5_instance', {'data': , 'shape': [1, 16, 32, 512]}), ('binary_segment_logits', {'data': , 'shape': [1, 256, 512, 2]}), ('instance_segment_logits', {'data': , 'shape': [1, 256, 512, 64]})])

特征提取完毕,做后处理

class LaneNetBackEnd(cnn_basenet.CNNBaseModel):        def inference(self, binary_seg_logits, instance_seg_logits, name, reuse):            """            :param binary_seg_logits:            :param instance_seg_logits:            :param name:            :param reuse:            :return:            """            with tf.variable_scope(name_or_scope=name, reuse=reuse):                with tf.variable_scope(name_or_scope='binary_seg'):                    binary_seg_score = tf.nn.softmax(logits=binary_seg_logits)                    binary_seg_prediction = tf.argmax(binary_seg_score, axis=-1)                with tf.variable_scope(name_or_scope='instance_seg'):                    pix_bn = self.layerbn(                        inputdata=instance_seg_logits, is_training=self._is_training, name='pix_bn')                    pix_relu = self.relu(inputdata=pix_bn, name='pix_relu')                    instance_seg_prediction = self.conv2d(                        inputdata=pix_relu,                        out_channel=CFG.TRAIN.EMBEDDING_FEATS_DIMS,                        kernel_size=1,                        use_bias=False,                        name='pix_embedding_conv'                    )            return binary_seg_prediction, instance_seg_prediction

对每个像素的分类,做softmax转成概率.再argmax求概率较大值的下标.对每个像素的向量表示,用1x1卷积核做卷积,得到channel维度=CFG.TRAIN.EMBEDDING_FEATS_DIMS(配置为4).即(1,256,512,64)卷积得到(1,256,512,4)的tensor.即每个像素用一个四维向量表示.

所以,整个LaneNet的inference返回的是两个tensor.一个shape为(1,256,512) 一个为(1,256,512,4).

后处理

class LaneNetPostProcessor(object):    def postprocess(self, binary_seg_result, instance_seg_result=None,                min_area_threshold=100, source_image=None,                data_source='tusimple'):

对binary_seg_result,先通过形态学操作将小的空洞去除.参考 https://www.cnblogs.com/sdu20112013/p/11672634.html

然后做聚类.

def _get_lane_embedding_feats(binary_seg_ret, instance_seg_ret):        """        get lane embedding features according the binary seg result        :param binary_seg_ret:        :param instance_seg_ret:        :return:        """        idx = np.where(binary_seg_ret == 255) #idx (b,h,w)        lane_embedding_feats = instance_seg_ret[idx]                # idx_scale = np.vstack((idx[0] / 256.0, idx[1] / 512.0)).transpose()        # lane_embedding_feats = np.hstack((lane_embedding_feats, idx_scale))        lane_coordinate = np.vstack((idx[1], idx[0])).transpose()        assert lane_embedding_feats.shape[0] == lane_coordinate.shape[0]        ret = {            'lane_embedding_feats': lane_embedding_feats,            'lane_coordinates': lane_coordinate        }        return ret

获取到坐标及对应坐标像素对应的向量表示.

np.where(condition)

只有条件 (condition),没有x和y,则输出满足条件 (即非0) 元素的坐标 (等价于numpy.nonzero)。这里的坐标以tuple的形式给出,通常原数组有多少维,输出的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。

测试结果

tensorflow-gpu 1.15.2

4张titan xp

(4, 256, 512) (4, 256, 512, 4)

I0302 17:04:31.276140 29376 test_lanenet.py:222] imgae inference cost time: 2.58794s

(32, 256, 512) (32, 256, 512, 4)

I0302 17:05:50.322593 29632 test_lanenet.py:222] imgae inference cost time: 4.31036s

类似于高吞吐量,高延迟.对单帧图片处理在1-2s,多幅图片同时处理,平均下来的处理速度在0.1s.

论文里的backbone为enet,在nvida 1080 ti上推理速度52fps.

对于这个问题的解释,作者的解释是

2.Origin paper use Enet as backbone net but I use vgg16 as backbone net so speed will not get as fast as that. 3.Gpu need a short time to warm up and you can adjust your batch size to test the speed again:)

一个是特征提取网络和论文里不一致,一个是gpu有一个短暂的warm up的时间.

我自己的测试结果是在extract image features耗时较多.换一个backbone可能会有改善.

def inference(self, input_tensor, name):        """        :param input_tensor:        :param name:        :return:        """        print("***************,input_tensor shape:",input_tensor.shape)        with tf.variable_scope(name_or_scope=name, reuse=self._reuse):            t_start = time.time()            # first extract image features            extract_feats_result = self._frontend.build_model(                input_tensor=input_tensor,                name='{:s}_frontend'.format(self._net_flag),                reuse=self._reuse            )            t_cost = time.time() - t_start            glog.info('extract image features cost time: {:.5f}s'.format(t_cost))            # second apply backend process            t_start = time.time()            binary_seg_prediction, instance_seg_prediction = self._backend.inference(                binary_seg_logits=extract_feats_result['binary_segment_logits']['data'],                instance_seg_logits=extract_feats_result['instance_segment_logits']['data'],                name='{:s}_backend'.format(self._net_flag),                reuse=self._reuse            )            t_cost = time.time() - t_start            glog.info('backend process cost time: {:.5f}s'.format(t_cost))            if not self._reuse:                self._reuse = True        return binary_seg_prediction, instance_seg_prediction

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql ehcache_MyBatis使用Ehcache作为二级缓存

特别说明:由于二级缓存是基于Mapper的,当你在不同的mapper中查询了相同的数据,例如不同的Mapper中有多表查询时结果中有相同的数据,当其中一个Mapper进行插入更新缓存时,另一个并没有插入更新,那么使用两个…

三角形一点到三边距离最小_初中数学:相似三角形以及重心、向量问题考点整理...

考点:相似三角形的概念、相似比的意义、画图形的放大和缩小考点:平行线分线段成比例定理、三角形一边的平行线的有关定理考点:相似三角形的判定和性质及其应用考点:三角形的重心考点:向量的有关概念考点:向…

mysql mongo关联查询语句_MongoDB 集合间关联查询后通过$filter进行筛选

在前面的分享中,有讲解 “详解MongoDB中的多表关联查询($lookup)” 一节,其内容涵盖了常见的集合管理的需求。我们知道文档的选择都是通过$match进行匹配刷选。但这是文档间的匹配筛选,并没有对单个新生成的文档进行内嵌子文档进行筛选。那么…

python自动化办公知识点整理汇总_python自动化办公小结

在日常办公中,经常免不了和Excel打交道,每次手工处理数据,稍微不细心点。数据可能就出错了。而且重复的任务又会占据大量的工作时间。那有没有办法可以解决这些问题呢?今天介绍一种方法,可以解决日常工作的重复工作&am…

php 图片生成vr_PHP 使用Krpano 生成全景图

技术背景:krpano是一款全景漫游制作软件和工具。引用链接:开发环境:Centos6.5\PHP5.5技术实现:一: 下载官方工具包二:执行生成代码exec( $krpano . krpanotools makepano -config . $krpano . templates/vtour-vr.config %F . $krpano_dir_beta . /*, $…

python ks曲线_python之KS曲线

# 自定义绘制ks曲线的函数def plot_ks(y_test, y_score, positive_flag):# 对y_test,y_score重新设置索引y_test.index np.arange(len(y_test))#y_score.index np.arange(len(y_score))# 构建目标数据集target_data pd.DataFrame({‘y_test’:y_test, ‘y_score’:y_score})…

python sum函数numpy_解决Numpy中sum函数求和结果维度的问题

使用Numpy(下面简称np)中的sum函数对某一维度求和时,由于该维度会在求和后变成一个数,所以所得结果的这一维度为空。比如下面的例子:a np.array([[1,2,3],[4,5,6]])b np.sum(a,axis1)print(b.shape)# (2,)所以,对于一个shape为(…

yii3正式版什么时候发布_华为mate50pro什么时候发布

阅读本文前,请您先点击上面的蓝色字体,再点击“关注”,这样您就可以继续免费收到文章了。每天都有分享,完全是免费订阅,请放心关注。 …

shiro如何保证session不失效_请问在不加锁的情况下如何保证线程安全?

概念compare and swap,解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数——内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器…

python visa模块_已经安装了pyvisa仍然报错没有模块

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼找到原因了。原因为pyvis是基于NIVISA的。而我现在的仪器是安捷伦的,必须用安捷伦的VISA。两者虽然都是visa32.dll但是彼此不兼容。只能用其他方法了。新方法。已实现搜索所有可用设备。希望能帮助到更多的人from ctype…

externalreferences 命令在 sdi 模式下不可用_一个适合新手交互式Git命令学习项目

前言在我们日常工作开发中,Git是必不可少的版本控制软件,很多时候我们都用Git来管理我们的项目。比较常用的有Github,Gitlab,Stash等。因此对于Git命令的掌握是我们工作必备的能力。今天分享一个Git命令学习项目:learn…

sqlyong 删除数据能否撤回_数据结构知识点总结

some quoted by Fundebug:代码面试需要知道的8种数据结构(附面试题及答案链接)​zhuanlan.zhihu.comadded with other sources8 种常用数据结构数组栈队列链表图树哈希表priorityqueue1. 数组数组(Array)大概是最简单,也是最常用的数据结构了。其他数据结…

matlab 点云特征_基于点云的3D障碍物检测

击上方“新机器视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达基于点云的3D障碍物检测主要有以下步骤:点云数据的处理基于点云的障碍物分割障碍物边框构建点云到图像平面的投影点云数据的处理KITTI数据集KITTI数据集有四个相…

重定义 不同的基类型_镍及铁镍基耐蚀合金高温合金哈氏合金镍基合金之第一篇概述...

纯镍是一种重要的应用于工业的原材料,它除具有良好 的强度、塑韧性外,在卤族元素及其氢化物活泼性气体、苛 性介质、不含氧和氧化剂的还原性酸介质中还具有良好的耐 蚀性,因此纯镍作为耐蚀金属材料得到广泛应用。此外,由 于提高耐…

mysql脚本模式创建索引_mysql创建脚本索引范例

查看表中索引的方法:show index from table_name; 查看索引索引的类型及创建例子::1.PRIMARY KEY (主键索引)alter table table_name add primary key ( column );2.UNIQUE 或 UNIQUE KEY (唯一索引)alter table table_name add unique (column);3. 删除索引alter table 表名 d…

cad统计面积长度插件vlx_用了它,画cad施工图再也不加班了!

文尾左下角阅读原文看视频教程好课推荐:1、CAD2014:点击查看 2、室内CAD:点击查看 3、CAD2019:点击查看4、CAD2018:点击查看5、Bim教程:点击查看6、室内手绘:点击查看7、CAD三维:点击…

mysql 视图 查询速度慢_mysql 视图查询速度慢

场景:表 stockpooldata_flashCREATE TABLE stockpooldata_flash (id bigint(15) NOT NULL AUTO_INCREMENT,formula_id int(8) DEFAULT NULL,period_type tinyint(3) DEFAULT NULL,gpMarket int(4) DEFAULT NULL,gpcode varchar(20) DEFAULT NULL,ymd int(11) DEFAUL…

局部页面切换url为什么不变_python爬虫 - 翻页url不变网页的爬虫探究

python爬虫-翻页url不变网页的爬虫探究url随着翻页改变的爬虫已经有非常多教程啦,这里主要记录一下我对翻页url不变网页的探究过程。学术菜鸡第一次写CSDN,请大家多多包容~ 如果对你有一点点帮助,请帮我点个赞吧!翻页u…

vtune mysql user_intel vtune 介绍、安装和使用

intel vtune 介绍intel vtune 安装包下载地址intel VTune™ Amplifier 2019 安装手册 - Linux* OS:intel VTune™ Amplifier 用户使用手册安装步骤:Intel VTune Amplifier在Linux环境下的安装: $tar zxvf vtune_amplifie_2018_update3.tar.gz $cd vtune…

python波峰波谷算法_波动均分算法

波动均分算法by leeenx on 2018-01-11「波动」和「均分」大部分读者朋友是知道的,但看到「波动均分」应该是一头雾水的。其实,这个名词是笔者拼凑出来的。什么是「波动均分」?把指定的数值 A,分成 N 份,此时每份的数值…