Я хотел бы умножить интенсивность куба данных EELS на карту толщины. Я пробовал использовать простую математическую команду, но получил результат только для первого среза. Я думаю, что расчет так же прост, как выполнение Result(x,y,E) = SI(x,y,E) * Thickness(x,y)
и цикл по x и y, но я не знаю, как это сделать с помощью сценария DM.
Спасибо
С Уважением
Это можно сделать разными способами. Следующий скрипт создает два тестовых изображения для ниже:
Image SIStack := RealImage( "Stack", 4, 32,32,64)
SIStack = iplane + 1 + random()
Image Map2D := RealImage( "Map", 4, 32, 32 )
Map2D = iradius * sin( irow/iwidth * pi() * 4 )
SIStack.ShowImage()
Map2D.ShowImage()
Чтобы перемножить эти два, вы действительно можете использовать выражение, очень похожее на то, что вы написали. Внутренние переменные icol
, irow
и iplane
(или, в более общем смысле, iindex(n)
) заменяются соответствующими индексами пикселей X, Y и Z (начиная с 0 для первого индекса, заметьте!). Вы можете использовать их как «текущие переменные» в своем выражении. Итак, следующее будет делать то, что вы хотите:
Image ResultStack := RealImage( "RStack", 4, 32,32,64)
ResultStack = SIStack[icol,irow,iplane] * Map2D[icol,irow]
ResultStack.ShowImage()
Вышеупомянутое уравнение представляет собой перевод вашего уравнения в соотношении 1: 1, и я напечатал его, чтобы прояснить это. Обратите внимание, что в этом типе выражения, по крайней мере, одна его часть должна иметь "статический" размер, т.е. не индексироваться. Это определит, в каком диапазоне будут работать индексы icol / irow / iplane. В приведенном выше примере ResultStack
с левой стороны обеспечивает это, поэтому icol
переходит от 0
к size-x of ResultStack minus 1
.
В качестве помощника: это работает, даже если Map2D
меньше, чем текущие переменные! Любой индекс, выходящий за границы, будет рассматриваться как последний доступный индекс, по существу экстраполяция значения «границы».
Теперь приведенный выше сценарий можно было бы записать более компактно (и без дополнительного 'ResultsStack') как:
SIStack *= Map2D[icol,irow]
Вы также можете использовать нарезку и перебирать размер z:
for( number i = 0; i<64; i++ )
SIStack.Slice2(0,0,i, 0,32,1 ,1,32,1 ) *= Map2D
Для получения дополнительной информации о любом из вариантов вы можете проверить этот ответ
Спасибо, мой сценарий следующий:
Спасибо. Вот сценарий, который я написал. Единственная проблема заключается в том, что созданный куб данных не распознается как куб данных EELS.
image thick, si, res, out
number width, height, xsize, ysize, zsize,i
//select images
string title = "Image Selection Dialog"
string prompt = "Please select two images."
string label_si = "SI :"
string label_thick = "Thickness map:"
if ( !GetTwoLabeledImagesWithPrompt( prompt, title, label_si, si, label_thick, thick ) )
Throw( "User pressed cancel." )
res=si
ImageCopyCalibrationFrom(res, si)
// size of the different images
thick.GetSize(width, height)
si.Get3DSize(xsize, ysize, zsize)
Result("width = "+width+" pixels"+", height = "+height+" pixels\n")
Result("SI xsize:"+xsize+" ysize:"+ysize+" Nb Energy channels:"+zsize+"\n")
for(number i=0; i<zsize; i++)
{
res.Slice2(0,0,i,0,xsize,1,1,ysize,1) *= thick
}
res.ShowImage()
Это связано с тем, что image = image
просто копирует значения, а информация SI сохраняется в метаданных. Часто лучше создать правильный (глубокий) клон с помощью image img := sourceImg.imageClone()
. В этом случае также не нужно копировать какие-либо калибровки. Так что просто используйте res := si.imageClone()
в приведенном выше сценарии.
В вашем уравнении вам действительно нужно перебрать все три переменные (x, y и E), поскольку каждое значение E представляет один «фрагмент изображения» стека. Первый вариант ответа ниже делает именно это. Если бы это было только для одного единственного значения E, у вас было бы просто пиксельное умножение двух изображений, что в DM-скрипте так же просто, как
A *= B
, это то, что делает второй вариант (повторение E).