Building ITK with emscripten

All,

'am trying to build ITK-4.9 on Windows 10 machine using emscripten. I’ve written a few filters in C++ using ITK but I now have to run them from a browser. I do not know javascript and therefore cannot use itk-js. My only option is to convert my C++ filters to WASM using emscripten.

I used the following flags and cmake to configure (followed by ninja to build ITK)

flags="-Wno-warn-absolute-paths --memory-init-file 0 -s DISABLE_EXCEPTION_CATCHING=0 -s ALLOW_MEMORY_GROWTH=1 -D_LARGEFILE64_SOURCE=1"

cmake -DCMAKE_TOOLCHAIN_FILE=“Emscripten.cmake” -G Ninja "-DCMAKE_CXX_FLAGS=“flags shown above” -DCMAKE_C_FLAGS=“flags shown above” -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF “C:\ITK-4.9.0”

I got an error at HDF5 build step. So, I followed section 2 in this link to fix that error. I seemed to get past that stage but i now get the following error:

ninja: build stopped: command failed

The lines above this error are the following:

InsightToolkit-4.9.1/Modules/Core/Common/include/itkPoint.h:308:48: note: previous declaration is here typedef typename PointContainerType::Element PointType;
3 warnings generated.

This is my first attempt at using ninja and emscripten. I might be posting an incomplete error message above. In CMake, I would look at CMakeError.log but i do not know the equivalent for that file in ninja. Can someone please point me in the right direction and help me build ITK using emscripten?

Thanks in advance

ITK 4.9 is quite old now. There have been emscripten-related improvements since then. Can you try 5.1 RC3, or at least 4.13.x?

Welcome to the ITK community, @prashanth.dumpuri! :sunny:

WASM is run through the browser via JavaScript, and itk.js is build on WASM – the best approach is to use itk.js.

Thanks @dzenanz. I did not try 5.1 but I got errors related to threading in ITK-5.0.1. The errors were in itkMultiThreaderBase.cxx about undeclared variable m_GlobalMaximumNumberOfThreads. I changed the corresponding header file and created a variable for m_GlobalMaximumNumberOfThreads but that just led to more errors. Did I do something wrong? If not, have they been fixed in ITK 5.1 for clang compiler?

Thanks @matt.mccormick. I’m eventually going to switch to itk-js but I do not know javacsript programming and you said that you are still working on examples related to segmentation (you replied to my post in itk-js too. thanks again for that). So, while I wait on the examples and teach myself javascript programming, converting the ITK C++ filters I wrote to WASM is my only option.

itk.js provides ITK 5.1 RC 3 compiled with Emscripten.

itk.js minimizes the need to learn JavaScript. If you have a segmentation pipeline written ITK / C++, itk.js makes it easy to build it and run it in a browser.

To build it, npx itk-js build . as described here:

https://insightsoftwareconsortium.github.io/itk-js/examples/hello_world_node.html

Here is what a simple test pipeline looks like (note that it is only standard ITK /CMake / C++):

https://github.com/InsightSoftwareConsortium/itk-js/tree/master/test/MedianFilterPipeline

Here is how to call it:

https://github.com/InsightSoftwareConsortium/itk-js/blob/16fe9367de0a28a29f3a4c17ad181ff3731ec168/test/Browser/runPipelineBrowserTest.js#L143-L155

1 Like

Thanks again, @matt.mccormick. The example link you provided me helped me a ton and i’m up and running.

Is there a way to pass an Arraybuffer (preferably as 16-bit and not 8-bit) to ITK based C++ code. In the example you provided, the input image to C++ is read from the disk. In my application, this file is read on the browser side using UTIF and I have access just to the Arraybuffer from UTIF’s reader. Do you have any examples for extracting pixel intensities from that arraybuffer and passing it to the C++ code?

Prashanth

Great!

In this case, you can create an itk/Image with something like:

const dimension = 2
const componentType = itk.IntTypes.UInt8
# possibly also specify the pixelType and numberOfComponents
const imageType = new itk.ImageType(dimension, componentType)
const image = new itk.Image(imageType)
image.size = [width, height]
image.data = new Uint8Array(arrayBuffer)

Then, pass the image to runPipelineBrowser.

Thanks @matt.mccormick. arrayBuffer that is passed to me has been encoded. Below is the code that the front-end developer on my team (working on HTML side) gave me.

    // Create a new XMLHttpRequest object to read the mock TIFF image as ArrayBuffer
    const xhr = new XMLHttpRequest();
    // Configure it: GET-request for the URL
    xhr.open('GET', 'assets/tif/test.tif', true); // read test.tif bundled in the assets folder
    xhr.responseType = 'arraybuffer'; // get array buffer
    xhr.timeout = 10000; // timeout in ms, 10 seconds 
    const arrayBuffer = xhr.response; // create javascript variable and assign it with pixel intensities

In the example code, front-end developer is creating a HTTP request to read a test.tif I gave him. test.tif is a 300x300 scalar image with unsigned char as its pixel type. Therefore, I expected arrayBuffer variable in the last line of the code block above to be a 90,000x1 array. However, when I print the contents of arrayBuffer to a text file it has additional 225 elements. And, it does not have the tiff tags associated with it. It looks like an encoded array. Is there a simple way to decode this array?

I tried to copy itk-js’ appoach for readImageHTTP and use axios reader do but realized that the input file has to be a json with a 90,000x1 array for pixel intensities. I seem to be stuck in a loop with this approach.

'am sure i’m missing something really simple. Can you please point me in the right direction?

Thanks

Hi @prashanth.dumpuri,

The function it sounds like you want is readImageArrayBuffer.

HTH,
Matt

Thanks again @matt.mccormick. I looked at source code for readImageArrayBuffer and it looked like even it was expecting a decoded tiff. I could be wrong here but my front end team figured out a way to decode TIFFs and send me just the pixel intensities. I’m using that in my C++ code to create an ITK image and set up my C++ processing pipeline.

1 Like