rii-mango / NIFTI-Reader-JS

A JavaScript NIfTI file format reader.
MIT License
137 stars 30 forks source link

How to read a complex-nifti file using NIFTI-Reader-JS #34

Closed qaz8788817 closed 1 year ago

qaz8788817 commented 1 year ago

Same as the title, Me and my friend don't know how to read a complex nifti file. We convert our raw data into this type : `else if (niftiHeader.datatypeCode === nifti.NIFTI1.TYPE_COMPLEX64) {

            typedData = new Float64Array(niftiImage);`

The complex file is displayed like: image And this is the console.log: image

We also have tried this: `// draw pixels

        for (var row = 0; row < rows; row++) {

            var rowOffset = row * cols;

            for (var col = 0; col < cols; col++) {

                var offset = sliceOffset + rowOffset + col;

                var temp = Math.sqrt(Math.pow(typedData[offset], 2) + Math.pow(typedData[offset + 1], 2));

                var valueS = temp / niftiHeader.cal_max * 255;

                canvasImageData.data[(rowOffset + col) * 4] = value & 0xFF;

                canvasImageData.data[(rowOffset + col) * 4 + 1] = value & 0xFF;

                canvasImageData.data[(rowOffset + col) * 4 + 2] = value & 0xFF;

                canvasImageData.data[(rowOffset + col) * 4 + 3] = 0xFF;

                // col += 1;

            }

        }`

and it's showed: image

Can someone help us? Thanks a lot. Sorry for my poor English. I'm not native English speaker, but still learning.

neurolabusc commented 1 year ago

The NIfTI format complex datatype stores real and imaginary data as neighboring pairs of floating point data, so the data is stored on disk r,i,r,i,r,i...

Crucially COMPLEX64 stores data as pairs of 2 32 bit floats, therefore you will want to use Float32Array for your data. You would only use Float64Array for the COMPLEX128 datatype.

It would make sense to choose to either view the real image (even elements in your array) or just the imaginary data (odd elements).

You may find it easier to parse your complex data into two NIfTI files so that the voxel's data are contiguous:

fslcomplex -realcartesian complex newreal newimag
qaz8788817 commented 1 year ago

The NIfTI format complex datatype stores real and imaginary data as neighboring pairs of floating point data, so the data is stored on disk r,i,r,i,r,i...

Crucially COMPLEX64 stores data as pairs of 2 32 bit floats, therefore you will want to use Float32Array for your data. You would only use Float64Array for the COMPLEX128 datatype.

It would make sense to choose to either view the real image (even elements in your array) or just the imaginary data (odd elements).

You may find it easier to parse your complex data into two NIfTI files so that the voxel's data are contiguous:

fslcomplex -realcartesian complex newreal newimag

Dear Neurolabusc: Thanks for your comments. We've tried your suggestion and it has worked. And here is the image showing. image image

Here is our code: (convert raw data)

            } else if (niftiHeader.datatypeCode === nifti.NIFTI1.TYPE_COMPLEX64) {

                let f32 = new Float32Array(niftiImage);

                let nvx = Math.floor(f32.length / 2);

                typedData = new Float32Array(nvx);

                typedData2 = new Float32Array(nvx);

                let r = 0;

                for (let i = 0; i < nvx - 1; i++) {

                    typedData[i] = f32[r];

                    typedData2[i] = f32[r + 1];

                    r += 2;

                }

(drawing)

for (var row = 0; row < rows; row++) {

                var rowOffset = row * cols;

                for (var col = 0; col < cols; col++) {

                    var offset = sliceOffset + rowOffset + col;

                    var temp = Math.sqrt(Math.pow(typedData[offset], 2) + Math.pow(typedData2[offset], 2));

                    var value = temp / niftiHeader.cal_max * 255;

                    canvasImageData.data[(rowOffset + col) * 4] = value & 0xFF;

                    canvasImageData.data[(rowOffset + col) * 4 + 1] = value & 0xFF;

                    canvasImageData.data[(rowOffset + col) * 4 + 2] = value & 0xFF;

                    canvasImageData.data[(rowOffset + col) * 4 + 3] = 0xFF;

                }

            }

Thanks for your help again!

neurolabusc commented 1 year ago

We have now added a live demo for viewing complex images into the NIFTI-Reader-JS dependent NiiVue. Note that as you move move the crosshairs to different locations, both the real and imaginary intensities are shown in the status text at the bottom left.