Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: docs: Add Input/Output types tutorial section #791

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/tutorial/_sidebar.md
Expand Up @@ -3,7 +3,8 @@

- [Hello World!](/tutorial/hello_world)
- [Hello Pipeline!](/tutorial/hello_pipeline)
- [Input/Output](/tutorial/inputs_outputs)
- [Pipeline Input/Output](/tutorial/pipeline_input_output)
- [Input/Output Types](/tutorial/input_output_types)
- [Debugging](/tutorial/debugging)

- [Examples](/examples/)
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/hello_pipeline.md
Expand Up @@ -2,7 +2,7 @@ Hello Pipeline World!

## Introduction

This example introduces the `itk::wasm::Pipeline`. An `itk::wasm::Pipeline` transforms elegant standalone C++ command line programs into powerful [WebAssembly](https://webassembly.org/) (Wasm) modules with a simple, efficient interface for execution in the browser, other programming languages, and on the command line.
This example introduces the `itk::wasm::Pipeline`. An `itk::wasm::Pipeline` transforms elegant standalone C++ command line programs into powerful [WebAssembly](https://webassembly.org/) (wasm) modules with a simple, efficient interface for execution in the browser, other programming languages, and on the command line.

Make sure to complete the [Hello World!](/tutorial/hello_world) example before you start your Hello Pipeline adventure.

Expand Down
7 changes: 7 additions & 0 deletions docs/tutorial/input_output_types.md
@@ -0,0 +1,7 @@
# Input/Output Types

## Introduction

This tutorial section

## Write the code
@@ -1,8 +1,8 @@
# Pipeline Inputs and Outputs
# Pipeline Input/Output

## Introduction

This example dives deeper into `itk::wasm::Pipeline` image inputs and outputs and how they are handled. We will create a pipeline to smooth an image with a median filter, run the Wasm from the command line, in Node.js.
This tutorial section dives deeper into `itk::wasm::Pipeline` image inputs and outputs and how they are handled. We will create a pipeline to smooth an image with a median filter, run the wasm from the command line, in Node.js.

Make sure to complete the [Hello Pipeline!](/tutorial/hello_pipeline) example before you start your filtering journey.

Expand Down
12 changes: 6 additions & 6 deletions examples/inputs-outputs/package.json
@@ -1,12 +1,12 @@
{
"name": "itk-wasm-inputs-outputs-example",
"version": "1.0.2",
"description": "An itk-wasm pipeline example for inputs/outputs",
"name": "@itk-wasm/inputs-outputs-tutorial",
"version": "1.0.3",
"description": "itk-wasm example for the pipeline inputs/outputs tutorial",
"main": "index.mjs",
"type": "module",
"scripts": {
"build": "npm run build:wasi && npm run build:emscripten",
"build:wasi": "itk-wasm -b wasi-build -i itkwasm/wasi build",
"build:wasi": "itk-wasm -i itkwasm/wasi build",
"build:emscripten": "itk-wasm -i itkwasm/emscripten:latest-debug build -b emscripten-build -- -DCMAKE_BUILD_TYPE=Debug",
"test": "npm run test:wasi && npm run test:wasi:help && npm run test:emscripten",
"test:wasi": "itk-wasm -b wasi-build run inputs-outputs.wasi.wasm -- -- cthead1.png smoothed.png",
Expand All @@ -17,7 +17,7 @@
"license": "Apache-2.0",
"dependencies": {
"fs-extra": "^10.0.0",
"itk-image-io": "^1.0.0-b.63",
"itk-wasm": "^1.0.0-b.63"
"itk-image-io": "^1.0.0-b.83",
"itk-wasm": "^1.0.0-b.83"
}
}
5 changes: 5 additions & 0 deletions examples/io-types/.gitignore
@@ -0,0 +1,5 @@
package-lock.json
smoothed.png
smoothed-uint16.png
emscripten-build/
wasi-build/
31 changes: 31 additions & 0 deletions examples/io-types/CMakeLists.txt
@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.16)
project(io-types)

# Use C++17 or newer with itk-wasm
set(CMAKE_CXX_STANDARD 17)

# We always want to build against the WebAssemblyInterface module.
set(itk_components
WebAssemblyInterface
ITKSmoothing # provides itkMedianImageFilter.h
)
# WASI or native binaries
if (NOT EMSCRIPTEN)
# WebAssemblyInterface supports the .iwi, .iwi.cbor itk-wasm format.
# We can list other ITK IO modules to build against to support other
# formats when building native executable or WASI WebAssembly.
# However, this will bloat the size of the WASI WebAssembly binary, so
# add them judiciously.
set(itk_components
${itk_components}
ITKIOPNG
# ITKImageIO # Adds support for all available image IO modules
)
endif()
find_package(ITK REQUIRED
COMPONENTS ${itk_components}
)
include(${ITK_USE_FILE})

add_executable(io-types io-types.cxx)
target_link_libraries(io-types PUBLIC ${ITK_LIBRARIES})
Binary file added examples/io-types/cthead1-uint16.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/io-types/cthead1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions examples/io-types/io-types.cxx
@@ -0,0 +1,91 @@
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#include "itkPipeline.h"
#include "itkInputImage.h"
#include "itkOutputImage.h"
#include "itkSupportInputImageTypes.h"

#include "itkImage.h"
#include "itkMedianImageFilter.h"

template<typename TImage>
int
MedianFilter(itk::wasm::Pipeline & pipeline, const TImage * inputImage)
{
using ImageType = TImage;

// For running the pipeline, mark the input image as required
// and specify its type name
pipeline.get_option("input-image")->required()->type_name("INPUT_IMAGE");

// Add a flag to specify the radius of the median filter.
unsigned int radius = 1;
pipeline.add_option("-r,--radius", radius, "Kernel radius in pixels");

// Add an output image argument.
using OutputImageType = itk::wasm::OutputImage<ImageType>;
OutputImageType outputImage;
pipeline.add_option("output-image", outputImage, "The output image")->required()->type_name("OUTPUT_IMAGE");

ITK_WASM_PARSE(pipeline);

// Process our data
using FilterType = itk::MedianImageFilter< ImageType, ImageType >;
auto filter = FilterType::New();
filter->SetInput(inputImage);
filter->SetRadius(radius);
filter->Update();

// Set the output image before the program completes.
outputImage.Set(filter->GetOutput());

return EXIT_SUCCESS;
}

template<typename TImage>
class PipelineFunctor
{
public:
int operator()(itk::wasm::Pipeline & pipeline)
{
using ImageType = TImage;

using InputImageType = itk::wasm::InputImage<ImageType>;
InputImageType inputImage;
pipeline.add_option("input-image", inputImage, "The input image");

// Use the ITK_WASM_PRE_PARSE macro, which checks only the defined options.
ITK_WASM_PRE_PARSE(pipeline);

typename ImageType::ConstPointer image = inputImage.Get();
return MedianFilter<ImageType>(pipeline, image);
}
};

int main( int argc, char * argv[] )
{
itk::wasm::Pipeline pipeline("different-input-types", "An itk-wasm pipeline example that demonstrates accepting different input types", argc, argv);

// Specify
// 1) Input image pixel types we want to support
// 2) Input image dimensions we want to support
return itk::wasm::SupportInputImageTypes<PipelineFunctor,
uint8_t,
uint16_t>
::Dimensions<2U>("input-image", pipeline);
}
19 changes: 19 additions & 0 deletions examples/io-types/package.json
@@ -0,0 +1,19 @@
{
"name": "@itk-wasm/io-types-tutorial",
"version": "1.0.2",
"description": "itk-wasm pipeline example for the input/output types tutorial",
"type": "module",
"scripts": {
"build": "npm run build:wasi",
"build:wasi": "itk-wasm -i itkwasm/wasi build",
"test": "npm run test:wasi && npm run test:wasi:help",
"test:wasi": "itk-wasm run wasi-build/io-types.wasi.wasm -- -- cthead1.png smoothed.png",
"test:wasi:uint16": "itk-wasm run wasi-build/io-types.wasi.wasm -- -- cthead1-uint16.png smoothed-uint16.png",
"test:wasi:help": "itk-wasm run wasi-build/io-types.wasi.wasm -- -- --help"
},
"author": "Matt McCormick <matt.mccormick@kitware.com>",
"license": "Apache-2.0",
"dependencies": {
"itk-wasm": "^1.0.0-b.83"
}
}