Команда сценария для выравнивания среза по горизонтали путем калибровки

Есть ли команда сценария, с помощью которой я могу указать конкретный срез в LinePlotImageDisplay и выполнить действие «Выровнять срез по горизонтали с помощью калибровки» (или «Некалиброванные (каналы))»?


person KEVIVI    schedule 10.10.2015    source источник


Ответы (2)


Нет, единой команды «удобства» для достижения такого выравнивания не существует. Вам нужно будет создать соответствующую функцию самостоятельно, прочитав калибровку срезов и установив систему координат отображения. Вы можете найти следующий (старый) учебник в формате PDF на домашней странице FELMI, который может оказаться полезным:

SlicesInLinePlotDisplay.pdf


Следующий пример сценария также может быть полезен. Он показывает, как один срез выравнивается относительно другого среза. (Только по оси X)

// All Slices in a LinePlot are grouped into a single 'group'
// Slices can be moved relative to each other by specifying their image-to-group transform, 
// and the whole image (i.e. the group) can be moved with respect to the display using the group-to-display transform.
// To set the image-to-group transform of the slice specified by 'slice_id', with respect to the slice specified by 'ref_id' 
// use the command: 
//  LinePlotImageDisplaySetImageToGroupTransform( LinePlotImageDisplay lpid, ScriptObject slice_id, ScriptObject ref_id, double  off_val, double  scale_val, double  off_dim_0, double scale_dim_0 )

/*********************************************************/
// Create 2 LinePlots and add them into one display
// (Initially they are aligned by their calibrations)
number sc1 = 1
number of1 = -50
number sc2 = 2
number of2 = -20

image sl1 := realImage("S1",4,300)
image sl2 := realImage("S2",4,300)
sl1 = (iwidth-icol)/iwidth
sl2 = (iwidth-icol)/iwidth
sl1[0,50,1,60] = 1
sl1[0,250,1,260] = 1
sl2[0,10,1,15] = 1
sl2[0,110,1,115] = 1
// Adding Calibrations
sl1.ImageSetDimensionCalibration(0,of1,sc1,"CH",0)
sl2.ImageSetDimensionCalibration(0,of2,sc2,"CH",0)

sl1.DisplayAt(20,30)
sl2.DisplayAt(750,30)
OKDialog( "Put into one Display" )

imageDisplay disp = sl1.ImageGetImageDisplay(0) 
disp.ImageDisplayAddImage( sl2, "S2")                       // When added like this, the slices are automatically aligned by their respective calibration!
disp.LinePlotImageDisplaySetDoAutoSurvey( 0, 0 )
object ref_id = disp.ImageDisplayGetSliceIDByIndex(0)       // Slice 0
object slice_id = disp.ImageDisplayGetSliceIDByIndex(1)     // Slice 1

OKDialog("Now align by channels (i.e. undo any relative sclice alignment)")
// Simply set the relative "shifts" and "scales" to 0 and 1.
disp.LinePlotImageDisplaySetImageToGroupTransform( slice_id, ref_id, 0, 1, 0, 1 )   

OKDialog("Now align by chalibration ")
number relScale = sc2/sc1
number relOff = of2-of1
disp.LinePlotImageDisplaySetImageToGroupTransform( slice_id, ref_id, 0, 1, relOff, relScale )   
person BmyGuest    schedule 10.10.2015
comment
Думаю, простого выхода нет, но нужно создать собственный сценарий. В коде примера есть одна небольшая ловушка, с которой нужно быть осторожным: число reloff = of2-of1 должно быть числом reloff = (of2-of1)/sc1 Спасибо! - person KEVIVI; 11.10.2015
comment
@KEVIVI Верно, спасибо. Мне нравится ваш полный сценарий ниже. Не хотите ли загрузить его в базу данных FELMI? - person BmyGuest; 11.10.2015

Следующий сценарий представляет собой полную имплантацию, основанную на примерах кодов, предоставленных BmyGuest. Он выровняет все срезы в LinePlotImageDisplay по горизонтали либо путем калибровки, либо по каналу (т. е. без калибровки).

class SliceAlignment : object {
    number true, false;     // boolean
    image imgLPID;
    imageDisplay LPID;      // line plot image display

number CalculateImageToGroupTransformFactors( object self, image slice_src, image slice_ref, number &relOff, number &relScale ) {
    number origin_ref, scale_ref, origin_src, scale_src;
    string unit_ref, unit_src;
    number calFMT = 0;          // origin is expressed in calibrated unit
    //
    slice_src.ImageGetDimensionCalibration( 0, origin_src, scale_src, unit_src, calFMT );
    slice_ref.ImageGetDimensionCalibration( 0, origin_ref, scale_ref, unit_ref, calFMT );
    //
    relScale = scale_src / scale_ref;
    relOff = (origin_src - origin_ref) / scale_ref ;
    // check if both images are calibrated in same unit
    if( unit_src != unit_ref ) return false
    return true;
};

void AlignNthSliceHorizontallyByChannel( object self, number slice_idx ) {
    // get current reference slice index
    number refSlice_idx = LPID.LinePlotImageDisplayGetSlice();
    // get slice ID's (as objects)
    object slice_ref = LPID.ImageDisplayGetSliceIDByIndex(refSlice_idx);
    object slice_src = LPID.ImageDisplayGetSliceIDByIndex(slice_idx);
    number int_offset = 0, int_scale = 1.0;         // vertical (intensity) offset and scaling factors
    number pos_offset = 0, pos_scale = 1.0;         // horizontal (position) offset and scaling factors
    LPID.LinePlotImageDisplaySetImageToGroupTransform( slice_src, slice_ref, int_offset, int_scale, pos_offset, pos_scale );
};  

void AlignNthSliceHorizontallyByCalibration( object self, number slice_idx ) {
    // get current reference slice index
    number refSlice_idx = LPID.LinePlotImageDisplayGetSlice();
    // get slice ID's (as objects)
    object slice_ref = LPID.ImageDisplayGetSliceIDByIndex(refSlice_idx);
    object slice_src = LPID.ImageDisplayGetSliceIDByIndex(slice_idx);
    number int_offset = 0, int_scale = 1.0;         // vertical (intensity) offset and scaling factors
    number pos_offset, pos_scale;                   // horizontal (position) offset and scaling factors
    number unit_check = self.CalculateImageToGroupTransformFactors( imgLPID{slice_idx}, imgLPID{refSlice_idx}, pos_offset, pos_scale );
    if( unit_check == false ) {
        string prompt = "slice #" + slice_idx + " [" + LPID.ImageDisplayGetSliceLabelById( LPID.ImageDisplayGetSliceIDByIndex(slice_idx) ) + "] is calibrated in different unit!";
        if( !ContinueCancelDialog( prompt ) ) return
    };
    LPID.LinePlotImageDisplaySetImageToGroupTransform( slice_src, slice_ref, int_offset, int_scale, pos_offset, pos_scale );
    return;
};

void AlignAllSlicesHorizontallyByChannel( object self ) {
    number nSlices = LPID.LinePlotImageDisplayCountSlices();
    for( number idx = 0; idx < nSlices; idx++ ) self.AlignNthSliceHorizontallyByChannel( idx );
    return;
};

void AlignAllSlicesHorizontallyByCalibration( object self ) {
    number nSlices = LPID.LinePlotImageDisplayCountSlices();
    for( number idx = 0; idx < nSlices; idx++ ) self.AlignNthSliceHorizontallyByCalibration( idx );
    return;
};

object init( object self, image img ) {
    // check if the image display is correct type
    imgLPID := img;
    LPID = imgLPID.ImageGetImageDisplay(0);
    if( LPID.ImageDisplayGetDisplayType() != 3 ) throw( "Please choose a valid line plot display" );
    return self;
};

SliceAlignment( object self ) {
    true = 1; false = 0;
    result( "SliceAlignment [obj ID:" + self.ScriptObjectGetID().hex() + "] constructured\n" );
};

~SliceAlignment( object self ) {
    result( "SliceAlignment [obj ID:" + self.ScriptObjectGetID().hex() + "] destructured\n\n" );
}; };

{; object objAlign = alloc(SliceAlignment);
objAlign.init( GetFrontImage() );
if( OptionDown() ) objAlign.AlignAllSlicesHorizontallyByChannel();
else objAlign.AlignAllSlicesHorizontallyByCalibration(); };
person KEVIVI    schedule 11.10.2015