磁共振的图像在做MPR时,重建的体数据,在各个轴向上的图像数量不正确
continuous-integration/drone/push Build is running
Details
continuous-integration/drone/push Build is running
Details
parent
b4db6b4990
commit
fdc23361f9
|
|
@ -68,7 +68,8 @@ export default {
|
|||
let { width, height } = allInfo.screen; // 分辨率
|
||||
// let discrete = allInfo.webgl.gpuType.discrete; // 是否独立显卡
|
||||
// let estimatedMemory = allInfo.webgl.memoryInfo.estimatedMemory; // 显卡内存
|
||||
if (parseFloat(deviceMemory) < 16 || width < 1920 || height < 1080) {
|
||||
// parseFloat(deviceMemory) < 16 ||
|
||||
if (width < 1920 || height < 1080) {
|
||||
if (this.tip) {
|
||||
this.tip += `<br/>`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2491,7 +2491,8 @@ export default {
|
|||
let { width, height } = allInfo.screen; // 分辨率
|
||||
let discrete = allInfo.webgl.gpuType.discrete; // 是否独立显卡
|
||||
let estimatedMemory = allInfo.webgl.memoryInfo.estimatedMemory; // 显卡内存
|
||||
if (parseFloat(deviceMemory) < 16 || width < 1920 || height < 1080 || !discrete || parseFloat(estimatedMemory) < 2) {
|
||||
// parseFloat(deviceMemory) < 16 ||
|
||||
if (width < 1920 || height < 1080 || !discrete || parseFloat(estimatedMemory) < 2) {
|
||||
let res = await this.$confirm(this.$t('browser:tip:ReadingConfiguration'))
|
||||
resolve(res)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@
|
|||
@dblclick="toggleFullScreen($event, index)" @click="activeViewport(index)">
|
||||
<VolumeViewport :ref="`viewport-volume-${index}`" :data-viewport-uid="`viewport-volume-${index}`"
|
||||
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-volume-${index}`"
|
||||
:viewport-index="index" @activeViewport="activeViewport"
|
||||
:viewport-index="index" :MPRInfo="MPRInfo" @activeViewport="activeViewport" @setMPRInfo="setMPRInfo"
|
||||
@toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
|
||||
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup" />
|
||||
</div>
|
||||
|
|
@ -673,7 +673,18 @@ export default {
|
|||
ManualsClose: false,
|
||||
|
||||
isMPR: false,
|
||||
volumeToolGroupId: "share-viewport-volume"
|
||||
volumeToolGroupId: "share-viewport-volume",
|
||||
MPRInfo: {
|
||||
AXIAL: {
|
||||
imageNum: 0
|
||||
},
|
||||
CORONAL: {
|
||||
imageNum: 0
|
||||
},
|
||||
SAGITTAL: {
|
||||
imageNum: 0
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -801,6 +812,10 @@ export default {
|
|||
document.addEventListener("click", this.foo);
|
||||
},
|
||||
methods: {
|
||||
setMPRInfo(obj) {
|
||||
let { type, key, value } = obj
|
||||
this.$set(this.MPRInfo[type], key, value)
|
||||
},
|
||||
handleReadingChart(row) {
|
||||
let { e, data } = row
|
||||
let obj = Object.assign({}, data)
|
||||
|
|
@ -3478,7 +3493,8 @@ export default {
|
|||
let { width, height } = allInfo.screen; // 分辨率
|
||||
let discrete = allInfo.webgl.gpuType.discrete; // 是否独立显卡
|
||||
let estimatedMemory = allInfo.webgl.memoryInfo.estimatedMemory; // 显卡内存
|
||||
if (parseFloat(deviceMemory) < 16 || width < 1920 || height < 1080 || !discrete || parseFloat(estimatedMemory) < 2) {
|
||||
// parseFloat(deviceMemory) < 16 ||
|
||||
if (width < 1920 || height < 1080 || !discrete || parseFloat(estimatedMemory) < 2) {
|
||||
let res = await this.$confirm(this.$t('browser:tip:ReadingConfiguration'), this.$t('system:menu:confirm:title:warning'), {
|
||||
type: 'warning'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ import {
|
|||
metaData,
|
||||
getRenderingEngine,
|
||||
utilities as csUtils,
|
||||
cache
|
||||
} from '@cornerstonejs/core'
|
||||
import * as cornerstoneTools from '@cornerstonejs/tools'
|
||||
import { createImageIdsAndCacheMetaData } from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/createImageIdsAndCacheMetaData'
|
||||
|
|
@ -91,6 +92,12 @@ export default {
|
|||
type: Number,
|
||||
required: true
|
||||
},
|
||||
MPRInfo: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -142,6 +149,25 @@ export default {
|
|||
this.initViewport()
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
MPRInfo: {
|
||||
handler() {
|
||||
if (!this.series.orientation) return false
|
||||
switch (this.series.orientation) {
|
||||
case 'AXIAL':
|
||||
this.imageInfo.size = `${this.MPRInfo.SAGITTAL.imageNum}*${this.MPRInfo.CORONAL.imageNum}`
|
||||
break;
|
||||
case 'CORONAL':
|
||||
this.imageInfo.size = `${this.MPRInfo.SAGITTAL.imageNum}*${this.MPRInfo.AXIAL.imageNum}`
|
||||
break;
|
||||
case 'SAGITTAL':
|
||||
this.imageInfo.size = `${this.MPRInfo.CORONAL.imageNum}*${this.MPRInfo.AXIAL.imageNum}`
|
||||
break;
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initViewport() {
|
||||
this.element = this.$refs['viewport-volume']
|
||||
|
|
@ -185,6 +211,58 @@ export default {
|
|||
|
||||
})
|
||||
},
|
||||
|
||||
determineImagePlane(imageOrientationPatient) {
|
||||
// imageOrientationPatient 是 [rowX, rowY, rowZ, colX, colY, colZ]
|
||||
// 我们只关心行方向向量 (rowX, rowY, rowZ)
|
||||
const [rowX, rowY, rowZ] = imageOrientationPatient;
|
||||
|
||||
// 计算行方向向量与 X, Y, Z 轴的点积(因为轴向量是单位向量,所以点积就是投影长度)
|
||||
const dotX = Math.abs(rowX);
|
||||
const dotY = Math.abs(rowY);
|
||||
const dotZ = Math.abs(rowZ);
|
||||
|
||||
// 找到最大的点积,确定主方向
|
||||
const maxDot = Math.max(dotX, dotY, dotZ);
|
||||
|
||||
// 根据主方向判断解剖面
|
||||
if (maxDot === dotX) {
|
||||
// 行方向接近 X 轴,说明视线方向接近 Y 或 Z 轴。
|
||||
// 更准确的判断是看视线方向(由行和列向量叉乘得到)。
|
||||
// 但一个简化的、在大多数情况下都成立的规则是:
|
||||
// 如果行向量主要在 X-Y 平面 (rowZ 很小),则为 Axial。
|
||||
// 如果行向量主要在 X-Z 平面 (rowY 很小),则为 Sagittal。
|
||||
// 为了简化,我们可以直接根据视线方向(法线)来判断。
|
||||
// 法线方向 = 行向量 × 列向量
|
||||
const [colX, colY, colZ] = imageOrientationPatient.slice(3);
|
||||
const normalX = rowY * colZ - rowZ * colY;
|
||||
const normalY = rowZ * colX - rowX * colZ;
|
||||
const normalZ = rowX * colY - rowY * colX;
|
||||
|
||||
const absNormalX = Math.abs(normalX);
|
||||
const absNormalY = Math.abs(normalY);
|
||||
const absNormalZ = Math.abs(normalZ);
|
||||
|
||||
const maxNormal = Math.max(absNormalX, absNormalY, absNormalZ);
|
||||
|
||||
if (maxNormal === absNormalZ) {
|
||||
return 'AXIAL';
|
||||
} else if (maxNormal === absNormalY) {
|
||||
return 'SAGITTAL';
|
||||
} else if (maxNormal === absNormalX) {
|
||||
return 'CORONAL';
|
||||
}
|
||||
|
||||
} else if (maxDot === dotY) {
|
||||
// 行方向接近 Y 轴,通常是 Coronal 面。
|
||||
return 'SAGITTAL';
|
||||
} else if (maxDot === dotZ) {
|
||||
// 行方向接近 Z 轴,通常是 Sagittal 面。
|
||||
return 'CORONAL';
|
||||
}
|
||||
|
||||
return 'unknown';
|
||||
},
|
||||
stackNewImage(e) {
|
||||
const { detail } = e
|
||||
this.series.SliceIndex = detail.imageIndex
|
||||
|
|
@ -195,26 +273,16 @@ export default {
|
|||
this.imageInfo.zoom = zoom.toFixed(4)
|
||||
let imageIds = viewport.getImageIds(this.volumeId)
|
||||
let imageId = imageIds[0]
|
||||
let volume = cache.getVolume(this.volumeId)
|
||||
let { spacing } = volume
|
||||
// if (this.series.orientation === 'AXIAL') imageId = viewport.getCurrentImageId()
|
||||
if (imageId) {
|
||||
this.$emit('setMPRInfo', { type: this.series.orientation, key: "imageNum", value: detail.numberOfSlices })
|
||||
const imagePlaneModule = metaData.get('imagePlaneModule', imageId)
|
||||
if (this.series.orientation === 'AXIAL') {
|
||||
this.imageInfo.size = `${imagePlaneModule.columns}*${imagePlaneModule.rows}`
|
||||
this.imageInfo.location = imagePlaneModule.sliceLocation
|
||||
this.imageInfo.total = imageIds.length
|
||||
this.imageInfo.sliceThickness = imagePlaneModule.sliceThickness
|
||||
}
|
||||
if (this.series.orientation === 'CORONAL') {
|
||||
this.imageInfo.size = `${imagePlaneModule.columns}*${imageIds.length}`
|
||||
this.imageInfo.total = imagePlaneModule.rows
|
||||
this.imageInfo.sliceThickness = imagePlaneModule.rowPixelSpacing
|
||||
}
|
||||
if (this.series.orientation === 'SAGITTAL') {
|
||||
this.imageInfo.size = `${imagePlaneModule.rows}*${imageIds.length}`
|
||||
this.imageInfo.total = imagePlaneModule.columns
|
||||
this.imageInfo.sliceThickness = imagePlaneModule.columnPixelSpacing
|
||||
}
|
||||
|
||||
let type = this.determineImagePlane(imagePlaneModule.imageOrientationPatient)
|
||||
this.imageInfo.location = type === this.series.orientation ? imagePlaneModule.sliceLocation : ''
|
||||
this.imageInfo.sliceThickness = type === this.series.orientation ? spacing[2] : spacing[0]
|
||||
this.imageInfo.total = detail.numberOfSlices
|
||||
this.getOrientationMarker()
|
||||
let properties = viewport.getProperties(this.volumeId)
|
||||
if (properties && properties.voiRange) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue