2017-02-17 10 views
0

Я работаю в Python2.7 с помощью 3D-массивов numpy и пытаюсь извлечь только пиксели, которые попадают на двумерный наклонный диск.Маскирование массива трехмерных чисел с наклонным диском

Вот мой код, чтобы построить границу диска (= круг) Я заинтересован в

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 


#creating a 3d numpy array (empty in this example, but will represent a binary 3D image in my application) 
space=np.zeros((40,40,20)) 

r = 8 #radius of the circle 
theta = np.pi/4 # "tilt" of the circle 
phirange = np.linspace(0, 2 * np.pi) #to make a full circle 

#center of the circle 
center=[20,20,10] 

#computing the values of the circle in spherical coordinates and converting them 
#back to cartesian 
for phi in phirange: 
    x = r * np.cos(theta) * np.cos(phi) + center[0] 
    y= r*np.sin(phi) + center[1] 
    z= r*np.sin(theta)* np.cos(phi) + center[2] 
    space[int(round(x)),int(round(y)),int(round(z))]=1 


x,y,z = space.nonzero() 

#plotting 
fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
ax.scatter(x, y, z, zdir='z', c= 'red') 
plt.show() 

Сюжет дает следующую цифру:

circle

, который является хорошее начало, но теперь я хочу, чтобы получить только значения пикселей space, которые расположены на диске, определенном кругом: те, которые находятся в розовой зоне на следующем изображении (в моей заявке space будет быть 3D бинарное изображение, здесь numpy.zeros() просто, чтобы иметь возможность построить и показать вам диск, я хочу):

disc

Как я procede? Я предполагаю, что есть какая-то многократная маскировка, я понимаю, как вы это сделаете в 2D (например, this question), но у меня возникли проблемы с применением этого в 3D.

+0

Что вы подразумеваете под "fall on"? Если пиксель является точкой, нет никакой гарантии, что он пересечет плоскость вообще, не говоря уже о круге. Вы вместо этого хотите заглянуть внутрь цилиндра высотой 1? – Eric

+0

Да, я знаю, что работа с аппроксимацией подходит для этого приложения, поэтому round() в коде, который я показываю: точки на рисунке приблизительно совпадают по кругу. Думаю, вы могли бы сказать, что это эквивалентно поиску точек в цилиндре с 1 пикселем, да. – Soltius

ответ

1

Одним простым способом было бы рассчитать нормальный вектор на вашей плоскости диска. Вы можете использовать для этого свои сферические координаты. Убедитесь, что не, чтобы добавить центр, установить phi в ноль и заменить cos и sin theta, также придерживать знак минус греху.

позволяет называть этот вектор v. Плоскость задается формулой v0 * x0 + v1 * x1 + v2 * x2 == c, которую вы можете вычислить c, вставив точку из вашего круга для x.

Далее вы можете сделать 2d сетку для x0 и x1 и решить для x2. это дает вам высоту x2 как функцию сетки x0, x1. для этих точек вы можете рассчитать расстояние от вашего центра диска и отбросить точки, которые находятся слишком далеко. Это вы действительно сделали бы с помощью маски.

Наконец, в зависимости от того, насколько точно вы хотите построить график, вы можете округлить значения x2 до единиц сетки, но, например, для поверхностного графика я бы этого не сделал.

Чтобы получить 3D-маску, как вы описали, вы бы округлили x2, а затем, начиная со всего нуля, задали пиксели диска с помощью пробела [x0, x1, x2] = True. Это предполагает, что вы замаскировали x0, x1, x2, как описано выше.

+0

Спасибо за ваш вклад, который ведет меня в правильном направлении. Я не сделал именно то, что вы предлагали, но мой код основан на вычислении нормальных векторов и тому подобных. Точнее, я использовал технику в http://demonstrations.wolfram.com/ParametricEquationOfACircleIn3D/, чтобы получить параметризацию внешнего круга. Затем я просто прошел радиус от 0 до моего максимума, чтобы получить диск! – Soltius

1

Ну, это проблема math, вы должны задать вопрос на сайте Mathematics Stack Exchange.

С моей точки зрения, вы должны сначала найти поверхность, на которой находится ваш диск, и выполнить расчет области внутри этой поверхности, например, методом, указанным в связанном вопросе.

numpy или matplotlib здесь определенно не несет ответственности за проекцию, вы делаете.

Без четкого указания, на какой (или какой) поверхности они находятся, и уравнение не гарантирует, что это плоскость, область ничего не значит.