Update wiki with new screenshots (OHIF-56). Add lossy compression ratio, slice location / thickness / spacing to viewport annotation
This commit is contained in:
parent
87cc2a5bc0
commit
5c41556965
@ -12,15 +12,18 @@ var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
|
||||
return {
|
||||
0x0020000D: studyInstanceUID ? studyInstanceUID : '',
|
||||
0x0020000E: (studyInstanceUID && seriesInstanceUID) ? seriesInstanceUID : '',
|
||||
0x00080005: '',
|
||||
0x00080020: '',
|
||||
0x00080030: '',
|
||||
0x00080090: '',
|
||||
0x00100010: '',
|
||||
0x00100020: '',
|
||||
0x00200010: '',
|
||||
0x0008103E: '',
|
||||
0x00200011: '',
|
||||
0x00080005: '', // specificCharacterSet
|
||||
0x00080020: '', // studyDate
|
||||
0x00080030: '', // studyDescription
|
||||
0x00080090: '', // referringPhysicianName
|
||||
0x00100010: '', // patientName
|
||||
0x00100020: '', // patientId
|
||||
0x00100030: '', // patientBirthDate
|
||||
0x00100040: '', // patientSex
|
||||
0x00200010: '', // studyId
|
||||
0x0008103E: '', // seriesDescription
|
||||
0x00200011: '', // seriesNumber
|
||||
0x00080080: '', // institutionName
|
||||
0x00080016: '', // sopClassUid
|
||||
0x00080018: '', // sopInstanceUid
|
||||
0x00080060: '', // modality
|
||||
@ -37,7 +40,9 @@ var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
|
||||
0x00281052: '', // rescaleIntercept
|
||||
0x00281053: '', // rescaleSlope
|
||||
0x00280002: '', // samplesPerPixel
|
||||
0x00180050: '', // sliceThickness
|
||||
0x00201041: '', // sliceLocation
|
||||
0x00189327: '', // tablePosition
|
||||
0x00281050: '', // windowCenter
|
||||
0x00281051: '', // windowWidth
|
||||
0x00280030: '', // pixelSpacing
|
||||
@ -47,9 +52,14 @@ var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
|
||||
0x00200032: '', // imagePositionPatient
|
||||
0x00200037: '', // imageOrientationPatient
|
||||
0x00200052: '', // frameOfReferenceUID
|
||||
0x00282110: '', // lossyImageCompression
|
||||
0x00282112: '', // lossyImageCompressionRatio
|
||||
0x00282114: '', // lossyImageCompressionMethod,
|
||||
0x00180088: '' // spacingBetweenSlices
|
||||
|
||||
// Orthanc has a bug here so we can't retrieve sequences at the moment
|
||||
// https://groups.google.com/forum/#!topic/orthanc-users/ghKJfvtnK8Y
|
||||
//0x00282111: '', // derivationDescription
|
||||
//0x00082112: '' // sourceImageSequence
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template name="lesionTrackerViewportOverlay">
|
||||
<div class="imageViewerViewportOverlay noselect">
|
||||
<div class="imageViewerViewportOverlay noselect {{#if gt numImages 1}}controlsVisible{{/if}}">
|
||||
<div class="topleft dicomTag">
|
||||
<div>{{formatPN patientName}}</div>
|
||||
<div>{{patientId}}</div>
|
||||
@ -16,11 +16,13 @@
|
||||
</div>
|
||||
<div class="bottomleft dicomTag">
|
||||
<div>Ser: {{seriesNumber}}</div>
|
||||
<div>Img: {{imageNumber}} ({{imageIndex}}/{{numImages}})</div>
|
||||
<div>{{#if gt numImages 1}}Img: {{instanceNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||
<div>{{frameRate}}</div>
|
||||
<div>{{imageDimensions}}</div>
|
||||
<div>{{seriesDescription}}</div>
|
||||
</div>
|
||||
{{>imageControls}}
|
||||
{{#if gt numImages 1}}
|
||||
{{> imageControls imageIndex=imageIndex numImages=numImages}}
|
||||
{{ /if }}
|
||||
</div>
|
||||
</template>
|
||||
@ -17,9 +17,13 @@
|
||||
</div>
|
||||
<div class="bottomleft dicomTag">
|
||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
||||
<div>{{#if gt numImages 1}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||
<div>{{#if gt numImages 1}}Img: {{instanceNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||
<div>{{imageDimensions}}</div>
|
||||
<div>{{#if location}}Loc: {{location}} mm{{/if}}
|
||||
{{#if thickness}}Thick: {{thickness}} mm{{/if}}
|
||||
{{#if spacingBetweenSlices}}Spacing: {{spacingBetweenSlices}} mm{{/if}}
|
||||
</div>
|
||||
<div>{{seriesDescription}}</div>
|
||||
</div>
|
||||
{{ /unless }}
|
||||
@ -34,7 +38,7 @@
|
||||
</div>
|
||||
<div class="bottomright dicomTag">
|
||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
||||
<div>{{#if gt numImages 1}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||
<div>{{#if gt numImages 1}}Img: {{instanceNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||
<div>{{imageDimensions}}</div>
|
||||
<div>{{seriesDescription}}</div>
|
||||
@ -54,7 +58,7 @@
|
||||
</div>
|
||||
<div class="bottomleft dicomTag">
|
||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
||||
<div>{{#if gt numImages 1}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||
<div>{{#if gt numImages 1}}Img: {{instanceNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||
<div>{{imageDimensions}}</div>
|
||||
<div>{{seriesDescription}}</div>
|
||||
|
||||
@ -180,6 +180,12 @@ Template.viewportOverlay.helpers({
|
||||
patientId: function() {
|
||||
return getPatient.call(this, 'id');
|
||||
},
|
||||
patientBirthDate: function() {
|
||||
return getPatient.call(this, 'birthDate');
|
||||
},
|
||||
patientSex: function() {
|
||||
return getPatient.call(this, 'sex');
|
||||
},
|
||||
studyDate: function() {
|
||||
return getStudy.call(this, 'studyDate');
|
||||
},
|
||||
@ -204,9 +210,67 @@ Template.viewportOverlay.helpers({
|
||||
seriesNumber: function() {
|
||||
return getSeries.call(this, 'seriesNumber');
|
||||
},
|
||||
imageNumber: function() {
|
||||
instanceNumber: function() {
|
||||
return getInstance.call(this, 'instanceNumber');
|
||||
},
|
||||
thickness() {
|
||||
// Displays Slice Thickness (0018,0050)
|
||||
return getInstance.call(this, 'sliceThickness');
|
||||
},
|
||||
|
||||
location() {
|
||||
// Displays Slice Location (0020,1041), if present.
|
||||
// - Otherwise, displays Table Position (0018,9327)
|
||||
// - TODO: Otherwise, displays a value derived from Image Position (Patient) (0020,0032)
|
||||
const sliceLocation = getInstance.call(this, 'sliceLocation');
|
||||
if (sliceLocation !== '') {
|
||||
return sliceLocation;
|
||||
}
|
||||
|
||||
const tablePosition = getInstance.call(this, 'tablePosition');
|
||||
if (tablePosition !== '') {
|
||||
return tablePosition;
|
||||
}
|
||||
|
||||
return getInstance.call(this, 'imagePositionPatient');
|
||||
},
|
||||
|
||||
spacingBetweenSlices() {
|
||||
// Displays Spacing Between Slices (0018,0088), if present.
|
||||
|
||||
// TODO: Otherwise, displays a value derived from successive values
|
||||
// of Image Position (Patient) (0020,0032) perpendicular to
|
||||
// the Image Orientation (Patient) (0020,0037)
|
||||
return getInstance.call(this, 'spacingBetweenSlices');
|
||||
},
|
||||
|
||||
compression() {
|
||||
// Displays whether or not lossy compression has been applied:
|
||||
//
|
||||
// - Checks Lossy Image Compression (0028,2110)
|
||||
// - If so, displays the value of Lossy Image Compression Ratio (0028,2112)
|
||||
// and Lossy Image Compression Method (0028,2114)
|
||||
|
||||
Session.get('CornerstoneNewImage' + this.viewportIndex);
|
||||
if (!this.imageId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var instance = cornerstoneTools.metaData.get('instance', this.imageId);
|
||||
if (!instance) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (instance.lossyImageCompression === '01' &&
|
||||
instance.lossyImageCompressionRatio !== '') {
|
||||
const compressionMethod = instance.lossyImageCompressionMethod || 'Lossy: ';
|
||||
const compressionRatio = parseFloat(instance.lossyImageCompressionRatio).toFixed(2);
|
||||
return compressionMethod + compressionRatio + ' : 1';
|
||||
}
|
||||
|
||||
return 'Lossless / Uncompressed';
|
||||
},
|
||||
|
||||
tagDisplayLeftOnly: function() {
|
||||
return getTagDisplay.call(this, 'side') === 'L';
|
||||
},
|
||||
@ -216,9 +280,6 @@ Template.viewportOverlay.helpers({
|
||||
tagDisplaySpecified: function() {
|
||||
return getTagDisplay.call(this, 'side');
|
||||
},
|
||||
imageIndex: function() {
|
||||
return getInstance.call(this, 'index');
|
||||
},
|
||||
imageIndex: function() {
|
||||
Session.get('CornerstoneNewImage' + this.viewportIndex);
|
||||
var stack = getStackDataIfNotEmpty(this.viewportIndex);
|
||||
|
||||
@ -26,7 +26,8 @@ addMetaData = function(imageId, data) {
|
||||
studyInstanceUid: studyMetaData.studyInstanceUid,
|
||||
studyDate: studyMetaData.studyDate,
|
||||
studyTime: studyMetaData.studyTime,
|
||||
studyDescription: studyMetaData.studyDescription
|
||||
studyDescription: studyMetaData.studyDescription,
|
||||
institutionName: studyMetaData.institutionName
|
||||
};
|
||||
|
||||
metaData.series = {
|
||||
@ -37,23 +38,13 @@ addMetaData = function(imageId, data) {
|
||||
numImages: numImages
|
||||
};
|
||||
|
||||
metaData.instance = {
|
||||
wadouri: instanceMetaData.wadouri,
|
||||
imageType: instanceMetaData.imageType,
|
||||
photometricInterpretation: instanceMetaData.photometricInterpretation,
|
||||
sopInstanceUid: instanceMetaData.sopInstanceUid,
|
||||
sopClassUid: instanceMetaData.sopClassUid,
|
||||
instanceNumber: instanceMetaData.instanceNumber,
|
||||
laterality: instanceMetaData.laterality,
|
||||
viewPosition: instanceMetaData.viewPosition,
|
||||
sliceThickness: instanceMetaData.sliceThickness,
|
||||
frameTime: instanceMetaData.frameTime,
|
||||
index: imageIndex
|
||||
};
|
||||
metaData.instance = instanceMetaData;
|
||||
|
||||
metaData.patient = {
|
||||
name: studyMetaData.patientName,
|
||||
id: studyMetaData.patientId
|
||||
id: studyMetaData.patientId,
|
||||
birthDate: studyMetaData.patientBirthDate,
|
||||
sex: studyMetaData.patientSex
|
||||
};
|
||||
|
||||
// If there is sufficient information, populate
|
||||
|
||||
@ -43,12 +43,15 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
||||
seriesList: seriesList,
|
||||
patientName: anInstance[0x00100010],
|
||||
patientId: anInstance[0x00100020],
|
||||
patientBirthDate: anInstance[0x00100030],
|
||||
patientSex: anInstance[0x00100040],
|
||||
accessionNumber: anInstance[0x00080050],
|
||||
studyDate: anInstance[0x00080020],
|
||||
modalities: anInstance[0x00080061],
|
||||
studyDescription: anInstance[0x00081030],
|
||||
imageCount: anInstance[0x00201208],
|
||||
studyInstanceUid: anInstance[0x0020000D]
|
||||
studyInstanceUid: anInstance[0x0020000D],
|
||||
institutionName: anInstance[0x00080080]
|
||||
};
|
||||
|
||||
resultData.forEach(function(instanceRaw) {
|
||||
@ -78,7 +81,9 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
||||
imagePositionPatient: instance[0x00200032],
|
||||
imageOrientationPatient: instance[0x00200037],
|
||||
frameOfReferenceUID: instance[0x00200052],
|
||||
sliceThickness: parseFloat(instance[0x00180050]),
|
||||
sliceLocation: parseFloat(instance[0x00201041]),
|
||||
tablePosition: parseFloat(instance[0x00189327]),
|
||||
samplesPerPixel: parseFloat(instance[0x00280002]),
|
||||
photometricInterpretation: instance[0x00280004],
|
||||
rows: parseFloat(instance[0x00280010]),
|
||||
@ -96,7 +101,12 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
||||
laterality: instance[0x00200062],
|
||||
viewPosition: instance[0x00185101],
|
||||
numFrames: parseFloat(instance[0x00280008]),
|
||||
frameTime: parseFloat(instance[0x00181063])
|
||||
frameTime: parseFloat(instance[0x00181063]),
|
||||
lossyImageCompression: instance[0x00282110],
|
||||
derivationDescription: instance[0x00282111],
|
||||
lossyImageCompressionRatio: instance[0x00282112],
|
||||
lossyImageCompressionMethod: instance[0x00282114],
|
||||
spacingBetweenSlices: instance[0x00180088]
|
||||
};
|
||||
|
||||
// Retrieve the actual data over WADO-URI
|
||||
|
||||
@ -59,7 +59,8 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
||||
modalities: DICOMWeb.getString(anInstance['00080061']),
|
||||
studyDescription: DICOMWeb.getString(anInstance['00081030']),
|
||||
imageCount: DICOMWeb.getString(anInstance['00201208']),
|
||||
studyInstanceUid: DICOMWeb.getString(anInstance['0020000D'])
|
||||
studyInstanceUid: DICOMWeb.getString(anInstance['0020000D']),
|
||||
institutionName: DICOMWeb.getString(anInstance['00080080'])
|
||||
};
|
||||
|
||||
resultData.forEach(function(instance) {
|
||||
@ -107,7 +108,11 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
||||
viewPosition: DICOMWeb.getString(instance['00185101']),
|
||||
numFrames: DICOMWeb.getNumber(instance['00280008']),
|
||||
frameTime: DICOMWeb.getNumber(instance['00181063']),
|
||||
sliceThickness: DICOMWeb.getNumber(instance['00180050'])
|
||||
sliceThickness: DICOMWeb.getNumber(instance['00180050']),
|
||||
lossyImageCompression: DICOMWeb.getString(instance['00282110']),
|
||||
derivationDescription: DICOMWeb.getString(instance['00282111']),
|
||||
lossyImageCompressionRatio: DICOMWeb.getString(instance['00282112']),
|
||||
lossyImageCompressionMethod: DICOMWeb.getString(instance['00282114']),
|
||||
};
|
||||
|
||||
if (server.imageRendering === 'wadouri') {
|
||||
|
||||
BIN
img/viewer.png
BIN
img/viewer.png
Binary file not shown.
|
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 662 KiB |
BIN
img/worklist.png
BIN
img/worklist.png
Binary file not shown.
|
Before Width: | Height: | Size: 254 KiB After Width: | Height: | Size: 277 KiB |
Loading…
Reference in New Issue
Block a user