Как повернуть трехмерное изображение спектра в цифровой микрофотографии с помощью сценариев? - PullRequest
0 голосов
/ 31 августа 2018

Я хочу найти эквивалент команды сценария rotate (изображение, градус) для поворота вокруг оси x или y (мне нужно только вращение на 90 °). Я знаю, что могу сделать это, используя меню инструментов, но было бы намного быстрее, если бы я мог найти команду или функцию, чтобы сделать это, используя скрипт.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Использование команды Slice поначалу может сбить с толку, поэтому здесь подробное объяснение использования команды для вращения вокруг X-ось.

В этом примере показано, как можно вращать 3D-данные по часовой стрелке вокруг своей оси X (при просмотре по X) с помощью команды Slice3.

Команда Slice3 указывает новое представление существующего массива данных.

  • Сначала указывается исходный пиксель, то есть координаты (в исходных данных), которые будут представлены (0,0,0) в новом виде.

  • Затем указывается направление выборки, длина и размер шага для каждой из трех новых осей.
    Первый триплет указывает, как координаты (в исходных данных) изменяются вдоль направления x нового изображения, второй триплет для направления y новых изображений и последний триплет для направления z нового изображения.

Таким образом, вращение вокруг оси x можно представить как: Rotation around X

Для "пересчитанных" данных:

  • Новые (повернутые) данные имеют происхождение в исходной точке данных (0,0, SZ-1).
  • Его X-направление остается неизменным, то есть один шаг в X в новых данных будет увеличивать триплет координат в исходных данных также на (1,0,0).
    И каждый идет SX-шаги с размер шага 1.
  • Его Y-направление по существу является отрицательным Z-направлением, т. Е. Один шаг по Y в новых данных будет увеличивать триплет координат в исходных данных также на (0,0, -1).
    Таким образом, каждый идет SZ шаги с размером шага -1.
  • Его Z-направление по сути является Y-направлением, то есть один шаг по Z в новых данных увеличит триплет координат в исходных данных на (0,1,0).
    SY шаги с размером шага 1.

Итак, для вращения по часовой стрелке вокруг оси X команда:
img.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 )

Эта команда просто создаст новое представление для тех же данных (т. Е. Дополнительная память не используется). Таким образом, чтобы получить повернутое изображение как новое изображение (со значениями данных, выровненными так, как они должны быть в памяти), можно было бы клонировать этот вид в новое изображение. usign ImageClone()

Всего следующий скрипт показывает это в качестве примера:

// Demo of rotating 3D data orthogonally around the X axis
// This is done by resampling the data using the Slice3 command

// Creation of test image with regcognizeable pattern
number SX = 100
number SY = 30
number SZ = 50
image img := RealImage("Test",4, SX,SY,SZ)

// trig. modulated linear increase in X
img =  icol/iwidth* sin( icol/(iwidth-1) * 5 * Pi() ) **2       
// Simple linear increase in Y
img += (irow/iheight) * 2                                   
// Modulation of values in Z 
// (doubling values for index 0,1, 3, 4, 9, 16, 25, 36, 49) 
img *= (SQRT(iplane) == trunc(SQRT(iplane)) ? 2 : 1 )       
img.ShowImage()

// Show captions. Image coordinate system is
// Origin (0,0,0) in top-left-front most pixel
// X axis goes left to right
// Y axis goes top to down
// Z axis goes front to back 
img.ImageSetDimensionCalibration(0,0,1,"orig X",0)
img.ImageSetDimensionCalibration(1,0,1,"orig Y",0)
img.ImageSetDimensionCalibration(2,0,1,"orig Z",0)
img.ImageGetImageDisplay(0).ImageDisplaySetCaptionOn(1)

// Rotation around X axis, clockwise looking along X
// X --> X`  (unchanged)
// Y --> Z'
// Z --> -Y'
// old origin moves to bottom-left-front most 
// This means for "new" sampling:
// Specify sampling starting point:
//   New origin (0,0,0)'  will be value which was at (0,0,SZ-1)
//   Going one step in X' in the new data, will be like going one step in X 
//   Going one step in Y' in the new data, will be like going one step backwards in Z 
//   Going one step in Z' in the new data, will be like going one step in Y
image rotXCW := img.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 ).ImageClone()
rotXCW.SetName("rotated X, CW")
rotXCW.ShowImage()
rotXCW.ImageGetImageDisplay(0).ImageDisplaySetCaptionOn(1)


Следующие методы выполняют вращение на 90 градусов:

// Functions for 90degree rotations of data
image RotateXCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 ).ImageClone()
}

image RotateXCCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( 0,SY-1,0, 0,SX,1, 2,SZ,1, 1,SY,-1 ).ImageClone()
}

image RotateYCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( SX-1,0,0, 2,SZ,1, 1,SY,1, 0,SX,-1 ).ImageClone()
}

image RotateYCCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( 0,0,SZ-1, 2,SZ,-1, 1,SY,1, 0,SX,1 ).ImageClone()
}

image RotateZCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( 0,SY-1,0, 1,SY,-1, 0,SX,1, 2,SZ,1 ).ImageClone()
}

image RotateZCCW( image input )
{
    number SX,SY,SZ
    input.Get3DSize(SX,SY,SZ)
    return input.Slice3( SX-1,0,0, 1,SY,1, 0,SX,-1, 2,SZ,1 ).ImageClone()
}

Вращения вокруг оси z также можно выполнить с RotateRight() и RotateLeft(). Однако обратите внимание, что эти команды не будут адаптировать калибровку размеров изображений, в то время как команда Slice3 будет.

0 голосов
/ 01 сентября 2018

Для чистого ортогонального вращения самый простой (и самый быстрый) способ - использовать команды 'lice', то есть 'slice3' для трехмерных изображений. Оказывается, что последняя версия GMS имеет пример этого в справочной документации, поэтому я просто скопирую код здесь:

number sx = 10
number sy = 10
number sz = 10

number csx, csy, csz 
image img3D := RealImage( "3D", 4, sx, sy, sz )
img3D = 1000 + sin( 2*PI() * iplane/(idepth-1) ) * 100 + icol * 10  + irow
img3D.ShowImage()

// Rotate existing image
if ( OKCancelDialog( "Rotate clockwise (each plane)\n= Rotate block around z-axis" ) )
 img3D.RotateRight()



if ( OKCancelDialog( "Rotate counter-clockwise (each plane)\n= Rotate block around z-axis" ) )
 img3D.RotateLeft()


if ( OKCancelDialog( "Rotate block counter-clockwise around X-axis" ) )
{
 // Equivalent of sampling the data anew
 // x-axis remains 
 // y- and z-axis change their role
 img3D.Get3DSize( csx, csy, csz )        // current size along axes
 img3D = img3D.Slice3( 0,0,0, 0,csx,1, 2,csz,1, 1,csy,1 )
}

if ( OKCancelDialog( "Rotate block clockwise around X-axis" ) )
{
 // Equivalent of sampling the data anew
 // x-axis remains 
 // y- and z-axis change their role
 img3D.Get3DSize( csx, csy, csz )        // current size along axes
 img3D = img3D.Slice3( 0,csy-1,csz-1, 0,csx,1, 2,csz,-1, 1,csy,-1 )
}

if ( OKCancelDialog( "Rotate 30 degree (each plane)\n= Rotate block around z-axis" ) )
{
 number aDeg = 30
 number interpolMeth = 2
 number keepSize = 1
 image rotImg := img3D.Rotate( 2*Pi()/360 * aDeg, interpolMeth, keepSize )
 rotImg.ShowImage()
}

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

...