nm/ct融合更改

uat_us
caiyiling 2026-03-30 14:13:52 +08:00
parent a987ac086b
commit aae5968d74
2 changed files with 76 additions and 13 deletions

View File

@ -5,7 +5,7 @@
:style="{ color: series.Modality === 'PT' || series.Modality === 'NM' || isMip ? '#666' : '#ddd' }"> :style="{ color: series.Modality === 'PT' || series.Modality === 'NM' || isMip ? '#666' : '#ddd' }">
<div v-if="isFusion" class="opacity-slider-wrapper" @mousedown.stop @mousemove.stop @mouseup.stop @wheel.stop> <div v-if="isFusion" class="opacity-slider-wrapper" @mousedown.stop @mousemove.stop @mouseup.stop @wheel.stop>
<div class="slider-title">{{ Math.round(fusionOpacity * 100) }}%</div> <div class="slider-title">{{ Math.round(fusionOpacity * 100) }}%</div>
<input type="range" min="0" max="1" step="0.05" v-model.number="fusionOpacity" @input="applyFusionOpacity" <input type="range" min="0" max="1" step="0.01" v-model.number="fusionOpacity" @input="applyFusionOpacity"
class="opacity-slider" /> class="opacity-slider" />
</div> </div>
<div v-if="series && taskInfo" class="left-top-text"> <div v-if="series && taskInfo" class="left-top-text">
@ -104,6 +104,7 @@ import {
setMipTransferFunctionForVolumeActor, setMipTransferFunctionForVolumeActor,
setPetTransferFunctionForVolumeActor setPetTransferFunctionForVolumeActor
} from './helpers/index.js' } from './helpers/index.js'
import setNmFusionColorMapTransferFunctionForVolumeActor from './helpers/setNmFusionColorMapTransferFunctionForVolumeActor'
const { BlendModes, OrientationAxis } = Enums; const { BlendModes, OrientationAxis } = Enums;
const { getColormap } = csUtils.colormap; const { getColormap } = csUtils.colormap;
import { vec3, mat4 } from 'gl-matrix' import { vec3, mat4 } from 'gl-matrix'
@ -173,7 +174,7 @@ export default {
ptVolumeId: null, ptVolumeId: null,
loading: false, loading: false,
Colorbar: null, Colorbar: null,
fusionOpacity: 0.5, fusionOpacity: 0.95,
topFusionVolumeActor: null, topFusionVolumeActor: null,
currentVoiUpper: null currentVoiUpper: null
} }
@ -278,13 +279,13 @@ export default {
} }
if (properties && properties.voiRange) { if (properties && properties.voiRange) {
var { lower, upper } = properties.voiRange var { lower, upper } = properties.voiRange
if ((!upper || upper === 0) && this.currentVoiUpper > 0) { if ((!upper || upper < 1) && this.currentVoiUpper >= 1) {
upper = this.currentVoiUpper upper = this.currentVoiUpper
} else if (upper) { } else if (upper) {
this.currentVoiUpper = upper this.currentVoiUpper = upper
} }
if (!upper) return if (!upper || upper < 1) return
const { windowWidth, windowCenter } = csUtils.windowLevel.toWindowLevel( const { windowWidth, windowCenter } = csUtils.windowLevel.toWindowLevel(
lower, lower,
@ -554,7 +555,17 @@ export default {
const ptFusionEntry = { const ptFusionEntry = {
volumeId: ptFusionVolumeId, volumeId: ptFusionVolumeId,
callback: (r) => { callback: (r) => {
setPetColorMapTransferFunctionForVolumeActor({ ...r, volumeId: ptFusionVolumeId }) if (this.series.Modality === 'NM') {
setNmFusionColorMapTransferFunctionForVolumeActor({
...r,
volumeId: ptFusionVolumeId,
})
} else {
setPetColorMapTransferFunctionForVolumeActor({
...r,
volumeId: ptFusionVolumeId,
})
}
if (!this.fusionCtOnTop) { if (!this.fusionCtOnTop) {
this.topFusionVolumeActor = r.volumeActor this.topFusionVolumeActor = r.volumeActor
} }
@ -564,14 +575,20 @@ export default {
} }
const volumes = [] const volumes = []
if (this.series.Modality !== 'NM') { // if (this.series.Modality !== 'NM') {
// volumes.push({
// volumeId: this.volumeId,
// callback: (r) => {
// console.log("pet");
// }
// })
// }
volumes.push({ volumes.push({
volumeId: this.volumeId, volumeId: this.volumeId,
callback: (r) => { callback: (r) => {
console.log("融合pet渲染成功"); console.log("融合pet渲染成功");
} }
}) })
}
if (this.fusionCtOnTop) { if (this.fusionCtOnTop) {
volumes.push(ptFusionEntry, ctEntry) volumes.push(ptFusionEntry, ctEntry)

View File

@ -0,0 +1,46 @@
import vtkColorTransferFunction from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction";
import vtkPiecewiseFunction from "@kitware/vtk.js/Common/DataModel/PiecewiseFunction";
import { cache, metaData, utilities } from "@cornerstonejs/core";
const { getColormap } = utilities.colormap;
function getWindowCenterFromVolumeId(volumeId) {
if (!volumeId) return null;
const imageVolume = cache.getVolume?.(volumeId);
const imageId = imageVolume?.imageIds?.[0];
if (!imageId) return null;
const voiLutModule = metaData.get("voiLutModule", imageId);
const rawCenter = Array.isArray(voiLutModule?.windowCenter)
? voiLutModule.windowCenter[0]
: voiLutModule?.windowCenter;
const center = Number(rawCenter);
return Number.isFinite(center) ? center : null;
}
export default function setPetColorMapTransferFunctionForVolumeActor({
volumeActor,
volumeId,
preset,
}) {
const mapper = volumeActor.getMapper?.();
if (mapper?.setSampleDistance) {
mapper.setSampleDistance(1.0);
}
const cfun = vtkColorTransferFunction.newInstance();
const presetToUse = preset || getColormap("siemens");
cfun.applyColorMap(presetToUse);
const center = getWindowCenterFromVolumeId(volumeId);
const upper = Number.isFinite(center) && center > 1 ? center : 5;
cfun.setMappingRange(1, upper);
volumeActor.getProperty().setRGBTransferFunction(0, cfun);
const ofun = vtkPiecewiseFunction.newInstance();
const rampX = Number.isFinite(upper) && upper > 0 ? Math.min(0.1, upper * 0.02) : 0.1;
ofun.addPoint(0, 0.0);
ofun.addPoint(rampX, 0.9);
ofun.addPoint(upper, 1.0);
volumeActor.getProperty().setScalarOpacity(0, ofun);
}