试图将dicom monochrome2呈现到HTML5画布上
- Currently using **incorrect** mapping of
const ctx = canvas.getContext( '2d' ) const imageData = ctx.createImageData( 512, 512 ) const pixelData = getPixelData( dataSet ) let rgbaIdx = 0 let rgbIdx = 0 let pixelCount = 512 \* 512 for ( let idx = 0; idx < pixelCount; idx++ ) { imageData.data[ rgbaIdx ] = pixelData[ rgbIdx ] imageData.data[ rgbaIdx + 1 ] = pixelData[ rgbIdx + 1 ] imageData.data[ rgbaIdx + 2 ] = 0 imageData.data[ rgbaIdx + 3 ] = 255 rgbaIdx += 4 rgbIdx += 2 } ctx.putImageData( imageData, 0, 0 )

图1.不正确的映射

图2.正确的映射,dicom显示在IrfanView中
发布于 2020-08-02 05:24:19
结果证明了需要做的四件主要事情(阅读fo-dicom源代码来找出这些事情)
导出const LutMonochrome2 = () => { let lut = [] for (设idx = 0,byt = 255;idx++,byt-){ // r,g,b,a lut.push( byt,0xff )}返回lut }
导出const bytesToShortSigned =(字节) => { let byteA =1 let byteB =byteB 0 let pixelVal const符号= byteA & (1 << 7);pixelVal =(byteA& 0xFF) << 8) << (byteB & 0xFF));if (符号){ pixelVal =0xFFF0000 pixelVal;//使用1's }返回pixelVal返回的最重要位
}
导出const getMinMax =( pixelData ) => { let pixelCount = pixelData.length let min = 0,max =0 for (设idx = 0;+= 2){ let pixelVal = bytesToShortSigned( [ pixelDataidx,pixelDataidx+1 ]) if (pixelVal < min) min = pixelVal if (pixelVal > max) max = pixelVal }返回{ min,max }
({ dataSet,画布}) => { const monochrome2 = LutMonochrome2() const ctx = canvas.getContext( '2d‘) const imageData = ctx.createImageData( 512,512 ) const pixelData = getPixelData( dataSet )让pixelCount = pixelData.length使{ min: minPixel,max: maxPixel }= getMinMax( pixelData - );让=(+)/ 2.0;()让=0( let idx = 0;idx <;+= 2){ let pixelVal = bytesToShortSigned( [ pixelDataidx,pixelDataidx+1 ])设binIdx = Math.floor( (pixelVal - minPixel) / windowWidth * 256 );设displayVal = monochrome2 binIdx if ( displayVal == null ) displayVal = 0,0,0,255 imageData.data rgbaIdx = displayVal imageData.data rgbaIdx +1= displayVal1 imageData.data rgbaIdx +2= displayVal2 imageData.data rgbaIdx +3= rgbaIdx 4}(,0,0)}en23#
发布于 2020-07-19 09:36:32
这里有两个问题:您的单色数据的分辨率(例如值范围)比在RGB中显示的要高,所以您不能直接将像素数据映射到RGB数据中。
值范围取决于Bits Stored标记-对于典型的值12,数据范围将为4096。最简单的实现可以将这个数字缩小,在本例中是16。
代码的第二个问题:要在RGB中表示单色值,必须添加3个具有相同值的颜色组件:
let rgbaIdx = 0
let rgbIdx = 0
let pixelCount = 512 * 512
let scaleFactor = 16 // has to be calculated in real code
for ( let idx = 0; idx < pixelCount; idx++ ) {
# assume Little Endian
let pixelValue = pixelData[ rgbIdx ] + pixelData[ rgbIdx + 1 ] * 256
let displayValue = Math.round(pixelValue / scaleFactor)
imageData.data[ rgbaIdx ] = displayValue
imageData.data[ rgbaIdx + 1 ] = displayValue
imageData.data[ rgbaIdx + 2 ] = displayValue
imageData.data[ rgbaIdx + 3 ] = 255
rgbaIdx += 4
rgbIdx += 2
}为了得到更好的表示,你必须考虑到VOI LUT,而不仅仅是缩小比例。如果定义了Window Center / Window Width标记,则可以计算最小值和最大值,并从该范围获得比例因子:
let minValue = windowCenter - windowWidth / 2
let maxValue = windowCenter + windowWidth / 2
let scaleFactor = (maxValue - minValue) / 256
...
let pixelValue = pixelData[ rgbIdx ] + pixelData[ rgbIdx + 1 ] * 256
let displayValue = max((pixelValue - minValue) / scaleFactor), 255)
...编辑:正如@WilfRosenbaum所观察到的:如果您没有VOI (如WindowCenter和WindowWidth的空值所建议的那样),那么最好自己计算一个。为此,必须计算像素数据的最小/最大值:
let minValue = 1 >> 16
let maxValue = 0
for ( let idx = 0; idx < pixelCount; idx++ ) {
let pixelValue = pixelData[ rgbIdx ] + pixelData[ rgbIdx + 1 ] * 256
minValue = min(minValue, pixelValue)
maxValue = max(maxValue, pixelValue)
}
let scaleFactor = (maxValue - minValue) / 256然后使用与VOI LUT相同的代码。
几个注意事项:
WindowCenter / WindowWindow值对,或者可能有一个value序列,这在这里也没有考虑--< code >F 215
https://stackoverflow.com/questions/62977280
复制相似问题