基于移动最小二乘法的点云曲面拟合(python)
1.移动最小二乘法介绍
为了更好地对数据量大且形状复杂的离散数据进行拟合,曾清红等人[1]开发出一种新的算法——移动最小二乘法。这种新的最小二乘算法为点云数据的处理提供了新的方法。使用点云数据拟合曲面时,由于点云的数据量大、形状复杂的特点,如果使用传统的最小二乘法拟合可能会得到病态的曲面方程,从而导致较大的误差。而使用移动最小二乘法拟合点云不仅能够减少误差,提升局部的准确率,还能避免分块拟合和平滑化的过程。下图为子区域的划分示意图。


通过某点确定一个子区域,在该区域内,移动最小二乘法是根据区域内的空间点加权拟合方程,并根据拟合方程解算这一点的坐标。使用移动最小二乘法拟合点云曲面可以看作是一个插值的过程,每一次插值都对应着一次加权最小二乘的方程拟合,所以它可以逼近曲面但不能得到曲面方程。
关于该算法的原理叙述请参看曾清红, 卢德唐. 基于移动最小二乘法的曲线曲面拟合
2.程序设计
在某个子区域中可能会出现空间点数量过少或分布复杂不规律的情况,这会导致最小二乘法解算方程系数时出现奇异矩阵。一般做法是迭代调整阈值,直到子区域内的空间点数量分布符合拟合要求,但这种方法复杂度较高且在点云本身分布失常的情况下调整阈值没有意义。为了方便,我们在点云分布不均匀导致出现奇异矩阵的情况下,引入几何中心(也可以根据情况选择其他方法)代替最小二乘的方程求解。
# -*- coding: utf-8 -*-
"""
Created on Sat Apr 11 17:39:16 2020 @author: L JL
"""
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D f = open('xuanze.txt','r')
point = f.read()
f.close()
data1 = point.replace('\n',' ')
data2 = data1.split(' ')
data2.pop() mat1 = np.array(data2[0:4806])
mat2 = mat1.reshape(1602,3)
mat3 = [] for each in mat2:
each_line = list(map(lambda x:float(x),each))
mat3.append(each_line)
mat4=np.array(mat3)
x = [k[0] for k in mat4]
y = [k[1] for k in mat4]
z = [k[2] for k in mat4] def D_radius(x,y,X,Y,N):
ind_mat = np.zeros((N,2))
for i in range(N):
s = ((x-X[i])**2+(y-Y[i])**2)**0.5
ind_mat[i][0] = s
ind_mat[i][1] = i
ind_mat = ind_mat[np.lexsort(ind_mat[:,::-1].T)]
return ind_mat def W_mat(d,x0,y0,x,y):
s=(((x-x0)**2+(y-y0)**2)**0.5)/d
#print((x-x0)**2+(y-y0)**2)
#print(s)
if (s<=0.5):
return (2/3)-4*s**2+4*s**3
elif(s<=1):
return (4/3)-4*s+4*s**2-(4/3)*s**3
else: return 0 def A_mat(W,P,M,N):
A = []
for m in range(M):
a = []
for n in range(M):
#pmn = p_mn(W,P,N,m,n)
pmn = 0
for i in range(N):
pmn = pmn + W[i]*P[i,m]*P[i,n]
a.append(float(pmn))
A.append(a)
return A def B_mat(u,W,P,M,N):
B = []
for i in range(M):
sumB = 0
for j in range(N):
sumB = sumB + W[j]*P[j,i]*u[j]
B.append(float(sumB))
return B X = np.array(x)
Y = np.array(y)
Z = np.array(z)
Xmax = int(np.max(X))
Xmin = int(np.min(X))
Ymax = int(np.max(Y))
Ymin = int(np.min(Y)) N = len(X)
M = 3
P = np.mat(np.zeros((N,M)))
W = np.mat(np.zeros((N,1)))
A = np.mat(np.zeros((M,M)))
B = np.mat(np.zeros((M,N)))
u = np.mat(Z).T
a = np.mat(np.zeros((M,1)))
d_mat = np.mat(np.zeros((N,1)))
#dataZ = [] dataX = np.arange(Xmin,Xmax,0.5)
dataY = np.arange(Ymin,Ymax,0.5) print(Xmin,Xmax)
print(Ymin,Ymax) f2 = open("dataZ.txt","w")
for i in dataX:
for j in dataY:
#d = D_radius(i,j,X,Y,N)
d = 2
ind_mat = D_radius(i,j,X,Y,N)
#print(ind_mat)
if ind_mat[3,0] <= d:
try:
W = np.mat(np.zeros((N,1)))
for n in range(0,N):
P[n,0] = 1
P[n,1] = X[n]
P[n,2] = Y[n]
W[n] = W_mat(d,X[n],Y[n],i,j)
#print(W)
A = A_mat(W,P,M,N)
B = B_mat(u,W,P,M,N)
c = np.linalg.solve(A,B)
#dataZ.append(c[0]+c[1]*i+c[2]*j)
dataZ = c[0]+c[1]*i+c[2]*j
print('A')
#print(dataZ)
except:
ind_Zsum = 0
for ind in range(0,4):
ind_Zsum += Z[int(ind_mat[ind,1])]
#dataZ.append(ind_Zsum/4)
dataZ = ind_Zsum/4
print('B')
#print(dataZ)
else:
ind_Zsum = 0
for ind in range(0,4):
ind_Zsum += Z[int(ind_mat[ind,1])]
#dataZ.append(ind_Zsum/4)
dataZ = ind_Zsum/4
print('C')
#print(dataZ)
f2.write(str(i) + ',' + str(j) + ',' + str(dataZ) + '\n')
print(i,j) f2.close()
# 3D绘图示意
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D fig = plt.figure()
ax = Axes3D(fig)
Xmin = -82
Xmax = 23
Ymin = 0
Ymax = 42 x = np.arange(Xmin, Xmax, 0.5)
y = np.arange(Ymin, Ymax, 0.5) y,x = np.meshgrid(y, x) f = open('dataZ.txt','r')
point = f.read()
f.close()
data1 = point.replace('\n',',')
data2 = data1.split(',')
data2.pop()
n = len(data2)
data2 = list(map(float,data2)) mat1 = np.array(data2[0:n])
mat2 = mat1.reshape(int(n/3),3) z = mat2[:,2].reshape(x.shape)
'''
print("网格化后的X=",x)
print("X维度信息",x.shape)
print("网格化后的Y=",y)
print("Y维度信息", y.shape)
print("网格化后的Z=",z)
''' ax.plot_surface(x, y, z, cmap=plt.cm.hot) # 渐变颜色
#ax.contourf(x, y, z,cmap=plt.cm.hot)
ax.set_xlabel('X Label (m)')
ax.set_ylabel('Y Label (m)')
ax.set_zlabel('Z Label (m)')
ax.set_title('Point Cloud Surface Fitting')
plt.show()


3.拟合情况及存在的问题
其他点云的拟合情况,如下图所示


(1)部分区域出现拟合异常
(2)程序计算量大,复杂度太高,有待优化
(3)对高分辨率点云,通过调整步长,可以调整插值步数,提高精度。
参考文献:
[1] 曾清红, 卢德唐. 基于移动最小二乘法的曲线曲面拟合 [J]. 工程图学学报, 2004, 01): 84-9.
基于移动最小二乘法的点云曲面拟合(python)的更多相关文章
- 腾讯云CDN python SDK
腾讯云CDN python SDK 博主在开发时偶尔要用到CDN,感觉适合学生党的应该是腾讯云的CDN了,还提供了每月10G的流量,博主平时学习使用已经足够了. 代码 #coding=utf-8 fr ...
- 【原创】基于Docker的CaaS容器云平台架构设计及市场分析
基于Docker的CaaS容器云平台架构设计及市场分析 ---转载请注明出处,多谢!--- 1 项目背景---概述: “在移动互联网时代,企业需要寻找新的软件交付流程和IT架构,从而实现架构平台化,交 ...
- 视频私有云实战:基于Docker构建点播私有云平台
私有云是为一个客户单独使用而构建的,因而提供对数据.安全性和服务质量的最有效控制.前置条件是客户拥有基础设施,并可以使用基础设施在其上部署应用程序.其核心属性是专有的资源.本篇文章将会结合网易云信的实 ...
- 基于zookeeper集群的云平台-配置中心的功能设计
最近准备找工作面试,就研究了下基于zookeeper集群的配置中心. 下面是自己设想的关于开源的基于zookeeper集群的云平台-配置中心的功能设计.大家觉得哪里有问题,请提出宝贵的意见和建议,谢谢 ...
- 利用百度智能云结合Python体验图像识别(转载来自qylruirui)
https://blog.csdn.net/qylruirui/article/details/94992917 利用百度智能云结合Python体验图像识别只要注册了百度账号就可以轻松体验百度智能云中 ...
- Python基于jieba的中文词云
今日学习了python的词云技术 from os import path from wordcloud import WordCloud import matplotlib.pyplot as plt ...
- 基于Kubernetes构建企业容器云
前言 团队成员有DBA.运维.Python开发,由于需要跨部门向公司私有云团队申请虚拟机, 此时我在思考能否在现有已申请的虚拟机之上,再进行更加细粒度的资源隔离和划分,让本团队的成员使用, 也就是在私 ...
- 金山云 KS3 Python SDK 多线程并发上传文件;下载断点续传 参考脚本
并发上传 基于py自带模块 concurrent.futures import ThreadPoolExecutor #!/usr/bin/env python3 # -*- coding:utf-8 ...
- mysql基于binlog回滚工具_flashback(python版本)
update.delete的条件写错甚至没有写,导致数据操作错误,需要恢复被误操作的行记录.这种情形,其实时有发生,可以选择用备份文件+binlog来恢复到测试环境,然后再做数据修复,但是这样 ...
随机推荐
- MySQL(9)— 规范数据库设计
九.规范数据库设计 9-1.为什么要设计? 当数据库比较复杂时,我们就需要设计了! 糟糕的数据库设计: 数据冗余,浪费大量存储空间 使用物理外键,大量的增删改操作麻烦,异常 查询效率低下 良好的数据库 ...
- AVL树的创建--C语言实现
AVL树是一种自平衡(Self-balancing)二叉查找树(Binary Search Tree),要求任何一个节点的左子树和右子树的高度之差不能超过1. AVL树的插入操作首先会按照普通二叉查找 ...
- 如何利用BeautifulSoup选择器抓取京东网商品信息
昨天小编利用Python正则表达式爬取了京东网商品信息,看过代码的小伙伴们基本上都坐不住了,辣么多的规则和辣么长的代码,悲伤辣么大,实在是受不鸟了.不过小伙伴们不用担心,今天小编利用美丽的汤来为大家演 ...
- Python-pygame案例AI贪吃蛇
# coding: utf-8 import pygame,sys,time,random from pygame.locals import * # 定义颜色变量 redColour = pygam ...
- Asp.Net Core入门之配置文件
ASP.NET Core配置框架已内建支持 JSON.XML 和 INI 配置文件,内存配置(直接通过代码设置值),环境变量配置等方式配置参数. 本文主要和大家讲一下我们在项目中常用的以配置文件的方式 ...
- [Python基础]009.os模块(1)
os模块(1) 介绍 os 常量 文件目录操作 文件属性操作 遍历文件夹 介绍 os模块是系统服务应用程序接口,是Python最常用的模块之一. os模块包含了对文件和文件夹的操作,操作系统相关的操作 ...
- Java中的自动装箱拆箱
Java中的自动装箱拆箱 一.自动装箱与自动拆箱 自动装箱就是将基本数据类型转换为包装类类型,自动拆箱就是将包装类类型转换为基本数据类型. 1 // 自动装箱 2 Integer total = 90 ...
- (九)显示交易记录 &解决相对路径问题
UserServlet.java package com.aff.bookstore.servlet; import java.io.IOException; import javax.servlet ...
- 编译sifive的freedom-u-sdk
在其它电脑搭建编译该sdk工程的环境,由于所在电脑的linux系统为新装系统(版本:Ubuntu 20.04 LTS),下面记录了编译过程中遇到的问题,以及解决过程供以后参考 问题1:error &q ...
- sql 索引常见失效的几种情况
1. 对于联合索引,没有遵循左前缀原则 2. 索引的字段区分度不大,可能引起索引近乎全表扫描 3. 对于join操作,索引字段的编码不一致,导致使用索引失效 4.对于hash索引,范围查询失效,has ...