基于仿射的非刚体配准方法(i) 法向
为啥闲呢,因为work干完了。
为啥补档呢,因为有新work了。
呃,因为新work让人自闭。
我现在干完了两部分。一是把最近邻的部分迁移过来。
二是求法向。
首先是给三个点,就能确定平面——因为是三角面片,也不太会有三点共线。
法向量垂直于平面,也就垂直于三个顶点之间构成的向量。
(x1-x2,y1-y2,z1-z2)垂直于法向量;
(x1-x3,y1-y3,z1-z3)垂直于法向量。
所以就是一个不定方程:
所以我们规定法向量z坐标为1——如果它不为0的话。
如果z坐标为零,我们规定y坐标为1——除非它也为0.
如果都为0,那除了(1,0,0)还能咋办。
- def normaloftri(xmat):
- x=np.zeros((2,2),dtype=float)
- y=np.zeros((2),dtype=float)
- coor=np.zeros((3),dtype=float)
- x[0][0]=xmat[0][0]-xmat[2][0]
- x[0][1]=xmat[0][1]-xmat[2][1]
- x[1][0]=xmat[1][0]-xmat[2][0]
- x[1][1]=xmat[1][1]-xmat[2][1]
- y[0]=-xmat[0][2]+xmat[2][2]
- y[1]=-xmat[1][2]+xmat[2][2]
- if np.linalg.matrix_rank(x)==2:
- z=np.dot(np.linalg.inv(x),y)
- coorsum=(z[0]**2+z[1]**2+1)**0.5
- coor[0]=z[0]/coorsum
- coor[1]=z[1]/coorsum
- coor[2]=1/coorsum
- elif x[0][0]==0 and x[1][0]==0:
- coor[0]=1
- else:
- coor[1]=1
- if x[0][0]!=0:
- coor[0]=-x[0][1]/x[0][0]
- else:
- coor[0]=-x[1][1]/x[1][0]
- coorsum=(1+coor[0]**2)**0.5
- coor[0]=coor[0]/coorsum
- coor[1]=coor[1]/coorsum
- #affine.cherk(xmat,coor)
- return coor
理论上我应该验证一下,这三种情况所规定的法向与面片的点的顺序是否一致。。。但是其实都在第一个分支里,你懂吧,可以,且没有必要。
法向量求好了,我现在是一个三角面片的法向量。
为了统一呢,我需要把它单位化。还需要检验。
- def cherk(xmat,norm):
- for i in range(3):
- for j in range(2):
- xmat[j][i]=xmat[j][i]-xmat[2][i]
- y=np.dot(xmat,norm)
- t=abs(y[0])+abs(y[1])
- if t>0.01:
- print("error")
- return 0
好,但我们其实要的点的坐标。
- def normalfei(beimat,feimat,trinumber):
- weimat=np.zeros((trinumber,3),dtype=float)
- xmat=np.zeros((3,3),dtype=float)
- for i in range(trinumber):
- xmat[0,:]=beimat[int(feimat[i][0]),:]
- xmat[1,:]=beimat[int(feimat[i][1]),:]
- xmat[2,:]=beimat[int(feimat[i][2]),:]
- weimat[i,:]=affine.normaloftri(xmat)
- return weimat
- def normalbei(beimat,feimat,weimat,potnumber,trinumber):
- yeimat=np.zeros((potnumber,3),dtype=float)
- for i in range(trinumber):
- for j in range(3):
- for k in range(3):
- yeimat[int(feimat[i][j])][k]=yeimat[int(feimat[i][j])][k]+weimat[i][k]
- for i in range(potnumber):
- coorsum=(yeimat[i][0]**2+yeimat[i][1]**2+yeimat[i][2]**2)**0.5
- for j in range(3):
- yeimat[i][j]=yeimat[i][j]/coorsum
- return yeimat
我们先按三角面片的信息,逐个找到每个面片的三顶点,算法向量。是第一部分。normalfei。
然后我们按每个面片,将每个三角面片的法向信息丢给每个顶点。
我们需要加权地丢:我想好了一个权重,就是按那个角的大小——啧啧啧,每个空间顶点都在不止一个空间三角形里,自然是在的顶角最大的那个should有最大的影响因子。
可以且有必要,但是我懒。[以后会有的。。。咕咕咕]
我就直接加了,权重都是1。
然后再单位化,就齐活了。
- import numpy as np
- import old
- import cv2
- import random
- import old
- import affine
- import icp
- f=open(r"11.ply",'r')
- g=open(r"22.ply",'r')
- [potnumber1,trinumber1,beimat1,feimat1]=old.fread(f,2)
- [potnumber2,trinumber2,beimat2,feimat2]=old.fread(g,2)
- weimat1=affine.normalfei(beimat1,feimat1,trinumber1)
- yeimat1=affine.normalbei(beimat1,feimat1,weimat1,potnumber1,trinumber1)
- maxmat1=icp.maxmatdeal(beimat1)
- maxmat2=icp.maxmatdeal(beimat2)
- for i in range(3):
- maxmat2[i][0]+=20
- maxmat2[i][1]-=20
- deta2=32
- choose2=5.5
- maxmat2=icp.maxmatdeta(maxmat2,deta2)
- #beimat: xyz *potnumber
- #intmat: i,j,k,n in bei2 *potnumber
- intmat1=np.zeros((potnumber1,7),dtype=int)
- floatmat1=np.zeros((potnumber1,7),dtype=float)
- [potmat2,intmatnew2]=icp.detadealnew(deta2,potnumber2,beimat2,maxmat2)
- potmatnew2=icp.potmatrandom(potmat2,choose2,deta2)
- [intmatnew1,floatmatnew1]=icp.nearestpoint(beimat1,beimat2,potnumber1,potmatnew2,maxmat2,deta2)
- for i in range(potnumber1):
- intmat1[i][6]=intmatnew1[i][0]
- floatmat1[i][3:6]=beimat2[int(intmatnew1[i][0]),:]
- intmat1[i][3:6]=intmatnew2[int(intmatnew1[i][0]),:]
- floatmat1[i,0:3]=beimat1[i,:]
- floatmat1[i][6]=floatmatnew1[i][0]
走菜!
也许,你从这里看最近点模块还虚浮一点,毕竟整合过。
affine是刚才那些函数的所在文件。
choose2=5.5就是按5.5个点取1个来减少运算量。
基于仿射的非刚体配准方法(i) 法向的更多相关文章
- 【图像配准】基于互信息的图像配准算法:MI、EMI、ECC算法
简单介绍: 基于互信息的图像配准算法以其较高的配准精度和广泛的适用性而成为图像配准领域研究的热点之中的一个.而基于互信息的医学图像配准方法被觉得是最好的配准方法之中的一个.基于此.本文将介绍简单的基于 ...
- 点云NDT配准方法介绍
三维配准中经常被提及的配准算法是ICP迭代的方法,这种方法一般般需要提供一个较好的初值,也就是需要粗配准,同时由于算法本身缺陷,最终迭代结果可能会陷入局部最优,导致配准失败,往往达不到我们想要的效果. ...
- 基于HALCON的模板匹配方法总结
注:很抱歉,忘记从转载链接了,作者莫怪.... 基于HALCON的模板匹配方法总结 很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间.去年有过一段时间的集中学习,做了许多 ...
- OpenCV Using Python——基于SURF特征提取和金字塔LK光流法的单目视觉三维重建 (光流、场景流)
https://blog.csdn.net/shadow_guo/article/details/44312691 基于SURF特征提取和金字塔LK光流法的单目视觉三维重建 1. 单目视觉三维重建问题 ...
- bug统计分析续(一)基于SQL的Bug统计方法
本文由 @lonelyrains 出品.转载请注明出处. 文章链接: http://blog.csdn.net/lonelyrains/article/details/44225533 上一篇为 bu ...
- CSharpGL(36)通用的非托管数组排序方法
CSharpGL(36)通用的非托管数组排序方法 如果OpenGL要渲染半透明物体,一个方法是根据顶点到窗口的距离排序,按照从远到近的顺序依次渲染.所以本篇介绍对 UnmanagedArray< ...
- 基于 Token 的身份验证方法
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录.大概的流程是这样的: 客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成功后,服务端会签发一个 Toke ...
- MVC 如何在一个同步方法(非async)方法中等待async方法
MVC 如何在一个同步方法(非async)方法中等待async方法 问题 首先,在ASP.NET MVC 环境下对async返回的Task执行Wait()会导致线程死锁.例: public Actio ...
- C# 非public的方法和属性的单元测试
有时候我们写好的类库中,某些类的属性和方法不应该暴露出来,那么如何对这些非public的方法和属性进行单元测试? MS为我们提供了PrivateObject类,可以解决这个问题,可以去MSDN的说明文 ...
随机推荐
- 【分布式存储】Glusterfs快速搭建
目录 环境准备 步骤1,保证至少有三台服务器 步骤2,格式化和配置硬盘 步骤3,安装GlusterFS 步骤4,配置防火墙 步骤5,配置 trusted pool 步骤6,设置GlusterFS卷 步 ...
- SLB外部端口非80时---》转发到nginx---》URL跳转丢失端口的解决方案
配置nginx反向代理时遇到一个问题,当设置nginx监听80端口时转发请求没有问题.但一旦设置为监听其他端口,就一直跳转不正常: 如,访问欢迎页面时应该是重定向到登录页面,在这个重定向的过程中端口丢 ...
- JXL工具包对Excle文件操作
1.简介: XL - JXL(Java Excel API)是一个用来动态读写 Excel 文件的开源框架,利用它可以 在任何支持 Java 的操作系统上动态读写 Excel 文件. 2.开发步骤 1 ...
- mysql 优化之 is null ,is not null 索引使用测试
关于mysql优化部分,有很多网友说尽量避免使用is null, is not null,select * 等,会导致索引失效,性能降低?那是否一定收到影响呢?真的就不会使用索引了吗? 本文的测试数据 ...
- serf 中去中心化系统的原理和实现
原文:https://www.infoq.cn/article/principle-and-impleme-of-de-centering-system-in-serf serf 是出自 Hashic ...
- python基础(35):协程
1. 前言 之前我们学习了线程.进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位.按道理来说我们已经算是把cpu的利用率提高很多了.但是我们知道无论是创建多进程还是创 ...
- JMeter处理form-data类型的接口
最近的需求中,有的接口入参是form-data类型的,除了用python多进程代码进行压测,考虑用Jmeter试试看,比对一下结果. 线程数设置的是50,循环次数为100,一共发送5000次请求. H ...
- HashMap、ConcurrentHashMap解析
一.HashMap分析 在JDK1.8之前,hashMap由数组+链表组成,1.8之后,对hashMap进行了一些修改,最大的不同就是利用了红黑树,所以其由数组+链表+红黑树组成.查找时,根据hash ...
- flex弹性布局没有生效
display: -webkit-flex; /* 新版本语法: Chrome 21+ */ display: -webkit-box; /* 老版本语法: Safari, iOS, Android ...
- u盘 安装 centOS 7
实际上, 对于服务器的安装, 最好是能够远程批量安装(可能有些难度, 不是专业运维) 镜像下载地址: http://59.80.44.49/isoredirect.centos.org/centos/ ...