机器学习之利用k-means算法对点云数据进行目标分割,提取其中的建筑物、房屋等

原始点云数据在CloudCompare的显示如下:

  利用k-means算法提取出其中的建筑物、房屋等,我这里的代码是根据k-means算法的原理编写的代码,这样有助于大家对k-means算法的运行原理有一个深层次的了解,当然也可以直接调用sklearn里的算法,但是那样的话对于将来发展是不利的,毕竟知道算法的原理并根据原理编写代码学到的知识还是更多一些的。

代码如下:

#Author ZTY
import csv
import numpy as np
def kmean(x,k,maxtimes):
    m,n = np.shape(x)
    # 建立一个比数据集多一列的零矩阵,多的一列用来存放标签
    dataset = np.zeros([m,n+1])
    dataset[:,:-1] = x
    #根据要聚类的数量,初始化相应数量的中心点,可以随机选择n个,也可以选前n个作为初始点
    #middle = dataset[np.random.randint(m,size=k),:]
    middle = dataset[0:3,:]
    #为选定的中心点赋予标签
    middle[:,-1] = range(1,k+1)
    times = 0
    oldmiddle = None
    #迭代更新中心点时,判断何时停止
    while not shouldstop(oldmiddle,middle,times,maxtimes):
        print('times:',times)
        print('dataset:',dataset)
        print('middle:',middle)
        oldmiddle = np.copy(middle)
        times = times + 1
        #根据中心点,更新其他各个点的标签
        update(dataset,middle)
        #获取新的中心点
        middle = getmiddles(dataset,k)
    return dataset

def shouldstop(oldmiddle,middle,times,maxtimes):
    if times > maxtimes:
        return True
    return np.array_equal(oldmiddle,middle)


def update(dataset,middle):
    m,n =dataset.shape
    for i in range(0,m):
        dataset[i,-1] = getLabelFromCloestCentroid(dataset[i,:-1],middle)

#找出各个点距离最近的中心点,将中心点的标签赋予当前点
def getLabelFromCloestCentroid(datasetRow,middle):
    label = middle[0,-1]
    minDist = np.linalg.norm(datasetRow - middle[0,:-1])
    #np.linalg.norm(a-b)用来计算a,b两点之间的距离,a.b如果是list,必须要np.array(a)进行格式转换
    for i in range(1,middle.shape[0]):
        dist = np.linalg.norm(datasetRow - middle[i,:-1])
        if dist < minDist:
            minDist = dist
            label = middle[i,-1]
    print('minDist',minDist)
    print('label',label)
    return label

def getmiddles(datatset,k):
    result = np.zeros((k,datatset.shape[1]))
    for i in range(1,k+1):
        oneCluster = datatset[datatset[:,-1]==i,:-1]
        result[i-1,:-1] = np.mean(oneCluster,axis=0)
        result[i-1,-1] = i
    return result

file = open(r'全部点云数据.csv','r')
reader = csv.reader(file)
reader = list(reader)
m,n = np.shape(reader)
for i in range(0,m):
    for j in range(0,3):
        #转换数据类型
        reader[i][j] = float(reader[i][j])
m,n = np.shape(reader)
list1 = np.zeros([m,2])
for i in range(0,m):
    for j in range(2,4):
        #获取数据的z指与强度值
        list1[i][j-2] = reader[i][j]

# x = np.vstack((a,b,c,d))
result = kmean(list1,3,10)
print('result:',result[0])
print(reader[0])
reader0 = np.zeros([m,5])
for i in range(0,m):
    for j in range(0,4):
        reader0[i][j] = reader[i][j]
for i in range(0,m):
    reader0[i][-1] = int(result[i][-1])
print(reader0)

w1=open("1.txt","w")
w2=open("2.txt","w")
w3=open("3.txt","w")
w4=open("4.txt","w")

for i in range(m):
    if(reader0[i][-1]==1):
        w1.write("%s %s %s %s\n"%(reader0[i][0],reader0[i][1],reader0[i][2],reader0[i][3]))
    if(reader0[i][-1]==2):
        w2.write("%s %s %s %s\n" % (reader0[i][0], reader0[i][1], reader0[i][2],reader0[i][3]))
    if (reader0[i][-1] ==3):
        w3.write("%s %s %s %s\n" % (reader0[i][0], reader0[i][1], reader0[i][2],reader0[i][3]))
    if (reader0[i][-1] == 4):
        w4.write("%s %s %s %s\n" % (reader0[i][0], reader0[i][1], reader0[i][2],reader0[i][3]))

  以上代码将k值设置为4,也就是将点云聚成4类。输出为4个txt数据,加载进软件,效果图如下,分别是提取的道路,建筑物:

还是利用上述代码,将道路数据放进代码,将K设置为2,可以将道路数据聚类为两类,提取出道路的主干和边界:

PS:附上数据链接  https://download.csdn.net/download/qq_39343904/10863193

 

 

### 回答1: 地面激光雷达进行单木分割的主要步骤和算法原理可以概括如下: 1. 数据预处理:将激光雷达获取到的三维点云数据进行去噪和滤波,得到清洁的点云数据。 2. 地面提取利用地面模型对点云数据进行分类,将地面点和非地面点分离开来。 3. 点云聚类:将非地面点根据空间位置和属性特征进行聚类,将同一颗树的点聚为一类。 4. 特征提取:对每个点云聚类进行特征提取,如高度、密度、形态等。 5. 单木分割:应用基于规则、基于机器学习或基于深度学习的算法点云聚类进行单木分割,即将同一颗树的点云从其它点云中分离出来。 6. 评估和优化:对分割结果进行评估和优化,如去除误分割和漏分割等。 其中,单木分割是整个过程的关键步骤。常用的单木分割算法包括基于规则的方法、基于机器学习的方法和基于深度学习的方法。基于规则的方法需要根据经验和规则手动设计特征和分类器,难以应对复杂场景。基于机器学习的方法需要先进行训练,得到分类器后再进行分割,但需要大量标注数据和特征工程。基于深度学习的方法则可以自动提取特征和分类器,不需要手动设计和标注,具有较好的泛化能力和适应性。常用的基于深度学习的单木分割算法包括 PointNet、PointNet++、DGCNN、PointCNN 等。 ### 回答2: 地面激光雷达进行单木分割的主要步骤和算法原理如下: 步骤1:点云预处理 首先,从地面激光雷达扫描中获取点云数据。然后对点云数据进行去噪处理,去除掉不符合条件的离群点。 步骤2:地面提取 利用地面分割算法将地面点从整个点云数据中分离出来。一种常用的地面分割算法是基于地面几何特征的RANSAC算法,通过随机抽样选择和拟合平面模型的方式,找到点云中最适合表示地面的平面模型。 步骤3:单木分割分割得到的非地面点云数据中,利用聚类算法点云数据中的每个单木聚类为一个独立的点云对象。一种常用的聚类算法是基于点云空间关系的欧几里得聚类算法,通过计算点云之间的距离和密度,将距离较近且密度较高的点云聚类到一起。 步骤4:单木分割优化 通过进一步对聚类结果进行分析和处理,对单木分割结果进行优化和筛选。常用的优化方法包括基于几何特征的滤波处理和基于点云形状的特征提取算法原理: 地面激光雷达进行单木分割主要基于点云的属性和几何特征。地面分割算法利用RANSAC算法拟合地面平面模型,通过计算点云与拟合平面之间的距离,将地面点与非地面点分离开。而单木分割算法则是通过计算点云之间的几何关系和距离等属性,实现对点云数据的聚类。聚类算法将距离较近且密度较高的点云聚类到一起,从而实现对单木的识别和分割。优化步骤则是对聚类结果进行进一步的处理和筛选,以提高单木分割的准确性和鲁棒性。整个算法的原理是基于点云的属性和几何特征,通过不同的算法步骤对点云数据进行处理和分析,最终实现地面激光雷达的单木分割。 ### 回答3: 地面激光雷达进行单木分割的主要步骤和算法原理如下: 步骤一:预处理。地面激光雷达获取到的原始点云数据通常会包含地面、建筑物、树木等各种物体。因此,首先需要对原始数据进行预处理,去除地面和建筑物等非树木的点云。 步骤二:点云聚类。利用聚类算法将预处理后的点云数据进行分组,将同一树木的点云划分到一个独立的聚类组中。常用的聚类算法有k-means算法、DBSCAN算法等。 步骤三:特征提取。在每个聚类组中,提取树木的特征,例如树木的高度、体积、分支数量等。常用的特征提取方法包括基于计数的方法、基于形状的方法等。 步骤四:树木分割。树木分割是通过分析点云数据中的特征来判断每个聚类组是否属于树木,并将属于树木的聚类组分割出来。常用的树木分割算法有基于形状的方法、基于高度差异的方法等。 算法原理:地面激光雷达进行单木分割算法原理主要是基于对点云数据的预处理和特征提取。首先,通过预处理去除非树木的点云数据,将预处理后的点云数据进行聚类,将同一树木的点云划分到一个聚类组中。然后,通过提取每个聚类组中的树木特征,例如高度、体积等,来判断聚类组是否属于树木。最后,根据树木特征进行分割,将属于树木的聚类组分割出来。通过这些步骤和算法原理,地面激光雷达可以实现对单木的有效分割
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值