Skip to content

Commit

Permalink
feat: Add merge labelmaps utility function
Browse files Browse the repository at this point in the history
  • Loading branch information
sedghi authored and swederik committed Mar 22, 2022
1 parent cd1535d commit 7278c72
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 3 deletions.
7 changes: 6 additions & 1 deletion packages/cornerstone-render/src/volumeLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ export function createAndCacheDerivedVolume(
*/
export function createAndCacheLocalVolume(
options: LocalVolumeOptions,
uid: string
uid: string,
preventCache = false
): ImageVolume {
const { scalarData, metadata, dimensions, spacing, origin, direction } =
options
Expand Down Expand Up @@ -360,6 +361,10 @@ export function createAndCacheLocalVolume(
sizeInBytes: numBytes,
})

if (preventCache) {
return derivedVolume
}

const volumeLoadObject = {
promise: Promise.resolve(derivedVolume),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { IImageVolume } from '@precisionmetrics/cornerstone-render/src/types'
import { createAndCacheLocalVolume } from '@precisionmetrics/cornerstone-render'
import isEqual from '../math/vec3/isEqual'

/**
* Given a list of labelmaps (with the possibility of overlapping regions),
* it generates a new labelmap with the same dimensions as the input labelmaps,
* by merging all the overlapping regions. This methods can be used
* to avoid double counting the segments in more than one labelmaps
*
* @param {} labelmaps
* @param {number} segmentIndex
* @returns {number} TMTV in ml
*/
function createMergedLabelmap(
labelmaps: Array<IImageVolume>,
segmentIndex = 1, // The segment index to use for the merged labelmap
uid = 'mergedLabelmap'
): IImageVolume {
labelmaps.forEach(({ direction, dimensions, origin, spacing }) => {
if (
!isEqual(dimensions, labelmaps[0].dimensions) ||
!isEqual(direction, labelmaps[0].direction) ||
!isEqual(spacing, labelmaps[0].spacing) ||
!isEqual(origin, labelmaps[0].origin)
) {
throw new Error('labelmaps must have the same size and shape')
}
})

const labelmap = labelmaps[0]

const arrayType = labelmap.scalarData.constructor
const outputData = new arrayType(labelmap.scalarData.length)

labelmaps.forEach((labelmap) => {
const { scalarData } = labelmap
for (let i = 0; i < scalarData.length; i++) {
if (scalarData[i] === segmentIndex) {
outputData[i] = segmentIndex
}
}
})

const options = {
scalarData: outputData,
metadata: labelmap.metadata,
spacing: labelmap.spacing,
origin: labelmap.origin,
direction: labelmap.direction,
dimensions: labelmap.dimensions,
}

const preventCache = true
const mergedVolume = createAndCacheLocalVolume(options, uid, preventCache)

return mergedVolume
}

export default createMergedLabelmap
3 changes: 3 additions & 0 deletions packages/cornerstone-tools/src/util/segmentation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import thresholdVolumeByRoiStats from './thresholdVolumeByRoiStats'
import triggerLabelmapRender from './triggerLabelmapRender'
import calculateSuvPeak from './calculateSuvPeak'
import calculateTMTV from './calculateTMTV'
import createMergedLabelmap from './createMergedLabelmap'

export {
getBoundingBoxAroundShape,
Expand All @@ -18,6 +19,7 @@ export {
triggerLabelmapRender,
calculateSuvPeak,
calculateTMTV,
createMergedLabelmap,
}

export default {
Expand All @@ -29,4 +31,5 @@ export default {
triggerLabelmapRender,
calculateSuvPeak,
calculateTMTV,
createMergedLabelmap,
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function thresholdVolumeByRange(
referenceVolumes: IImageVolume[],
labelmap: IImageVolume,
options: ThresholdRangeOptions
): void {
): IImageVolume {
if (referenceVolumes.length > 1) {
throw new Error('thresholding more than one volumes is not supported yet')
}
Expand Down Expand Up @@ -104,6 +104,7 @@ function thresholdVolumeByRange(
})

triggerLabelmapRender(renderingEngine, labelmap, labelmapImageData)
return labelmap
}

function worldToIndex(imageData, ain) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function thresholdVolumeByRoiStats(
referenceVolumes: IImageVolume[],
labelmap: IImageVolume,
options: ThresholdRoiStatsOptions
): void {
): IImageVolume {
if (referenceVolumes.length > 1) {
throw new Error('thresholding more than one volumes is not supported yet')
}
Expand Down Expand Up @@ -105,6 +105,7 @@ function thresholdVolumeByRoiStats(

// Run threshold volume by the new range
thresholdVolumeByRange(toolDataList, referenceVolumes, labelmap, rangeOptions)
return labelmap
}

function _worldToIndex(imageData, ain) {
Expand Down

0 comments on commit 7278c72

Please sign in to comment.