imagingdatacommons / dicom-microscopy-viewer Goto Github PK
View Code? Open in Web Editor NEWWeb-based DICOM slide microscopy viewer library
Home Page: https://imagingdatacommons.github.io/dicom-microscopy-viewer/
License: MIT License
Web-based DICOM slide microscopy viewer library
Home Page: https://imagingdatacommons.github.io/dicom-microscopy-viewer/
License: MIT License
At the moment, regions of interest (geometries rendered by the viewer) and controls (buttons for the overview map, fullscreen mode, etc.) are rendered with the Openlayers default style. We want to allow an application to customize styling, such that the style of library elements can be matched to that of the application.
Openlayers provides a nice styling API (see Style). The following types may be worth looking into:
However, we don't want to expose the Openlayers API directly. We could either wrap Openlayers classes or implement our own styling logic.
Further, we may want to override some Openlayers CSS classes, such that an application can specify dicom-microscopy-viewer rather than Openlayers CSS.
In some scenarios, it is showing that the passed coordinates are not inside the bounding box
@CPBridge @igoroctaviano
Dear Sir,
As we know, Z-stacking(plane of focus) involves scanning a glass slide at different focal planes along the vertical z-axis and stacking the images on top of each other to produce a composite multiplane image.
Z-stack scanning, however, takes longer and produces larger digital files.
Is dicom-microscopy-viewer support Z-stacks image?
If dicom-microscopy-viewer can support, it will be easily used after feeding DICOM into viewer.
If not, how to display Z-stacks image? Any information we need to know from DICOM tags or scanner manufacturer?
Could you give some suggestions?
Thanks.
Here we are passing the mimetype to dicomweb-client:
We are passing image/jpeg; transfer-syntax=1.2.840.10008.1.2.4.50
.
dicomweb-client is wrapping this with type="${blah}"
This means that the quotation marks end up in the wrong place, and we end up with:
type="image/jpeg; transfer-syntax=1.2.840.10008.1.2.4.50"
which is invalid. dcm4chee doesn't seem to care, but Google Cloud Healthcare API is more stringent and so we end up with 406 errors. It's weird because I swear I tested this before merging and it was working.
I'm not sure if this is something we should fix here or in dicomweb-client. We should probably just finish off this PR: dcmjs-org/dicomweb-client#16 which makes dwc act more like the Python version.
Just posting this for visibility.
It would be helpful to add a TileDebug source to the map to enable debugging (e.g., to debug tile shifts ImagingDataCommons/slim#39).
I think the message here shall be remove ROI ${uid}
.
We might have missed it, but from an ROI, it wasn't obvious how to obtain the frame that the measurement was made upon. We have coordinates, but I'm not sure that's sufficient. It depends on how we encode the measurements in dcmjs (@hackermd mentioned scoord3d at one point, maybe @fedorov or @pieper have some other ideas).
Note: We started making a dcmjs adapter here:
https://github.com/dcmjs-org/dcmjs/tree/dicom-microscopy-adapter
We should add some simple tests for annotations, where we add ROIs to the viewer, retrieve them back and compare them for equality.
Something like:
const viewer = new DICOMMicroscopyViewer.api.VLWholeSlideMicroscopyImageViewer(...)
const circle = new DICOMMicroscopyViewer.scoord3d.Circle([1000, 1000, 1], 100);
const roi = new DICOMMicroscopyViewer.roi.ROI({scoord3d: circle});
viewer.addROI(roi);
const retrievedROIs = viewer.getAllROIs();
// assert that original and retrieved objects are equal, i.e. have identical coordinate values
Whole-slide Image Converted By Orthanc gives issue When Display in Viewer.
I am converting .tiff image to dicom using Orthanc Dicomizer. with the command having a dataset.
./OrthancWSIDicomizer Source.tif --dataset=dataset.json
My dataset.json are
`{
"PatientID": "C123456789",
"PatientName": "SOME^PATIENT",
"PatientBirthDate": "19700101",
"PatientSex": "M",
"StudyID": "NONE",
"SeriesNumber": "1",
"ReferringPhysicianName": "SOME^PHYSICIAN",
"AccessionNumber": "123456789",
"Manufacturer": "MyManufacturer",
"ManufacturerModelName": "MyModel",
"DeviceSerialNumber": "MySerialNumber",
"SoftwareVersions": "MyVersion",
"ImageType": "DERIVED\PRIMARY\VOLUME\NONE",
"FocusMethod": "AUTO",
"ExtendedDepthOfField": "NO",
"AcquisitionContextSequence": [],
"AcquisitionDuration": "100",
"ContainerIdentifier": "CI_12345",
"IssuerOfTheContainerIdentifierSequence": [],
"ContainerTypeCodeSequence": [],
"IssuerOfTheContainerIdentifierSequence": [],
"FrameOfReferenceUID": "",
"DerivationDescription": "Derived from a lossy compressed image in NDPi format (JPEG baseline, quality factor 80%, compression ratio 9.7:1)",
"SpecimenDescriptionSequence": [
{
"SpecimenIdentifier": "Specimen^Identifier",
"SpecimenUID": "1.2.276.0.7230010.3.1.4.3252829876.4112.1426166133.871",
"IssuerOfTheSpecimenIdentifierSequence": [],
"SpecimenPreparationSequence": []
}
],
"SpecimenLabelInImage": "NO",
"BurnedInAnnotation": "NO"
}
`
@hackermd the npm repo is currently tied to your account. Can you either make a deployment for 0.45.0 or somehow migrate it to an IDC account or something?
I'm currently working with a Slim deployment which is retrieving JPEG encoded SM instances. The request's accept header is as follows:
multipart/related; type="image/jls"; transfer-syntax=1.2.840.10008.1.2.4.80, multipart/related; type="image/jls"; transfer-syntax=1.2.840.10008.1.2.4.81, multipart/related; type="image/jp2"; transfer-syntax=1.2.840.10008.1.2.4.90, multipart/related; type="image/jp2"; transfer-syntax=1.2.840.10008.1.2.4.91, multipart/related; type="image/jpx"; transfer-syntax=1.2.840.10008.1.2.4.92, multipart/related; type="image/jpx"; transfer-syntax=1.2.840.10008.1.2.4.93, multipart/related; type="application/octet-stream"; transfer-syntax=*, multipart/related; type="image/jpeg"; transfer-syntax=1.2.840.10008.1.2.4.50
and the response's content type
is:
multipart/related;start="<***@resteasy-multipart>";type="application/octet-stream"; boundary***
The source image is JPEG encoded, so I think that since JPEG appears after octet-stream, it chooses octet-stream instead. I assume the issue is introduced here:
dicom-microscopy-viewer/src/pyramid.js
Lines 461 to 472 in 097282b
Would it be sufficient to just put push the octet stream mediatype after the jpeg mediatype if statement?
Currently, there are no checks for the arguments of the constructor of classes derived from Scoord3D
. This is dangerous because these values are returned by the graphicData()
getter, which is indented to return the coordinates in the format required by DICOM.
We should check for the type (e.g. Array
or Number
) and as well as the values (e.g. whether first and last array element are identical for Polygon
).
For example:
class Point extends Scoord3D {
constructor(coordinates) {
super()
if (!Array.isArray(coordinates)) {
console.error('coordinates of Point must be an array')
}
if (coordinates.length !== 3) {
console.error('coordinates of Point must be an array of length 3')
}
this.coordinates = coordinates
}
get graphicData() {
return this.coordinates;
}
get graphicType() {
return 'POINT';
}
}
We need to prevent that users modify the coordinates
property of Scoord3D
objects. Otherwise, the value returned by graphicData
getter may no longer be correct, i.e. no longer be in the format required for DICOM SR.
I have a requirement where I am suppose to zoom an image upto 200% of its maximum resolution. The default behaviour doesn't allow beyond 100%. I couldn't find any configuration to change the same.
So, if, for eg. I have an SM modality whole slide image with 7 levels - I can zoom in to the last level, but not able to digitally zoom beyond that.
So, would like to know if there is any option to digitally zoom beyond the base image resolution if we want to?
Can give more details if required to understand the requirement better.
Apologies, if there is any mistake in the framing of the question.
dicom-microscopy-viewer.js:51463 Uncaught TypeError: Cannot read property 'getGeometry' when I called getROI(0)
and hadn't drawn anything yet.
All of the other dcmjs-org
libraries appear to transpile/target IE 11
using babel
. I believe, consumers of dicom-microscopy-viewer
that target IE 11
will need to transpile this dependency on every build unless an IE 11 build is provided.
Please consider adopting the same approach used in the other repositories to make this package easier to add as a dependency ๐
The current bootstrap style allows users to pinch zoom and rotate the screen but sometimes is annoying when users are drawing geometric such as Polygons, where the geometry is composed by multiple points and by mistake users, could rotate the screen.
There are some related topics over StackOverflow about the same thing:
const controls = ol.control.defaults({rotate: false});
const interactions = ol.interaction.defaults({altShiftDragRotate:false, pinchRotate:false});
const map = new ol.Map {
controls: controls,
interactions: interactions
};
and
view: new ol.View({ ... enableRotation: false })
But none of them worked properly.
Similar to the issue #31 , but different reason.
The reason is: FrameOfReferenceUID
of each layer of the image pyramid is often different ( usually not totally different but with some matches, for example, 2.16.840.1.113883.3.8467.132979444839078229637890676839078229.10
and 2.16.840.1.113883.3.8467.132979444839078229637890676839078229.9
, only the last number 10
and 9
is different), when the DICOM is generated by aggregating the layer images.
I recognize if these numbers are different between layers, we would have problems when rendering annotations.
But on the condition that we are not using the annotations, it should at least render the image.
This is the line where it was blocked by throwing error:
dicom-microscopy-viewer/src/pyramid.js
Line 78 in 097282b
Hi
we are using Slim viewer and Azure Dicom service and need to pass Accept Header "transfer-syntax=*" as a first option, currently last.
Required for Dicom service to be able to stream large images
To summarise, the method coordinateFormatGeometry2Scoord was only considering the top-level TotalPixelMatrixOriginSequence attribute even if it was absent.
There is a case where a study didn't have this top-level attribute causing the viewer to break when attempting to add new ROIs. Although this attribute did exist nested inside the sequences.
I have updated the metadata provider to get the highest TotalPixelMatrixOriginSequence attribute among the sequences (under PerFrameFunctionalGroupsSequence) and assign it at the top level of the pyramid metadata to work as an approximation. With that, at least the viewer stopped breaking and I can add the annotations in certain places. The problem now is that the calculation is probably not correct, looks like there is a gap/offset between the image and the overlay causing the coordinates of the annotation to be negative in a small percentage of the viewer's (top).
@hackermd if TotalPixelMatrixOriginSequence is absent (at the top level of the pyramid metadata), how can we calculate it based on the nested sequence values?
Do we have to update here to consider the offsets under PerFrameFunctionalGroupsSequence?
Not all classes derived from Scoord3D
have a coordinates
attribute. For example, Circle
doesn't.
This assumption currently breaks the getROI()
viewer method:
https://github.com/dcmjs-org/dicom-microscopy-viewe/blob/0aa5e768029a5a5d6b9c8fa224081218dae76b6f/src/api.js#L731-L737
There are further issues with this approach:
coordinates
attribute of an object of type Point
should no longer be 2, but 3 (since we switched from Scoord
to Scoord3D
)coordinates
attribute of an object of type Point
should be an array of numbers of length 3. Changing the value to an array of arrays would break the graphicData() getter, which would return incorrect graphic data._geometry2Scoord3D()
should already be in the correct format, i.e. in the slide coordinate system in millimeter unit. This line should thus not be necessary.The get methods isDrawInteractionActive, isSelectInteractionActive and isModifyInteractionActive are failing because this[_interaction].modify !== undefined;
should be this[_interactions].modify !== undefined;
_interactions in plural
The on line example website (https://microscopy.dcmjs.org/) doesn't display WSIs and shows white blank pages.
Do we want to store ROI Measurements or Qualitative Evaluations on ROI objects?
@igoroctaviano the markup measurements still seem to be off by quite a bit.
I am using OHIF as a viewer which is erroring out on this assertion when attempting to view WSI studies:
assert(isSorted(this.resolutions_, function(a, b) {
return b - a;
}, true), 17);
I'm unclear on the purpose of this, or why it might be failing. Any insights would be much appreciated.
Thanks
@Punzo it seems recent changes (#54) broke the unit tests:
Evaluation failed: Error: No channels or colorImage found.
at new VolumeImageViewer (build/dicom-microscopy-viewer.js:141168)
at Suite.<anonymous> (test/multichannel.spec.js:39)
at Object.require.57.../build/dicom-microscopy-viewer.js (test/multichannel.spec.js:13)
Error: Exit 1
The dicom-microscopy-viewer library is a valuable tool for displaying DICOM (Digital Imaging and Communications in Medicine) microscopy images within web applications. However, the recent release of version seems to have introduced module import issues for users, leading to two distinct error scenarios:
When developers include the library using the <script type="module"> tag like this:
<script type="module" src="https://unpkg.com/[email protected]"></script>
The error message Uncaught TypeError: Failed to resolve module specifier "mathjs". Relative references must start with either "/", "./", or "../"
. appears in the console. This error suggests an issue with module resolution and specifier handling.
Alternatively, when developers attempt to include the library without the type="module" attribute:
<script src="https://unpkg.com/[email protected]"></script>
They encounter the error message Uncaught SyntaxError: Cannot use import statement outside a module
. This error implies that the library's code is written as ES6 modules, and without the type="module" attribute, it cannot properly handle import statements.
I can't use it maybe there's a more specific example in the import section (a full example) and my dicomWeb works fine.
I think this code (and all DICOM code) would be more readable and maintainable if we avoided the use of hex and use the dictionary. Since we have control over the dictionary class this is a well defined mapping even if the standard is updated and the terminology changes (this happens only very rarely).
So this code:
dict = dcmjs.data.DicomMetaDictionary
dict.nameMap.FrameOfReferenceUID.tag
Gives the string "(0020,0052)"
which can be passed to dict.unpunctuateTag
to get 00200052
for use with the metadata in code like this.
We can also look at maybe adding something like dict.rawTags.FrameOfReferenceUID
to further simplify the code.
The DICOM standard requires origin servers to support URL query parameters for the retrieve rendered transaction (see DICOM Part 18 Section 10.4.1.2 Query Parameters). Unfortunately, not all archives are fully compliant with this part of the standard and including query parameters can crash a web applications.
The library currently uses two separate frameworks for defining and running test cases (mochify and jest) and there are two separate targets for testing defined in package.json
("test"
and "test:unit"
).
@igoroctaviano you introduced jest and added unit tests using jest. Could we use jets for the other unit tests as well?
It appears that the viewer does not show up when you run the examples. It turns out that it is because the root element has no height or width and so it never gets displayed.
Not sure when this broke. We can just change it to <div id="root" style="height:1000px; width:1000px"></div>
and it works fine.
Making an issue for anyone else that runs into it
We need some event listeners or callbacks that allow us to add custom behavior to the viewer. For example, an application may want to automatically compute measurements for each geometry that has been drawn by a user and update the measurements when a user modifies the geometry.
Openlayers exposes several types of events that we could leverage for this purpose. However, we don't want to rely on Openlayer events directly, but want to fully abstract the Openlayers API.
The following events fire for drawInteraction
, selectInteraction
, and modifyInteraction
, respectively:
In addition, Openlayers fires an event whenever a geometry gets drawn and collected:
We may want to allow users of the library to provide callbacks, which could be specified as an option for the constructor and/or for activateDrawInteraction
, activateSelectInteraction
, and activateModifyInteraction
.
I have some questions. Is it possible to add this lib to OHIF?
I tested OHIF and i loaded images in a Orthanc Server and visualized with OHIF but there is not annotation tools for example.
Someone can explain the difference betwwen this dicom-microscopy-viewer and the other one that is in OHIF?
On the other hand. Can someone explain where i can modify and develop over OpenLayers. I saw that OpenLayers is installed to render WSI images.
Kind regards.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.