2012-05-04 37 views
5

Tôi có một điểm đám mây thu được từ phép đo ảnh từ lưng của một người. Tôi đang cố gắng để nội suy nó để có được một lưới thường xuyên, và cho rằng tôi đang sử dụng scipy.interpolate với kết quả tốt cho đến nay. Vấn đề là: hàm tôi đang sử dụng (scipy.interpolate.griddata) sử dụng thân lồi của điểm mây trong mặt phẳng x, y, do đó cho kết quả là một số giá trị không tồn tại trong bề mặt ban đầu, có chu vi lõm.Chỉ nhận được các điểm "hợp lệ" trong nội suy 2D của điểm đám mây sử dụng Scipy/Numpy

Hình minh họa sau đây cho thấy điểm gốc ban đầu ở bên trái (những gì được hiển thị dưới dạng đường ngang thực sự là một đám mây có hình dạng điểm dày đặc), kết quả là griddata mang lại cho tôi ở giữa và kết quả tôi muốn nhận được ở bên phải - loại "bóng tối" của cloudpoint trên mặt phẳng x, y, nơi các điểm không tồn tại trong bề mặt ban đầu sẽ là 0 hoặc Nans.

enter image description here

Tôi biết tôi có thể loại bỏ các Z phối hợp trên cloudpoint và kiểm tra từng vị trí lưới vì sự gần gũi, nhưng điều này là để brute-force, và tôi tin rằng đây sẽ là một vấn đề thường gặp trên các ứng dụng point-điện toán đám mây . Một khả năng khác có thể là một số thao tác vất vả để thực hiện trên đám mây điểm, tìm một mặt nạ sần hoặc mảng 2D boolean để "áp dụng" kết quả từ griddata, nhưng tôi không tìm thấy bất kỳ (các hoạt động này vượt quá một chút Kiến thức Numpy/Scipy).

Bất kỳ đề xuất nào?

Cảm ơn bạn đã đọc!

Trả lời

4

Mặt nạ phù hợp có thể được xây dựng nhanh chóng bằng cách sử dụng KDTree. Thuật toán nội suy được griddata sử dụng không có khái niệm về các điểm "hợp lệ", vì vậy bạn cần điều chỉnh dữ liệu của mình trước hoặc sau nội suy.

Trước:

import numpy as np 
from scipy.spatial import cKDTree as KDTree 
from scipy.interpolate import griddata 
import matplotlib.pyplot as plt 

# Some input data 
t = 1.2*np.pi*np.random.rand(3000) 
r = 1 + np.random.rand(t.size) 
x = r*np.cos(t) 
y = r*np.sin(t) 
z = x**2 - y**2 

# -- Way 1: seed input with nan 

def excluding_mesh(x, y, nx=30, ny=30): 
    """ 
    Construct a grid of points, that are some distance away from points (x, 
    """ 

    dx = x.ptp()/nx 
    dy = y.ptp()/ny 

    xp, yp = np.mgrid[x.min()-2*dx:x.max()+2*dx:(nx+2)*1j, 
         y.min()-2*dy:y.max()+2*dy:(ny+2)*1j] 
    xp = xp.ravel() 
    yp = yp.ravel() 

    # Use KDTree to answer the question: "which point of set (x,y) is the 
    # nearest neighbors of those in (xp, yp)" 
    tree = KDTree(np.c_[x, y]) 
    dist, j = tree.query(np.c_[xp, yp], k=1) 

    # Select points sufficiently far away 
    m = (dist > np.hypot(dx, dy)) 
    return xp[m], yp[m] 

# Prepare fake data points 
xp, yp = excluding_mesh(x, y, nx=35, ny=35) 
zp = np.nan + np.zeros_like(xp) 

# Grid the data plus fake data points 
xi, yi = np.ogrid[-3:3:350j, -3:3:350j] 
zi = griddata((np.r_[x,xp], np.r_[y,yp]), np.r_[z, zp], (xi, yi), 
       method='linear') 
plt.imshow(zi) 
plt.show() 

Ý tưởng là "hạt giống" các dữ liệu đầu vào với các điểm dữ liệu giả mạo có chứa nan giá trị. Khi sử dụng nội suy tuyến tính, chúng sẽ làm mờ các khu vực của hình ảnh không có các điểm dữ liệu thực tế gần đó.

Bạn cũng có thể xóa hết dữ liệu không hợp lệ sau khi suy:

# -- Way 2: blot out afterward 

xi, yi = np.mgrid[-3:3:350j, -3:3:350j] 
zi = griddata((x, y), z, (xi, yi)) 

tree = KDTree(np.c_[x, y]) 
dist, _ = tree.query(np.c_[xi.ravel(), yi.ravel()], k=1) 
dist = dist.reshape(xi.shape) 
zi[dist > 0.1] = np.nan 

plt.imshow(zi) 
plt.show() 
+0

Tôi đã bận rộn, nhưng câu trả lời của bạn như tôi đọc bây giờ (có đã gãi đầu của tôi rất nhiều) làm cho rất nhiều ý nghĩa. Cuối cùng, tôi đang sử dụng KDtree để thực hiện phép nội suy cho từng điểm lưới, thực hiện điều này: Tôi tạo ra một mạng lưới NaN; Tôi kiểm tra mỗi nút lưới, với kdtree, cho sự hiện diện của vùng lân cận (bỏ qua z phối hợp của cloudpoint); Nếu có vùng lân cận, nội suy bằng cách sử dụng Rbf (cuối cùng, griddata không tốt cho vấn đề này), và gán kết quả cho nút tương ứng của đầu ra. – heltonbiker

Các vấn đề liên quan