From 9fdf36bcf36feaa66611ec5ee7e568ef97204e96 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Mon, 21 Aug 2023 17:20:38 -0400 Subject: [PATCH] feat(compare-images): add compare-images.ts --- .../typescript/src/compare-images-node.ts | 33 ++----------- .../typescript/src/compare-images.ts | 46 +++++++++++++++++++ .../compare-images/typescript/src/index.ts | 3 ++ .../typescript/src/to-scalar-double.ts | 34 ++++++++++++++ 4 files changed, 87 insertions(+), 29 deletions(-) create mode 100644 packages/compare-images/typescript/src/compare-images.ts create mode 100644 packages/compare-images/typescript/src/to-scalar-double.ts diff --git a/packages/compare-images/typescript/src/compare-images-node.ts b/packages/compare-images/typescript/src/compare-images-node.ts index 46da0863e..edad51866 100644 --- a/packages/compare-images/typescript/src/compare-images-node.ts +++ b/packages/compare-images/typescript/src/compare-images-node.ts @@ -1,38 +1,13 @@ import { Image, - FloatTypes, - PixelTypes, - castImage, } from 'itk-wasm' import CompareDoubleImagesOptions from './compare-double-images-options.js' import CompareDoubleImagesNodeResult from './compare-double-images-node-result.js' import compareDoubleImagesNode from './compare-double-images-node.js' -import vectorMagnitudeNode from './vector-magnitude-node.js' - -async function _toScalarDouble(image: Image): Promise { - let scalarDouble = image - - if (scalarDouble.imageType.componentType !== FloatTypes.Float64) { - let pixelType = undefined - if (image.imageType.pixelType !== PixelTypes.Scalar && image.imageType.pixelType !== PixelTypes.VariableLengthVector) { - pixelType = PixelTypes.VariableLengthVector - } - scalarDouble = castImage(image, { componentType: FloatTypes.Float64, pixelType }) - } else { - if (image.imageType.pixelType !== PixelTypes.Scalar && image.imageType.pixelType !== PixelTypes.VariableLengthVector) { - const pixelType = PixelTypes.VariableLengthVector - scalarDouble = castImage(image, { pixelType }) - } - } - if (scalarDouble.imageType.pixelType === PixelTypes.VariableLengthVector) { - const magnitude = await vectorMagnitudeNode(scalarDouble) - scalarDouble = magnitude.magnitudeImage - } - - return scalarDouble -} +import toScalarDouble from './to-scalar-double.js' +import vectorMagnitudeNode from './vector-magnitude-node.js' /** * Compare images with a tolerance for regression testing. @@ -50,9 +25,9 @@ async function compareImagesNode( options: CompareDoubleImagesOptions = { baselineImages: [] as Image[], } ) : Promise { - const testImageDouble = await _toScalarDouble(testImage) + const testImageDouble = await toScalarDouble(vectorMagnitudeNode, testImage) const baselineImagesDouble = await Promise.all(options.baselineImages.map(async (image) => { - return await _toScalarDouble(image) + return await toScalarDouble(vectorMagnitudeNode, image) })) const otherOptions = { ...options } diff --git a/packages/compare-images/typescript/src/compare-images.ts b/packages/compare-images/typescript/src/compare-images.ts new file mode 100644 index 000000000..cbd0f6abd --- /dev/null +++ b/packages/compare-images/typescript/src/compare-images.ts @@ -0,0 +1,46 @@ +import { + Image, +} from 'itk-wasm' + +import CompareDoubleImagesOptions from './compare-double-images-options.js' +import CompareDoubleImagesResult from './compare-double-images-result.js' +import compareDoubleImages from './compare-double-images.js' + +import toScalarDouble from './to-scalar-double.js' +import vectorMagnitude from './vector-magnitude.js' + +/** + * Compare images with a tolerance for regression testing. + * + * For multi-component images, the intensity difference threshold + * is based on the pixel vector magnitude. + * + * @param {Image} testImage - The input test image + * @param {CompareDoubleImagesOptions} options - options object + * + * @returns {Promise} - result object + */ +async function compareImages( + webWorker: null | Worker, + testImage: Image, + options: CompareDoubleImagesOptions = { baselineImages: [] as Image[], } +) : Promise { + + async function vectorMagnitudeWorker(image: Image) { + const { webWorker: usedWebWorker, magnitudeImage } = await vectorMagnitude(null, image) + usedWebWorker?.terminate() + return { magnitudeImage } + } + + const testImageDouble = await toScalarDouble(vectorMagnitudeWorker, testImage) + const baselineImagesDouble = await Promise.all(options.baselineImages.map(async (image) => { + return await toScalarDouble(vectorMagnitudeWorker, image) + })) + + const otherOptions = { ...options } + otherOptions.baselineImages = baselineImagesDouble + + return compareDoubleImages(webWorker, testImageDouble, otherOptions) +} + +export default compareImages diff --git a/packages/compare-images/typescript/src/index.ts b/packages/compare-images/typescript/src/index.ts index c0b334cfd..1e59d0e4d 100644 --- a/packages/compare-images/typescript/src/index.ts +++ b/packages/compare-images/typescript/src/index.ts @@ -12,3 +12,6 @@ export type { CompareDoubleImagesOptions } import compareDoubleImages from './compare-double-images.js' export { compareDoubleImages } + +import compareImages from './compare-images.js' +export { compareImages } \ No newline at end of file diff --git a/packages/compare-images/typescript/src/to-scalar-double.ts b/packages/compare-images/typescript/src/to-scalar-double.ts new file mode 100644 index 000000000..c2a0bee5f --- /dev/null +++ b/packages/compare-images/typescript/src/to-scalar-double.ts @@ -0,0 +1,34 @@ +import { + Image, + FloatTypes, + PixelTypes, + castImage, +} from 'itk-wasm' + +import VectorMagnitudeNodeResult from './vector-magnitude-node-result' + +async function toScalarDouble(vectorMagnitudeFn: (img: Image) => Promise, image: Image): Promise { + let scalarDouble = image + + if (scalarDouble.imageType.componentType !== FloatTypes.Float64) { + let pixelType = undefined + if (image.imageType.pixelType !== PixelTypes.Scalar && image.imageType.pixelType !== PixelTypes.VariableLengthVector) { + pixelType = PixelTypes.VariableLengthVector + } + scalarDouble = castImage(image, { componentType: FloatTypes.Float64, pixelType }) + } else { + if (image.imageType.pixelType !== PixelTypes.Scalar && image.imageType.pixelType !== PixelTypes.VariableLengthVector) { + const pixelType = PixelTypes.VariableLengthVector + scalarDouble = castImage(image, { pixelType }) + } + } + + if (scalarDouble.imageType.pixelType === PixelTypes.VariableLengthVector) { + const magnitude = await vectorMagnitudeFn(scalarDouble) + scalarDouble = magnitude.magnitudeImage + } + + return scalarDouble +} + +export default toScalarDouble