Есть два способа сделать это, один из них подходит только для данных до 3D и, как правило, медленнее, чем другой, но более гибкий. Поскольку вы просили об произвольной субдискретизации, я начну с этого варианта, но более вероятно, что второй вариант даст вам то, что вы хотите: ортогональная, регулярная субдискретизация .
Если вы спешите, краткий ответ: Используйте команду SliceN
.
1) Использование выражений (произвольная подвыборка)
Отдельные позиции пикселей в данных Image (img
) можно адресовать с помощью обозначений
img[ X, 0 ]
... для 1D-данных в позиции X
img[ X, Y ]
... для 2D-данных в позиции X/Y
img[ X, Y, Z ]
... для 3D-данных в позиции X/Y/Z
Обратите внимание, что даже если это относится к одному числу, результатом будет выражение размера 1x1 или 1x1x1, а не скалярное число, поэтому вы < strong>не могу сделать: number num = img[10,4]
Однако вы можете использовать небольшую хитрость, чтобы использовать любую из функций, которые преобразуют выражение в одно число, например, f.e. суммирование. Итак, вы можете сделать: number num = sum(img[10,4])
Так как это относится к вашему вопросу? Что ж, в приведенных выше выражениях мы использовали скалярные значения как X
, Y
и Z
, а полученные выражения были выражениями размера 1x1 и 1x1x1, но
Вы можете использовать выражения любого размера как X
, Y
, Z
в этих обозначениях, если все они являются выражениями одного и того же размера. Результирующие адресуемые данные имеют этот размер со ссылками на значения по соответствующим координатам.
Это станет яснее с приведенными ниже примерами. Начнем с простого примера 1D:
image img1D := RealImage( "TestData", 4, 100 )
image coord := RealImage( "Coordinates", 4, 10 )
img1D = 1000 + icol // Just sum test data
coord = trunc(100*Random()) // random integer 0-99
image subImg := img1D[coord,0]
img1D.ShowImage()
coord.ShowImage()
subImg.ShowImage()
![Пример произвольной подвыборки 1D](https://i.stack.imgur.com/OONXP.jpg)
Наши тестовые данные (img1D
) здесь представляют собой просто линейный график от 1000 до 1099 с использованием выражения icol
, которое для каждого пикселя представляет координату X этого пикселя.
Изображение координат (coord
) содержит случайные целые числа от 0 до 99.
«Волшебство» происходит в subImg
. Мы используем выражение с изображением coord
в качестве координат X. Это изображение имеет размер 10(x1), поэтому результирующее выражение имеет размер 10(x1), который мы присваиваем изображению subImg
перед его отображением.
Обратите внимание, что построенное нами выражение на самом деле просто указывает на эти данные изображения. Вместо того, чтобы показывать его как новое изображение, мы могли бы использовать это выражение для изменения этих точек в данных, используя:
img1D[coord,0] = 0
![Пример установки данных по выражению](https://i.stack.imgur.com/mtpjb.jpg)
Взяв его отсюда, можно прямо расширить пример до 2D:
image img2D := RealImage( "TestData", 4, 30, 30 )
image coordX := RealImage( "Coordinates X", 4, 10 )
image coordY := RealImage( "Coordinates Y", 4, 10 )
img2D = 10000 + icol + irow * 100
coordX = trunc(30*Random())
coordY = trunc(30*Random())
img2D[coordX,coordY] = 0
coordX.ShowImage()
coordY.ShowImage()
img2D.ShowImage()
![Пример для 2D](https://i.stack.imgur.com/eit0y.jpg)
...и 3D:
image img3D := RealImage( "TestData", 4, 30, 30, 30 )
image coordX := RealImage( "Coordinates X", 4, 10 )
image coordY := RealImage( "Coordinates Y", 4, 10 )
image coordZ := RealImage( "Coordinates Y", 4, 10 )
img3D = 10000 + icol + irow * 100 + iplane * 1000
coordX = trunc(30*Random())
coordY = trunc(30*Random())
coordZ = trunc(30*Random())
img3D[coordX,coordY,coordZ] = 0
coordX.ShowImage()
coordY.ShowImage()
coordZ.ShowImage()
img3D.ShowImage()
К сожалению, это заканчивается здесь.
Вы больше не можете использовать этот тип адресации в данных 4D или 5D, потому что выражение с 4 параметрами уже определено для адресации прямоугольной области в данных 2D как img[T,L,B,R]
2) Использование SliceN (ортогональная субдискретизация)
Подмножества данных вдоль направлений измерения данных могут быть адресованы с помощью команды SliceN
и ее упрощенных вариантов Slice1
, Slice2
и Slice3
.
Команда SliceN
, пожалуй, одна из моих любимых команд языка при работе с данными. Сначала это выглядит пугающе, но это прямолинейно.
Давайте начнем с его упрощенной версии для извлечения 1D, Slice1
.
Чтобы извлечь 1D-данные из любых данных вплоть до 3D с помощью команды Slice1
, вам необходимо следующее (и это ровно 7 параметров, используемых командой-):
- источник данных
- начальная точка в источнике
- направление отбора проб
- длина выборки
- размер шага выборки
Единственное, что вам нужно знать вдобавок к этому:
- Начальная точка всегда определяется как триплет
X,Y,Z
, даже если источником данных является только 2D или 1D.
0
используется для ненужных измерений.
- Направления указаны в виде индекса измерения: 0 = X, 1 = Y, 2 = Z
- Размер шага может быть отрицательным, чтобы указать противоположные направления.
- Указанная выборка должна содержаться в исходных данных.
(Вы не можете "экстраполировать").
Таким образом, очень простым примером извлечения 1D-данных из набора 3D-данных будет:
number sx = 20
number sy = 20
number sz = 20
image img3D := RealImage( "Spectrum Image", 4, sx, sy, sz )
img3D = 5000000 + icol + irow * 100 + iplane * 10000
number px = 5
number py = 7
image spec1D := Slice1( img3D, px,py,0, 2,sz,1 )
ShowImage( img3D )
ShowImage( spec1D )
Этот пример демонстрирует довольно типичную ситуацию в аналитической микроскопии при работе с данными «3D Spectrum Image»: Извлечение «1D Spectrum» в определенном пространственном положении.
В примере это было сделано для пространственной точки px,py
. Начиная с точки в этой позиции (px,py,0
), выполняется выборка по направлению Z (2
) для всех пикселей данных (sz
) с размером шага 1
.
Обратите внимание, что команда снова возвращает выражение в исходных данных, и что вы также можете использовать это для установки значений, просто используя f.e.:
Slice1( img3D, px,py,0, 2,sz,1 ) = 0
Расширение для 2D- и 3D-данных с помощью команд Slice2
и Slice3
осуществляется напрямую. Вместо определения одного направления вывода вы определяете два или три соответственно. Каждый с тройкой чисел: направление, длина, размер шага.
В следующем примере извлекается «плоскость изображения» из «изображения 3D Spectrum»:
number sx = 20
number sy = 20
number sz = 20
image img3D := RealImage( "Spectrum Image", 4, sx, sy, sz )
img3D = 5000000 + icol + irow * 100 + iplane * 10000
number pz = 3
image plane2D := Slice2( img3D, 0,0,pz, 0,sx,1, 1,sy,1 )
ShowImage( img3D )
ShowImage( plane2D )
А следующий пример «вращает» 3D-изображение:
number sx = 6
number sy = 4
number sz = 3
image img3D := RealImage( "Spectrum Image", 4, sx, sy, sz )
img3D = 1000 + icol + irow * 10 + iplane * 100
image rotated := Slice3( img3D, 0,0,0, 0,sx,1, 2,sz,1, 1,sy,1 )
ShowImage( img3D )
ShowImage( rotated )
С помощью этих команд вы можете получить все виды поворотов, зеркального отображения, биннинга. Если вам нужна полная гибкость для получения любого выражения до 5D из любых исходных данных до 5D, то вам нужна самая универсальная команда SliceN
.
Работает точно так же, но нужно указать как размерность исходных данных, так и размерность выходного выражения. Затем необходимо определить «начальную» точку с таким количеством координат, которое предполагает измерение исходных данных, и вам потребуется один триплет спецификации для каждого выходного измерения.
Для исходных данных из N
измерений и получения выходных данных из M
измерений вам необходимо: 2 + N + 3*M
параметров.
В качестве примера давайте извлечем «плоскость» в определенном пространственном положении из данных «4D Diffraction image», которые хранят 2D-изображение в каждом пространственном местоположении 2D-скана:
number sx = 9
number sy = 9
number kx = 9
number ky = 9
image img4D := RealImage( "Diffraction Image", 4, sx, sy, kx, ky )
img4D = 50000 + icol + irow * 10 + idimindex(2)*100 + idimindex(3)*1000
number px = 3
number py = 4
image img2D := SliceN( img4D, 4, 2, px,py,0,0, 2,kx,1, 3,ky,1 )
ShowImage( img4D )
ShowImage( img2D )
person
BmyGuest
schedule
04.05.2018
quick
таков: все функции меню Громкость легко воспроизводятся с помощью очень небольшого количества строк кода с использованием командыSliceN
, как описано в нижней части моего ответа. - person BmyGuest   schedule 04.05.2018