【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

智能推荐

情人节表白网页源码_恋爱网站源码-程序员宅基地

文章浏览阅读565次。介绍:情人节表白网页源码,两个模板,手机电脑自适应演示一:www.qrj.zkxz.xyz演示二:www.qrj.zkxz.xyz/index02.html源码如下,网盘下载地址:https://zijiewangpan.com/wBpMWivQEPF图片:_恋爱网站源码

SVM支持向量机-核函数python实现(7)_non-bound iter-程序员宅基地

文章浏览阅读2.1w次,点赞31次,收藏173次。数据可视化上篇文章介绍了线性不可分和线性可分两种情况,以及五种核函数,线性核函数(linear),多项式核函数(poly),高斯核函数(rbf),拉普拉斯核函数(laplace)和Sigmoid核函数,基于《机器学习实战》的数据,我们使用各种核函数对数据尝试分类,下面看一下效果如何.首先看一下我们的数据集:........._non-bound iter

简单了解USB通信协议-程序员宅基地

文章浏览阅读855次,点赞24次,收藏22次。​在一个USB通信系统中,只能有一个主机存在,USB通信只存在于主机和设备之间,每次通信都必须由主机发起,而设备和设备之间无法通信。

myeclipse properties文件中文乱码_myeclipse修proper-程序员宅基地

文章浏览阅读128次。话不多说,直接上图(把默认编码改成UTF-8)_myeclipse修proper

Newtonsoft.Json - JObject与JArray总结_jobject转jarray-程序员宅基地

文章浏览阅读2.3w次,点赞3次,收藏35次。Newtonsoft.Json是一款.net下的Json序列化/反序列化库,省去了手动拼Json的麻烦,可以通过官网或者NuGet下载。JObject是其中比较万金油的一个类,可以在不使用实体类的情况下构建/解析Json。1.字符串转JObject引入命名空间:using Newtonsoft.Json.Linq;Json数据:{ "name": "steam"..._jobject转jarray

SpringBoot过滤器获取Request的body数据_springboot 重新实现dofilterinternal方法 读取请求body信息-程序员宅基地

文章浏览阅读546次。由于在SpringBoot过滤器或者拦截器中,request中getReader()和getInputStream()只能调用一次,到controller里数据就为空了,因此会导致Controller中@RequestBody的参数无法注入而导致 400 错误。_springboot 重新实现dofilterinternal方法 读取请求body信息

随便推点

遍历vtkRenderer中的vtkActor_vtk 中的 actor刷新-程序员宅基地

文章浏览阅读3.4k次。这篇博客 主要 想让大家知道如何遍历Render中的Actor,对Actor进行修改。vtkActorCollection* actorCollection = render->GetActors();int num = actorCollection->GetNumberOfItems();// Description: // Initialize the traversal o_vtk 中的 actor刷新

用户画像5步骤_用户画像五个步骤-程序员宅基地

文章浏览阅读3.7k次。此文章为转载文章,转载地址请点击此处 原标题:干货 | 搞定用户画像只需5个步骤 有一句话是,千万人撩你,不如一人懂你,这句话在互联网圈可以说成是,真正的了解用户,才能得到用户,所以,用户画像的重要性不言而喻。 什么是用户画像? 用户画像可以简单理解成是海量数据的标签,根据用户的目标、行为和观点的差异,将他们区分为不同的类型,然后每种类型中抽取出典型特征,..._用户画像五个步骤

在Eclipse中创建一个Web自动化测试脚本_eclipse自动化测试用例的设计及执行-程序员宅基地

文章浏览阅读893次。打开Eclipse,File -> New -> Project。必须在 src/test/java 目录下新建包,再新建类。在搜索框中输入selenium,选择第一个。PS:注意在外层添加* *_eclipse自动化测试用例的设计及执行

使用R语言提取包含特定字符串的数据行_保留含有特定数据的行r-程序员宅基地

文章浏览阅读1.4k次,点赞2次,收藏4次。使用R语言提取包含特定字符串的数据行在数据分析和处理过程中,我们经常需要从大型数据框中提取特定条件的数据行。在R语言中,我们可以使用各种方法来实现这个目标。本文将介绍如何使用R语言提取包含特定字符串的数据行。首先,我们需要导入需要处理的数据框。假设我们有一个名为"df"的数据框,包含多个列。我们的目标是提取包含特定字符串的数据行。假设我们希望提取包含字符串"New"的数据行。_保留含有特定数据的行r

基于阿里云部署和搭建私人云笔记完整教程—leanote_阿里云建为知笔记私有-程序员宅基地

文章浏览阅读3.7k次,点赞5次,收藏9次。本篇教程主要是带大家在自己的Linux服务器上搭建属于自己的开源云笔记系统。leanote官网 https://leanote.com/ 【蚂蚁笔记 = 笔记 + 博客 + 协作 + 私有云】私有部署:阿里云/腾讯云/华为云(随意选一个云计算平台进行部署)特点:Leanote云笔记产品包括: Leanote Web & Server(即本仓库), 桌面客户端, IOS, android. 4端全部开源!如果想试用我们的产品,欢迎在 https://leanote.com 上注册, Le._阿里云建为知笔记私有

RxAndroid jar包引入异常导致java.lang.NoClassDefFoundError: Failed resolution of: Lio/reactivex/android/sche-程序员宅基地

文章浏览阅读1.8k次。前言:项目引用第三方sdk,运行报错:java.lang.NoClassDefFoundError: Failed resolution of: Lio/reactivex/android/schedulers/AndroidSchedulers;原因:没有引入RxAndroid。解决:Build.gradle中增加implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'但是:项目服务器不是用gradle 编译的,而是mk。所以要找jar.._java.lang.noclassdeffounderror: failed resolution of: landroidx/activity/res

推荐文章

热门文章

相关标签