Skip to content

Commit

Permalink
WIP: before rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
jadh4v committed Jul 25, 2024
1 parent a40def8 commit 25c9792
Show file tree
Hide file tree
Showing 16 changed files with 230 additions and 56 deletions.
2 changes: 1 addition & 1 deletion packages/dicom/dcmtk/read-overlapping-segmentation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ int runPipeline(

int main(int argc, char * argv[])
{
itk::wasm::Pipeline pipeline("read-overlapping-segmentation", "Read DICOM segmentation objects", argc, argv);
itk::wasm::Pipeline pipeline("read-overlapping-segmentation", "Read DICOM segmentation object with overlapping segments into a VectorImage.", argc, argv);

std::string dicomFileName;
pipeline.add_option("dicom-file", dicomFileName, "Input DICOM file")->required()->check(CLI::ExistingFile)->type_name("INPUT_BINARY_FILE");
Expand Down
6 changes: 3 additions & 3 deletions packages/dicom/dcmtk/write-multi-segmentation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ int runPipeline(

int main(int argc, char * argv[])
{
itk::wasm::Pipeline pipeline("write-multi-segmentation", "Write DICOM segmentation object using multiple input images", argc, argv);
itk::wasm::Pipeline pipeline("write-multi-segmentation", "Write DICOM segmentation object using multiple input images.", argc, argv);

//itk::wasm::InputImage<ScalarImageType> inputImage;
//pipeline.add_option("seg-image", inputImage, "dicom segmentation object as an image")->required()->type_name("INPUT_IMAGE");
Expand All @@ -226,7 +226,7 @@ int main(int argc, char * argv[])
pipeline.add_option("-i,--seg-images", segImageFiles, "List of input segmentation images." \
"image that was segmented.")->required()->check(CLI::ExistingFile)->expected(1,-1)->type_name("INPUT_BINARY_FILE");

bool skipEmptySlices{true};
bool skipEmptySlices{false};
pipeline.add_flag("-s,--skip-empty-slices", skipEmptySlices, "Skip empty slices while encoding segmentation image." \
"By default, empty slices will not be encoded, resulting in a smaller output file size.");

Expand All @@ -236,7 +236,7 @@ int main(int argc, char * argv[])

ITK_WASM_PARSE(pipeline);

runPipeline(
return runPipeline(
metaInfo,
refDicomSeriesFiles,
segImageFiles,
Expand Down
2 changes: 1 addition & 1 deletion packages/dicom/dcmtk/write-overlapping-segmentation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ int runPipeline(

int main(int argc, char * argv[])
{
itk::wasm::Pipeline pipeline("write-overlapping-segmentation", "Write DICOM segmentation object", argc, argv);
itk::wasm::Pipeline pipeline("write-overlapping-segmentation", "Write DICOM segmentation object for overlapping segments.", argc, argv);

itk::wasm::InputImage<VectorImageType> inputImage;
pipeline.add_option("seg-image", inputImage, "dicom segmentation object as an image")->required()->type_name("INPUT_IMAGE");
Expand Down
6 changes: 3 additions & 3 deletions packages/dicom/dcmtk/write-segmentation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ int runPipeline(

int main(int argc, char * argv[])
{
itk::wasm::Pipeline pipeline("write-segmentation", "Write DICOM segmentation object", argc, argv);
itk::wasm::Pipeline pipeline("write-segmentation", "Write DICOM segmentation object.", argc, argv);
// pipeline.set_version("2.0.0");

itk::wasm::InputImage<ScalarImageType> inputImage;
Expand All @@ -151,7 +151,7 @@ int main(int argc, char * argv[])
pipeline.add_option("-r,--ref-dicom-series", refDicomSeriesFiles, "List of DICOM files that correspond to the original." \
"image that was segmented.")->required()->check(CLI::ExistingFile)->expected(1,-1)->type_name("INPUT_BINARY_FILE");

bool skipEmptySlices{true};
bool skipEmptySlices{false};
pipeline.add_flag("-s,--skip-empty-slices", skipEmptySlices, "Skip empty slices while encoding segmentation image." \
"By default, empty slices will not be encoded, resulting in a smaller output file size.");

Expand All @@ -161,7 +161,7 @@ int main(int argc, char * argv[])

ITK_WASM_PARSE(pipeline);

runPipeline(
return runPipeline(
inputImage,
metaInfo,
refDicomSeriesFiles,
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions packages/dicom/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"itk-wasm": "workspace:^"
},
"devDependencies": {
"@itk-wasm/compare-images": "workspace:*",
"@itk-wasm/dicom-build": "workspace:*",
"@itk-wasm/image-io": "workspace:*",
"@itk-wasm/demo-app": "workspace:*",
Expand Down
237 changes: 212 additions & 25 deletions packages/dicom/typescript/test/node/dcmtk.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import {
readSegmentationNode,
writeOverlappingSegmentationNode,
writeSegmentationNode,
writeMultiSegmentationNode,
} from '../../dist/index-node.js'
import { readImageNode, writeImageNode } from '@itk-wasm/image-io'
// import { compareImageToBaseline } from 'cypress/support/compareImageToBaseline.js'
// /home/jadhav/code/itk-wasm/packages/dicom/typescript/cypress/support/compareImageToBaseline.ts
import { compareImagesNode, vectorMagnitudeNode, toScalarDouble } from '@itk-wasm/compare-images'
//import toScalarDouble from '@itk-wasm/compare-images/toScalarDouble';

function arrayEquals(a, b) {
return (a.length === b.length && a.every((val, idx) => val === b[idx]))
Expand Down Expand Up @@ -227,7 +228,9 @@ test('Apply presentation state to a dicom image.', async t => {
//t.assert(baselinePixels.data.length === outputImage.data.length)
//t.assert(Buffer.compare(baselinePixels.data, outputImage.data) === 0)
//})
*/

/*
test('DCMQI read DICOM segmentation object: scalar image', async t => {
const fileName = 'dicom-images/SEG/ReMIND-001/tumor_seg_MR_ref_3DSAGT2SPACE/1-1.dcm'
const testFilePath = path.join(testPathPrefix, fileName)
Expand All @@ -251,6 +254,7 @@ test('DCMQI read DICOM segmentation object: scalar image', async t => {
const baselineJsonObject = JSON.parse(baselineJsonFileBuffer)
t.assert(JSON.stringify(baselineJsonObject) === JSON.stringify(output.metaInfo))
})
*/

test('DCMQI read DICOM segmentation object (read-overlapping-segmentation)', async t => {
const fileName = 'dicom-images/SEG/ABDLYMPH001-abdominal-lymph-seg.dcm'
Expand All @@ -266,6 +270,7 @@ test('DCMQI read DICOM segmentation object (read-overlapping-segmentation)', asy
t.assert(arrayEquals(output.segImage.direction, [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]))
t.deepEqual(output.segImage.size, [ 512, 512, 69 ])
t.deepEqual(output.segImage.data.length, 72351744)
/*
t.deepEqual(output.segImage.imageType, {
dimension: 3,
componentType: 'int16',
Expand All @@ -279,8 +284,10 @@ test('DCMQI read DICOM segmentation object (read-overlapping-segmentation)', asy
const baselineJsonObject = JSON.parse(baselineJsonFileBuffer)
t.assert(JSON.stringify(baselineJsonObject) === JSON.stringify(output.metaInfo))
//await writeImageNode(output.segImage, outputPathPrefix + 'segVectorImage.nrrd');
*/
})

/*
test('DCMQI write DICOM segmentation object: non-overlapping labels', async t => {
const inputSegImageFile = path.join(testPathPrefix, 'dicom-images/SEG/ReMIND-001/tumor_seg_MR_ref_3DSAGT2SPACE.nrrd')
Expand Down Expand Up @@ -333,19 +340,24 @@ test('DCMQI write DICOM segmentation object: overlapping labels', async t => {
console.log('Exception while calling writeOverlappingSegmentationNode: ', error)
}
})
*/
/*
async function writeDoubleImage(image, filepath) {
const testImageDouble = await toScalarDouble(vectorMagnitudeNode, image);
await writeImageNode(testImageDouble, filepath);
}
await writeDoubleImage(output.segImage, outputPathPrefix + '/output_makeSeg_double.nrrd');
* /
// dcmqi native tests migrated to TypeScript:
// Path to test data from dcmqi is in its source dir
const dcmqi_lib_SOURCE_DIR = '../emscripten-build/_deps/dcmqi_lib-src'
const BASELINE = path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations')
const JSON_DIR = path.join(dcmqi_lib_SOURCE_DIR, '/doc/examples')
test('write-segmentation_makeSEG', async t => {
const inputSegImageFile = path.join(BASELINE,'/liver_seg.nrrd')
const inputSegImageFile = path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/liver_seg.nrrd')
const inputSegImage = await readImageNode(inputSegImageFile)
t.assert(inputSegImage)
const metaInfoFile = path.join(JSON_DIR, '/seg-example.json')
const metaInfoFile = path.join(dcmqi_lib_SOURCE_DIR, 'doc/examples/seg-example.json')
const jsonFileBuffer = fs.readFileSync(metaInfoFile)
const jsonObject = JSON.parse(jsonFileBuffer)
const outputDicomFile = path.join(outputPathPrefix,'liver-seg.dcm')
Expand All @@ -362,27 +374,202 @@ test('write-segmentation_makeSEG', async t => {
console.log('Exception while calling writeSegmentationNode: ', error)
}
console.log('now read back the liver-seg.dcm')
// Now read back the liver-seg.dcm file and compare with original nrrd.
const output = await readSegmentationNode(outputDicomFile)
t.assert(output.segImage)
t.assert(output.metaInfo)
compareImageToBaseline(t, output.segImage, inputSegImage)
try {
const r1 = await compareImagesNode(
inputSegImage, {
baselineImages: [output.segImage],
spatialTolerance: 0.0001,
})
t.assert(r1)
t.assert(r1 && r1.metrics)
t.assert(r1.metrics.almostEqual)
t.assert(r1.metrics.maximumDifference < 1e-8)
}
catch (error) {
console.log('Exception while calling compareImagesNode: ', error)
}
})
test('write-multi-segmentation_makeSEG_merged', async t => {
const segImages = [
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/partial_overlaps-1.nrrd'),
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/partial_overlaps-2.nrrd'),
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/partial_overlaps-3.nrrd'),
]
const metaInfoFile = path.join(dcmqi_lib_SOURCE_DIR, 'doc/examples/seg-example_partial_overlaps.json')
const jsonFileBuffer = fs.readFileSync(metaInfoFile)
const jsonObject = JSON.parse(jsonFileBuffer)
const outputDicomFile = path.join(outputPathPrefix,'partial_overlaps-output.dcm')
const dcmSeries = [
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/01.dcm'),
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/02.dcm'),
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/03.dcm'),
]
try{
const writeOutput = await writeMultiSegmentationNode(jsonObject, outputDicomFile, {
refDicomSeries: dcmSeries,
segImages,
useLabelidAsSegmentnumber: true
})
t.assert(writeOutput != null)
}
catch (error) {
console.log('Exception while calling writeMultiSegmentationNode: ', error)
}
// Now read back the liver-seg.dcm file and compare with original nrrd.
console.log('Now read back the partial_overlaps-output.dcm file and compare with original nrrd')
const readOutput = await readOverlappingSegmentationNode(outputDicomFile)
t.assert(readOutput.segImage)
t.assert(readOutput.metaInfo)
/*
console.log('JSON.stringify(readOutput.metaInfo) = ', JSON.stringify(readOutput.metaInfo))
console.log('JSON.stringify(jsonObject)) = ', JSON.stringify(jsonObject))
t.deepEqual(JSON.stringify(readOutput.metaInfo) === JSON.stringify(jsonObject))
t.assert(JSON.stringify(readOutput.metaInfo) === JSON.stringify(jsonObject))
const r1 = await compareImagesNode(
inputSegImage, {
baselineImages: [readOutput.segImage],
spatialTolerance: 0.000001,
})
t.assert(r1)
t.assert(r1 && r1.metrics)
t.assert(r1.metrics.almostEqual)
t.assert(r1.metrics.maximumDifference < 1e-8)
* /
})
test('write-multi-segmentation_makeSEG_multiple_segment_files', async t => {
const segImages = [
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/liver_seg.nrrd'),
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/spine_seg.nrrd'),
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/heart_seg.nrrd'),
]
const metaInfoFile = path.join(dcmqi_lib_SOURCE_DIR, 'doc/examples/seg-example_multiple_segments.json')
const jsonFileBuffer = fs.readFileSync(metaInfoFile)
const jsonObject = JSON.parse(jsonFileBuffer)
const outputDicomFile = path.join(outputPathPrefix,'liver_heart_seg.dcm')
const dcmSeries = [
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/01.dcm'),
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/02.dcm'),
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/03.dcm'),
]
try {
const writeOutput = await writeMultiSegmentationNode(jsonObject, outputDicomFile, {
refDicomSeries: dcmSeries,
segImages,
//useLabelidAsSegmentnumber: true
})
t.assert(writeOutput != null)
}
catch (error) {
console.log('Exception while calling writeMultiSegmentationNode: ', error)
}
// Now read back the liver-seg.dcm file and compare with original nrrd.
const readOutput = await readOverlappingSegmentationNode(outputDicomFile)
t.assert(readOutput.segImage)
t.assert(readOutput.metaInfo)
/*
dcmqi_add_test(
NAME ${dcm2itk}_makeNRRD
MODULE_NAME ${MODULE_NAME}
COMMAND $<TARGET_FILE:${dcm2itk}Test>
--compare ${BASELINE}/liver_seg.nrrd
${MODULE_TEMP_DIR}/makeNRRD-1.nrrd
${dcm2itk}Test
--inputDICOM ${MODULE_TEMP_DIR}/liver.dcm
--outputDirectory ${MODULE_TEMP_DIR}
--outputType nrrd
--prefix makeNRRD
TEST_DEPENDS
${itk2dcm}_makeSEG
)
*/

})
const r1 = await compareImagesNode(
readOutput.segImage, {
baselineImages: [readOutput.segImage],
spatialTolerance: 0.000001,
})
t.assert(r1)
t.assert(r1 && r1.metrics)
t.assert(r1.metrics.almostEqual)
t.assert(r1.metrics.maximumDifference < 1e-8)
* /
})
test('write-multi-segmentation_makeSEG_multiple_segment_files_reordered', async t => {
const segImages = [
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/heart_seg.nrrd'),
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/liver_seg.nrrd'),
path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations/spine_seg.nrrd'),
]
const metaInfoFile = path.join(dcmqi_lib_SOURCE_DIR, 'doc/examples/seg-example_multiple_segments_reordered.json')
const jsonFileBuffer = fs.readFileSync(metaInfoFile)
const jsonObject = JSON.parse(jsonFileBuffer)
const outputDicomFile = path.join(outputPathPrefix,'liver_heart_seg_reordered.dcm')
const dcmSeries = [
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/01.dcm'),
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/02.dcm'),
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/ct-3slice/03.dcm'),
]
try {
const writeOutput = await writeMultiSegmentationNode(jsonObject, outputDicomFile, {
refDicomSeries: dcmSeries,
segImages,
useLabelidAsSegmentnumber: true
})
t.assert(writeOutput != null)
} catch (error) {
console.log('Exception while calling writeMultiSegmentationNode: ', error)
}
// Now read back the liver-seg.dcm file and compare with original nrrd.
const readOutput = await readOverlappingSegmentationNode(outputDicomFile)
t.assert(readOutput.segImage)
t.assert(readOutput.metaInfo)
//const r1 = await compareImagesNode(
// inputSegImage, {
// baselineImages: [readOutput.segImage],
// spatialTolerance: 0.000001,
//})
//t.assert(r1)
//t.assert(r1 && r1.metrics)
//t.assert(r1.metrics.almostEqual)
//t.assert(r1.metrics.maximumDifference < 1e-8)
})
test('itk2dcm_makeSEG_seg_size', async t => {
//['24x38x3', '23x38x3'].forEach(async (seg_size) =>
for (const seg_size of ['24x38x3', '23x38x3']) {
const jsonObject = JSON.parse(fs.readFileSync(path.join(dcmqi_lib_SOURCE_DIR, 'doc/examples/seg-example.json')))
const inputSegImageFile = path.join(dcmqi_lib_SOURCE_DIR, 'data/segmentations', `${seg_size}/nrrd/label.nrrd`)
const inputSegImage = await readImageNode(inputSegImageFile)
const dcmSeries = [
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/',`${seg_size}/image/IMG0001.dcm`),
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/',`${seg_size}/image/IMG0002.dcm`),
path.join(dcmqi_lib_SOURCE_DIR, '/data/segmentations/',`${seg_size}/image/IMG0003.dcm`),
]
const outputDicomFile = path.join(outputPathPrefix, `${seg_size}_seg.dcm`)
const writeOutput = await writeSegmentationNode(inputSegImage, jsonObject, outputDicomFile, {
refDicomSeries: dcmSeries,
skipEmptySlices: false,
useLabelidAsSegmentnumber: true
})
t.assert(writeOutput != null)
// Now read back the liver-seg.dcm file and compare with original nrrd.
const readOutput = await readSegmentationNode(outputDicomFile)
t.assert(readOutput.segImage)
t.assert(readOutput.metaInfo)
// console.log('inputSegImage: ', inputSegImage)
// console.log('readOutput.segImage: ', readOutput.segImage)
const r1 = await compareImagesNode(
inputSegImage, {
baselineImages: [readOutput.segImage],
spatialTolerance: 0.00001,
})
t.assert(r1)
t.assert(r1 && r1.metrics)
t.assert(r1.metrics.almostEqual)
t.assert(r1.metrics.maximumDifference < 1e-8)
}
})
*/
Loading

0 comments on commit 25c9792

Please sign in to comment.