javascripthtmlcanvasdicomfileparsing

Displaying multiframe dicom images using HTML5 canvas and Javascript


I'm trying to display multi-frame dicom images in a browser using HTML5 canvas and javascript. So far I can render single framed images just fine but I'm having trouble with multi framed images.

For parsing the file I'm using the DicomParser plugin.

When I break the data into it's fragments(frames) and try to display them the canvas just renders bars of noise. Heres an example of rendering a single frame from a multi frame image.

Noise produced by loading single frame from multiframe dicom image

Below is the javscript code

// CREATE A CANVAS REFERENCE
// -------------------------------------------------------------------------------------------------
var canvas = document.getElementById( 'canvas' );
canvas.with = 200;
canvas.height = 200;


// ADD A HANDLER FOR READING FILES FROM COMPUTER
// -------------------------------------------------------------------------------------------------
var dicomFile = document.getElementById( 'dicomfile' );

dicomFile.onchange = function( evt ) {
    var tgt = evt.target || window.event.srcElement,
        files = tgt.files;


// FILEREADER SUPPORT
// ---------------------------------------------------------------------------------------------
if ( FileReader && files && files.length ) {
    var fr = new FileReader(),
        extension = files[ 0 ].name.split( '.' ).pop().toLowerCase();

    // IF EXTENSION IS NOT DCM ,THEN STOP PROCESSING FURTHER AND EXIT.
    if ( extension !== 'dcm' ) {
        alert( 'please choose a Dicom file' );
        return;
    } else {

        // PARSE AND PROCESS THE DICOM FILE.
        fr.onload = function( e ) {

            var dicomArray = new Uint8Array( e.target.result ), 

                // PARSE THE DICOM FILE
                dataSet = dicomParser.parseDicom( dicomArray ),

                // GET WIDTH AND HEIGHT OF THE DICOM IMAGE.
                width = dataSet.uint16( 'x00280011' ), height = dataSet.uint16( 'x00280010' ),

                // GET THE PIXEL DATA ELEMENT FROM THE DATASET.
                pixelDataElement = dataSet.elements.x7fe00010;

            // NOW GET THE PIXEL DATA FROM THE DICOM FILE.
            var pixelData = [];

            pixelDataElement.basicOffsetTable.forEach( function(offset){ 
                pixelDataElement.fragments.forEach(function(fragment){
                    pixelData.push( new Uint8Array( dataSet.byteArray.buffer, offset, fragment.length ) );
                });
            });

            // NOW WE HAVE GOT WIDTH, HEIGHT AND PIXEL DATA WHICH IS ALL IT TAKES TO RENDER A IMAGE TO THE CANVAS.
            canvas.width = width;
            canvas.height = height;

            // GET CONTEXT
            var context = canvas.getContext( '2d' ),

            // GET IMAGE DATA TO UPDATE
                imageData = context.getImageData( 0, 0, width, height ),
                data = imageData.data;

            // UPDATING ALPHA
            for ( var i = 3, k = 0; i < data.byteLength; i = i + 4, k = k + 2 ) {

                // CONVERT 16-BIT TO 8-BIT ,BECAUSE WE CANNOT RENDER A 16-BIT VALUE TO THE CANVAS.
                var result = ((pixelData[0][ k + 1 ] & 0xFF) << 8) | (pixelData[0][ k ] & 0xFF);
                result = (result & 0xFFFF) >> 8;
                data[ i ] = 255 - result;
            }

            imageData[0] =  data[0];

            context.putImageData( imageData, 0, 0 );

            // SHOW THE CANVAS
            canvas.style.display = 'block';
        };
        fr.readAsArrayBuffer( this.files[ 0 ] );
    }
}
};

Could anyone tell me where I'm going wrong. Any information at all, however general, would be helpful.

The end goal is to use these frames as textures for webGl and three.js to create volumetric rendering of dicom images


Solution

  • The image frames in your multi-frame file are likely compressed and dicomParser does not include decompression code. Take a look at CornerstoneWADOImageLoader for codecs and how to use them: https://github.com/chafey/cornerstoneWADOImageLoader