Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction'; import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray'; import { VOIRange } from '../types'; import * as windowLevelUtil from './windowLevel'; /** * A utility that can be used to generate an Sigmoid RgbTransferFunction. * Sigmoid transfer functions are used in the dicom specification: * https://dicom.nema.org/medical/dicom/2018b/output/chtml/part03/sect_C.11.2.html * * @example * Setting an RGB Transfer function from the viewport: * ``` * const sigmoidRGBTransferFunction = createSigmoidRGBTransferFunction(0, 255, { lower: 0, upper: 255} ); * viewport * .getActor() * .getProperty() * .setRGBTransferFunction(0, sigmoidRGBTransferFunction); * ``` * * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction} * @param rgbTransferFunction */ export default function createSigmoidRGBTransferFunction( voiRange: VOIRange, approximationNodes = 1024 // humans can precieve no more than 900 shades of gray doi: 10.1007/s10278-006-1052-3 ): vtkColorTransferFunction { const { windowWidth, windowCenter } = windowLevelUtil.toWindowLevel( voiRange.lower, voiRange.upper ); // Function is defined by dicom spec // https://dicom.nema.org/medical/dicom/2018b/output/chtml/part03/sect_C.11.2.html const sigmoid = (x: number, wc: number, ww: number) => { return 1 / (1 + Math.exp((-4 * (x - wc)) / ww)); }; // This function is the analytical inverse of the dicom spec sigmoid function // for values y = [0, 1] exclusive. We use this to perform better sampling of // points for the LUT as some images can have 2^16 unique values. This method // can be deprecated if vtk supports LUTFunctions rather than look up tables // or if vtk supports logistic scale. It currently only supports linear and // log10 scaling which can be set on the vtkColorTransferFunction const logit = (y: number, wc: number, ww: number) => { return wc - (ww / 4) * Math.log((1 - y) / y); }; // we slice out the first and last value to avoid 0 and 1 Infinity values const range = [...Array(approximationNodes + 2).keys()] .map((v) => v / (approximationNodes + 2)) .slice(1, -1); const table = range.reduce((res, y) => { const x = logit(y, windowCenter, windowWidth); return res.concat(x, y, y, y, 0.5, 0.0); }, []); const cfun = vtkColorTransferFunction.newInstance(); cfun.buildFunctionFromArray( vtkDataArray.newInstance({ values: table, numberOfComponents: 6 }) ); return cfun; } |