Как произвольно извлечь определенное подмножество изображений из набора данных? - PullRequest
0 голосов
/ 04 мая 2018

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

В DM есть несколько полезных функций в меню Громкость, но, к сожалению, они не могут полностью выполнить то, что я хочу сделать.

Мне просто интересно, может ли эта идея быть реализована с помощью сценариев.

Большое спасибо за вашу помощь заранее.

1 Ответ

0 голосов
/ 04 мая 2018

Есть два способа сделать это: один из них подходит только для данных вплоть до 3D и, как правило, медленнее, чем другой, но более гибкий. Поскольку вы просили произвольную подвыборку, я начинаю с этой опции, но более вероятно, что вторая опция дает вам то, что вы хотите: ортогональная, обычная подвыборка.

Если вы спешите, краткий ответ: Используйте команду SliceN.


1) Использование выражений (произвольная подвыборка)

Можно указать отдельные позиции пикселей в изображении данных (img) используя обозначения

  • img[ X, 0 ] ... для 1D данных в позиции X
  • img[ X, Y ] ... для 2D-данных в позиции X/Y
  • img[ X, Y, Z ] ... для трехмерных данных в позиции X/Y/Z

Обратите внимание, что даже если это адрес одного числа, результатом будет выражение размера 1x1 или 1x1x1 , а не скалярное число, поэтому вы не может делать: 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()

Example of arbitrary subsampling 1D

Наши тестовые данные (img1D) - это просто линейный график от 1000 до 1099, использующий выражение icol, которое в каждом пикселе представляет координату X этих пикселей.

Координатное изображение (coord) содержит случайные целые значения в диапазоне от 0 до 99.

«Волшебство» происходит в subImg. Мы используем выражение с изображением coord в качестве координат X. Размер этих изображений 10 (x1) , поэтому исходящее выражение имеет размер 10 (x1) , который мы присваиваем изображению subImg перед его показом.

Обратите внимание, что построенное нами выражение на самом деле просто указывает на эти данные изображения. Вместо того, чтобы показывать его как новое изображение, мы могли бы использовать это выражение для изменения этих точек в данных, используя:

img1D[coord,0] = 0

Example of setting data by expression


Если взять это отсюда, то просто продлить пример до 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()

Example for 2D


... и 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.

Чтобы извлечь одномерные данные из любых данных вплоть до 3D с помощью команды Slice1, вам необходимо следующее (-и это именно те 7 параметров, которые используются командой -):

  • источник данных
  • начальная точка в источнике
  • направление отбора проб
  • длина выборки
  • размер шага выборки

Единственное, что вам нужно знать, это:

  • Начальная точка всегда , определенная как триплет X,Y,Z, даже если источник данных только 2D или 1D.
    0 используется для ненужных размеры.
  • Направления даны как индекс измерения: 0 = X, 1 = Y, 2 = Z
  • Размер шага может быть отрицательным для обозначения противоположных направлений
  • Указанная выборка должна содержаться в исходных данных.
    (Вы не можете «экстраполировать»)

Итак, очень простым примером извлечения одномерных данных из набора 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 является прямым. Вместо определения one выходного направления вы определяете two или three соответственно. Каждый с тройкой чисел: направление, длина, размер шага .

В следующем примере извлекается «плоскость изображения» из «изображения 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 pz = 3
image plane2D := Slice2( img3D, 0,0,pz, 0,sx,1, 1,sy,1 )

ShowImage( img3D )
ShowImage( plane2D )

А следующий пример «поворачивает» трехмерное изображение:

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-дифракционного изображения», которые сохраняют 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 )
...