结合GPS的SAT图道路识别

news2024/11/19 21:17:53

文章目录

  • 2019' Leveraging Crowdsourced GPS Data for Road Extraction from Aerial Imagery
    • 基本介绍
    • 对GPS的使用
      • 关于怎么证明GPS信息有效
      • How to render gps to image
        • GPS信息简介
        • GPS点状特征
        • GPS其他特征挖掘
      • 可借鉴的点
  • 2020' Convolutional Recurrent Network for Road Boundary Extraction

2019’ Leveraging Crowdsourced GPS Data for Road Extraction from Aerial Imagery

  • PDF arxiv
  • 代码 Github
  • 数据未提供

基本介绍

  • 网络结构:类UNet左右对称网络,主要设计体现在Decoder阶段上采样模块(文中提到:1D的上采样decoder模块,对于稀疏点的输入会比较鲁棒,Our 1D decoder has similar effect at roads with sparse samples, and they are not affected by sampling intervals.)
class DecoderBlock1DConv4(nn.Module):
    def __init__(self, in_channels, n_filters):
        super(DecoderBlock1DConv4, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, in_channels // 4, 1)
        self.norm1 = nn.BatchNorm2d(in_channels // 4)
        self.relu1 = nonlinearity

        self.deconv1 = nn.ConvTranspose2d(
            in_channels // 4, in_channels // 8, (1, 9), padding=(0, 4)
        )
        self.deconv2 = nn.ConvTranspose2d(
            in_channels // 4, in_channels // 8, (9, 1), padding=(4, 0)
        )
        self.deconv3 = nn.ConvTranspose2d(
            in_channels // 4, in_channels // 16, (9, 1), padding=(4, 0)
        )
        self.deconv4 = nn.ConvTranspose2d(
            in_channels // 4, in_channels // 16, (1, 9), padding=(0, 4)
        )

        self.norm2 = nn.BatchNorm2d(in_channels // 4 + in_channels // 8)
        self.relu2 = nonlinearity
        self.conv3 = nn.Conv2d(
            in_channels // 4 + in_channels // 8, n_filters, 1)
        self.norm3 = nn.BatchNorm2d(n_filters)
        self.relu3 = nonlinearity

    def forward(self, x):
        x = self.conv1(x)
        x = self.norm1(x)
        x = self.relu1(x)
        x1 = self.deconv1(x) # vertical 
        x2 = self.deconv2(x) # horizonal
        x3 = self.inv_h_transform(self.deconv3(self.h_transform(x))) # diag 
        x4 = self.inv_v_transform(self.deconv4(self.v_transform(x))) # anti-diag
        x = torch.cat((x1, x2, x3, x4), 1)

        x = F.interpolate(x, scale_factor=2)
        x = self.norm2(x)
        x = self.relu2(x)
        x = self.conv3(x)
        x = self.norm3(x)
        x = self.relu3(x)
        return x

    def h_transform(self, x):
        shape = x.size()
        x = torch.nn.functional.pad(x, (0, shape[-1]))
        x = x.reshape(shape[0], shape[1], -1)[..., :-shape[-1]]
        x = x.reshape(shape[0], shape[1], shape[2], 2*shape[3]-1)
        return x

    def inv_h_transform(self, x):
        shape = x.size()
        x = x.reshape(shape[0], shape[1], -1).contiguous()
        x = torch.nn.functional.pad(x, (0, shape[-2]))
        x = x.reshape(shape[0], shape[1], shape[-2], 2*shape[-2])
        x = x[..., 0: shape[-2]]
        return x

    def v_transform(self, x):
        x = x.permute(0, 1, 3, 2)
        shape = x.size()
        x = torch.nn.functional.pad(x, (0, shape[-1]))
        x = x.reshape(shape[0], shape[1], -1)[..., :-shape[-1]]
        x = x.reshape(shape[0], shape[1], shape[2], 2*shape[3]-1)
        return x.permute(0, 1, 3, 2)

    def inv_v_transform(self, x):
        x = x.permute(0, 1, 3, 2)
        shape = x.size()
        x = x.reshape(shape[0], shape[1], -1)
        x = torch.nn.functional.pad(x, (0, shape[-2]))
        x = x.reshape(shape[0], shape[1], shape[-2], 2*shape[-2])
        x = x[..., 0: shape[-2]]
        return x.permute(0, 1, 3, 2)
  • 拼接 GPS点状信息,并拼接 speed 和 timeinterval 两个GPS属性 的最大值和最小值特征 和 RGB 图像进行通道维拼接作为网络输入
  • 网络输出为单通道对于路面的二分类分割图
    在这里插入图片描述
  • LOSS设计:逐像素级别的二元交叉熵BCE进行路面和背景的区分,并加上预测路面和GT路面的IoU,即 BCE + IoU , 代码如下:
class dice_bce_loss(nn.Module):
    def __init__(self, batch=True):
        super(dice_bce_loss, self).__init__()
        self.batch = batch
        self.bce_loss = nn.BCELoss()

    def soft_dice_coeff(self, y_true, y_pred):
        smooth = 1.0  # may change
        if self.batch:
            i = torch.sum(y_true)
            j = torch.sum(y_pred)
            intersection = torch.sum(y_true * y_pred)
        else:
            i = y_true.sum(1).sum(1).sum(1)
            j = y_pred.sum(1).sum(1).sum(1)
            intersection = (y_true * y_pred).sum(1).sum(1).sum(1)
        score = (2. * intersection + smooth) / (i + j + smooth)
        # score = (intersection + smooth) / (i + j - intersection + smooth)#iou
        return score.mean()

    def soft_dice_loss(self, y_true, y_pred):
        loss = 1 - self.soft_dice_coeff(y_true, y_pred)
        return loss

    def __call__(self, y_true, y_pred):
        a = self.bce_loss(y_pred, y_true)
        b = self.soft_dice_loss(y_true, y_pred)
        return a + b

对GPS的使用

关于怎么证明GPS信息有效

  • 实验验证部分,进行了相关结果对比
    在这里插入图片描述

How to render gps to image

  • 即如何充分利用点状GPS信息,得到在二维图像坐标下的GPS特征
  • 将GPS信息渲染成图像形式,作为网络的输入

GPS信息简介

  • GPS信息的缺点,如下:
    在这里插入图片描述
    • GPS的点状信息的稠密和采样频率相关,如果只有如果直接在图像上进行点绘制(即二值图),会导致受噪声影响太大,比如上图左上,从而导致真实的道路信息被掩盖;
  • GPS点状信息属性:In both cases, each sample includes a timestamp, latitude, longitude, speed, bearing, and taxi status flags. GPS信息的分布遵循高斯分布

GPS点状特征

  • 采用密度图思路绘制:基于上小节对GPS点状信息的缺点分析,我们知道二值图绘制GPS点作为输入图是不可以的,本文采用灰度图来替代二值图,类似统计图像像素·对应的GPS点的数量 进行“密度”的统计 ;那么GPS数据点越多,越能得到道路信息(道路处像素点值远远大于周围的非道路区域点的像素)
  • 采用Kernel Density Estimation (KDE)思路绘制:受核密度估计(KDE)频繁使用的启发 在GPS数据的道路推断[9]中,我们也可以渲染 对GPS数据进行高斯核平滑处理,如下图可视化(Figure 6a is the Gaussian kernel rendering of Fig. 2a. Because of data disparity between highways and residential roads, log scale could make infrequently traveled roads more prominent. For example in Fig. 6b, the horizontal road at the bottom becomes much more visible than in the linear scale.)
    在这里插入图片描述

1、引入随机信息的GPS 数据增广

  • “sampling”:随机抽样,可以指定采样率(aug_sampling_rate)。
  • “precision”:移动GPS坐标的小数位数,可以指定精度率(aug_precision_rate)。
  • “perturbation”:数据扰动,随机添加高斯噪声。
  • “omission”:数据遗漏,随机删除GPS数据中某一区域内的点。
    def _gps_augmentation(self, patchedGPS, aug_mode, length=1024):
        if "sampling" in aug_mode:
            if self.aug_sampling_rate is None:
                sampling_rate = np.random.uniform(0.01, 1.0, None)
            else:
                sampling_rate = self.aug_sampling_rate
            patchedGPS = patchedGPS.sample(frac=sampling_rate)

        if "precision" in aug_mode:
            if self.aug_precision_rate is None:
                precision_rate = np.random.uniform(0.1, 1.0, None)
            else:
                precision_rate = self.aug_precision_rate
            patchedGPS['lat'] = np.floor(np.floor(patchedGPS['lat'] * precision_rate) / precision_rate)
            patchedGPS['lon'] = np.floor(np.floor(patchedGPS['lon'] * precision_rate) / precision_rate)

        if "perturbation" in aug_mode:
            num_records = patchedGPS.shape[0]
            sigma = 10 * np.random.rand()
            patchedGPS['lat'] += (sigma *
                                  np.random.randn(num_records)).astype(np.int)
            patchedGPS['lon'] += (sigma *
                                  np.random.randn(num_records)).astype(np.int)

        if "omission" in aug_mode:
            omission_start_x = length * np.random.rand() - length / 2
            omission_start_y = length * np.random.rand() - length / 2
            omission_end_x = omission_start_x + length / 2
            omission_end_y = omission_start_y + length / 2

            patchedGPS = patchedGPS[~((omission_start_y <= patchedGPS['lat']) & (patchedGPS['lat'] < omission_end_y) &
                                      (omission_start_x <= patchedGPS['lon']) & (patchedGPS['lon'] < omission_end_x))]
        return patchedGPS

  • 论文中给出的图示
    在这里插入图片描述

2、点状信息的稠密化

  • 该函数是将处理过的GPS数据转换为图像格式的函数。输入为处理过的GPS数据的DataFrame(patchedGPS),和一个图像的尺寸(length,默认为1024)。
    • 该函数首先创建一个大小为(length,length,1)的全0矩阵,表示图像像素的灰度值,
    • 然后对于patchedGPS中的每一个GPS坐标(经度,纬度),根据转换比例计算其在图像矩阵中的坐标,并将对应像素值设为255(白色)。
    • 最后,使用opencv库中的膨胀操作(dilate)扩大所有白色像素点,最终得到一个二值图像。

最后,该函数返回大小为(length,length,1)的GPS数据图像。

    def _sparse_to_dense(self, patchedGPS, length=1024):
        gps = np.zeros((length, length, 1), np.uint8)
        ratio = length / 1024.
        patchedGPS = patchedGPS[(0 <= patchedGPS['lat']) & (patchedGPS['lat'] < 1024) &
                                (0 <= patchedGPS['lon']) & (patchedGPS['lon'] < 1024)]
        y = np.array(patchedGPS['lon'] * ratio, np.int)
        x = np.array(patchedGPS['lat'] * ratio, np.int)
        gps[x, y] = 255
        gps = cv2.dilate(gps, np.ones((3, 3)))
        gps = gps[..., None]
        return gps

GPS其他特征挖掘

  • 均值特征:统计图像每个像素位置对应的所有经纬度GPS的特征的均值
    def _mean_of_feature_value(self, patchedGPS, feature_name, scale_factor, length=1024):
        feature_map = np.zeros((length, length, 1),  np.float)
        count = np.zeros((length, length, 1),  np.float)
        ratio = length / 1024.
        y = np.array(patchedGPS['lon'] * ratio, np.int)
        x = np.array(patchedGPS['lat'] * ratio, np.int)
        # to make 99% speed values in [0..255]
        value = np.array(np.clip(patchedGPS[feature_name] * scale_factor, 0, 255),  np.float)

        def additon(x, y, value):
            if 0 <= x < length and 0 <= y < length:
                feature_map[x, y] += value
                count[x, y] += 1
        average_vfunc = np.vectorize(additon)
        average_vfunc(x, y, value)
        feature_map = np.divide(feature_map, count,
                out=np.zeros_like(feature_map), where=(count!=0))# np.nan_to_num(feature_map / count)
        return feature_map.astype(np.uint8)
  • 最值特征:和上面类似,不过不取均值,而是取最大值
    def _max_of_feature_value(self, patchedGPS, feature_name, scale_factor, length=1024):
        feature_map = np.zeros((length, length),  np.float)
        ratio = length / 1024.
        y = np.array(patchedGPS['lon'] * ratio, np.int)
        x = np.array(patchedGPS['lat'] * ratio, np.int)
        # to make 99% speed values in [0..255]
        value = np.array(np.clip(patchedGPS[feature_name] * scale_factor, 0, 255),  np.float)

        def maximize(x, y, value):
            if 0 <= x < length and 0 <= y < length:
                feature_map[x, y] = max(value, feature_map[x, y])
        max_vfunc = np.vectorize(maximize)
        max_vfunc(x, y, value)
        return feature_map[..., None].astype(np.uint8)
  • 角度特征:统计每个图像像素对应的GPS点的角度cos和sin值
    def _aggregate_heading(self, patchedGPS, length=1024):
        feature_map = np.zeros((length, length, 2))
        ratio = length / 1024.
        patchedGPS = patchedGPS[(patchedGPS['dir']
                                 <= 360) & (patchedGPS['dir'] > 0)]
        def degree_to_rad(arr):
            return np.pi * arr / 180
        def aevrage(x, y, sin_value, cos_value):
            if 0 <= x < length and 0 <= y < length:
                if feature_map[x, y].any():
                    feature_map[x, y] = (
                        feature_map[x, y] + np.array([sin_value, cos_value])) / 2
                else:
                    feature_map[x, y] = [sin_value, cos_value]
        aevrage_vfunc = np.vectorize(aevrage)
        y = np.array(patchedGPS['lon'] * ratio, np.int)
        x = np.array(patchedGPS['lat'] * ratio, np.int)
        value = degree_to_rad(np.array(patchedGPS['dir']))
        sin_value = np.sin(value) * 127
        cos_value = np.cos(value) * 127
        aevrage_vfunc(x, y, sin_value, cos_value)
        feature_map += 128
        return feature_map.astype(np.uint8)
  • 本文除了点状特征,还增加了几个特征,包括:speed的均值和最大值特征,timeinterval的均值和最大值特征,角度的2通道特征,总共6个特征 (the pixel values of the interval, speed, and bearing layers are the average sampling interval, average speed, and average sinusoid of the bearing for all the samples projected to the pixel, respectively.)

可借鉴的点

  1. gps的点状信息先进行四种数据增广,再进行稠密化(密度图+高斯平滑+log+截断在0~255+膨胀操作) 、有一些其他操作比如在较为稀疏的点之间加上线段连接,但是这种操作在稀疏场景下会缩短曲线的长度,也和真实的道路情况不同,所以不建议
  2. 基于数据增广的gps点状信息,再提取速度,角度,和timeinterval(这个不知道是啥)相关特征,一起concat和rgb一起输入网络,GPS特征挖掘
  3. 网络Decoder的设计DecoderBlock1DConv4 以及基于路面的 loss 设计 bce + iou

2020’ Convolutional Recurrent Network for Road Boundary Extraction

  • Github
  • 将camera,LiDar、elevation gradient 三类图作为输入,进行道路边界提取‘
    在这里插入图片描述

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

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

相关文章

《黑马头条》SpringBoot+SpringCloud+ Nacos等企业级微服务架构项目

环境搭建、SpringCloud微服务(注册发现、服务调用、网关) 1)课程对比 2)项目概述 2.1)能让你收获什么 2.2)项目课程大纲 2.3)项目概述 随着智能手机的普及&#xff0c;人们更加习惯于通过手机来看新闻。由于生活节奏的加快&#xff0c;很多人只能利用碎片时间来获取信息&#x…

红帽认证考试流程详解,让你少走弯路

参加红帽认证考试涉及以下三个流程 账号和证件的准备 1 RHN 账号注册 考试前需要您提前注册红帽帐号(RHN) 注册地址&#xff1a;https://www.redhat.com/wapps/ugc/register.html 注册时以下条目请重点注意&#xff1a; ▸ 账户类型选择 Personal ▸ 红帽账户登录名…

onnx修改模型节点【改变input的shape】

因为转onnx后模型的输入无法转rknn&#xff0c;所以要对onnx进行节点修改成左边 import onnx import onnx.helper as helper from onnx.helper import TensorProto import numpy as npmodel onnx.load(demo.change.onnx) #自己创建新的节点 ###############################…

【LeetCode热题100】打卡第29天:二叉树的层序遍历二叉树的最大深度

文章目录 【LeetCode热题100】打卡第29天&#xff1a;二叉树的层序遍历&二叉树的最大深度⛅前言 二叉树的层序遍历&#x1f512;题目&#x1f511;题解 二叉树的最大深度&#x1f512;题目&#x1f511;题解 【LeetCode热题100】打卡第29天&#xff1a;二叉树的层序遍历&am…

Stage模型HarmonyOS服务卡片开发ArkTS卡片相关模块

图1 ArkTS卡片相关模块 FormExtensionAbility&#xff1a;卡片扩展模块&#xff0c;提供卡片创建、销毁、刷新等生命周期回调。 FormExtensionContext&#xff1a;FormExtensionAbility的上下文环境&#xff0c;提供FormExtensionAbility具有的接口和能力。 formProvider&…

CASAIM三维扫描仪在运动防护的应用高端运动器材设计定制器材头盔

CASAIM三维扫描技术在运动防护领域有广泛的应用&#xff0c;可以帮助设计和生产高端运动器材&#xff0c;检测运动器材适配性&#xff0c;以提供更好的运动防护。 CASAIM三维扫描仪可以将运动员的身体尺寸和形状精确地捕捉下来&#xff0c;以便制造出符合其个人需求的定制化器…

稳坐钓鱼台,第三大手机操作系统?华为鸿蒙OS 4.0首批测试版推送

华为鸿蒙OS 4.开发者Beta版首期招募正式开始&#xff0c;首批机型包括华为P60、P60 Pro、Mate 50、MatePad Pro 11英寸性能版等8款。 不可思议的是&#xff0c;华为方才开始招募没几天&#xff0c;就已经开始向用户推送鸿蒙OS 4.开发者Beta版的升级。它的更新速度令人瞩目&…

ChatGPT 话题相关和类 ChatGPT 工具 | 优质文章、相关论文、应用、学习资源整理

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 人工智能与手机和互联网一样具有革命性。 2023 年已经过去一半&#xff0c;ChatGPT 在今年以来一直备受瞩目。目前 ChatGPT 的更新速度逐渐放缓&#…

常见的远程协助软件简介

1.RayLink远程控制软件 RayLink是一个支持多系统多设备间相互远程控制的软件&#xff0c;是具有远程制作、远程办公、远程游戏、远程协助等需求的IT技术、游戏玩家、网络办公等这些人的最佳选择。通过使用RayLink&#xff0c;可随时随地远程控制其他电脑或手机&#xff0c;远程…

AI日报:DragGAN通过拖拽像素点实现图像调整 等

&#x1f989; AI新闻 &#x1f680; DragGAN&#xff1a;一种直观的图像编辑工具&#xff0c;通过拖拽像素点实现图像调整 摘要&#xff1a;研究者们来自马克斯・普朗克计算机科学研究所、MIT CSAIL和谷歌&#xff0c;他们开发了一种名为DragGAN的图像编辑工具。通过拖拽像素…

MATLAB 之 Simulink 子系统及其封装

这里写目录标题 一、子系统及其封装1. 子系统的创建1.1 通过 Subsystem 模块建立子系统1.2 通过已有的模块建立子系统 2. 子系统的条件执行2.1 使能子系统2.2 触发子系统2.3 使能加触发子系统 3. 子系统的封装3.1 lcon & Ports 选项卡的参数设置3.2 Parameters & Dialo…

最大池化|知识补充

最大池化的超参数&#xff1a;规模为2的过滤器&#xff0c;步幅为2 对于左上角深蓝色的区域&#xff0c;其中最大的数值是9&#xff0c;所以得到的输出为9&#xff1b; 向右移动两个步幅&#xff0c;输出为2&#xff1b; 第二行&#xff0c;22的绿色区域内输出为6&#xff1b;…

2023版新鲜出炉,1000多道互联网Java高频面试真题及详解汇总

最近感慨面试难的人越来越多了&#xff0c;一方面是市场环境&#xff0c;更重要的一方面是企业对Java的人才要求越来越高了。 基本上这样感慨的分为两类人&#xff1a; 第一&#xff0c;虽然挂着3、5年经验&#xff0c;但肚子里货少&#xff0c;也没啥拿得出手的项目&#xff…

元宇宙装备展正式拉开帷幕,深眸科技CEO周礼出席产业论坛发表主题演讲

6月27日&#xff0c;一场令人期待已久的工业元宇宙盛会在昆山国际会展中心拉开帷幕&#xff0c;大会由昆山市人民政府主办&#xff0c;昆山市工业和信息化局、赛迪工业和信息化研究院集团&#xff08;苏州&#xff09;有限公司联合承办&#xff0c;并得到了十数家单位的支持&am…

Python入门的60个基础练习(二)

关注“Python专栏”微信公众号&#xff0c;回复暗号【面试大全】&#xff0c;立即领取面试题简历模板。 21-while-break break 是结束循环&#xff0c;break 之后、循环体内代码不再执行。 while True:yn input(Continue(y/n): )if yn in [n, N]:breakprint(running...)22-w…

机器学习12:分类 Classification

分类&#xff08;Classification&#xff09;是一个有监督的学习过程&#xff0c;目标数据集&#xff08;示例集&#xff09;中具有的类别是已知的&#xff0c;分类过程需要做的就是把每一条记录归到对应的类别下。由于必须事先知道各个类别的信息&#xff0c;并且所有待分类的…

vite项目集成eslint和prettier

一、eslint介绍 eslint中文官网&#xff1a;https://zh-hans.eslint.org/docs/latest/use/getting-started 1. 什么是eslint ESLint是一个开源的JavaScript代码静态分析工具&#xff0c;用于找出代码中的问题&#xff0c;并提供一致的编码风格。它可以扫描代码&#xff0c;并…

SpringCloud之Stream消息驱动RocketMQ讲解

文章目录 1 Stream消息驱动1.1 简介1.1.1 定义1.1.2 抽象模型1.1.3 绑定器 1.2 操作实操1.2.1 pom.xml1.2.2 操作实体 1.3 Stream 3.x 之前操作1.3.1 自定义通道1.3.2 消费消息1.3.3 发送消息1.3.4 配置文件 1.4 Stream 3.x 之后操作1.4.1 Stream 3.x 之后讲解1.4.2 消费消息1.…

linux屏幕旋转/weston去掉边框

目录 屏幕旋转 去掉边框 buildroot运行QT&#xff0c;你需要修改的都在这里了。 首先QT界面大小需要适应屏幕的分辨率&#xff0c;如果屏幕是1280*800&#xff0c;QT界面大小就不能设置为800*1280&#xff0c;一样需要设置为1280*800 屏幕旋转 方法一&#xff1a; xrandr…

GBASE观察 | 展望大模型与数据库相融合的未来

大模型和数据库的相互作用是数据处理领域的重要发展趋势之一&#xff0c;在目前的大数据时代中正发挥着越来越重要的作用。大模型需要依托于海量数据进行训练和学习&#xff0c;在实际应用中需要依托于数据库进行实时的数据存储、筛选、处理、甚至还可以实现数据的可视化和转化…