热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于遥感影像的道路完整性与连接性评价指标

前言考虑到道路这一特殊地物的拓扑结构信息,本博文引入两个指标RoadCompleteness和RoadConnectivity分别用于统计道路结果的完整性与连接性。
前言

考虑到道路这一特殊地物的拓扑结构信息,本博文引入两个指标 Road Completeness 和 Road Connectivity 分别用于统计道路结果的完整性与连接性。

Road Completeness

Lpred为预测出来的路的长度,Ltruth是真实标签中路的长度,其中,路的预测结果与真实标签都是单像素的栅格数据。Lpred是通过统计Ltruth在预测出来的道路路面范围内的长度。
在这里插入图片描述
下图表示了计算 Road Completeness 的方式。其中黄色为预测出来的道路,蓝色为真实道路,经过细化之后为蓝色的细线,即Ltruth,在第三幅中,经过叠加,落在预测结果上的绿色的代表预测成功的长度,即Lpred,红色的为缺失的长度。
在这里插入图片描述

import numpy as np
import skimage
from skimage import morphology
import cv2def thin_image(mask_dir, mask_file):im = cv2.imread(mask_dir + mask_file, 0)im = im > 128selem = skimage.morphology.disk(2)im = skimage.morphology.binary_dilation(im, selem)im = skimage.morphology.thin(im)return im.astype(np.uint8) * 255mask_dir = 'E:/shao_xing/out/result_boost12345/'
gt_dir = 'E:/shao_xing/test/lab/'
region = 'd'mylogs = open('E:/shao_xing/out/tiny_evalog/new_metric/' + region + '_boost12345.log','w')
ratio_list=[]
for i in range(-4, 4):for j in range(-4, 4):gt_file = region + '_' + str(i) + '_' + str(j) + '_osm.png'mask_file = gt_file[:-7] + 'merge.png'mask = cv2.imread(mask_dir + mask_file, 0)thin_gt = thin_image(gt_dir, gt_file)num_mask = np.sum(thin_gt[mask > 128]) / 255num_gt = np.sum(thin_gt) / 255ratio = num_mask / (num_gt+0.00001)if num_gt != 0:ratio_list.append(ratio)print('test image ', str(i), '_', str(j), 'ratio:', round(ratio, 2), file=mylogs)print('test image ', str(i), '_', str(j), 'ratio:', round(ratio, 2))print('********************************', file=mylogs)
print('Average Ratio:', round((sum(ratio_list) / len(ratio_list)), 2), file=mylogs)
print('********************************')
print('Average Ratio:', round((sum(ratio_list) / len(ratio_list)), 2))
mylogs.close()

Road Connectivity

下式表示 Road Connectivity 的计算方法。Nconnected代表预测结果中连续的道路片段的数量,Ntotal代表真实值中道路的片段的数量。统计的方法是将真实值的矢量数据分割成等长的片段,然后统计这些片段是否被完整预测出来,如果完整预测出来,则记为connected,没有完全预测出来记为unconnected。
在这里插入图片描述
下图表示 Road Connectivity 的统计过程。黄色为预测出来的道路,蓝色和红色的细线为矢量格式的道路真实标签,由很多片段组成。红色的表示断裂的部分,即 unconnected,蓝色的为 connected。
在这里插入图片描述

import sys
sys.path.append("./discoverlib")
from discoverlib import geom, graph
import numpy as np
import cv2
import skimage
from skimage import morphology"""
evaluate connectivity based on ground truth graph
We split the total graph into segments with length of around 20 pixels
Then, statistic the number of fully connected segments in segmentation masks.
The connectivity ratio is the percentage of fully connected segments.
"""
log_name = 'mask' # evaluation log file
mask_dir = '~/data/out/mask/' # segmentation masks for evaluatingtotal_gt_number = 0
total_connected_number = 0
total_not_connected_number = 0
total_pred_number = 0total_connected_length = 0
total_gt_length = 0
total_pred_length = 0
mylog = open('~/data/out/eval_log/' + log_name + '_connect.log', 'w')region_name_list = [["amsterdam",-4,-4,4,4], ["chicago",-4,-4,4,4], ["denver",-4,-4,4,4]]
for region_info in region_name_list:print("test region: "&#43;region_info[0])graph_name &#61; &#39;~/data/graph_gt/&#39;&#43; region_info[0] &#43; ".graph" # ground truth graphgt_graph &#61; graph.read_graph(graph_name)edge_nodes&#61;[]for i,edge in enumerate(gt_graph.edges):if i % 2 &#61;&#61;0:edge_nodes.append([edge.src.point.x,edge.src.point.y,edge.dst.point.x,edge.dst.point.y])base_gt_mask&#61;np.zeros((1024, 1024))edge_nodes&#61;np.array(edge_nodes)for i in range(region_info[1], region_info[3]):for j in range(region_info[2], region_info[4]):mask_file &#61; region_info[0] &#43; &#39;_&#39; &#43; str(i) &#43; &#39;_&#39; &#43; str(j) &#43; &#39;_fusion.png&#39;# print(mask_dir &#43; mask_file)mask &#61; cv2.imread(mask_dir &#43; mask_file, 0)/255patch_gt_number&#61;0patch_connected_number&#61;0patch_not_connected_number&#61;0patch_connected_length &#61; 0patch_gt_length &#61; 0offset&#61;[-i*1024, -j*1024, -i*1024, -j*1024]patch_nodes&#61;edge_nodes&#43;offsetfor seg_edge in patch_nodes:if (seg_edge>&#61;[0,0,0,0]).all() and (seg_edge<[1024,1024,1024,1024]).all():base_gt_mask &#61; np.zeros((1024, 1024))patch_gt_number&#43;&#61;1 # number of segments on the ground-truth graphbase_gt_mask&#61;cv2.line(base_gt_mask,(seg_edge[0],seg_edge[1]),(seg_edge[2],seg_edge[3]),color&#61;1, thickness&#61;1)pred_seg_length&#61;np.sum(mask[base_gt_mask>0])gt_length&#61;np.sum(base_gt_mask>0)patch_gt_length &#43;&#61; gt_lengthif pred_seg_length < gt_length:patch_not_connected_number&#43;&#61;1else:patch_connected_number&#43;&#61;1patch_connected_length &#43;&#61; gt_lengthelse:passim &#61; (mask*255) > 128selem &#61; skimage.morphology.disk(2)im &#61; skimage.morphology.binary_dilation(im, selem)im &#61; skimage.morphology.thin(im)thin_mask &#61; im.astype(np.uint8) * 255patch_pred_length &#61; np.sum(thin_mask > 0)patch_pred_number &#61; patch_pred_length / 20.0 # number of segments on the prediction graphratio &#61; 2*patch_connected_length/(patch_gt_length&#43;patch_pred_length&#43;0.00001)print(&#39;test image {}_{} connected:not:total {}/{}/{}, ratio: {}&#39;.format(i,j,patch_connected_number,patch_not_connected_number,patch_gt_number,round(ratio, 4)))print(&#39;test image {}_{} connected:not:total {}/{}/{}, ratio: {}&#39;.format(i, j, patch_connected_number,patch_not_connected_number,patch_gt_number,round(ratio, 4)), file&#61;mylog)total_gt_number &#43;&#61; patch_gt_numbertotal_connected_number &#43;&#61; patch_connected_numbertotal_not_connected_number &#43;&#61; patch_not_connected_numbertotal_pred_number &#43;&#61; patch_pred_numbertotal_connected_length &#43;&#61; patch_connected_lengthtotal_gt_length &#43;&#61; patch_gt_lengthtotal_pred_length &#43;&#61; patch_pred_length# total_ratio &#61; 2*total_connected_number/(total_gt_number&#43;total_pred_number)
total_ratio &#61; 2*total_connected_length/(total_gt_length&#43;total_pred_length)print(&#39;********************************&#39;)
print("total connected:not:total {}/{}/{}, ratio: {}".format(total_connected_number,total_not_connected_number,total_gt_number,round(total_ratio, 4)))
print("total_gt_length:{}".format(total_gt_length))
print("average gt length:{}".format(total_gt_length/total_gt_number))
print(&#39;********************************&#39;, file&#61;mylog)
print("total connected:not:total {}/{}/{}, ratio: {}".format(total_connected_number,total_not_connected_number,total_gt_number,round(total_ratio, 4)),file&#61;mylog)
print("total_gt_length:{}".format(total_gt_length),file&#61;mylog)
print("average gt length:{}".format(total_gt_length/total_gt_number),file&#61;mylog)mylog.close()

参考

https://github.com/astro-ck/Road-Extraction


推荐阅读
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 本文介绍了贝叶斯垃圾邮件分类的机器学习代码,代码来源于https://www.cnblogs.com/huangyc/p/10327209.html,并对代码进行了简介。朴素贝叶斯分类器训练函数包括求p(Ci)和基于词汇表的p(w|Ci)。 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • 本文介绍了在Python张量流中使用make_merged_spec()方法合并设备规格对象的方法和语法,以及参数和返回值的说明,并提供了一个示例代码。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • java drools5_Java Drools5.1 规则流基础【示例】(中)
    五、规则文件及规则流EduInfoRule.drl:packagemyrules;importsample.Employ;ruleBachelorruleflow-group ... [详细]
  • Python基础知识:注释、输出和input交互
    本文介绍了Python基础知识,包括注释的使用、输出函数print的用法以及input函数的交互功能。其中涉及到字符串和整数的类型转换等内容。 ... [详细]
  • Python教学练习二Python1-12练习二一、判断季节用户输入月份,判断这个月是哪个季节?3,4,5月----春 ... [详细]
  • tcpdump 4.5.1 crash 深入分析
    tcpdump 4.5.1 crash 深入分析 ... [详细]
  • 颜色迁移(reinhard VS welsh)
    不要谈什么天分,运气,你需要的是一个截稿日,以及一个不交稿就能打爆你狗头的人,然后你就会被自己的才华吓到。------ ... [详细]
  • WPF之Binding初探
      初学wpf,经常被Binding搞晕,以下记录写Binding的基础。首先,盗用张图。这图形象的说明了Binding的机理。对于Binding,意思是数据绑定,基本用法是:1、 ... [详细]
author-avatar
bliss
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有