【ATL03学习】-程序员宅基地

技术标签: python  机器学习  numpy  

介绍

关于四叉树应用于点云数据的分割应用相对较少,网上有少量的四叉树应用于图像分割的文章,我自己写了一个基础的四叉树分割点云,欢迎大家讨论指正

建立四叉树

{ D k − 1 ′ = { X ∣ X ⊆ D k − 1 , s u m ( X ) > max ⁡ l i m i t } D k = s p l i t ( D k − 1 ′ ) \left\{\begin{matrix} D'_{k-1}=\{X|X\subseteq D_{k-1},sum(X)>\max_{limit}\} \\ D_k=split(D'_{k-1}) \end{matrix}\right. { Dk1={ XXDk1,sum(X)>maxlimit}Dk=split(Dk1)
对整片光子区域建立划分为矩形片区,对于矩形片区中当矩形内光子的数量大于 max ⁡ l i m i t \max_{limit} maxlimit时继续划分为小矩阵,否则停止。

def dgs(k, x, h, maxl, l):
    # 构建四叉树
    ks = {
    }
    k2 = np.array([[k[0], k[0] + (k[1] - k[0]) / 2, k[2], k[2] + (k[3] - k[2]) / 2],
                   [k[0] + (k[1] - k[0]) / 2, k[1], k[2], k[2] + (k[3] - k[2]) / 2],
                   [k[0], k[0] + (k[1] - k[0]) / 2, k[2] + (k[3] - k[2]) / 2, k[3]],
                   [k[0] + (k[1] - k[0]) / 2, k[1], k[2] + (k[3] - k[2]) / 2, k[3]]])
    for i in range(4):
        # print(i)
        ns = tj(k2[i], x, h)
        # print(k2[i])
        if ns > maxl:
            ks[str(i)] = dgs(k2[i], x, h, maxl, l)
        else:
            k2s = k2[i]
            cens = np.around(np.log2(l / (k2s[1] - k2s[0] + 0.1)))
            # print(cens)
            k2s = np.append(k2s, [ns, int(cens)], axis=0)
            ks[str(i)] = k2s
            # print(ns)
    return ks

大津法求阈值

利用每一级的光子数量构建频率直方图,求类间方差,获取阈值。

def otsu(jz):
    #otsu算法求阈值
    jz = np.array(jz)
    t = jz[:, 5]
    s = jz[:, 4]
    ns = np.array(hfh(t, s))
    t = list(ns[:, 0])
    s = ns[:, 1]
    p = s / np.sum(s)
    w1 = []
    w2 = []
    miu1 = []
    miu2 = []
    miu = []
    I = list(range(len(t)))
    sig2 = []
    for i in range(len(t)):
        w1.append(sum(p[:i]))
        w2.append(sum(p[i:]))
        miu1.append(sum(I[:i]) * sum(p[:i]) / (w1[i] + 0.01))
        miu2.append(sum(I[i:]) * sum(p[i:]) / (w2[i] + 0.01))
        miu.append(w1[i] * miu1[i] + w2[i] * miu2[i])
        sig2.append(w1[i] * (miu2[i] - miu[i]) + w2[i] * (miu2[i] - miu[i]))

    return t[sig2.index(max(sig2))]

结果展示

原始点云
去噪结果

完整代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def tj(k, x, h):
    #统计方块内的光子数量
    return np.sum((x >= k[0]) & (x <= k[1]) & (h >= k[2]) & (h <= k[3]))


def area(k):
    #求面积
    return (k[1] - k[0]) * (k[3] - k[2])


def dgs(k, x, h, maxl, l):
    # 构建四叉树
    ks = {
    }
    k2 = np.array([[k[0], k[0] + (k[1] - k[0]) / 2, k[2], k[2] + (k[3] - k[2]) / 2],
                   [k[0] + (k[1] - k[0]) / 2, k[1], k[2], k[2] + (k[3] - k[2]) / 2],
                   [k[0], k[0] + (k[1] - k[0]) / 2, k[2] + (k[3] - k[2]) / 2, k[3]],
                   [k[0] + (k[1] - k[0]) / 2, k[1], k[2] + (k[3] - k[2]) / 2, k[3]]])
    for i in range(4):
        # print(i)
        ns = tj(k2[i], x, h)
        # print(k2[i])
        if ns > maxl:
            ks[str(i)] = dgs(k2[i], x, h, maxl, l)
        else:
            k2s = k2[i]
            cens = np.around(np.log2(l / (k2s[1] - k2s[0] + 0.1)))
            # print(cens)
            k2s = np.append(k2s, [ns, int(cens)], axis=0)
            ks[str(i)] = k2s
            # print(ns)
    return ks



def zhuanghua(x, h, k):
    #判断方块内是否含有光子
    return (x >= k[0]) & (x <= k[1]) & (h >= k[2]) & (h <= k[3])


def qz(x, h, jz, thr):
    #去噪函数,jz为转化矩阵,thr为阈值
    label = np.zeros(len(x))
    for i in jz:
        if i[5] >= thr:
            label[zhuanghua(x, h, i)] = 1
    return label


def zh(ks, kf):
    #字典转化为,矩阵
    for i in ks:
        if isinstance(ks[i], dict):
            zh(ks[i], kf)
        else:
            kf.append(list(ks[i]))
    return kf


def hfh(t, s):
    #统计各级的光子数量
    ns = dict()
    for i in range(len(t)):
        if t[i] in ns.keys():
            ns[t[i]] += s[i]
        else:
            ns[t[i]] = s[i]
    ns = sorted(ns.items(), key=lambda x: x[0])
    return ns


def otsu(jz):
    #otsu算法求阈值
    jz = np.array(jz)
    t = jz[:, 5]
    s = jz[:, 4]
    ns = np.array(hfh(t, s))
    t = list(ns[:, 0])
    s = ns[:, 1]
    p = s / np.sum(s)
    w1 = []
    w2 = []
    miu1 = []
    miu2 = []
    miu = []
    I = list(range(len(t)))
    sig2 = []
    for i in range(len(t)):
        w1.append(sum(p[:i]))
        w2.append(sum(p[i:]))
        miu1.append(sum(I[:i]) * sum(p[:i]) / (w1[i] + 0.01))
        miu2.append(sum(I[i:]) * sum(p[i:]) / (w2[i] + 0.01))
        miu.append(w1[i] * miu1[i] + w2[i] * miu2[i])
        sig2.append(w1[i] * (miu2[i] - miu[i]) + w2[i] * (miu2[i] - miu[i]))

    return t[sig2.index(max(sig2))]

f = 'ATL03_20200327094144_00130706_005_01_gt3r.csv'
data = pd.read_csv(f)
print(data.keys())
#预处理
x, h, lat = np.array(data['x']), np.array(data['h']), np.array(data['lat'])
r1 = np.argsort(x)
x, h, lat = x[r1], h[r1], lat[r1]
r_id = np.where((lat < 44.9) & (lat > 44.8))
print(r_id[-1])
x = x[r_id]
h = h[r_id]
lat = lat[r_id]
#去噪前点云
plt.figure()
plt.scatter(x,h,marker='.',c='black')
plt.xlabel('Along-track distance/m')
plt.ylabel('Heights/m')
plt.show()

xiankuang = np.array([np.min(x), np.max(x), np.min(h), np.max(h)])
s = np.sum((x >= xiankuang[0]) & (x <= xiankuang[1]) & (h >= xiankuang[2]) & (h <= xiankuang[3]))
# k=xiankuang
l = xiankuang[1] - xiankuang[0]
ks = dgs(xiankuang, x, h, 2, l)
# print(ks.values())
jz = zh(ks, [])

#jz2 = np.array(jz)
thr = otsu(jz)
lab = qz(x, h, jz, thr)
plt.figure()
plt.scatter(x[lab == 0], h[lab == 0], marker='.', c='black', label='noise')
plt.scatter(x[lab == 1], h[lab == 1], marker='.', c='red', label='signal')
plt.xlabel('Along-track distance/m')
plt.ylabel('Heights/m')
plt.legend()
plt.show()
# s1 = (x < 2) & (h < 1000)
# lab = np.zeros(len(x))
# lab = qz(x, h, ks, 0.1, lab)

还是对字典结构不熟悉,后续又将字典结构转化为矩阵做后续处理,欢迎大家批评指正。

参考文献

[1]刘翔,张立华,戴泽源,陈秋,周寅飞.一种无输入参数的强噪声背景下ICESat-2点云去噪方法[J].光子学报,2022,51(11):354-364.
[2]Xie H, Sun Y, Xu Q, Li B, Guo Y, Liu X, Huang P, Tong X. Converting along-track photons into a point-region quadtree to assist with ICESat-2-based canopy cover and ground photon detection[J]. International Journal of Applied Earth Observation and Geoinformation, 2022, 112: 102872

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45694711/article/details/129665715

智能推荐

Spring、SpringBoot常见面试题与答案_spring和springboot的常见面试题-程序员宅基地

文章浏览阅读390次。SpringSpring Bean 的作用域有哪些?它的注册方式有几种?Spring 容器中管理一个或多个 Bean,这些 Bean 的定义表示为 BeanDefinition 对象,具体包含以下重要信息:Bean 的实际实现类;Bean 的引用或者依赖项;Bean 的作用范围;singleton:单例(默认);prototype:原型,每次调用bean都会创建新实例;request:每次http请求都会创建新的bean;session:同一个http session共享一个bean_spring和springboot的常见面试题

openstack认证服务(认证组件)3_openstack 认证服务-程序员宅基地

文章浏览阅读1.9k次。Openstack认证服务(认证组件)3_openstack 认证服务

职场生存法则:一个外企女白领的日记...-程序员宅基地

文章浏览阅读4.5k次。第11节:人与人的相处(1)   2006-6-7 8∶40∶00  人与人的相处  一、有后台的下属。  我遇见过,也处理得很好。你不能得罪他背后的人,那么就通过他去利用他背后的人。比如说他是老板的亲戚,碰见别的部门有什么搞不定的人,你美言他几句叫他去搞,成功了自然是别人给老板面子,失败了你也可以多多积累他的错误,日后真到不得不踢人的时候也派得上..._外企重视documentation

iOS踩坑App Store Connect Operation Error_sdk version issue. this app was built with the ios-程序员宅基地

文章浏览阅读3.4k次。这个应用程序是用iOS 15.5 SDK构建的。从2023年4月开始,所有提交到应用商店的iOS应用程序都必须使用iOS 16.1 SDK或更高版本构建,包括在Xcode 14.1或更高版本中。目前iOS 开发工具Xcode 版本号是13.4.1 ,系统无法升级,也会导致Xcode无法升级。1、苹果官方提示: 2023年4月开始,开发必须使用 Xcode 14.1 以上的版本,2、目前此电脑无法在升级, 2023年4月开始 ,此电脑就无法正常开发使用,应用程序商店连接操作错误。_sdk version issue. this app was built with the ios 15.5 sdk. all ios and ipa

接单平台汇总_excel接单平台-程序员宅基地

文章浏览阅读335次。接单平台汇总程序员客栈码市开源众包智慧外包实现网猿急送人人开发网开发邦点鸭网快码网英选网外包大师我爱方案网智筹网自由智客接单注意事项:1、没有第三方担保的个人单子,尽量少接2、无需求文档、没有具体要求的不接3、没有预付的不做,尽量用442的分步步骤方式4、没有金刚钻,别揽瓷器活5、急单勿接6、任何不付定金的单子都是耍赖7、不计得失,不怕吃亏..._excel接单平台

CPU如何跑分_cpu跑分教程-程序员宅基地

文章浏览阅读1k次。烤CPU的时候,占用率满了,CPU频率的槽有一些还是空的…… 有没有能跑分的软件?好像有的【聊电Jing】你的CPU性能如何? 来跑个分测试看看吧! | Cinebench R15 & R20 使用教学_哔哩哔哩_bilibili 好像还是免费的Cinebench - Maxon Cinebench - Microsoft Store Apps 频率为什么就是超不过3Ghz? 多核,100度了? 可能频率最高只能这么高,再高可能就烧掉了…… 多核结果.................._cpu跑分教程

随便推点

调用百度地图画圈并标出属于圈内的点位信息_bmap.circle-程序员宅基地

文章浏览阅读1.3k次。直接上代码:fanweiss(){//画圈varaaa=this.gaojingDatadebuggervarmap=newBMap.Map("ydmap");//创建Map实例varmPoint=newBMap.Point(this.gaojingData.longitude,this.gaojingData.latitude);//中心点map.setMapStyle({style:"midni..._bmap.circle

VisualVM 插件地址_visualvm 插件中心地址-程序员宅基地

文章浏览阅读1.4k次。VisualVM原插件地址是oracle的打不开,已经移到github上了,具体如下:介绍:https://visualvm.github.io/plugins.html下载地址:https://visualvm.github.io/pluginscenters.html 选择对应JDK版本下载即可! 注意事项:在使用Visual VM进行heapdump分析的时候,发..._visualvm 插件中心地址

understand 代码解析工具的使用_understand代码-程序员宅基地

文章浏览阅读8.8k次,点赞15次,收藏80次。understand 常用操作文章目录understand 常用操作简单介绍软件下载常用基本操作新建工程并添加现有文件如何找到自己当前想要去编辑的文件?如何在当前文件中找到你要编辑的函数?如何跳转到定义?查看当前文件的函数列表如何查看函数都被谁调用了?查看函数的调用逻辑如何查找如何找到函数的被调用图除此之外可以分析出代码的各种结构文本的编辑格式设置双屏一边看代码,一遍看代码地图简单介绍understand对分析代码有非常强的能力,完全可以代替sourceinsight,并且可以在linux上mac上使_understand代码

Oracle 闪回(flashback)数据库到指定时间点_数据库 oracle时间戳闪回-程序员宅基地

文章浏览阅读4.1k次。如果是update,delete类误操作且已经commit,优先考虑使用flashback query进行恢复。select * from test1 as of timestamp to_timestamp('2018-01-13 16:59:29','YYYY-MM-DD hh24:mi:ss');如果是drop或truncate table,则不能使用闪回查询,需要使用备库进行整库..._数据库 oracle时间戳闪回

[bigdata-124] docker+django2.0 构建web服务_docker django print-程序员宅基地

文章浏览阅读660次。在本地运行django1.python3.42.安装django,安装特定版本pip3 install django==2.03.测试安装python3import djangoprint(django.get_version())4.django使用创建一个新目录test_djangopython -m django --version_docker django print

话题的发布与订阅_话题订阅频率和发布频率一样-程序员宅基地

文章浏览阅读2.6k次,点赞3次,收藏11次。Ros话题发布与订阅节点的编写(C++)_话题订阅频率和发布频率一样

推荐文章

热门文章

相关标签