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)的更多相关文章

  1. 腾讯云CDN python SDK

    腾讯云CDN python SDK 博主在开发时偶尔要用到CDN,感觉适合学生党的应该是腾讯云的CDN了,还提供了每月10G的流量,博主平时学习使用已经足够了. 代码 #coding=utf-8 fr ...

  2. 【原创】基于Docker的CaaS容器云平台架构设计及市场分析

    基于Docker的CaaS容器云平台架构设计及市场分析 ---转载请注明出处,多谢!--- 1 项目背景---概述: “在移动互联网时代,企业需要寻找新的软件交付流程和IT架构,从而实现架构平台化,交 ...

  3. 视频私有云实战:基于Docker构建点播私有云平台

    私有云是为一个客户单独使用而构建的,因而提供对数据.安全性和服务质量的最有效控制.前置条件是客户拥有基础设施,并可以使用基础设施在其上部署应用程序.其核心属性是专有的资源.本篇文章将会结合网易云信的实 ...

  4. 基于zookeeper集群的云平台-配置中心的功能设计

    最近准备找工作面试,就研究了下基于zookeeper集群的配置中心. 下面是自己设想的关于开源的基于zookeeper集群的云平台-配置中心的功能设计.大家觉得哪里有问题,请提出宝贵的意见和建议,谢谢 ...

  5. 利用百度智能云结合Python体验图像识别(转载来自qylruirui)

    https://blog.csdn.net/qylruirui/article/details/94992917 利用百度智能云结合Python体验图像识别只要注册了百度账号就可以轻松体验百度智能云中 ...

  6. Python基于jieba的中文词云

    今日学习了python的词云技术 from os import path from wordcloud import WordCloud import matplotlib.pyplot as plt ...

  7. 基于Kubernetes构建企业容器云

    前言 团队成员有DBA.运维.Python开发,由于需要跨部门向公司私有云团队申请虚拟机, 此时我在思考能否在现有已申请的虚拟机之上,再进行更加细粒度的资源隔离和划分,让本团队的成员使用, 也就是在私 ...

  8. 金山云 KS3 Python SDK 多线程并发上传文件;下载断点续传 参考脚本

    并发上传 基于py自带模块 concurrent.futures import ThreadPoolExecutor #!/usr/bin/env python3 # -*- coding:utf-8 ...

  9. mysql基于binlog回滚工具_flashback(python版本)

        update.delete的条件写错甚至没有写,导致数据操作错误,需要恢复被误操作的行记录.这种情形,其实时有发生,可以选择用备份文件+binlog来恢复到测试环境,然后再做数据修复,但是这样 ...

随机推荐

  1. 约瑟夫环(超好的代码存档)--19--约瑟夫环--LeetCode面试题62(圆圈最后剩下的数字)

    圆圈中最后剩下的数字 0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆圈,从数字0 ...

  2. Git创建子分支,合并分支并提交到Gitee码云

    Git合并分支后,需要将子分支提交到git仓库,这个时候就需要单独提交子分支,其步骤如下: 先创建子分支,并包含最新当前分支下的修改数据 git checkout -b sonBranch 将新分支内 ...

  3. 关于mobileSelect.js日期数据获取封装,动态时间,封装

    传入起始年份和起始月份 得到 插件的标准格式放到 效果 let getAllDatas = (stime, etime) => { //接收传进来的参数月份 var data_M = etime ...

  4. MySQL性能分析(Explain)

    更多知识,请移步我的小破站:http://hellofriend.top 1. 概述 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的.分析你的查 ...

  5. UIAutomator2安装及连接

    记录一下自己的偿试过程,内容来自:https://github.com/openatx/uiautomator2 d.service("uiautomator").stop()是因 ...

  6. PIC单片机的XC8

    用MPLAB IDE 对pic16f887进行编程的时候需要配置字 用__CONFIG(0xc3e4);__CONFIG(0xffff); 就可以 但是用MPLAB X IDE 对pic16f887编 ...

  7. SpringBoot的 HelloWorld

    SpringBoot HelloWorld 功能需求 ​ 浏览器发送hello请求,服务器接收请求并处理,相应HelloWorld字符串 1.创建一个maven工程:(jar) 2.导入SpringB ...

  8. matlab单目相机标定——标定步骤以及参数含义

    参考博客园的一篇文章: https://www.cnblogs.com/flyinggod/p/8470407.html#commentform

  9. C语言 俄罗斯方块demo

    这是我的第一篇随笔,当然是发我写的第一个游戏啦! 大一(本人现在大二)寒假过完年,在家待着想起放假前计划写一个游戏的,因为本人立志走游戏开发这条路,加上大一上册学了C语言,就想写个游戏练练手.想了很久 ...

  10. 50个SQL语句(MySQL版) 问题二

    --------------------------表结构-------------------------- student(StuId,StuName,StuAge,StuSex) 学生表 tea ...