Introduction to VivoScript – Part IV: Image Arithmetics

Introduction to VivoScript – Part IV: Image Arithmetics

This example will further explore using VivoScript libraries by adding three more functions and then dive into co-registering two images (using one of these functions) and applying some a image arithmetic, in this case calculating the relative difference.

The details

Before running this example, please save the two library files (‘MouseLoader.vqs’ and ‘Coregister.vqs’) below, which are used in our example script using #include “filename.vqs” lines:

#include "MouseLoader.vqs"
#include "Coregister.vqs"

load_mouse_15(0); // imported from MouseLoader.vqs
load_mouse_16(1);

coregister();     // imported from Coregister.vqs

// Switch to Arithmetics Operator:
VQ.mainWin().setViewMode("Slice View", "Arithmetics");
var op = VQ.currentOp();

// Divide both images:
op.subtractImage(0, 1); // img0 = img0 - img1
op.divideImage(0, 1);   // img0 = img0 / img1

var c = VQ.controler();
c.setPal(0, "ratio2black"); 
c.setActive(1, false);     // hide img1

VQ.showMessage("Calculated img0 = (img0-img1)/img1");

// Also available are these functions:
// void addScalar( int id, float scalar );
// void multScalar( int id, float scalar );
// void addImage( int id, int img );       // adds img to id
// void multImage( int id, int img );      // multiplies img to id
// void subtractImage( int id, int img );
// void divideImage( int id, int img );
// void averageImages(int id, QList<int> list);
// void mergeImages(int id, QList<int> list);

After loading two example mouse CTs and an initial fast co-registration we open the Arithmetic operator and ask VQ for the operator object, which provides all arithmetic functions:

// Switch to Arithmetics Operator:
VQ.mainWin().setViewMode("Slice View", "Arithmetics");
var op = VQ.currentOp();

Subsequently, we calculate the relative difference between the two images with image based functions subtractImage(…) and divideImage(…):

// Divide both images:
op.subtractImage(0, 1); // img0 = img0 - img1
op.divideImage(0, 1);   // img0 = img0 / img1

These functions expect the ids (reference is 0, input 1 is 1, …) of the left and right image and modify the first image, so above subtracts the content of img1 from img0, the result is stored in img0.

Finally, we chose a more telling color pallet for the reference image and hide the input image by setting reference as an active modality only:

var c = VQ.controler();
c.setPal(0, "ratio2black"); 
c.setActive(1, false);     // hide img1

Besides image-based operations, which work on a voxel-by-voxel basis such as addImage(…) and multImage(…) the operator also provides scalar arithmetic which is applied to all voxels, e.g.

// add scalar value 0.123 to reference image
op.addScalar( 0, 0.123 );

// multiply input 1 image by scalar 1/37
op.multScalar( 1, 1/37 );

Finally, there are two functions that work on multiple images:

// average input images 1, 2, 3 and store as reference
op.averageImages(0, [ 1, 2, 3]);

// merge images ref, inp1, inp2 and store as inp1:
op.mergeImages(1, [ 0, 1, 2]);

The mergeImages(…) function is mainly useful to merge multiple ROI volumes with distinct values together, non-0 voxels will get the highest value of all input images.

Libary files

You will need below to files to run above example.

[accordion]
[acc_item title=”Description”]Please copy these two files with their respective names to your VivoScript library directories. See Part III on how this works.[/acc_item]
[acc_item title=”MouseLoader.vqs”]Provides two convenient functions to quickly load two different mouse CTs to play around with in other scripts:

function load_mouse_15(id) {
    var dm = VQ.dataManager();
    {
        var dcmRep = VQ.dcmRep("ipacss://vqintro:blog42@training.ipacs.invicro.com/examples");
        dcmRep.setProject("/examples");
        var files = VQ.downloadImages(dcmRep,
                "1.3.6.1.4.1.12842.1.1.14.3.20100526.145653.234.3400598378",
                "1.3.6.1.4.1.33793.1.4.0.58478.1299815611.1");
        dm.openDat(id, files);
        dm.setDesc(id, "__repository_url", "ipacss://training.ipacs.invicro.com/examples");
        dm.setDesc(id, "__project", "/examples");
    }
}

function load_mouse_16(id) {
    var dm = VQ.dataManager();
    {
        var dcmRep = VQ.dcmRep("ipacss://vqintro:blog42@training.ipacs.invicro.com/examples");
        dcmRep.setProject("/examples");
        var files = VQ.downloadImages(dcmRep,
                "1.3.6.1.4.1.12842.1.1.14.3.20100526.140006.890.3697812169",
                "1.3.6.1.4.1.33793.1.4.0.58478.1299815896.3");
        dm.openDat(id, files);
        dm.setDesc(id, "__repository_url", "ipacss://training.ipacs.invicro.com/examples");
        dm.setDesc(id, "__project", "/examples");
    }

}

[/acc_item]
[acc_item title=”Coregister.vqs”]Opens the reorientation operator and performs a fast, translation-only registration, a step often found in pro-processing protocols.

function coregister() {
    VQ.mainWin().setViewMode("Slice View", "Reorientation/Registration");
    var op = VQ.currentOp();

    op.changeMode(2);
    VQ.getWidget("gbBasicSettings").setChecked(true);
    // VQ.getWidget("buttonTransformVersor").click();
    VQ.getWidget("buttonTransformTranslate").click();
    VQ.getWidget("buttonQualityFast").click();
    VQ.getWidget("buttonRegister").click();
}

[/acc_item]
[/accordion]