三维点云数据的哈希快速查找方法

三维点云数据的哈希快速查找方法

对于三维空间中的浮点坐标点云数据,实现快速查找需要考虑浮点数的精度问题以及空间分布特性。以下是几种有效的哈希查找方法:

1. 网格哈希 (Grid Hashing)

原理:将三维空间划分为均匀的网格,每个点根据坐标分配到对应的网格单元。

python 复制代码
import math

class GridHash:
    def __init__(self, cell_size=0.1):
        self.cell_size = cell_size
        self.hash_table = {}
    
    def _get_cell_key(self, point):
        x, y, z = point
        return (
            math.floor(x / self.cell_size),
            math.floor(y / self.cell_size),
            math.floor(z / self.cell_size)
        )
    
    def insert(self, point):
        key = self._get_cell_key(point)
        if key not in self.hash_table:
            self.hash_table[key] = []
        self.hash_table[key].append(point)
    
    def query(self, point):
        key = self._get_cell_key(point)
        return self.hash_table.get(key, [])

2. 空间填充曲线哈希 (Z-order/Morton Code)

原理:使用空间填充曲线将三维坐标映射为一维哈希值。

python 复制代码
def interleave_bits(x, y, z):
    # 将三个坐标的二进制位交错排列
    def spread_bits(n):
        n = (n | (n << 16)) & 0x030000FF
        n = (n | (n << 8)) & 0x0300F00F
        n = (n | (n << 4)) & 0x030C30C3
        n = (n | (n << 2)) & 0x09249249
        return n
    return spread_bits(x) | (spread_bits(y) << 1) | (spread_bits(z) << 2)

class MortonHash:
    def __init__(self, precision=1e-6):
        self.precision = precision
        self.hash_table = {}
    
    def _quantize(self, coord):
        return int(coord / self.precision)
    
    def insert(self, point):
        x, y, z = [self._quantize(c) for c in point]
        key = interleave_bits(x, y, z)
        if key not in self.hash_table:
            self.hash_table[key] = []
        self.hash_table[key].append(point)
    
    def query(self, point):
        x, y, z = [self._quantize(c) for c in point]
        key = interleave_bits(x, y, z)
        return self.hash_table.get(key, [])

3. 近似最近邻哈希 (Locality Sensitive Hashing, LSH)

原理:使用随机投影将相近的点映射到相同哈希桶的概率更高。

python 复制代码
import numpy as np

class LSHHash:
    def __init__(self, dim=3, num_tables=5, hash_size=10, w=4.0):
        self.num_tables = num_tables
        self.hash_size = hash_size
        self.w = w
        
        # 生成随机投影向量
        self.hash_tables = []
        for _ in range(num_tables):
            table = {
                'projection': np.random.randn(dim, hash_size),
                'bias': np.random.uniform(0, w, size=hash_size),
                'table': {}
            }
            self.hash_tables.append(table)
    
    def _hash(self, point, table):
        projections = np.dot(point, table['projection']) + table['bias']
        hash_key = tuple(np.floor(projections / self.w).astype(int))
        return hash_key
    
    def insert(self, point):
        point = np.array(point)
        for table in self.hash_tables:
            key = self._hash(point, table)
            if key not in table['table']:
                table['table'][key] = []
            table['table'][key].append(point)
    
    def query(self, point):
        point = np.array(point)
        results = set()
        for table in self.hash_tables:
            key = self._hash(point, table)
            if key in table['table']:
                for p in table['table'][key]:
                    results.add(tuple(p))
        return list(results)

4. 八叉树 (Octree) 索引

虽然不是严格的哈希表,但八叉树也能提供快速的空间查找:

python 复制代码
class OctreeNode:
    def __init__(self, center, size, capacity=10, max_depth=5):
        self.center = center
        self.size = size
        self.capacity = capacity
        self.max_depth = max_depth
        self.points = []
        self.children = None
    
    def insert(self, point, depth=0):
        if self.children is not None:
            index = self._get_child_index(point)
            self.children[index].insert(point, depth+1)
        else:
            self.points.append(point)
            if len(self.points) > self.capacity and depth < self.max_depth:
                self._split()
    
    def _get_child_index(self, point):
        x, y, z = point
        cx, cy, cz = self.center
        index = 0
        if x > cx: index |= 1
        if y > cy: index |= 2
        if z > cz: index |= 4
        return index
    
    def _split(self):
        child_size = self.size / 2
        self.children = []
        for i in range(8):
            offset = [
                child_size if (i & 1) else -child_size,
                child_size if (i & 2) else -child_size,
                child_size if (i & 4) else -child_size
            ]
            child_center = [self.center[j] + offset[j] for j in range(3)]
            self.children.append(OctreeNode(child_center, child_size, 
                                         self.capacity, self.max_depth))
        
        for point in self.points:
            index = self._get_child_index(point)
            self.children[index].insert(point)
        self.points = []
    
    def query(self, point, radius):
        results = []
        if self.children is not None:
            index = self._get_child_index(point)
            results.extend(self.children[index].query(point, radius))
            # 检查相邻节点
            for i in range(8):
                if i != index and self._check_overlap(i, point, radius):
                    results.extend(self.children[i].query(point, radius))
        else:
            for p in self.points:
                if np.linalg.norm(np.array(p) - np.array(point)) <= radius:
                    results.append(p)
        return results

选择建议

  1. 网格哈希:最简单直接,适合均匀分布的点云
  2. Morton哈希:对空间局部性有更好保留,适合范围查询
  3. LSH:适合高维数据和近似最近邻搜索
  4. 八叉树:适合非均匀分布的点云,动态更新效率高

对于浮点坐标,关键是要处理好精度问题,通常需要将浮点数量化到适当的精度后再进行哈希。

相关推荐
半间烟雨7 小时前
Web3(阶段一:入门)——哈希算法
算法·web3·区块链·哈希算法
梭七y8 小时前
【力扣hot100题】(034)LRU缓存
leetcode·缓存·哈希算法
luckyme_2 天前
leetcode-代码随想录-哈希表-哈希理论基础
leetcode·哈希算法·散列表
爱的叹息2 天前
华为高斯(GaussDB)数据库中 Range、List、Hash三种分区方式 的完整SQL示例及增删改查操作,并附上总结对比表格
数据库·哈希算法·gaussdb
爱的叹息4 天前
RedisTemplate 的 6 个可配置序列化器属性对比
算法·哈希算法
小林熬夜学编程4 天前
【高并发内存池】第八弹---脱离new的定长内存池与多线程malloc测试
c语言·开发语言·数据结构·c++·算法·哈希算法
敲上瘾4 天前
高并发内存池(二):Central Cache的实现
linux·服务器·c++·缓存·哈希算法
凸头5 天前
I/O多路复用 + Reactor和Proactor + 一致性哈希
java·哈希算法
green5+16 天前
LeetCode1两数之和
算法·哈希算法·散列表