2017-08-09 46 views
2

在附圖中,我們可以看到點的運動的groundtruth(綠色)和估計(紅色)。帶圓柱的圓圈旁邊的每個數字(=模式)對應於一個時間。現在所有算法都已經開發出來了,我想通過將所有圖案連接在一起考慮位置以及方向(由條的方向定義)來提高可視化的質量。我試圖找到一種方法來做到這一點,但找不到任何。任何人有想法?如何連接考慮每個點的位置和方向的點

有關信息:如果需要,我有座標(x,y)和可以更改爲導數的角度。

編輯:這裏有一些關於我想將模式連接在一起的方式的澄清。

  • 我想所有的模式中編號順序連接相鄰的圖案
  • 我想我的曲線去通過每個圖案的中心
  • 我想的陡度我每個圖案的曲線與拉桿所具有的曲線相同。

總結:我正在尋找一種方法來繪製一個連接點的曲線,並在每個點上擬合所需的陡度。

Image available here

+0

您需要解釋*「將所有模式連接在一起」* **更詳細。否則,沒有人能夠理解你想要做什麼。此外,實現這一目標的問題究竟是什麼?你有什麼嘗試,在多遠沒有奏效。如果你沒有告訴你有什麼問題,這個問題可能太寬泛而無法回答。 – ImportanceOfBeingErnest

+0

謝謝你的提示!我編輯它。我希望這將有助於理解我想要連接模式的方式。我的主要問題是沒有找到任何讓我做我想做的功能。我曾期待那些已經試圖做同樣事情的人可以給我一些關於如何實現這樣的任務的暗示。 –

+0

我不認爲你會找到一個預定義的函數來做你想做的事情,因爲問題是二維的(你實際上有二維梯度,而不是一維導數),因此沒有獨特的解決方案來連接點。如果這是一個一維問題,像'scipy.interpolate.KroghInterpolator'可以幫助你。但是,在這種情況下,它會失敗。 – ImportanceOfBeingErnest

回答

3

總結問題:你想通過多個點進行插值的平滑曲線。對於2D空間中的每個點,您都有座標以及一個角度,該角度定義了此時曲線的切線。

解決方案可能是使用Bézier curves的第三階。這樣的曲線將被定義爲4點;兩個端點,即圖中兩個連續點,以及兩個中間點,它們定義曲線的方向。 Bézier曲線通常用於圖形軟件,Matplotlib也可以在內部繪製路徑。

enter image description here

因此,我們可以定義具有它的兩個中間點沿着由角度到每個點的給定的正切Bezier曲線。 本身沒有任何暗示兩個中間點應該位於該切線上的位置,所以我們可以從兩個端點選擇一些任意距離。在下面的代碼中這就是所謂的r。爲此參數r選擇一個合適的值是獲得平滑曲線的關鍵。

import numpy as np 
from scipy.special import binom 
import matplotlib.pyplot as plt 

bernstein = lambda n, k, t: binom(n,k)* t**k * (1.-t)**(n-k) 

def bezier(points, num=200): 
    N = len(points) 
    t = np.linspace(0, 1, num=num) 
    curve = np.zeros((num, 2)) 
    for i in range(N): 
     curve += np.outer(bernstein(N - 1, i, t), points[i]) 
    return curve 

class Segment(): 
    def __init__(self, p1, p2, angle1, angle2, **kw): 
     self.p1 = p1; self.p2 = p2 
     self.angle1 = angle1; self.angle2 = angle2 
     self.numpoints = kw.get("numpoints", 100) 
     method = kw.get("method", "const") 
     if method=="const": 
      self.r = kw.get("r", 1.) 
     else: 
      r = kw.get("r", 0.3) 
      d = np.sqrt(np.sum((self.p2-self.p1)**2)) 
      self.r = r*d 
     self.p = np.zeros((4,2)) 
     self.p[0,:] = self.p1[:] 
     self.p[3,:] = self.p2[:] 
     self.calc_intermediate_points(self.r) 

    def calc_intermediate_points(self,r): 
     self.p[1,:] = self.p1 + np.array([self.r*np.cos(self.angle1), 
            self.r*np.sin(self.angle1)]) 
     self.p[2,:] = self.p2 + np.array([self.r*np.cos(self.angle2+np.pi), 
            self.r*np.sin(self.angle2+np.pi)]) 
     self.curve = bezier(self.p,self.numpoints) 


def get_curve(points, **kw): 
    segments = [] 
    for i in range(len(points)-1): 
     seg = Segment(points[i,:2], points[i+1,:2], points[i,2],points[i+1,2],**kw) 
     segments.append(seg) 
    curve = np.concatenate([s.curve for s in segments]) 
    return segments, curve 


def plot_point(ax, xy, angle, r=0.3): 
    ax.plot([xy[0]],[xy[1]], marker="o", ms=9, alpha=0.5, color="indigo") 
    p = xy + np.array([r*np.cos(angle),r*np.sin(angle)]) 
    ax.plot([xy[0],p[0]], [xy[1],p[1]], color="limegreen") 


if __name__ == "__main__":   
    #     x y angle   
    points =np.array([[ 6.0, 0.5, 1.5], 
         [ 5.4, 1.2, 2.2], 
         [ 5.0, 1.7, 2.6], 
         [ 2.8, 2.4, 2.1], 
         [ 1.3, 3.2, 1.6], 
         [ 1.9, 3.9,-0.2], 
         [ 4.0, 3.0, 0.2], 
         [ 5.1, 3.7, 1.4]]) 

    fig, ax = plt.subplots() 

    for point in points: 
     plot_point(ax, point[:2],point[2], r=0.1) 

    s1, c1 = get_curve(points, method="const", r=0.7) 
    ax.plot(c1[:,0], c1[:,1], color="crimson", zorder=0, label="const 0.7 units") 

    s2, c2 = get_curve(points, method="prop", r=0.3) 
    ax.plot(c2[:,0], c2[:,1], color="gold", zorder=0, label="prop 30% of distance") 
    plt.legend() 
    plt.show() 

enter image description here

在上述兩種情況下的曲線圖進行比較。其中r是恆定的0.7個單位,其他r是其中兩個點之間距離的相對30%。

+0

這完全是**我正在尋找的東西。非常感謝您的詳細解釋!這非常有幫助! –

+1

太好了。請注意以下幾點:問題本身的質量相當低,通常不會回答或關閉(參見[問]);我在這裏提供答案的原因只是我自己發現有興趣潛入,因爲我以前從未做過這樣的事情。但是,我想你下一次提出問題時不能依賴這種情況。 – ImportanceOfBeingErnest

相關問題