八种点云聚类方法(三)

        本节主要介绍OPTICS、Spectral Clustering(SC,即谱聚类)、 Hierarchical Clustering(层次聚类)、Mean-shift(即:均值迁移)、BIRCH、Affinity Propagation等聚类算法在点云聚类上的简单应用效果。DBSCAN和KMEANS聚类已在前两节介绍。skit-lean各个聚类算法的简要介绍请查看sklearn聚类方法详解_飞奔的帅帅的博客-CSDN博客_sklearn 聚类

 

1 OPTICS

        OPTICS是一种类似于DBSCAN的聚类算法,也是基于密度聚类。skit-learn中的OPTICS同样有多个参数。这里仅设置其中两个min_samples、max_eps,即累中最小的样本数和最大邻域距离。同样地,OPTICS聚类结果的类别也是未知的。

class sklearn.cluster.OPTICS(*, min_samples=5, max_eps=inf, metric='minkowski', p=2, metric_params=None, cluster_method='xi', eps=None, xi=0.05, predecessor_correction=True, min_cluster_size=None, algorithm='auto', leaf_size=30, n_jobs=None)

2 Spectral Clustering 谱聚类

        Spectral Clustering(SC,即谱聚类),是一种基于图论的聚类方法,它能够识别任意形状的样本空间且收敛于全局最有解。skit-learn中对应函数类为SpectralClustering,其主要参数之一也是分类的个数n_clusters。和Kmeans相同,其最终聚类的类别数量也是固定的。函数返回值请参考Kmeans五种点云聚类方法(二)— KMeans_Coding的叶子的博客-CSDN博客。

from sklearn.clustering import SpectralClustering
result = SpectralClustering(n_clusters=8).fit(points)

3 Hierarchical Clustering 层次聚类

        Hierarchical Clustering(层次聚类):就是按照某种方法进行层次分类,直到满足某种条件为止。 skit-learn中对应函数类为AgglomerativeClustering,其主要参数之一也是分类的个数n_clusters。和Kmeans相同,其最终聚类的类别数量也是固定的。函数返回值请参考Kmeans五种点云聚类方法(二)— KMeans_Coding的叶子的博客-CSDN博客。

from sklearn.clustering import AgglomerativeClustering
result = AgglomerativeClustering(n_clusters=8).fit(points)

4 Mean-shift 均值迁移

        Mean-shift(即:均值迁移)的基本思想:在数据集中选定一个点,然后以这个点为圆心,r为半径,画一个圆(二维下是圆),求出这个点到所有点的向量的平均值,而圆心与向量均值的和为新的圆心,然后迭代此过程,直到满足一点的条件结束。skit-learn中对应函数类为MeanShift,其主要参数为bandwidth,相当于半径r。

from sklearn.clustering import MeanShift
result = MeanShift(bandwidth=2).fit(points)

5 BIRCH聚类

        BIRCH主要用于对大型数据集执行分层聚类。skit-learn中对应函数类为Birch,其主要参数之一也是分类的个数n_clusters。和Kmeans相同,其最终聚类的类别数量也是固定的。

from sklearn.clustering import Birch
Birch = AgglomerativeClustering(n_clusters=8).fit(points)

6 Affinity Propagation聚类

       AP(Affinity Propagation)通常被翻译为近邻传播算法或者亲和力传播算法。AP算法的基本思想是将全部数据点都当作潜在的聚类中心(称之为exemplar),然后数据点两两之间连线构成一个网络(相似度矩阵),再通过网络中各条边的消息(responsibility和availability)传递计算出各样本的聚类中心。skit-learn中对应函数类为AffinityPropagation,其主要参数为preference,决定着聚类后的类别数量。该聚类方法的类别的熟练是不固定的。

from sklearn.clustering import AffinityPropagation
result = AffinityPropagation(preference=-10).fit(points)

7 样例程序

          pcd文件请参考:pcd格式点云样例文件-深度学习文档类资源-CSDN下载。

# -*- coding: utf-8 -*-
"""
@author: https://blog.csdn.net/suiyingy
"""

import open3d as o3d
import numpy as np
from copy import deepcopy
from sklearn.cluster import OPTICS, SpectralClustering, AgglomerativeClustering, estimate_bandwidth, MeanShift, Birch, AffinityPropagation


if __name__ == '__main__':
    file_path = 'rabbit.pcd'
    pcd = o3d.io.read_point_cloud(file_path)
    pcd = pcd.uniform_down_sample(10)#每50个点采样一次
    pcd.paint_uniform_color([0.5, 0.5, 0.5])#指定显示为灰色
    print(pcd)
    
    pcd1 = deepcopy(pcd)
    pcd1.translate((20, 0, 0)) #整体进行x轴方向平移20
    points = np.array(pcd1.points)
    result = OPTICS(min_samples=2, max_eps=5).fit(points)
    #各个类别中心
    # labels返回聚类成功的类别,从0开始,每个数据表示一个类别
    labels = result.labels_
    #最大值相当于共有多少个类别
    max_label = np.max(labels) + 1 #从0开始计算标签
    print(max(labels))
    #生成k个类别的颜色,k表示聚类成功的类别
    colors = np.random.randint(255, size=(max_label+1, 3))/255.
    colors = colors[labels]
    #没有分类成功的点设置为黑色
    colors[labels < 0] = 0 
    pcd1.colors = o3d.utility.Vector3dVector(colors[:, :3])
    
    
    pcd2 = deepcopy(pcd)
    pcd2.translate((-20, 0, 0)) #整体进行x轴方向平移-20
    points = np.array(pcd2.points)
    result = SpectralClustering(n_clusters=8).fit(points)
    #各个类别中心
    # labels返回聚类成功的类别,从0开始,每个数据表示一个类别
    labels = result.labels_
    #最大值相当于共有多少个类别
    max_label = np.max(labels) + 1 #从0开始计算标签
    print(max(labels))
    #生成k个类别的颜色,k表示聚类成功的类别
    colors = np.random.randint(255, size=(max_label+1, 3))/255.
    colors = colors[labels]
    #没有分类成功的点设置为黑色
    colors[labels < 0] = 0 
    pcd2.colors = o3d.utility.Vector3dVector(colors[:, :3])
    
    pcd3 = deepcopy(pcd)
    pcd3.translate((0, 20, 0)) #整体进行y轴方向平移20
    points = np.array(pcd3.points)
    result = AgglomerativeClustering(n_clusters=8).fit(points)
    #各个类别中心
    # labels返回聚类成功的类别,从0开始,每个数据表示一个类别
    labels = result.labels_
    #最大值相当于共有多少个类别
    max_label = np.max(labels) + 1 #从0开始计算标签
    print(max(labels))
    #生成k个类别的颜色,k表示聚类成功的类别
    colors = np.random.randint(255, size=(max_label+1, 3))/255.
    colors = colors[labels]
    #没有分类成功的点设置为黑色
    colors[labels < 0] = 0 
    pcd3.colors = o3d.utility.Vector3dVector(colors[:, :3])
    
    pcd4 = deepcopy(pcd)
    pcd4.translate((0, -20, 0)) #整体进行y轴方向平移-20
    points = np.array(pcd4.points)
    #定义搜索半径,也可以直接初始化一个数值
    bandwidth = estimate_bandwidth(points, quantile=0.2, n_samples=500)
    result = MeanShift(bandwidth=bandwidth).fit(points)
    #各个类别中心
    # labels返回聚类成功的类别,从0开始,每个数据表示一个类别
    labels = result.labels_
    #最大值相当于共有多少个类别
    max_label = np.max(labels) + 1 #从0开始计算标签
    print(max(labels))
    #生成k个类别的颜色,k表示聚类成功的类别
    colors = np.random.randint(255, size=(max_label+1, 3))/255.
    colors = colors[labels]
    #没有分类成功的点设置为黑色
    colors[labels < 0] = 0 
    pcd4.colors = o3d.utility.Vector3dVector(colors[:, :3])
    
    pcd5 = deepcopy(pcd)
    pcd5.translate((40, 0, 0)) #整体进行x轴方向平移40
    points = np.array(pcd5.points)
    result = Birch(n_clusters=8).fit(points)
    #各个类别中心
    # labels返回聚类成功的类别,从0开始,每个数据表示一个类别
    labels = result.labels_
    #最大值相当于共有多少个类别
    max_label = np.max(labels) + 1 #从0开始计算标签
    print(max(labels))
    #生成k个类别的颜色,k表示聚类成功的类别
    colors = np.random.randint(255, size=(max_label+1, 3))/255.
    colors = colors[labels]
    #没有分类成功的点设置为黑色
    colors[labels < 0] = 0 
    pcd5.colors = o3d.utility.Vector3dVector(colors[:, :3])
    
    
    pcd6 = deepcopy(pcd)
    pcd6.translate((-40, 0, 0)) #整体进行x轴方向平移-40
    points = np.array(pcd6.points)
    result = AffinityPropagation(preference=-20).fit(points)
    #各个类别中心
    # labels返回聚类成功的类别,从0开始,每个数据表示一个类别
    labels = result.labels_
    #最大值相当于共有多少个类别
    max_label = np.max(labels) + 1 #从0开始计算标签
    print(max(labels))
    #生成k个类别的颜色,k表示聚类成功的类别
    colors = np.random.randint(255, size=(max_label+1, 3))/255.
    colors = colors[labels]
    #没有分类成功的点设置为黑色
    colors[labels < 0] = 0 
    pcd6.colors = o3d.utility.Vector3dVector(colors[:, :3])
    

    # 点云显示
    o3d.visualization.draw_geometries([pcd, pcd1, pcd2, pcd3, pcd4, pcd5, pcd6], #点云列表
                                      window_name="点云聚类",
                                      point_show_normal=False,
                                      width=800,  # 窗口宽度
                                      height=600)  # 窗口高度

8 各算法聚类效果

八种点云聚类方法(三)_第1张图片

python三维点云从基础到深度学习_Coding的叶子的博客-CSDN博客_3d点云 python从三维基础知识到深度学习,将按照以下目录持续进行更新。https://blog.csdn.net/suiyingy/article/details/124017716

你可能感兴趣的:(三维点云,python,聚类,点云聚类,python,机器学习)