二維點雲ICP的python實現

2021-10-07 07:25:10 字數 3296 閱讀 2270

使用python語言來實現二維點雲的icp演算法

二維點雲icp演算法原理及推導,請見我的另外一篇部落格

二維點雲icp原理推導

特點說明:

icp演算法中的loss計算方式,可以根據自己實際需要來調整。我這裡使用的是,目標點雲a中的某個點 a,從源點雲 b 中找到距離點 a 最近的點 b,總的loss就是這些a-b距離之和

正常的loss計算方式,應該是從源點雲b中的每個點 b,去目標點雲a裡尋找最近點

loss的定義方式一定要好好思考,結合自己的實際需要,不要只會把***的**搬過去,因為可能不work

import numpy as np

import math

import matplotlib.pyplot as plt

# 求出兩個點之間的向量角度,向量方向由點1指向點2

defgetthetaoftwopoints

(x1, y1, x2, y2)

:return math.atan2(y2-y1, x2-x1)

# 求出兩個點的距離

defgetdistoftwopoints

(x1, y1, x2, y2)

:return math.sqrt(math.

pow(x2-x1,2)

+ math.

pow(y2-y1,2)

)# 在pt_set點集中找到距(p_x, p_y)最近點的id

defgetclosestid

(p_x, p_y, pt_set):id

=0min=

10000000

for i in

range

(pt_set.shape[1]

):dist = getdistoftwopoints(p_x, p_y, pt_set[0]

[i], pt_set[1]

[i])

if dist <

min:

id= i

min= dist

return

id# 求出兩個點集之間的平均點距

defdistoftwoset

(set1, set2)

: loss =0;

for i in

range

(set1.shape[1]

):id= getclosestid(set1[0]

[i], set1[1]

[i], set2)

dist = getdistoftwopoints(set1[0]

[i], set1[1]

[i], set2[0]

[id], set2[1]

[id])

loss = loss + dist

return loss/set1.shape[1]

# icp核心**

deficp

(sourcepoints, targetpoints)

: a = targetpoints

b = sourcepoints

iteration_times =

0 dist_now =

1 dist_improve =

1 dist_before = distoftwoset(a, b)

while iteration_times <

10and dist_improve >

0.001

: x_mean_target = a[0]

.mean(

) y_mean_target = a[1]

.mean(

) x_mean_source = b[0]

.mean(

) y_mean_source = b[1]

.mean(

) a_ = a - np.array(

[[x_mean_target]

,[y_mean_target]])

b_ = b - np.array(

[[x_mean_source]

,[y_mean_source]])

w_up =

0 w_down =

0for i in

range

(a_.shape[1]

):j = getclosestid(a_[0]

[i], a_[1]

[i], b_)

w_up_i = a_[0]

[i]*b_[1]

[j]- a_[1]

[i]*b_[0]

[j] w_down_i = a_[0]

[i]*b_[0]

[j]+ a_[1]

[i]*b_[1]

[j] w_up = w_up + w_up_i

w_down = w_down + w_down_i

theta = math.atan2(w_up, w_down)

x = x_mean_target - math.cos(theta)

*x_mean_source - math.sin(theta)

*y_mean_source

y = y_mean_target + math.sin(theta)

*x_mean_source - math.cos(theta)

*y_mean_source

r = np.array(

[[math.cos(theta)

, math.sin(theta)],

[-math.sin(theta)

, math.cos(theta)]]

) b = np.matmul(r, b)

+ np.array(

[[x]

,[y]])

iteration_times = iteration_times +

1 dist_now = distoftwoset(a, b)

dist_improve = dist_before - dist_now

print

("迭代第"

+str

(iteration_times)

+"次, 損失是"

+str

(dist_now)

+",提公升了"

+str

(dist_improve)

) dist_before = dist_now

return b

用webgl來繪製二維點雲吧

執行測試平台 小強ros機械人 做圖形化程式web是非常方便的。最近做了乙個專案就是用webgl來繪製二維點雲,執行效果還是不錯的。下面簡單介紹一下webgl的使用方法和二維點雲的繪製方法。首先什麼是webgl?opengl大家一定都知道,就是 open graphic library.webgl ...

點雲資料二維變換 「福」字變換

問題 通過二維變換實現圖形重合 分析 圖形要找到變換規則,即平移,旋轉,放縮的引數與次序,需要知道兩圖形的差距,這個差距,即位置 大小與方向。零階矩和一階矩可以描述乙個圖形的質心,二階矩可以描述乙個圖形的大小方向,即橢圓區域擬合,橢圓的確定需要圓心 長軸 短軸與旋轉角4個引數 具體公式為 其中的v是...

Python中max函式用於二維列表的例項

最近寫乙個和二維eqqgkuijxf列表有關的演算法時候發現的 當用max求二維列表中最大值時,輸出的結果是子列表首元素最大的那個列表 測試如下 c 1,2,1 0,5,6 a 0,3,1 1,4,6 print max c max a 結果是這樣的 1,2,程式設計客棧 1 1,4,6 以上這篇p...