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 {
|
return {
|
||||||
0x0020000D: studyInstanceUID ? studyInstanceUID : '',
|
0x0020000D: studyInstanceUID ? studyInstanceUID : '',
|
||||||
0x0020000E: (studyInstanceUID && seriesInstanceUID) ? seriesInstanceUID : '',
|
0x0020000E: (studyInstanceUID && seriesInstanceUID) ? seriesInstanceUID : '',
|
||||||
0x00080005: '',
|
0x00080005: '', // specificCharacterSet
|
||||||
0x00080020: '',
|
0x00080020: '', // studyDate
|
||||||
0x00080030: '',
|
0x00080030: '', // studyDescription
|
||||||
0x00080090: '',
|
0x00080090: '', // referringPhysicianName
|
||||||
0x00100010: '',
|
0x00100010: '', // patientName
|
||||||
0x00100020: '',
|
0x00100020: '', // patientId
|
||||||
0x00200010: '',
|
0x00100030: '', // patientBirthDate
|
||||||
0x0008103E: '',
|
0x00100040: '', // patientSex
|
||||||
0x00200011: '',
|
0x00200010: '', // studyId
|
||||||
|
0x0008103E: '', // seriesDescription
|
||||||
|
0x00200011: '', // seriesNumber
|
||||||
|
0x00080080: '', // institutionName
|
||||||
0x00080016: '', // sopClassUid
|
0x00080016: '', // sopClassUid
|
||||||
0x00080018: '', // sopInstanceUid
|
0x00080018: '', // sopInstanceUid
|
||||||
0x00080060: '', // modality
|
0x00080060: '', // modality
|
||||||
@ -37,7 +40,9 @@ var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
|
|||||||
0x00281052: '', // rescaleIntercept
|
0x00281052: '', // rescaleIntercept
|
||||||
0x00281053: '', // rescaleSlope
|
0x00281053: '', // rescaleSlope
|
||||||
0x00280002: '', // samplesPerPixel
|
0x00280002: '', // samplesPerPixel
|
||||||
|
0x00180050: '', // sliceThickness
|
||||||
0x00201041: '', // sliceLocation
|
0x00201041: '', // sliceLocation
|
||||||
|
0x00189327: '', // tablePosition
|
||||||
0x00281050: '', // windowCenter
|
0x00281050: '', // windowCenter
|
||||||
0x00281051: '', // windowWidth
|
0x00281051: '', // windowWidth
|
||||||
0x00280030: '', // pixelSpacing
|
0x00280030: '', // pixelSpacing
|
||||||
@ -47,9 +52,14 @@ var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
|
|||||||
0x00200032: '', // imagePositionPatient
|
0x00200032: '', // imagePositionPatient
|
||||||
0x00200037: '', // imageOrientationPatient
|
0x00200037: '', // imageOrientationPatient
|
||||||
0x00200052: '', // frameOfReferenceUID
|
0x00200052: '', // frameOfReferenceUID
|
||||||
|
0x00282110: '', // lossyImageCompression
|
||||||
|
0x00282112: '', // lossyImageCompressionRatio
|
||||||
|
0x00282114: '', // lossyImageCompressionMethod,
|
||||||
|
0x00180088: '' // spacingBetweenSlices
|
||||||
|
|
||||||
// Orthanc has a bug here so we can't retrieve sequences at the moment
|
// Orthanc has a bug here so we can't retrieve sequences at the moment
|
||||||
// https://groups.google.com/forum/#!topic/orthanc-users/ghKJfvtnK8Y
|
// https://groups.google.com/forum/#!topic/orthanc-users/ghKJfvtnK8Y
|
||||||
|
//0x00282111: '', // derivationDescription
|
||||||
//0x00082112: '' // sourceImageSequence
|
//0x00082112: '' // sourceImageSequence
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template name="lesionTrackerViewportOverlay">
|
<template name="lesionTrackerViewportOverlay">
|
||||||
<div class="imageViewerViewportOverlay noselect">
|
<div class="imageViewerViewportOverlay noselect {{#if gt numImages 1}}controlsVisible{{/if}}">
|
||||||
<div class="topleft dicomTag">
|
<div class="topleft dicomTag">
|
||||||
<div>{{formatPN patientName}}</div>
|
<div>{{formatPN patientName}}</div>
|
||||||
<div>{{patientId}}</div>
|
<div>{{patientId}}</div>
|
||||||
@ -16,11 +16,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bottomleft dicomTag">
|
<div class="bottomleft dicomTag">
|
||||||
<div>Ser: {{seriesNumber}}</div>
|
<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>{{frameRate}}</div>
|
||||||
<div>{{imageDimensions}}</div>
|
<div>{{imageDimensions}}</div>
|
||||||
<div>{{seriesDescription}}</div>
|
<div>{{seriesDescription}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{>imageControls}}
|
{{#if gt numImages 1}}
|
||||||
|
{{> imageControls imageIndex=imageIndex numImages=numImages}}
|
||||||
|
{{ /if }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -17,9 +17,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bottomleft dicomTag">
|
<div class="bottomleft dicomTag">
|
||||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
<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>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||||
<div>{{imageDimensions}}</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>{{seriesDescription}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{ /unless }}
|
{{ /unless }}
|
||||||
@ -34,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bottomright dicomTag">
|
<div class="bottomright dicomTag">
|
||||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
<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>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||||
<div>{{imageDimensions}}</div>
|
<div>{{imageDimensions}}</div>
|
||||||
<div>{{seriesDescription}}</div>
|
<div>{{seriesDescription}}</div>
|
||||||
@ -54,7 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bottomleft dicomTag">
|
<div class="bottomleft dicomTag">
|
||||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
<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>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||||
<div>{{imageDimensions}}</div>
|
<div>{{imageDimensions}}</div>
|
||||||
<div>{{seriesDescription}}</div>
|
<div>{{seriesDescription}}</div>
|
||||||
|
|||||||
@ -180,6 +180,12 @@ Template.viewportOverlay.helpers({
|
|||||||
patientId: function() {
|
patientId: function() {
|
||||||
return getPatient.call(this, 'id');
|
return getPatient.call(this, 'id');
|
||||||
},
|
},
|
||||||
|
patientBirthDate: function() {
|
||||||
|
return getPatient.call(this, 'birthDate');
|
||||||
|
},
|
||||||
|
patientSex: function() {
|
||||||
|
return getPatient.call(this, 'sex');
|
||||||
|
},
|
||||||
studyDate: function() {
|
studyDate: function() {
|
||||||
return getStudy.call(this, 'studyDate');
|
return getStudy.call(this, 'studyDate');
|
||||||
},
|
},
|
||||||
@ -204,9 +210,67 @@ Template.viewportOverlay.helpers({
|
|||||||
seriesNumber: function() {
|
seriesNumber: function() {
|
||||||
return getSeries.call(this, 'seriesNumber');
|
return getSeries.call(this, 'seriesNumber');
|
||||||
},
|
},
|
||||||
imageNumber: function() {
|
instanceNumber: function() {
|
||||||
return getInstance.call(this, 'instanceNumber');
|
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() {
|
tagDisplayLeftOnly: function() {
|
||||||
return getTagDisplay.call(this, 'side') === 'L';
|
return getTagDisplay.call(this, 'side') === 'L';
|
||||||
},
|
},
|
||||||
@ -216,9 +280,6 @@ Template.viewportOverlay.helpers({
|
|||||||
tagDisplaySpecified: function() {
|
tagDisplaySpecified: function() {
|
||||||
return getTagDisplay.call(this, 'side');
|
return getTagDisplay.call(this, 'side');
|
||||||
},
|
},
|
||||||
imageIndex: function() {
|
|
||||||
return getInstance.call(this, 'index');
|
|
||||||
},
|
|
||||||
imageIndex: function() {
|
imageIndex: function() {
|
||||||
Session.get('CornerstoneNewImage' + this.viewportIndex);
|
Session.get('CornerstoneNewImage' + this.viewportIndex);
|
||||||
var stack = getStackDataIfNotEmpty(this.viewportIndex);
|
var stack = getStackDataIfNotEmpty(this.viewportIndex);
|
||||||
|
|||||||
@ -26,7 +26,8 @@ addMetaData = function(imageId, data) {
|
|||||||
studyInstanceUid: studyMetaData.studyInstanceUid,
|
studyInstanceUid: studyMetaData.studyInstanceUid,
|
||||||
studyDate: studyMetaData.studyDate,
|
studyDate: studyMetaData.studyDate,
|
||||||
studyTime: studyMetaData.studyTime,
|
studyTime: studyMetaData.studyTime,
|
||||||
studyDescription: studyMetaData.studyDescription
|
studyDescription: studyMetaData.studyDescription,
|
||||||
|
institutionName: studyMetaData.institutionName
|
||||||
};
|
};
|
||||||
|
|
||||||
metaData.series = {
|
metaData.series = {
|
||||||
@ -37,23 +38,13 @@ addMetaData = function(imageId, data) {
|
|||||||
numImages: numImages
|
numImages: numImages
|
||||||
};
|
};
|
||||||
|
|
||||||
metaData.instance = {
|
metaData.instance = instanceMetaData;
|
||||||
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.patient = {
|
metaData.patient = {
|
||||||
name: studyMetaData.patientName,
|
name: studyMetaData.patientName,
|
||||||
id: studyMetaData.patientId
|
id: studyMetaData.patientId,
|
||||||
|
birthDate: studyMetaData.patientBirthDate,
|
||||||
|
sex: studyMetaData.patientSex
|
||||||
};
|
};
|
||||||
|
|
||||||
// If there is sufficient information, populate
|
// If there is sufficient information, populate
|
||||||
|
|||||||
@ -43,12 +43,15 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
|||||||
seriesList: seriesList,
|
seriesList: seriesList,
|
||||||
patientName: anInstance[0x00100010],
|
patientName: anInstance[0x00100010],
|
||||||
patientId: anInstance[0x00100020],
|
patientId: anInstance[0x00100020],
|
||||||
|
patientBirthDate: anInstance[0x00100030],
|
||||||
|
patientSex: anInstance[0x00100040],
|
||||||
accessionNumber: anInstance[0x00080050],
|
accessionNumber: anInstance[0x00080050],
|
||||||
studyDate: anInstance[0x00080020],
|
studyDate: anInstance[0x00080020],
|
||||||
modalities: anInstance[0x00080061],
|
modalities: anInstance[0x00080061],
|
||||||
studyDescription: anInstance[0x00081030],
|
studyDescription: anInstance[0x00081030],
|
||||||
imageCount: anInstance[0x00201208],
|
imageCount: anInstance[0x00201208],
|
||||||
studyInstanceUid: anInstance[0x0020000D]
|
studyInstanceUid: anInstance[0x0020000D],
|
||||||
|
institutionName: anInstance[0x00080080]
|
||||||
};
|
};
|
||||||
|
|
||||||
resultData.forEach(function(instanceRaw) {
|
resultData.forEach(function(instanceRaw) {
|
||||||
@ -78,7 +81,9 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
|||||||
imagePositionPatient: instance[0x00200032],
|
imagePositionPatient: instance[0x00200032],
|
||||||
imageOrientationPatient: instance[0x00200037],
|
imageOrientationPatient: instance[0x00200037],
|
||||||
frameOfReferenceUID: instance[0x00200052],
|
frameOfReferenceUID: instance[0x00200052],
|
||||||
|
sliceThickness: parseFloat(instance[0x00180050]),
|
||||||
sliceLocation: parseFloat(instance[0x00201041]),
|
sliceLocation: parseFloat(instance[0x00201041]),
|
||||||
|
tablePosition: parseFloat(instance[0x00189327]),
|
||||||
samplesPerPixel: parseFloat(instance[0x00280002]),
|
samplesPerPixel: parseFloat(instance[0x00280002]),
|
||||||
photometricInterpretation: instance[0x00280004],
|
photometricInterpretation: instance[0x00280004],
|
||||||
rows: parseFloat(instance[0x00280010]),
|
rows: parseFloat(instance[0x00280010]),
|
||||||
@ -96,7 +101,12 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
|||||||
laterality: instance[0x00200062],
|
laterality: instance[0x00200062],
|
||||||
viewPosition: instance[0x00185101],
|
viewPosition: instance[0x00185101],
|
||||||
numFrames: parseFloat(instance[0x00280008]),
|
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
|
// Retrieve the actual data over WADO-URI
|
||||||
|
|||||||
@ -59,7 +59,8 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
|||||||
modalities: DICOMWeb.getString(anInstance['00080061']),
|
modalities: DICOMWeb.getString(anInstance['00080061']),
|
||||||
studyDescription: DICOMWeb.getString(anInstance['00081030']),
|
studyDescription: DICOMWeb.getString(anInstance['00081030']),
|
||||||
imageCount: DICOMWeb.getString(anInstance['00201208']),
|
imageCount: DICOMWeb.getString(anInstance['00201208']),
|
||||||
studyInstanceUid: DICOMWeb.getString(anInstance['0020000D'])
|
studyInstanceUid: DICOMWeb.getString(anInstance['0020000D']),
|
||||||
|
institutionName: DICOMWeb.getString(anInstance['00080080'])
|
||||||
};
|
};
|
||||||
|
|
||||||
resultData.forEach(function(instance) {
|
resultData.forEach(function(instance) {
|
||||||
@ -107,7 +108,11 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
|||||||
viewPosition: DICOMWeb.getString(instance['00185101']),
|
viewPosition: DICOMWeb.getString(instance['00185101']),
|
||||||
numFrames: DICOMWeb.getNumber(instance['00280008']),
|
numFrames: DICOMWeb.getNumber(instance['00280008']),
|
||||||
frameTime: DICOMWeb.getNumber(instance['00181063']),
|
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') {
|
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