使用 HTML5 canvas 和 Javascript 显示多帧 dicom 图像

Displaying multiframe dicom images using HTML5 canvas and Javascript

我正在尝试使用 HTML5 canvas 和 javascript 在浏览器中显示多帧 dicom 图像。到目前为止,我可以很好地渲染单帧图像,但我在处理多帧图像时遇到了问题。

为了解析文件,我使用了 DicomParser 插件。

当我将数据分解成片段(帧)并尝试显示它们时,canvas 只会呈现噪音条。这是从多帧图像渲染单帧的示例。

下面是javscript代码

// 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 ] );
    }
}
};

谁能告诉我哪里出错了。任何信息,无论多么笼统,都会有所帮助。

最终目标是使用这些帧作为 webGl 的纹理和 three.js 来创建 dicom 图像的体积渲染

您的多帧文件中的图像帧可能已压缩,dicomParser 不包含解压缩代码。查看编解码器的 CornerstoneWADOImageLoader 以及如何使用它们: https://github.com/chafey/cornerstoneWADOImageLoader

另一个解决方案是使用dicom.ts

用几行代码在 canvas 上显示 DICOM:

  // parse the raw data
  const image = dicomts.parseImage(new DataView(rawBuffer));
  // render to canvas element
  const renderer = new dicomjs.Renderer(canvas);
  // decode, and display frame 0 on the canvas
  renderer.render(image, 0);

请在此处找到可用的代码笔: https://codepen.io/nickhingston/pen/PojrXZg

(免责声明 - 有点像我们的库的广告,但可能是我见过的最简单的解决方案)