fix: Ensure we take into account pixel spacing fields properly (#1555)
* fix: Ensure we take into account pixel spacing fields properly * Rename to getPixelSpacingInformation
This commit is contained in:
parent
1c306dd243
commit
77ab0ad9a1
@ -1,7 +1,7 @@
|
|||||||
import * as dcmjs from 'dcmjs';
|
import * as dcmjs from 'dcmjs';
|
||||||
import queryString from 'query-string';
|
import queryString from 'query-string';
|
||||||
import dicomParser from 'dicom-parser';
|
import dicomParser from 'dicom-parser';
|
||||||
import { getFallbackTagFromInstance } from '../utils/metadataProvider/metadataProviderFallbackTags';
|
import getPixelSpacingInformation from '../utils/metadataProvider/getPixelSpacingInformation';
|
||||||
import fetchPaletteColorLookupTableData from '../utils/metadataProvider/fetchPaletteColorLookupTableData';
|
import fetchPaletteColorLookupTableData from '../utils/metadataProvider/fetchPaletteColorLookupTableData';
|
||||||
import fetchOverlayData from '../utils/metadataProvider/fetchOverlayData';
|
import fetchOverlayData from '../utils/metadataProvider/fetchOverlayData';
|
||||||
|
|
||||||
@ -161,18 +161,6 @@ class MetadataProvider {
|
|||||||
return instance[naturalizedTagOrWADOImageLoaderTag];
|
return instance[naturalizedTagOrWADOImageLoaderTag];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.fallback) {
|
|
||||||
// Perhaps the tag has fallbacks?
|
|
||||||
const fallbackTag = getFallbackTagFromInstance(
|
|
||||||
naturalizedTagOrWADOImageLoaderTag,
|
|
||||||
instance
|
|
||||||
);
|
|
||||||
|
|
||||||
if (fallbackTag) {
|
|
||||||
return fallbackTag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maybe its a legacy CornerstoneWADOImageLoader tag then:
|
// Maybe its a legacy CornerstoneWADOImageLoader tag then:
|
||||||
return this._getCornerstoneWADOImageLoaderTag(
|
return this._getCornerstoneWADOImageLoaderTag(
|
||||||
naturalizedTagOrWADOImageLoaderTag,
|
naturalizedTagOrWADOImageLoaderTag,
|
||||||
@ -218,10 +206,9 @@ class MetadataProvider {
|
|||||||
const { ImageOrientationPatient } = instance;
|
const { ImageOrientationPatient } = instance;
|
||||||
|
|
||||||
// Fallback for DX images.
|
// Fallback for DX images.
|
||||||
const PixelSpacing = getFallbackTagFromInstance(
|
// TODO: We should use the rest of the results of this function
|
||||||
'PixelSpacing',
|
// to update the UI somehow
|
||||||
instance
|
const { PixelSpacing } = getPixelSpacingInformation(instance);
|
||||||
);
|
|
||||||
|
|
||||||
let rowPixelSpacing;
|
let rowPixelSpacing;
|
||||||
let columnPixelSpacing;
|
let columnPixelSpacing;
|
||||||
|
|||||||
@ -0,0 +1,90 @@
|
|||||||
|
import log from '../../log';
|
||||||
|
|
||||||
|
export default function getPixelSpacingInformation(instance) {
|
||||||
|
// See http://gdcm.sourceforge.net/wiki/index.php/Imager_Pixel_Spacing
|
||||||
|
|
||||||
|
// TODO: Add Ultrasound region spacing
|
||||||
|
// TODO: Add manual calibration
|
||||||
|
|
||||||
|
// TODO: Use ENUMS from dcmjs
|
||||||
|
const projectionRadiographSOPClassUIDs = [
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1', // CR Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.1', // Digital X-Ray Image Storage – for Presentation
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.1.1', // Digital X-Ray Image Storage – for Processing
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.2', // Digital Mammography X-Ray Image Storage – for Presentation
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.2.1', // Digital Mammography X-Ray Image Storage – for Processing
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.3', // Digital Intra – oral X-Ray Image Storage – for Presentation
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.3.1', // Digital Intra – oral X-Ray Image Storage – for Processing
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.1', // X-Ray Angiographic Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.1.1', // Enhanced XA Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.2', // X-Ray Radiofluoroscopic Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.2.1', // Enhanced XRF Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.3' // X-Ray Angiographic Bi-plane Image Storage Retired
|
||||||
|
];
|
||||||
|
|
||||||
|
const { PixelSpacing, ImagerPixelSpacing, SOPClassUID, PixelSpacingCalibrationType, PixelSpacingCalibrationDescription, EstimatedRadiographicMagnificationFactor } = instance;
|
||||||
|
const isProjection = projectionRadiographSOPClassUIDs.includes(SOPClassUID);
|
||||||
|
|
||||||
|
const TYPES = {
|
||||||
|
NOT_APPLICABLE: 'NOT_APPLICABLE',
|
||||||
|
UNKNOWN: 'UNKNOWN',
|
||||||
|
CALIBRATED: 'CALIBRATED',
|
||||||
|
DETECTOR: 'DETECTOR'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isProjection === false && !ImagerPixelSpacing) {
|
||||||
|
// If only Pixel Spacing is present, and this is not a projection radiograph,
|
||||||
|
// we can stop here
|
||||||
|
return {
|
||||||
|
PixelSpacing,
|
||||||
|
type: TYPES.NOT_APPLICABLE,
|
||||||
|
isProjection
|
||||||
|
};
|
||||||
|
} else if (isProjection && !ImagerPixelSpacing) {
|
||||||
|
// If only Pixel Spacing is present, and this is a projection radiograph,
|
||||||
|
// PixelSpacing should be used, but the user should be informed that
|
||||||
|
// what it means is unknown
|
||||||
|
return {
|
||||||
|
PixelSpacing,
|
||||||
|
type: TYPES.UNKNOWN,
|
||||||
|
isProjection
|
||||||
|
};
|
||||||
|
} else if (PixelSpacing && ImagerPixelSpacing && PixelSpacing === ImagerPixelSpacing) {
|
||||||
|
// If Imager Pixel Spacing and Pixel Spacing are present and they have the same values,
|
||||||
|
// then the user should be informed that the measurements are at the detector plane
|
||||||
|
return {
|
||||||
|
PixelSpacing,
|
||||||
|
type: TYPES.DETECTOR,
|
||||||
|
isProjection
|
||||||
|
};
|
||||||
|
} else if (PixelSpacing && ImagerPixelSpacing && PixelSpacing !== ImagerPixelSpacing) {
|
||||||
|
// If Imager Pixel Spacing and Pixel Spacing are present and they have different values,
|
||||||
|
// then the user should be informed that these are "calibrated"
|
||||||
|
// (in some unknown manner if Pixel Spacing Calibration Type and/or
|
||||||
|
// Pixel Spacing Calibration Description are absent)
|
||||||
|
return {
|
||||||
|
PixelSpacing,
|
||||||
|
type: TYPES.CALIBRATED,
|
||||||
|
isProjection,
|
||||||
|
PixelSpacingCalibrationType,
|
||||||
|
PixelSpacingCalibrationDescription
|
||||||
|
};
|
||||||
|
} else if (!PixelSpacing && ImagerPixelSpacing) {
|
||||||
|
let CorrectedImagerPixelSpacing = ImagerPixelSpacing;
|
||||||
|
if (EstimatedRadiographicMagnificationFactor) {
|
||||||
|
// Note that in IHE Mammo profile compliant displays, the value of Imager Pixel Spacing is required to be corrected by
|
||||||
|
// Estimated Radiographic Magnification Factor and the user informed of that.
|
||||||
|
// TODO: should this correction be done before all of this logic?
|
||||||
|
CorrectedImagerPixelSpacing = ImagerPixelSpacing.map(pixelSpacing => pixelSpacing / EstimatedRadiographicMagnificationFactor);
|
||||||
|
} else {
|
||||||
|
log.info('EstimatedRadiographicMagnificationFactor was not present. Unable to correct ImagerPixelSpacing.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
PixelSpacing: CorrectedImagerPixelSpacing,
|
||||||
|
isProjection,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info('Unknown combination of PixelSpacing and ImagerPixelSpacing identified. Unable to determine spacing.');
|
||||||
|
}
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import log from '../../log';
|
|
||||||
|
|
||||||
function getFallbackTagFromInstance(tag, instance) {
|
|
||||||
if (instance[tag]) {
|
|
||||||
return instance[tag];
|
|
||||||
}
|
|
||||||
|
|
||||||
const fallbackTags = fallbackTagsMap[tag];
|
|
||||||
|
|
||||||
if (fallbackTags) {
|
|
||||||
for (let i = 0; i < fallbackTags.length; i++) {
|
|
||||||
const fallbackTag = fallbackTags[i];
|
|
||||||
|
|
||||||
if (instance[fallbackTag]) {
|
|
||||||
log.info(`metadata provider fallback tag ${tag} to ${fallbackTag}`);
|
|
||||||
|
|
||||||
return instance[fallbackTag];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const fallbackTagsMap = {
|
|
||||||
PixelSpacing: ['ImagerPixelSpacing'],
|
|
||||||
};
|
|
||||||
|
|
||||||
export { fallbackTagsMap, getFallbackTagFromInstance };
|
|
||||||
Loading…
Reference in New Issue
Block a user