-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(compare-images): add vector-magnitude typescript bindings
Also remove some unnecessary file and add .gitignore.
- Loading branch information
Showing
12 changed files
with
349 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
typescript/demo-app/ | ||
dist/ | ||
package-lock.json | ||
typescript/test/browser/demo-app/public |
16 changes: 0 additions & 16 deletions
16
packages/compare-images/typescript/dist/pipelines/compare-double-images.js
This file was deleted.
Oops, something went wrong.
21 changes: 0 additions & 21 deletions
21
packages/compare-images/typescript/dist/pipelines/compare-double-images.umd.js
This file was deleted.
Oops, something went wrong.
Binary file removed
BIN
-926 KB
packages/compare-images/typescript/dist/pipelines/compare-double-images.wasm
Binary file not shown.
11 changes: 11 additions & 0 deletions
11
packages/compare-images/typescript/src/vector-magnitude-node-result.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Generated file. To retain edits, remove this comment. | ||
|
||
import { Image } from 'itk-wasm' | ||
|
||
interface VectorMagnitudeNodeResult { | ||
/** Output magnitude image */ | ||
magnitudeImage: Image | ||
|
||
} | ||
|
||
export default VectorMagnitudeNodeResult |
65 changes: 65 additions & 0 deletions
65
packages/compare-images/typescript/src/vector-magnitude-node.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Generated file. To retain edits, remove this comment. | ||
|
||
import { | ||
Image, | ||
InterfaceTypes, | ||
PipelineOutput, | ||
PipelineInput, | ||
runPipelineNode | ||
} from 'itk-wasm' | ||
|
||
import VectorMagnitudeNodeResult from './vector-magnitude-node-result.js' | ||
|
||
|
||
import path from 'path' | ||
|
||
/** | ||
* Generate a scalar magnitude image based on the input vector's norm. | ||
* | ||
* @param {Image} vectorImage - Input vector image | ||
* | ||
* @returns {Promise<VectorMagnitudeNodeResult>} - result object | ||
*/ | ||
async function vectorMagnitudeNode( | ||
vectorImage: Image | ||
|
||
) : Promise<VectorMagnitudeNodeResult> { | ||
|
||
const desiredOutputs: Array<PipelineOutput> = [ | ||
{ type: InterfaceTypes.Image }, | ||
] | ||
|
||
const inputs: Array<PipelineInput> = [ | ||
{ type: InterfaceTypes.Image, data: vectorImage }, | ||
] | ||
|
||
const args = [] | ||
// Inputs | ||
const vectorImageName = '0' | ||
args.push(vectorImageName as string) | ||
|
||
// Outputs | ||
const magnitudeImageName = '0' | ||
args.push(magnitudeImageName) | ||
|
||
// Options | ||
args.push('--memory-io') | ||
|
||
const pipelinePath = path.join(path.dirname(import.meta.url.substring(7)), '..', 'pipelines', 'vector-magnitude') | ||
|
||
const { | ||
returnValue, | ||
stderr, | ||
outputs | ||
} = await runPipelineNode(pipelinePath, args, desiredOutputs, inputs) | ||
if (returnValue !== 0) { | ||
throw new Error(stderr) | ||
} | ||
|
||
const result = { | ||
magnitudeImage: outputs[0].data as Image, | ||
} | ||
return result | ||
} | ||
|
||
export default vectorMagnitudeNode |
14 changes: 14 additions & 0 deletions
14
packages/compare-images/typescript/src/vector-magnitude-result.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Generated file. To retain edits, remove this comment. | ||
|
||
import { Image } from 'itk-wasm' | ||
|
||
interface VectorMagnitudeResult { | ||
/** WebWorker used for computation */ | ||
webWorker: Worker | null | ||
|
||
/** Output magnitude image */ | ||
magnitudeImage: Image | ||
|
||
} | ||
|
||
export default VectorMagnitudeResult |
69 changes: 69 additions & 0 deletions
69
packages/compare-images/typescript/src/vector-magnitude.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Generated file. To retain edits, remove this comment. | ||
|
||
import { | ||
Image, | ||
InterfaceTypes, | ||
PipelineOutput, | ||
PipelineInput, | ||
runPipeline | ||
} from 'itk-wasm' | ||
|
||
import VectorMagnitudeResult from './vector-magnitude-result.js' | ||
|
||
|
||
import { getPipelinesBaseUrl } from './pipelines-base-url.js' | ||
import { getPipelineWorkerUrl } from './pipeline-worker-url.js' | ||
|
||
/** | ||
* Generate a scalar magnitude image based on the input vector's norm. | ||
* | ||
* @param {Image} vectorImage - Input vector image | ||
* | ||
* @returns {Promise<VectorMagnitudeResult>} - result object | ||
*/ | ||
async function vectorMagnitude( | ||
webWorker: null | Worker, | ||
vectorImage: Image | ||
|
||
) : Promise<VectorMagnitudeResult> { | ||
|
||
const desiredOutputs: Array<PipelineOutput> = [ | ||
{ type: InterfaceTypes.Image }, | ||
] | ||
|
||
const inputs: Array<PipelineInput> = [ | ||
{ type: InterfaceTypes.Image, data: vectorImage }, | ||
] | ||
|
||
const args = [] | ||
// Inputs | ||
const vectorImageName = '0' | ||
args.push(vectorImageName as string) | ||
|
||
// Outputs | ||
const magnitudeImageName = '0' | ||
args.push(magnitudeImageName) | ||
|
||
// Options | ||
args.push('--memory-io') | ||
|
||
const pipelinePath = 'vector-magnitude' | ||
|
||
const { | ||
webWorker: usedWebWorker, | ||
returnValue, | ||
stderr, | ||
outputs | ||
} = await runPipeline(webWorker, pipelinePath, args, desiredOutputs, inputs, { pipelineBaseUrl: getPipelinesBaseUrl(), pipelineWorkerUrl: getPipelineWorkerUrl() }) | ||
if (returnValue !== 0) { | ||
throw new Error(stderr) | ||
} | ||
|
||
const result = { | ||
webWorker: usedWebWorker as Worker, | ||
magnitudeImage: outputs[0].data as Image, | ||
} | ||
return result | ||
} | ||
|
||
export default vectorMagnitude |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
116 changes: 116 additions & 0 deletions
116
packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// Generated file. To retain edits, remove this comment. | ||
|
||
import { readImageFile } from 'itk-wasm' | ||
import { writeImageArrayBuffer, copyImage } from 'itk-wasm' | ||
import * as compareImages from '../../../dist/bundles/compare-images.js' | ||
import vectorMagnitudeLoadSampleInputs from "./vector-magnitude-load-sample-inputs.js" | ||
|
||
class VectorMagnitudeModel { | ||
|
||
inputs: Map<string, any> | ||
options: Map<string, any> | ||
outputs: Map<string, any> | ||
|
||
constructor() { | ||
this.inputs = new Map() | ||
this.options = new Map() | ||
this.outputs = new Map() | ||
} | ||
} | ||
|
||
|
||
class VectorMagnitudeController { | ||
|
||
constructor(loadSampleInputs) { | ||
this.loadSampleInputs = loadSampleInputs | ||
|
||
this.model = new VectorMagnitudeModel() | ||
const model = this.model | ||
|
||
this.webWorker = null | ||
|
||
if (loadSampleInputs) { | ||
const loadSampleInputsButton = document.querySelector("#vectorMagnitudeInputs [name=loadSampleInputs]") | ||
loadSampleInputsButton.setAttribute('style', 'display: block-inline;') | ||
loadSampleInputsButton.addEventListener('click', async (event) => { | ||
loadSampleInputsButton.loading = true | ||
await loadSampleInputs(model) | ||
loadSampleInputsButton.loading = false | ||
}) | ||
} | ||
|
||
// ---------------------------------------------- | ||
// Inputs | ||
const vectorImageElement = document.querySelector('#vectorMagnitudeInputs input[name=vector-image-file]') | ||
vectorImageElement.addEventListener('change', async (event) => { | ||
const dataTransfer = event.dataTransfer | ||
const files = event.target.files || dataTransfer.files | ||
|
||
const { image, webWorker } = await readImageFile(null, files[0]) | ||
webWorker.terminate() | ||
model.inputs.set("vectorImage", image) | ||
const details = document.getElementById("vectorMagnitude-vector-image-details") | ||
details.innerHTML = `<pre>${globalThis.escapeHtml(JSON.stringify(image, globalThis.interfaceTypeJsonReplacer, 2))}</pre>` | ||
details.disabled = false | ||
}) | ||
|
||
// ---------------------------------------------- | ||
// Options | ||
// ---------------------------------------------- | ||
// Outputs | ||
const magnitudeImageOutputDownload = document.querySelector('#vectorMagnitudeOutputs sl-button[name=magnitude-image-download]') | ||
magnitudeImageOutputDownload.addEventListener('click', async (event) => { | ||
event.preventDefault() | ||
event.stopPropagation() | ||
if (model.outputs.has("magnitudeImage")) { | ||
const magnitudeImageDownloadFormat = document.getElementById('magnitude-image-output-format') | ||
const downloadFormat = magnitudeImageDownloadFormat.value || 'nrrd' | ||
const fileName = `magnitudeImage.${downloadFormat}` | ||
const { webWorker, arrayBuffer } = await writeImageArrayBuffer(null, copyImage(model.outputs.get("magnitudeImage")), fileName) | ||
|
||
webWorker.terminate() | ||
globalThis.downloadFile(arrayBuffer, fileName) | ||
} | ||
}) | ||
|
||
const runButton = document.querySelector('#vectorMagnitudeInputs sl-button[name="run"]') | ||
runButton.addEventListener('click', async (event) => { | ||
event.preventDefault() | ||
|
||
if(!model.inputs.has('vectorImage')) { | ||
globalThis.notify("Required input not provided", "vectorImage", "danger", "exclamation-octagon") | ||
return | ||
} | ||
|
||
|
||
try { | ||
runButton.loading = true | ||
const t0 = performance.now() | ||
|
||
const { webWorker, magnitudeImage, } = await compareImages.vectorMagnitude(this.webWorker, | ||
model.inputs.get('vectorImage'), | ||
Object.fromEntries(model.options.entries()) | ||
) | ||
|
||
const t1 = performance.now() | ||
globalThis.notify("vectorMagnitude successfully completed", `in ${t1 - t0} milliseconds.`, "success", "rocket-fill") | ||
this.webWorker = webWorker | ||
|
||
model.outputs.set("magnitudeImage", magnitudeImage) | ||
magnitudeImageOutputDownload.variant = "success" | ||
magnitudeImageOutputDownload.disabled = false | ||
const magnitudeImageDetails = document.getElementById("vectorMagnitude-magnitude-image-details") | ||
magnitudeImageDetails.innerHTML = `<pre>${globalThis.escapeHtml(JSON.stringify(magnitudeImage, globalThis.interfaceTypeJsonReplacer, 2))}</pre>` | ||
magnitudeImageDetails.disabled = false | ||
const magnitudeImageOutput = document.getElementById('vectorMagnitude-magnitude-image-details') | ||
} catch (error) { | ||
globalThis.notify("Error while running pipeline", error.toString(), "danger", "exclamation-octagon") | ||
throw error | ||
} finally { | ||
runButton.loading = false | ||
} | ||
}) | ||
} | ||
} | ||
|
||
const vectorMagnitudeController = new VectorMagnitudeController(vectorMagnitudeLoadSampleInputs) |
21 changes: 21 additions & 0 deletions
21
...es/compare-images/typescript/test/browser/demo-app/vector-magnitude-load-sample-inputs.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Generated file. To retain edits, remove this comment. | ||
|
||
export default null | ||
// export default async function vectorMagnitudeLoadSampleInputs (model) { | ||
|
||
// Load sample inputs for the vectorMagnitude function. | ||
// | ||
// This function should load sample inputs: | ||
// | ||
// 1) In the provided model map. | ||
// 2) Into the corresponding HTML input elements. | ||
// | ||
// Example for an input named `exampleInput`: | ||
|
||
// const exampleInput = 5 | ||
// model.inputs.set("exampleInput", exampleInput) | ||
// const exampleElement = document.querySelector("#vectorMagnitudeInputs [name=example-input]") | ||
// exampleElement.value = 5 | ||
|
||
// return model | ||
// } |