dicomParser icon indicating copy to clipboard operation
dicomParser copied to clipboard

How to convert DICOM to jpg or png?

Open communque opened this issue 4 years ago • 12 comments

So far I haven't been able to figure this out. The examples on the sample pages weren't working for me (at least not MacOS Safari & Chrome)

The following bit of code seems to work (or at least produces no errors) but the final step attempting generating a png or jpg from pixelDataBuffer does't properly generate the desired file.

	fs=require("fs");
	dicomParser=require("dicom-parser");
	dicomData=fs.readFileSync("/path/to/DicomFile");
	dicomParsed=dicomParser.parseDicom(dicomData);
	pixelData = dicomParsed.elements.x7fe00010;
	pixelDataBuffer = dicomParser.sharedCopy(dicomData, pixelData.dataOffset, pixelData.length);
	fs.writeFileSync("/path/to/File.png", pixelDataBuffer); // Doesn't work.  Nor does jpg, so no doubt there's more to all this.

communque avatar Feb 20 '21 05:02 communque

I'm not sure raw DICOM pixel data is suitable for PNG or JPEG.

AntonOnyshch avatar Feb 22 '21 09:02 AntonOnyshch

@AntonOnyshch is correct. You'd need to use a library like pngjs to take in the bytes and save to png. For a basic greyscale image, that might work almost right out of the box, but there's potential for needing to convert the pixels as stored in the DICOM to something PNG understands. If you need to do that conversion, you'll need to read up on samples per pixel, planar configuration, etc.(you can find a good run down here).

yagni avatar Feb 22 '21 14:02 yagni

@communque If terms like "samples per pixel", "high bit" and other tags seems to be complicated for you I could help you grasp this concept as much as I can. I just need to know your initial understanding level.

AntonOnyshch avatar Feb 22 '21 20:02 AntonOnyshch

This is also a great resource to better understand pixels in DICOM.

yagni avatar Feb 22 '21 20:02 yagni

Any updates? i have the same problem and dont find any solution

I need to convert the parsedDicom into a base64 png

cabraljv avatar Oct 22 '21 00:10 cabraljv

What do you want to be converted? Whole *dcm file or bunch of pixels in it?

AntonOnyshch avatar Dec 13 '21 10:12 AntonOnyshch

@AntonOnyshch is it possible to convert data under tag "Pixel data" to jpg or any picture format, if it is how can we do that? Right now I get 500k pixels in an array but when I try to convert it to Image, I get an exception Invalid image data

asimceman avatar Jan 10 '22 11:01 asimceman

@asimceman did you pass your pixels through look up table before converting them?

AntonOnyshch avatar Jan 10 '22 14:01 AntonOnyshch

@AntonOnyshch No, I havent. What kind of look up table? Can I find any documentation about that? Thanks for your response :)

asimceman avatar Jan 10 '22 14:01 asimceman

@asimceman Here is documentation

Normally, in dentistry pixels data is in 16 bit range. You should convert your pixel by this formula: pixel value*Rescale Slope+Rescale Intercept. The pixel you get is ready for look up table(LUT). LUT is just an array that contains values from 0 to 255.

Typescript

export function calculateLUT(windowWidth: number, windowCenter: number): Uint8ClampedArray {
    const lut = new Uint8ClampedArray(windowWidth);
    const wW = windowWidth - 1;
    const wC = windowCenter - 0.5;
    const min = wC - wW / 2;
    const max = wC + wW / 2;

    const factor = 255 / (max - min);
    for (let i = 0; i < lut.length; ++i) {
        if (i <= min)
            lut[i] = 0;
        else if (i >= max)
            lut[i] = 255;
        else
            lut[i] = (i - min) * factor;
    }

    return lut;
}

AntonOnyshch avatar Jan 10 '22 15:01 AntonOnyshch

But your converted pixel always be from -1000 to 4000 for example. So I do not use "+ Rescale Intercept"(actually you should) which generally negative and therefore I can pass it through LUT indices(which only positive). LUT may be from 0 to 5000. And -1000 is 0, -500 is 500 in LUT index.

lutValue = lut[pxlBuffer[dataOffset + dataPxl] * meta.rescaleSlope];

AntonOnyshch avatar Jan 10 '22 15:01 AntonOnyshch

@AntonOnyshch thank you for your help!

asimceman avatar Jan 13 '22 14:01 asimceman