Skip to content

Commit

Permalink
Merge pull request #746 from thewtex/different-input-types
Browse files Browse the repository at this point in the history
docs(Examples): Add different-input-types examples
  • Loading branch information
thewtex authored Feb 6, 2023
2 parents a328d98 + 0f02eb8 commit 0e37262
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,29 @@ jobs:
npm run emscripten-build-release
npm run emscripten-build-debug
npm run wasi-build-debug
test-different-input-types-example:
name: different-input-types
runs-on: ubuntu-22.04
defaults:
run:
working-directory: ./examples/different-input-types

steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: '18'

- name: Install
run: |
npm install
- name: Build
run: |
npm run build
- name: Test
run: |
npm run test
1 change: 1 addition & 0 deletions examples/different-input-types/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wasi-build/
31 changes: 31 additions & 0 deletions examples/different-input-types/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.16)
project(different-input-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
ITKImageFusion
)
# 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(different-input-types different-input-types.cxx)
target_link_libraries(different-input-types PUBLIC ${ITK_LIBRARIES})
Binary file added examples/different-input-types/Gourds.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
117 changes: 117 additions & 0 deletions examples/different-input-types/different-input-types.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*=========================================================================
*
* 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 "itkLabelObject.h"
#include "itkLabelMap.h"
#include "itkLabelImageToLabelMapFilter.h"
#include "itkLabelMapOverlayImageFilter.h"

template<typename TImage, typename TLabelImage>
int
OverlayLabelMap(itk::wasm::Pipeline & pipeline, const TImage * inputImage, const TLabelImage * labelImage)
{
using ImageType = TImage;
using LabelImageType = TLabelImage;
constexpr unsigned int Dimension = ImageType::ImageDimension;

using LabelType = typename LabelImageType::PixelType;
using LabelObjectType = itk::LabelObject<LabelType, Dimension>;
using LabelMapType = itk::LabelMap<LabelObjectType>;

using ConverterType = itk::LabelImageToLabelMapFilter<LabelImageType, LabelMapType>;
using FilterType = itk::LabelMapOverlayImageFilter<LabelMapType, ImageType>;

pipeline.get_option("input-image")->required()->type_name("INPUT_IMAGE");
pipeline.get_option("label-image")->required()->type_name("INPUT_IMAGE");

using OutputImageType = itk::wasm::OutputImage<typename FilterType::OutputImageType>;
OutputImageType outputImage;
pipeline.add_option("output-image", outputImage, "The output image")->required()->type_name("OUTPUT_IMAGE");

ITK_WASM_PARSE(pipeline);

auto converter = ConverterType::New();
converter->SetInput(labelImage);

auto filter = FilterType::New();
filter->SetInput(converter->GetOutput());
filter->SetFeatureImage(inputImage);
filter->SetOpacity(0.5);

filter->UpdateLargestPossibleRegion();

outputImage.Set(filter->GetOutput());

return EXIT_SUCCESS;
}

template<typename TImage>
class InputImagePipelineFunctor
{
public:
int operator()(itk::wasm::Pipeline & pipeline)
{
using InputImageType = itk::wasm::InputImage<TImage>;
InputImageType inputImage;
pipeline.add_option("input-image", inputImage, "The input image");

ITK_WASM_PRE_PARSE(pipeline);

typename TImage::ConstPointer image = inputImage.Get();
parsedImage = image;
return itk::wasm::SupportInputImageTypes<LabelImagePipelineFunctor,
uint8_t>
::template Dimensions<TImage::ImageDimension>("label-image", pipeline);
}

private:
template<typename TLabelImage>
class LabelImagePipelineFunctor
{
public:
int operator()(itk::wasm::Pipeline & pipeline)
{
using LabelImageType = itk::wasm::InputImage<TLabelImage>;
LabelImageType labelImage;
pipeline.add_option("label-image", labelImage, "The label image");

ITK_WASM_PRE_PARSE(pipeline);

typename TLabelImage::ConstPointer label = labelImage.Get();
return OverlayLabelMap<TImage, TLabelImage>(pipeline, parsedImage, label);
}
};

static inline const TImage * parsedImage;
};

int main( int argc, char * argv[] )
{
// Create the pipeline for parsing arguments. Provide a description.
itk::wasm::Pipeline pipeline("different-input-types", "An itk-wasm pipeline example that demonstrates accepting different input types", argc, argv);

return itk::wasm::SupportInputImageTypes<InputImagePipelineFunctor,
uint8_t,
uint16_t>
::Dimensions<2U>("input-image", pipeline);
}
Binary file added examples/different-input-types/label.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions examples/different-input-types/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "itk-wasm-different-input-types-example",
"version": "1.0.0",
"description": "An itk-wasm pipeline example that demonstrates accepting different input types",
"type": "module",
"scripts": {
"build": "npm run build:wasi",
"build:wasi": "itk-wasm -b wasi-build -i itkwasm/wasi build",
"test": "npm run test:wasi && npm run test:wasi:help",
"test:wasi": "itk-wasm -b wasi-build run different-input-types.wasi.wasm -- -- ./Gourds.png label.png overlay.png",
"test:wasi:help": "itk-wasm -b wasi-build run different-input-types.wasi.wasm -- -- --help"
},
"author": "Matt McCormick <[email protected]>",
"license": "Apache-2.0",
"dependencies": {
"itk-wasm": "^1.0.0-b.66"
}
}

0 comments on commit 0e37262

Please sign in to comment.