分割添加轮廓工具
parent
d07adc4948
commit
4e5ecb3938
|
|
@ -0,0 +1 @@
|
||||||
|
<svg width="24px" height="24px" viewBox="0 0 24 24" class="h-6 w-6"><g id="tool-seg-brush" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><rect id="Rectangle" x="0" y="0" width="24" height="24"></rect><path d="M3.24640621,21.8286833 C3.09173375,21.7551472 2.99513748,21.5971513 3.00018895,21.4259625 C3.00524042,21.2547737 3.11098486,21.1027485 3.26972426,21.0384606 C5.3260304,20.2059201 4.66362518,17.8620247 5.27421252,16.6088957 C6.02197747,15.1026514 7.84114758,14.4766383 9.35746132,15.2037675 C13.9485253,17.4422999 8.48346644,24.3211232 3.24640621,21.8286833 Z" id="Path" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M21.5968442,2.302022 C21.1256527,1.8826075 20.4094461,1.90228142 19.9619901,2.34693083 L9.69255027,12.5887345 C11.0536437,13.0051578 12.1843437,13.9616637 12.8206229,15.2349008 L21.7410706,3.93687606 C22.1347378,3.44008272 22.0714081,2.72222021 21.5968442,2.302022 Z" id="Path" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1774331916694" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1627" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M198.4 960A134.4 134.4 0 0 1 64 825.6V198.4A134.4 134.4 0 0 1 198.4 64h268.8a44.8 44.8 0 0 1 44.8 44.8 44.8 44.8 0 0 1-44.8 44.8H198.4a44.8 44.8 0 0 0-44.8 44.8v627.2a44.8 44.8 0 0 0 44.8 44.8h627.2a44.8 44.8 0 0 0 44.8-44.8V556.8a44.8 44.8 0 0 1 44.8-44.8 44.8 44.8 0 0 1 44.8 44.8v268.8A134.4 134.4 0 0 1 825.6 960z m281.984-416.384a44.8 44.8 0 0 1 0-63.296L807.232 153.6H646.464a44.8 44.8 0 0 1-44.8-44.8 44.8 44.8 0 0 1 44.8-44.8h267.264a44.8 44.8 0 0 1 28.288 8.896l1.408 1.152 0.64 0.512 1.024 0.96a41.216 41.216 0 0 1 3.136 3.072l0.896 1.088 0.512 0.64 1.152 1.344a44.8 44.8 0 0 1 8.832 28.288V377.28a44.8 44.8 0 0 1-44.8 44.8 44.8 44.8 0 0 1-44.8-44.8V216.512l-326.4 326.4a44.8 44.8 0 0 1-32 13.248A44.8 44.8 0 0 1 480 543.616z" p-id="1628" fill="#2c2c2c"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -363,9 +363,9 @@
|
||||||
<el-tab-pane :label="$t('trials:reading:dicom3D:tabs:segment')" name="segment">
|
<el-tab-pane :label="$t('trials:reading:dicom3D:tabs:segment')" name="segment">
|
||||||
<Segmentations ref="Segmentations" :visitInfo="taskInfo" :isMPR="isMPR"
|
<Segmentations ref="Segmentations" :visitInfo="taskInfo" :isMPR="isMPR"
|
||||||
:volumeToolGroupId="volumeToolGroupId" :viewportKey="viewportKey"
|
:volumeToolGroupId="volumeToolGroupId" :viewportKey="viewportKey"
|
||||||
:activeViewportIndex="activeViewportIndex" :activeTool.sync="activeTool"
|
:rendering-engine-id="renderingEngineId" :activeViewportIndex="activeViewportIndex"
|
||||||
:actionConfiguration="actionConfiguration" @setToolsPassive="setToolsPassive"
|
:activeTool.sync="activeTool" :actionConfiguration="actionConfiguration"
|
||||||
@resetQuestion="resetQuestion" />
|
@setToolsPassive="setToolsPassive" @resetQuestion="resetQuestion" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|
@ -479,7 +479,7 @@
|
||||||
|
|
||||||
<el-dialog :visible.sync="segmentVisible" :close-on-click-modal="false" :title="$t('trials:segment:title:bind')"
|
<el-dialog :visible.sync="segmentVisible" :close-on-click-modal="false" :title="$t('trials:segment:title:bind')"
|
||||||
width="550px">
|
width="550px">
|
||||||
<SegmentForm v-if="segmentVisible" :visible.sync="segmentVisible" :visitInfo="segmentVisitInfo"
|
<SegmentForm ref="SegmentForm" v-if="segmentVisible" :visible.sync="segmentVisible" :visitInfo="segmentVisitInfo"
|
||||||
@handleSegmentSave="handleSegmentSave" />
|
@handleSegmentSave="handleSegmentSave" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :subject-id="uploadSubjectId"
|
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :subject-id="uploadSubjectId"
|
||||||
|
|
@ -569,7 +569,7 @@ const {
|
||||||
CrosshairsTool,
|
CrosshairsTool,
|
||||||
EllipticalROITool,
|
EllipticalROITool,
|
||||||
synchronizers,
|
synchronizers,
|
||||||
PlanarFreehandContourSegmentationTool,
|
LabelMapEditWithContourTool,
|
||||||
BrushTool,
|
BrushTool,
|
||||||
SegmentBidirectionalTool,
|
SegmentBidirectionalTool,
|
||||||
utilities: CStUtils,
|
utilities: CStUtils,
|
||||||
|
|
@ -898,9 +898,13 @@ export default {
|
||||||
this.$refs[`ecrf_${this.lastViewportTaskId}`][0].handleSegmentSave(obj)
|
this.$refs[`ecrf_${this.lastViewportTaskId}`][0].handleSegmentSave(obj)
|
||||||
},
|
},
|
||||||
openSegmentForm(obj) {
|
openSegmentForm(obj) {
|
||||||
let { visitInfo } = obj
|
// let { visitInfo, operateStateEnum } = obj
|
||||||
this.segmentVisitInfo = visitInfo
|
this.segmentVisitInfo = obj
|
||||||
this.segmentVisible = true
|
this.segmentVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.SegmentForm.setSeries(this.$refs[`viewport-${this.activeViewportIndex}`][0].series)
|
||||||
|
this.$refs.SegmentForm.init()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
handleClick(tab, event) {
|
handleClick(tab, event) {
|
||||||
this.formWrapperActiveName = tab.name
|
this.formWrapperActiveName = tab.name
|
||||||
|
|
@ -1323,7 +1327,7 @@ export default {
|
||||||
cornerstoneTools.addTool(MIPJumpToClickTool)
|
cornerstoneTools.addTool(MIPJumpToClickTool)
|
||||||
cornerstoneTools.addTool(VolumeRotateTool)
|
cornerstoneTools.addTool(VolumeRotateTool)
|
||||||
cornerstoneTools.addTool(CrosshairsTool)
|
cornerstoneTools.addTool(CrosshairsTool)
|
||||||
cornerstoneTools.addTool(PlanarFreehandContourSegmentationTool)
|
cornerstoneTools.addTool(LabelMapEditWithContourTool)
|
||||||
cornerstoneTools.addTool(BrushTool)
|
cornerstoneTools.addTool(BrushTool)
|
||||||
cornerstoneTools.addTool(SegmentBidirectionalTool)
|
cornerstoneTools.addTool(SegmentBidirectionalTool)
|
||||||
viewportIds.forEach((viewportId, i) => {
|
viewportIds.forEach((viewportId, i) => {
|
||||||
|
|
@ -1364,21 +1368,8 @@ export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
toolGroup.addTool(PlanarFreehandContourSegmentationTool.toolName, {
|
toolGroup.addTool(LabelMapEditWithContourTool.toolName);
|
||||||
cachedStats: true,
|
toolGroup.addTool(SegmentBidirectionalTool.toolName);
|
||||||
});
|
|
||||||
toolGroup.addTool(SegmentBidirectionalTool.toolName, {});
|
|
||||||
// toolGroup.setToolActive(PlanarFreehandContourSegmentationTool.toolName, {
|
|
||||||
// bindings: [
|
|
||||||
// {
|
|
||||||
// mouseButton: MouseBindings.Primary, // Left Click
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// mouseButton: MouseBindings.Primary, // Shift + Left Click
|
|
||||||
// modifierKey: cornerstoneTools.Enums.KeyboardBindings.Shift,
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
if (volumeViewportIds.includes(viewportId)) {
|
if (volumeViewportIds.includes(viewportId)) {
|
||||||
toolGroup.addTool(WindowLevelTool.toolName, {
|
toolGroup.addTool(WindowLevelTool.toolName, {
|
||||||
|
|
@ -1490,7 +1481,7 @@ export default {
|
||||||
toolGroup.setToolPassive(AngleTool.toolName)
|
toolGroup.setToolPassive(AngleTool.toolName)
|
||||||
toolGroup.setToolPassive(CobbAngleTool.toolName)
|
toolGroup.setToolPassive(CobbAngleTool.toolName)
|
||||||
if (this.readingTool === 3) {
|
if (this.readingTool === 3) {
|
||||||
toolGroup.setToolPassive(PlanarFreehandContourSegmentationTool.toolName)
|
toolGroup.setToolPassive(LabelMapEditWithContourTool.toolName)
|
||||||
toolGroup.setToolPassive(SegmentBidirectionalTool.toolName, {});
|
toolGroup.setToolPassive(SegmentBidirectionalTool.toolName, {});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1504,11 +1495,10 @@ export default {
|
||||||
toolGroup.setToolEnabled(FixedRadiusCircleROITool.toolName)
|
toolGroup.setToolEnabled(FixedRadiusCircleROITool.toolName)
|
||||||
toolGroup.setToolEnabled(AngleTool.toolName)
|
toolGroup.setToolEnabled(AngleTool.toolName)
|
||||||
toolGroup.setToolEnabled(CobbAngleTool.toolName)
|
toolGroup.setToolEnabled(CobbAngleTool.toolName)
|
||||||
if (this.readingTool === 3) toolGroup.setToolEnabled(PlanarFreehandContourSegmentationTool.toolName)
|
if (this.readingTool === 3) toolGroup.setToolEnabled(LabelMapEditWithContourTool.toolName)
|
||||||
}
|
}
|
||||||
toolGroup.setToolPassive(EraserTool.toolName)
|
toolGroup.setToolPassive(EraserTool.toolName)
|
||||||
})
|
})
|
||||||
|
|
||||||
eventTarget.addEventListener('cornerstoneimageloadprogress', this.imageLoadProgress)
|
eventTarget.addEventListener('cornerstoneimageloadprogress', this.imageLoadProgress)
|
||||||
// console.log(Events, toolsEvents)
|
// console.log(Events, toolsEvents)
|
||||||
if (this.readingTool === 2) {
|
if (this.readingTool === 2) {
|
||||||
|
|
@ -1517,6 +1507,7 @@ export default {
|
||||||
if ((this.criterionType === 0 && this.readingTool === 0) || this.readingTool === 3) {
|
if ((this.criterionType === 0 && this.readingTool === 0) || this.readingTool === 3) {
|
||||||
this.setUpSynchronizersMPR()
|
this.setUpSynchronizersMPR()
|
||||||
}
|
}
|
||||||
|
renderingEngine.render();
|
||||||
},
|
},
|
||||||
// 影像下载进度回调
|
// 影像下载进度回调
|
||||||
imageLoadProgress(e) {
|
imageLoadProgress(e) {
|
||||||
|
|
@ -1720,7 +1711,7 @@ export default {
|
||||||
if (!annotation) return
|
if (!annotation) return
|
||||||
const i = this.tools.findIndex(i => i.toolName === annotation.metadata.toolName)
|
const i = this.tools.findIndex(i => i.toolName === annotation.metadata.toolName)
|
||||||
if (i === -1) {
|
if (i === -1) {
|
||||||
if (annotation.metadata.toolName !== PlanarFreehandContourSegmentationTool.toolName) this.setToolsPassive()
|
if (annotation.metadata.toolName !== LabelMapEditWithContourTool.toolName) this.setToolsPassive()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (annotation.data.segmentation || annotation.data.segment) return
|
if (annotation.data.segmentation || annotation.data.segment) return
|
||||||
|
|
@ -1807,7 +1798,7 @@ export default {
|
||||||
if (!annotation) return
|
if (!annotation) return
|
||||||
const i = this.tools.findIndex(i => i.toolName === annotation.metadata.toolName)
|
const i = this.tools.findIndex(i => i.toolName === annotation.metadata.toolName)
|
||||||
if (i === -1) {
|
if (i === -1) {
|
||||||
if (annotation.metadata.toolName !== PlanarFreehandContourSegmentationTool.toolName) this.setToolsPassive()
|
if (annotation.metadata.toolName !== LabelMapEditWithContourTool.toolName) this.setToolsPassive()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (annotation.data.segmentation || annotation.data.segment) return
|
if (annotation.data.segmentation || annotation.data.segment) return
|
||||||
|
|
@ -3026,7 +3017,7 @@ export default {
|
||||||
obj.IsMarked = true
|
obj.IsMarked = true
|
||||||
obj.MeasureData = annotation
|
obj.MeasureData = annotation
|
||||||
}
|
}
|
||||||
if (annotation.from === 'MPR' && checkFrom) {
|
if ((annotation.from === 'MPR' || annotation.metadata.volumeId) && checkFrom) {
|
||||||
obj = Object.assign({}, seriesList[seriesIdx])
|
obj = Object.assign({}, seriesList[seriesIdx])
|
||||||
obj.SliceIndex = annotation?.metadata?.sliceIndex
|
obj.SliceIndex = annotation?.metadata?.sliceIndex
|
||||||
obj.IsMarked = true
|
obj.IsMarked = true
|
||||||
|
|
@ -3792,6 +3783,15 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.form-wrapper {
|
||||||
|
::v-deep .el-tabs__nav-scroll {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.read-page-container {
|
.read-page-container {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getSegmentationList, getSegmentList } from '@/api/reading'
|
import { getSegmentationList, getSegmentList, getSegmentBindingList } from '@/api/reading'
|
||||||
export default {
|
export default {
|
||||||
name: 'FusionForm',
|
name: 'FusionForm',
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -64,13 +64,17 @@ export default {
|
||||||
seriesList: [],
|
seriesList: [],
|
||||||
segmentGroupList: [],
|
segmentGroupList: [],
|
||||||
segmentList: [],
|
segmentList: [],
|
||||||
segmentionList: []
|
segmentionList: [],
|
||||||
|
series: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
// mounted() {
|
||||||
this.init()
|
// this.init()
|
||||||
},
|
// },
|
||||||
methods: {
|
methods: {
|
||||||
|
setSeries(series) {
|
||||||
|
this.series = series
|
||||||
|
},
|
||||||
async init() {
|
async init() {
|
||||||
let studyList = this.visitInfo.StudyList
|
let studyList = this.visitInfo.StudyList
|
||||||
let s = await this.getSegmentationList()
|
let s = await this.getSegmentationList()
|
||||||
|
|
@ -82,6 +86,25 @@ export default {
|
||||||
study.SeriesList = study.SeriesList.filter(item => SeriesIds.includes(item.Id))
|
study.SeriesList = study.SeriesList.filter(item => SeriesIds.includes(item.Id))
|
||||||
})
|
})
|
||||||
this.studyList = studyList
|
this.studyList = studyList
|
||||||
|
if (this.visitInfo.operateStateEnum === 21) {
|
||||||
|
this.form.studyId = this.series.StudyId
|
||||||
|
this.form.seriesId = this.series.Id
|
||||||
|
}
|
||||||
|
if (this.visitInfo.operateStateEnum === 22) {
|
||||||
|
let o = {}
|
||||||
|
if (this.isTableQuestion) {
|
||||||
|
o.TableQuestionId = this.visitInfo.operateQuestionId
|
||||||
|
o.RowId = this.visitInfo.operateRowId
|
||||||
|
} else {
|
||||||
|
o.QuestionId = this.visitInfo.operateQuestionId
|
||||||
|
}
|
||||||
|
let list = await this.getSegmentBindingList(o)
|
||||||
|
this.form.segmentGroupId = list[0].SegmentationId
|
||||||
|
this.form.segmentId = list[0].SegmentId
|
||||||
|
let segmentGroup = this.segmentionList.find(item => item.Id === this.form.segmentGroupId)
|
||||||
|
this.form.studyId = segmentGroup.StudyId
|
||||||
|
this.form.seriesId = segmentGroup.SeriesId
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async handleChange(e, key) {
|
async handleChange(e, key) {
|
||||||
if (key === 'study') {
|
if (key === 'study') {
|
||||||
|
|
@ -147,6 +170,23 @@ export default {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 获取当前任务分割标记与问题绑定关系
|
||||||
|
async getSegmentBindingList(param = {}) {
|
||||||
|
try {
|
||||||
|
let data = {
|
||||||
|
VisitTaskId: this.visitInfo.VisitTaskId,
|
||||||
|
PageSize: 9999,
|
||||||
|
PageIndex: 1,
|
||||||
|
}
|
||||||
|
data = Object.assign(data, param)
|
||||||
|
let res = await getSegmentBindingList(data)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
return res.Result.CurrentPageData
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,16 @@
|
||||||
</template>
|
</template>
|
||||||
<div class="tool-frame">
|
<div class="tool-frame">
|
||||||
<div :title="$t('trials:Segmentations:tools:contour')"
|
<div :title="$t('trials:Segmentations:tools:contour')"
|
||||||
|
:class="['tool-item', activeTool === 'LabelMapEditWithContour' && segmentList.length > 0 ? 'tool-item-active' : '']"
|
||||||
|
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) ? 'not-allowed' : 'pointer' }"
|
||||||
|
@click.prevent="setToolActive('LabelMapEditWithContour')">
|
||||||
|
<svg-icon icon-class="contour" class="svg-icon" />
|
||||||
|
</div>
|
||||||
|
<div :title="$t('trials:Segmentations:tools:circularbrush')"
|
||||||
:class="['tool-item', activeTool === 'CircularBrush' && segmentList.length > 0 ? 'tool-item-active' : '']"
|
:class="['tool-item', activeTool === 'CircularBrush' && segmentList.length > 0 ? 'tool-item-active' : '']"
|
||||||
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) ? 'not-allowed' : 'pointer' }"
|
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) ? 'not-allowed' : 'pointer' }"
|
||||||
@click.prevent="setToolActive('CircularBrush')">
|
@click.prevent="setToolActive('CircularBrush')">
|
||||||
<svg-icon icon-class="contour" class="svg-icon" />
|
<svg-icon icon-class="circularbrush" class="svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
<div :class="['tool-item', activeTool === 'CircularEraser' && segmentList.length > 0 ? 'tool-item-active' : '']"
|
<div :class="['tool-item', activeTool === 'CircularEraser' && segmentList.length > 0 ? 'tool-item-active' : '']"
|
||||||
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) ? 'not-allowed' : 'pointer' }"
|
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) ? 'not-allowed' : 'pointer' }"
|
||||||
|
|
@ -38,7 +44,7 @@
|
||||||
</template>
|
</template>
|
||||||
<div class="addSegmentBox viewHover" @click.stop="addSegment" v-if="segmentList.length <= 0">
|
<div class="addSegmentBox viewHover" @click.stop="addSegment" v-if="segmentList.length <= 0">
|
||||||
<span><i class="el-icon-plus"></i>
|
<span><i class="el-icon-plus"></i>
|
||||||
{{ $t('trials:reading:Segmentations:button:addSegment') }}
|
{{ $t('trials:reading:Segmentations:button:addSegmention') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="SegmentConfigBox" v-if="showSegmentConfig && segmentList.length > 0">
|
<div class="SegmentConfigBox" v-if="showSegmentConfig && segmentList.length > 0">
|
||||||
|
|
@ -78,7 +84,7 @@
|
||||||
</el-switch>
|
</el-switch>
|
||||||
<span style="margin-left: 5px;">{{
|
<span style="margin-left: 5px;">{{
|
||||||
$t('trials:reading:Segmentations:title:InactiveSegmentationsShow')
|
$t('trials:reading:Segmentations:title:InactiveSegmentationsShow')
|
||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="SegmentConfig">
|
<div class="SegmentConfig">
|
||||||
<span>{{ $t('trials:reading:Segmentations:title:Opacity') }}</span>
|
<span>{{ $t('trials:reading:Segmentations:title:Opacity') }}</span>
|
||||||
|
|
@ -89,7 +95,7 @@
|
||||||
</div>
|
</div>
|
||||||
<template v-if="segmentList.length > 0">
|
<template v-if="segmentList.length > 0">
|
||||||
<div class="SegmentGroupBox">
|
<div class="SegmentGroupBox">
|
||||||
<el-popover placement="bottom" width="40" trigger="click">
|
<el-popover placement="left" width="40" trigger="click">
|
||||||
<div class="SegmentGroupBtnBox">
|
<div class="SegmentGroupBtnBox">
|
||||||
<div class="SegmentGroupBtn" @click.stop="addSegmentGroup">
|
<div class="SegmentGroupBtn" @click.stop="addSegmentGroup">
|
||||||
{{ $t('trials:reading:Segmentations:button:addSegmentGroup') }}
|
{{ $t('trials:reading:Segmentations:button:addSegmentGroup') }}
|
||||||
|
|
@ -126,8 +132,7 @@
|
||||||
v-for="(item) in curSegmentGroup.segments"
|
v-for="(item) in curSegmentGroup.segments"
|
||||||
:key="`${item.segmentationId}_${item.segmentIndex}`" @click.stop="selectSegment(item)">
|
:key="`${item.segmentationId}_${item.segmentIndex}`" @click.stop="selectSegment(item)">
|
||||||
<div class="messageBox">
|
<div class="messageBox">
|
||||||
<el-popover placement="top-start" :title="item.SegmentLabel" width="200"
|
<el-popover placement="left" :title="item.SegmentLabel" width="200" trigger="hover">
|
||||||
trigger="hover">
|
|
||||||
<div class="Bidirectionalbox">
|
<div class="Bidirectionalbox">
|
||||||
<div class="BidirectionalBtn" @click.stop="getBidirectional(item)"
|
<div class="BidirectionalBtn" @click.stop="getBidirectional(item)"
|
||||||
v-if="!item.bidirectional">
|
v-if="!item.bidirectional">
|
||||||
|
|
@ -140,8 +145,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="btnBox">
|
<div class="btnBox">
|
||||||
<svg-icon :icon-class="!item.bidirectionalView ? 'eye' : 'eye-open'"
|
<svg-icon :icon-class="!item.bidirectionalView ? 'eye' : 'eye-open'"
|
||||||
style="color:#000"
|
style="color:#000;margin-right: 5px;cursor: pointer;"
|
||||||
@click.stop="viewBidirectional(item, !item.bidirectionalView)" />
|
@click.stop="viewBidirectional(item, !item.bidirectionalView)" />
|
||||||
|
<svg-icon icon-class="jumpto" style="color:#000;cursor: pointer;"
|
||||||
|
@click.stop="jumpBidirectional(item)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -149,7 +156,7 @@
|
||||||
<div v-for="k in statsKey" :key="k" class="statsBox">
|
<div v-for="k in statsKey" :key="k" class="statsBox">
|
||||||
<span>{{ k }}</span>
|
<span>{{ k }}</span>
|
||||||
<span v-if="item.stats[k]">{{ Number(item.stats[k].value).toFixed(2)
|
<span v-if="item.stats[k]">{{ Number(item.stats[k].value).toFixed(2)
|
||||||
}}<i>{{ item.stats[k].unit }}</i></span>
|
}}<i>{{ item.stats[k].unit }}</i></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="serialNum" slot="reference">{{ item.segmentIndex }}</div>
|
<div class="serialNum" slot="reference">{{ item.segmentIndex }}</div>
|
||||||
|
|
@ -161,13 +168,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="btnBox">
|
<div class="btnBox">
|
||||||
<svg-icon :icon-class="item && !item.view ? 'eye' : 'eye-open'"
|
<svg-icon :icon-class="item && !item.view ? 'eye' : 'eye-open'"
|
||||||
@click.stop="viewSegment(item, !item.view)"
|
@click.stop="viewSegment(item, !item.view)" class="docShow" />
|
||||||
:class="{ segmentBtn: true, docShow: item.segmentIndex === segmentIndex || !item.view }" />
|
<i class="el-icon-lock" v-if="item.lock" @click.stop="lockSegment(item, false)"></i>
|
||||||
<i class="el-icon-lock" v-if="item.lock"></i>
|
<el-popover placement="bottom" width="40" trigger="click" class="docShow">
|
||||||
<el-popover placement="bottom" width="40" trigger="click"
|
|
||||||
:class="{ segmentBtn: true, docShow: item.segmentIndex === segmentIndex }">
|
|
||||||
<div class="SegmentGroupBtnBox">
|
<div class="SegmentGroupBtnBox">
|
||||||
<div class="SegmentGroupBtn" @click.stop="rename('segment', item.segmentIndex)">
|
<div class="SegmentGroupBtn" @click.stop="rename('segment', item)">
|
||||||
{{ $t('trials:reading:Segmentations:button:renameSegmentGroup') }}
|
{{ $t('trials:reading:Segmentations:button:renameSegmentGroup') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="SegmentGroupBtn" @click.stop="delSegment(item.segmentIndex)">
|
<div class="SegmentGroupBtn" @click.stop="delSegment(item.segmentIndex)">
|
||||||
|
|
@ -203,18 +208,21 @@ import dcmjs from '@/utils/dcmUpload/dcmjs'
|
||||||
import * as cornerstoneAdapters from "@cornerstonejs/adapters";
|
import * as cornerstoneAdapters from "@cornerstonejs/adapters";
|
||||||
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
|
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
|
||||||
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
|
||||||
|
import { getCustomizeStandardsSegmentDicomTools } from './toolConfig'
|
||||||
const {
|
const {
|
||||||
ToolGroupManager,
|
ToolGroupManager,
|
||||||
Enums: csToolsEnums,
|
Enums: csToolsEnums,
|
||||||
segmentation,
|
segmentation,
|
||||||
annotation,
|
annotation,
|
||||||
|
LabelMapEditWithContourTool,
|
||||||
SegmentBidirectionalTool,
|
SegmentBidirectionalTool,
|
||||||
|
CrosshairsTool,
|
||||||
utilities: CStUtils,
|
utilities: CStUtils,
|
||||||
} = cornerstoneTools;
|
} = cornerstoneTools;
|
||||||
const { MouseBindings, Events: toolsEvents } = csToolsEnums
|
const { MouseBindings, Events: toolsEvents } = csToolsEnums
|
||||||
const { segmentation: segmentationUtils, roundNumber } = CStUtils;
|
const { segmentation: segmentationUtils } = CStUtils;
|
||||||
const { cache, getRenderingEngine, imageLoader, eventTarget, metaData, utilities: csUtils, volumeLoader } = cornerstone;
|
const { cache, getRenderingEngine, imageLoader, eventTarget, metaData, utilities: csUtils, volumeLoader } = cornerstone;
|
||||||
const { downloadDICOMData } = cornerstoneAdapters.helpers;
|
// const { downloadDICOMData } = cornerstoneAdapters.helpers;
|
||||||
const { Cornerstone3D } = cornerstoneAdapters.adaptersSEG;
|
const { Cornerstone3D } = cornerstoneAdapters.adaptersSEG;
|
||||||
export default {
|
export default {
|
||||||
name: "Segmentations",
|
name: "Segmentations",
|
||||||
|
|
@ -250,7 +258,11 @@ export default {
|
||||||
default: () => {
|
default: () => {
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
renderingEngineId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -285,8 +297,7 @@ export default {
|
||||||
'#fb628b',
|
'#fb628b',
|
||||||
],
|
],
|
||||||
viewprotIds: ['viewport-0', 'viewport-1', 'viewport-2', 'viewport-3', 'viewport-MPR-0', 'viewport-MPR-1', 'viewport-MPR-2'], //
|
viewprotIds: ['viewport-0', 'viewport-1', 'viewport-2', 'viewport-3', 'viewport-MPR-0', 'viewport-MPR-1', 'viewport-MPR-2'], //
|
||||||
renderingEngineId: 'myRenderingEngine',
|
statsKey: [],
|
||||||
statsKey: ['max', 'min', 'volume', 'count', 'mean', 'stdDev'],
|
|
||||||
drawing: false, // 是否正在分割
|
drawing: false, // 是否正在分割
|
||||||
isDel: false,
|
isDel: false,
|
||||||
digitPlaces: 2
|
digitPlaces: 2
|
||||||
|
|
@ -294,8 +305,9 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.SegmentHight = window.innerHeight * 0.4;
|
this.SegmentHight = window.innerHeight * 0.4;
|
||||||
console.log(segmentation, 'segmentation')
|
this.statsKey = getCustomizeStandardsSegmentDicomTools('Labelmap')[0].props.filter(item => item !== 'width' && item !== 'length')
|
||||||
console.log(annotation, 'annotation')
|
// console.log(segmentation, 'segmentation')
|
||||||
|
// console.log(annotation, 'annotation')
|
||||||
eventTarget.addEventListener(
|
eventTarget.addEventListener(
|
||||||
'CORNERSTONE_TOOLS_SEGMENTATION_DATA_MODIFIED',
|
'CORNERSTONE_TOOLS_SEGMENTATION_DATA_MODIFIED',
|
||||||
this.segmentationModifiedCallback
|
this.segmentationModifiedCallback
|
||||||
|
|
@ -386,6 +398,15 @@ export default {
|
||||||
segmentationId: item.segmentationId,
|
segmentationId: item.segmentationId,
|
||||||
segmentIndices: [item.segmentIndex],
|
segmentIndices: [item.segmentIndex],
|
||||||
});
|
});
|
||||||
|
// console.log(bidirectionalData, 'bidirectionalData')
|
||||||
|
if (bidirectionalData.length <= 0) {
|
||||||
|
let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex);
|
||||||
|
annotations.forEach(i => {
|
||||||
|
annotation.state.removeAnnotation(i.annotationUID)
|
||||||
|
})
|
||||||
|
this.resetViewport(false)
|
||||||
|
item.bidirectional = null
|
||||||
|
}
|
||||||
bidirectionalData.forEach((bidirectional) => {
|
bidirectionalData.forEach((bidirectional) => {
|
||||||
const { segmentIndex } = bidirectional;
|
const { segmentIndex } = bidirectional;
|
||||||
const { majorAxis, minorAxis, maxMajor, maxMinor } = bidirectional;
|
const { majorAxis, minorAxis, maxMajor, maxMinor } = bidirectional;
|
||||||
|
|
@ -418,11 +439,19 @@ export default {
|
||||||
const toolGroupId = this.isMPR ? this.volumeToolGroupId : `${this.viewportKey}-${this.activeViewportIndex}`
|
const toolGroupId = this.isMPR ? this.volumeToolGroupId : `${this.viewportKey}-${this.activeViewportIndex}`
|
||||||
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
|
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
|
||||||
if (this.activeTool === toolName) {
|
if (this.activeTool === toolName) {
|
||||||
toolGroup.setToolPassive(this.activeTool)
|
if (toolName === CrosshairsTool.toolName) {
|
||||||
|
toolGroup.setToolDisabled(this.activeTool)
|
||||||
|
} else {
|
||||||
|
toolGroup.setToolPassive(this.activeTool)
|
||||||
|
}
|
||||||
this.$emit('update:activeTool', '')
|
this.$emit('update:activeTool', '')
|
||||||
} else {
|
} else {
|
||||||
if (this.activeTool) {
|
if (this.activeTool) {
|
||||||
toolGroup.setToolPassive(this.activeTool)
|
if (toolName === CrosshairsTool.toolName) {
|
||||||
|
toolGroup.setToolDisabled(this.activeTool)
|
||||||
|
} else {
|
||||||
|
toolGroup.setToolPassive(this.activeTool)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
toolGroup.setToolActive(toolName, {
|
toolGroup.setToolActive(toolName, {
|
||||||
bindings: [{ mouseButton: MouseBindings.Primary }]
|
bindings: [{ mouseButton: MouseBindings.Primary }]
|
||||||
|
|
@ -442,6 +471,18 @@ export default {
|
||||||
item.bidirectionalView = view
|
item.bidirectionalView = view
|
||||||
this.resetViewport()
|
this.resetViewport()
|
||||||
},
|
},
|
||||||
|
jumpBidirectional(item) {
|
||||||
|
if (item.bidirectional) {
|
||||||
|
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
|
||||||
|
if (!an) return false
|
||||||
|
let referencedImageId = an.metadata.referencedImageId;
|
||||||
|
let sliceIndex = metaData.get('generalImageModule', referencedImageId).instanceNumber
|
||||||
|
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||||
|
const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
|
||||||
|
const viewport = renderingEngine.getViewport(viewportId)
|
||||||
|
csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIndex - 1 });
|
||||||
|
}
|
||||||
|
},
|
||||||
viewSegmentGroup(item) {
|
viewSegmentGroup(item) {
|
||||||
let view = !item.view
|
let view = !item.view
|
||||||
this.viewprotIds.forEach(id => {
|
this.viewprotIds.forEach(id => {
|
||||||
|
|
@ -479,16 +520,7 @@ export default {
|
||||||
this.segmentationId = item.segmentationId;
|
this.segmentationId = item.segmentationId;
|
||||||
this.segmentIndex = item.segmentIndex;
|
this.segmentIndex = item.segmentIndex;
|
||||||
segmentation.segmentIndex.setActiveSegmentIndex(item.segmentationId, item.segmentIndex);
|
segmentation.segmentIndex.setActiveSegmentIndex(item.segmentationId, item.segmentIndex);
|
||||||
if (item.bidirectional) {
|
this.jumpBidirectional(item)
|
||||||
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
|
|
||||||
if (!an) return false
|
|
||||||
let referencedImageId = an.metadata.referencedImageId;
|
|
||||||
let sliceIndex = metaData.get('generalImageModule', referencedImageId).instanceNumber
|
|
||||||
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
|
||||||
const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
|
|
||||||
const viewport = renderingEngine.getViewport(viewportId)
|
|
||||||
csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIndex - 1 });
|
|
||||||
}
|
|
||||||
if (item.lock) {
|
if (item.lock) {
|
||||||
this.$emit('setToolsPassive')
|
this.$emit('setToolsPassive')
|
||||||
}
|
}
|
||||||
|
|
@ -498,7 +530,7 @@ export default {
|
||||||
this.viewprotIds.forEach(id => {
|
this.viewprotIds.forEach(id => {
|
||||||
segmentation.activeSegmentation.setActiveSegmentation(id, this.segmentationId)
|
segmentation.activeSegmentation.setActiveSegmentation(id, this.segmentationId)
|
||||||
})
|
})
|
||||||
this.selectSegment({ segmentIndex: 1 })
|
this.selectSegment({ segmentationId: this.segmentationId, segmentIndex: 1 })
|
||||||
// this.changeSegmentConfig()
|
// this.changeSegmentConfig()
|
||||||
},
|
},
|
||||||
async addSegmentGroup() {
|
async addSegmentGroup() {
|
||||||
|
|
@ -507,6 +539,7 @@ export default {
|
||||||
let obj = {
|
let obj = {
|
||||||
name: this.$t('trials:reading:Segmentations:name:SegmentGroup') + (this.segmentList.length + 1),
|
name: this.$t('trials:reading:Segmentations:name:SegmentGroup') + (this.segmentList.length + 1),
|
||||||
view: true,
|
view: true,
|
||||||
|
segmentationId: null,
|
||||||
segments: []
|
segments: []
|
||||||
}
|
}
|
||||||
let segmentationId = await this.addOrUpdateSegmentation({ name: obj.name })
|
let segmentationId = await this.addOrUpdateSegmentation({ name: obj.name })
|
||||||
|
|
@ -798,7 +831,8 @@ export default {
|
||||||
const RecommendedDisplayCIELabValue = dcmjs.data.Colors.rgb2DICOMLAB(
|
const RecommendedDisplayCIELabValue = dcmjs.data.Colors.rgb2DICOMLAB(
|
||||||
color.slice(0, 3).map(value => value / 255)
|
color.slice(0, 3).map(value => value / 255)
|
||||||
).map(value => Math.round(value));
|
).map(value => Math.round(value));
|
||||||
let SegmentLabel = group.segments.find(item => item.segmentIndex === segmentIndex).SegmentLabel
|
let segment = group.segments.find(item => item.segmentIndex === segmentIndex)
|
||||||
|
let SegmentLabel = segment.SegmentLabel
|
||||||
const segmentMetadata = {
|
const segmentMetadata = {
|
||||||
SegmentNumber: segmentIndex.toString(),
|
SegmentNumber: segmentIndex.toString(),
|
||||||
SegmentLabel: SegmentLabel,
|
SegmentLabel: SegmentLabel,
|
||||||
|
|
@ -816,24 +850,42 @@ export default {
|
||||||
CodeMeaning: "Tissue"
|
CodeMeaning: "Tissue"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
labelmap3D.metadata[segmentIndex] = segmentMetadata;
|
if (segment.bidirectional && segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata;
|
||||||
});
|
});
|
||||||
|
if (labelmap3D.metadata.length <= 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
const generatedSegmentation =
|
const generatedSegmentation =
|
||||||
Cornerstone3D.Segmentation.generateSegmentation(
|
Cornerstone3D.Segmentation.generateSegmentation(
|
||||||
referencedImages,
|
referencedImages,
|
||||||
labelmap3D,
|
labelmap3D,
|
||||||
metaData
|
metaData
|
||||||
);
|
);
|
||||||
console.log(generatedSegmentation.dataset, 'generatedSegmentation.dataset')
|
|
||||||
if (!isFile) {
|
if (!isFile) {
|
||||||
const buffer = Buffer.from(dcmjs.data.datasetToDict(generatedSegmentation.dataset).write());
|
const buffer = Buffer.from(dcmjs.data.datasetToDict(generatedSegmentation.dataset).write());
|
||||||
let blob = new Blob([buffer], { type: "application/dicom" });
|
let blob = new Blob([buffer], { type: "application/dicom" });
|
||||||
return blob
|
return blob
|
||||||
} else {
|
} else {
|
||||||
downloadDICOMData(generatedSegmentation.dataset, `${group.name}.dcm`);
|
this.downloadDICOMData(generatedSegmentation.dataset, `${group.name}.dcm`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
downloadDICOMData(bufferOrDataset, filename) {
|
||||||
|
let blob;
|
||||||
|
if (bufferOrDataset instanceof ArrayBuffer) {
|
||||||
|
blob = new Blob([bufferOrDataset], { type: 'application/dicom' });
|
||||||
|
} else {
|
||||||
|
if (!bufferOrDataset._meta) {
|
||||||
|
throw new Error('Dataset must have a _meta property');
|
||||||
|
}
|
||||||
|
blob = dcmjs.data.datasetToBlob(bufferOrDataset);
|
||||||
|
}
|
||||||
|
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = window.URL.createObjectURL(blob);
|
||||||
|
link.download = filename;
|
||||||
|
link.click();
|
||||||
|
},
|
||||||
|
|
||||||
// 导入SEG
|
// 导入SEG
|
||||||
beginScanFiles(e) {
|
beginScanFiles(e) {
|
||||||
let files = e.target.files
|
let files = e.target.files
|
||||||
|
|
@ -936,14 +988,11 @@ export default {
|
||||||
CStUtils.segmentation.setBrushSizeForToolGroup(toolGroupId, this.brushSize);
|
CStUtils.segmentation.setBrushSizeForToolGroup(toolGroupId, this.brushSize);
|
||||||
},
|
},
|
||||||
async createSegmentation(segmentationId) {
|
async createSegmentation(segmentationId) {
|
||||||
// const derivedSegmentationImages =
|
const toolGroupId = this.isMPR ? this.volumeToolGroupId : `${this.viewportKey}-${this.activeViewportIndex}`
|
||||||
// await imageLoader.createAndCacheDerivedLabelmapImages(
|
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
|
||||||
// this.series.ImageIds
|
toolGroup.setToolActive(
|
||||||
// );
|
LabelMapEditWithContourTool.toolName,
|
||||||
|
);
|
||||||
// const derivedSegmentationImageIds = derivedSegmentationImages.map(
|
|
||||||
// image => image.imageId
|
|
||||||
// );
|
|
||||||
if (!cache.getVolume(segmentationId)) {
|
if (!cache.getVolume(segmentationId)) {
|
||||||
await volumeLoader.createAndCacheDerivedLabelmapVolume(
|
await volumeLoader.createAndCacheDerivedLabelmapVolume(
|
||||||
this.series.SeriesInstanceUid,
|
this.series.SeriesInstanceUid,
|
||||||
|
|
@ -960,7 +1009,6 @@ export default {
|
||||||
type: cornerstoneTools.Enums.SegmentationRepresentations
|
type: cornerstoneTools.Enums.SegmentationRepresentations
|
||||||
.Labelmap,
|
.Labelmap,
|
||||||
data: {
|
data: {
|
||||||
// imageIds: derivedSegmentationImageIds
|
|
||||||
volumeId: segmentationId
|
volumeId: segmentationId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -969,11 +1017,13 @@ export default {
|
||||||
},
|
},
|
||||||
segmentationModifiedCallback(evt) {
|
segmentationModifiedCallback(evt) {
|
||||||
const { detail } = evt;
|
const { detail } = evt;
|
||||||
|
// console.log(detail)
|
||||||
if (detail.segmentIndex === 0) {
|
if (detail.segmentIndex === 0) {
|
||||||
this.drawing = true
|
this.drawing = true
|
||||||
this.isDel = true
|
this.isDel = true
|
||||||
}
|
}
|
||||||
if (!detail || !detail.segmentIndex || detail.segmentIndex === 255) {
|
// || !detail.segmentIndex
|
||||||
|
if (!detail || detail.segmentIndex === 255) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.drawing = true
|
this.drawing = true
|
||||||
|
|
@ -986,13 +1036,12 @@ export default {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (mode === 'individual') {
|
if (mode === 'individual') {
|
||||||
// Handle individual mode where stats is an object with segment indices as keys
|
|
||||||
const segmentStats = stats;
|
const segmentStats = stats;
|
||||||
|
|
||||||
for (const segmentIndex of indices) {
|
for (const segmentIndex of indices) {
|
||||||
if (segmentStats[segmentIndex]) {
|
if (segmentStats[segmentIndex]) {
|
||||||
const segmentStat = segmentStats[segmentIndex];
|
const segmentStat = segmentStats[segmentIndex];
|
||||||
console.log(segmentStat, 'segmentStat')
|
// console.log(segmentStat, 'segmentStat')
|
||||||
segmentStat.count.label = 'Voxels';
|
segmentStat.count.label = 'Voxels';
|
||||||
let segmentGroup = this.segmentList.find(item => item.segmentationId === segmentationId)
|
let segmentGroup = this.segmentList.find(item => item.segmentationId === segmentationId)
|
||||||
let segment = segmentGroup.segments.find(item => item.segmentIndex === segmentIndex)
|
let segment = segmentGroup.segments.find(item => item.segmentIndex === segmentIndex)
|
||||||
|
|
@ -1017,6 +1066,7 @@ export default {
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
this.$emit('setToolsPassive')
|
||||||
},
|
},
|
||||||
contentMouseup() {
|
contentMouseup() {
|
||||||
// console.log("segment contentMouseup")
|
// console.log("segment contentMouseup")
|
||||||
|
|
@ -1131,11 +1181,14 @@ export default {
|
||||||
})
|
})
|
||||||
// 生成文件路径
|
// 生成文件路径
|
||||||
let blob = this.exportSegmentation(segmentGroup.segmentationId, segmentGroup)
|
let blob = this.exportSegmentation(segmentGroup.segmentationId, segmentGroup)
|
||||||
let path = `/${this.$route.query.trialId}/Segment/${this.visitInfo.SubjectId
|
if (blob) {
|
||||||
}/${this.visitInfo.VisistId}/${this.series.StudyId
|
let path = `/${this.$route.query.trialId}/Segment/${this.visitInfo.SubjectId
|
||||||
}/${this.series.Id}/${segmentGroup.name}.dcm`
|
}/${this.visitInfo.VisistId}/${this.series.StudyId
|
||||||
const result = await this.OSSclient.put(path, blob)
|
}/${this.series.Id}/${segmentGroup.name}.dcm`
|
||||||
segmentGroup.segUrl = this.$getObjectName(result.url)
|
const result = await this.OSSclient.put(path, blob)
|
||||||
|
segmentGroup.segUrl = this.$getObjectName(result.url)
|
||||||
|
}
|
||||||
|
|
||||||
this.addOrUpdateSegmentation({ name: segmentGroup.name, id: segmentGroup.segmentationId, url: segmentGroup.segUrl })
|
this.addOrUpdateSegmentation({ name: segmentGroup.name, id: segmentGroup.segmentationId, url: segmentGroup.segUrl })
|
||||||
segmentGroup.segments.forEach(s => {
|
segmentGroup.segments.forEach(s => {
|
||||||
this.addOrUpdateSegment({ name: s.SegmentLabel, color: s.color, segmentIndex: s.segmentIndex, segmentationId: s.segmentationId, segmentJson: JSON.stringify({ stats: s.stats, bidirectional: s.bidirectional }), id: s.id })
|
this.addOrUpdateSegment({ name: s.SegmentLabel, color: s.color, segmentIndex: s.segmentIndex, segmentationId: s.segmentationId, segmentJson: JSON.stringify({ stats: s.stats, bidirectional: s.bidirectional }), id: s.id })
|
||||||
|
|
|
||||||
|
|
@ -608,7 +608,7 @@ export default {
|
||||||
})
|
})
|
||||||
DicomEvent.$on('setTableQuestionAnswer', async (DATA) => {
|
DicomEvent.$on('setTableQuestionAnswer', async (DATA) => {
|
||||||
let { id, answer, ParentQsId, data } = DATA
|
let { id, answer, ParentQsId, data } = DATA
|
||||||
console.log(ParentQsId, this.question.Id)
|
// console.log(ParentQsId, this.question.Id)
|
||||||
if (this.question.Id === ParentQsId) {
|
if (this.question.Id === ParentQsId) {
|
||||||
this.QuestionsForm[id] = answer
|
this.QuestionsForm[id] = answer
|
||||||
if (data.RowId) {
|
if (data.RowId) {
|
||||||
|
|
@ -1456,13 +1456,13 @@ export default {
|
||||||
getAnnotationProp(annotation, prop) {
|
getAnnotationProp(annotation, prop) {
|
||||||
if (!annotation) return
|
if (!annotation) return
|
||||||
let referencedImageId = null
|
let referencedImageId = null
|
||||||
if (annotation.from) {
|
if (annotation.from || annotation.metadata.volumeId) {
|
||||||
referencedImageId = `${annotation?.metadata?.volumeId}?sliceIndex=${annotation?.metadata?.sliceIndex}&viewPlaneNormal=${annotation?.metadata?.viewPlaneNormal.map(i => i == 0 ? 0 : i).join(',')}`
|
referencedImageId = `${annotation?.metadata?.volumeId}?sliceIndex=${annotation?.metadata?.sliceIndex}&viewPlaneNormal=${annotation?.metadata?.viewPlaneNormal.map(i => i == 0 ? Number(0).toFixed(3) : Number(i).toFixed(3)).join(',')}`
|
||||||
} else {
|
} else {
|
||||||
referencedImageId = annotation?.metadata?.referencedImageId
|
referencedImageId = annotation?.metadata?.referencedImageId
|
||||||
}
|
}
|
||||||
if (!referencedImageId) return null
|
if (!referencedImageId) return null
|
||||||
const cacheKey = annotation.from ? `volumeId:${referencedImageId}` : `imageId:${referencedImageId}`
|
const cacheKey = annotation.from || annotation.metadata.volumeId ? `volumeId:${referencedImageId}` : `imageId:${referencedImageId}`
|
||||||
const points = ['x', 'y', 'z'];
|
const points = ['x', 'y', 'z'];
|
||||||
const cachedStats = annotation.markTool === "ArrowAnnotate" ? annotation.data?.handles?.points[0] : annotation.data?.cachedStats?.[cacheKey]
|
const cachedStats = annotation.markTool === "ArrowAnnotate" ? annotation.data?.handles?.points[0] : annotation.data?.cachedStats?.[cacheKey]
|
||||||
const hasProp = cachedStats
|
const hasProp = cachedStats
|
||||||
|
|
|
||||||
|
|
@ -442,7 +442,7 @@ export default {
|
||||||
VIEW_SEGMENT: 23, // 查看分割标记
|
VIEW_SEGMENT: 23, // 查看分割标记
|
||||||
REMOVE_SEGMENT: 24, // 移除分割标记
|
REMOVE_SEGMENT: 24, // 移除分割标记
|
||||||
}
|
}
|
||||||
console.log(obj, 'obj')
|
// console.log(obj, 'obj')
|
||||||
const { question, operateStateEnum, rowId, answer } = obj
|
const { question, operateStateEnum, rowId, answer } = obj
|
||||||
const { Id, IsTableQuestion, ImageTool, ImageToolAttribute, ParentQsId, RowId, QuestionName, QuestionEnName } = question
|
const { Id, IsTableQuestion, ImageTool, ImageToolAttribute, ParentQsId, RowId, QuestionName, QuestionEnName } = question
|
||||||
|
|
||||||
|
|
@ -506,7 +506,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleBindSegment(obj) {
|
handleBindSegment(obj) {
|
||||||
this.$emit("openSegmentForm", { visitInfo: this.visitInfo })
|
this.$emit("openSegmentForm", { visitInfo: this.visitInfo, operateStateEnum: obj.operateStateEnum, isTableQuestion: this.isTableQuestion, operateQuestionId: this.operateQuestionId, operateRowId: this.operateRowId })
|
||||||
},
|
},
|
||||||
handleSegmentSave(obj) {
|
handleSegmentSave(obj) {
|
||||||
let imageToolAttribute = this.imageToolAttribute
|
let imageToolAttribute = this.imageToolAttribute
|
||||||
|
|
@ -1227,13 +1227,13 @@ export default {
|
||||||
getAnnotationProp(annotation, prop) {
|
getAnnotationProp(annotation, prop) {
|
||||||
if (!annotation || !prop) return
|
if (!annotation || !prop) return
|
||||||
let referencedImageId = null
|
let referencedImageId = null
|
||||||
if (annotation.from) {
|
if (annotation.from || annotation.metadata.volumeId) {
|
||||||
referencedImageId = `${annotation?.metadata?.volumeId}?sliceIndex=${annotation?.metadata?.sliceIndex}&viewPlaneNormal=${annotation?.metadata?.viewPlaneNormal.map(i => i == 0 ? 0 : i).join(',')}`
|
referencedImageId = `${annotation?.metadata?.volumeId}?sliceIndex=${annotation?.metadata?.sliceIndex}&viewPlaneNormal=${annotation?.metadata?.viewPlaneNormal.map(i => i == 0 ? Number(0).toFixed(3) : Number(i).toFixed(3)).join(',')}`
|
||||||
} else {
|
} else {
|
||||||
referencedImageId = annotation?.metadata?.referencedImageId
|
referencedImageId = annotation?.metadata?.referencedImageId
|
||||||
}
|
}
|
||||||
if (!referencedImageId) return null
|
if (!referencedImageId) return null
|
||||||
const cacheKey = annotation.from ? `volumeId:${referencedImageId}` : `imageId:${referencedImageId}`
|
const cacheKey = annotation.from || annotation.metadata.volumeId ? `volumeId:${referencedImageId}` : `imageId:${referencedImageId}`
|
||||||
const points = ['x', 'y', 'z']
|
const points = ['x', 'y', 'z']
|
||||||
const cachedStats = annotation.markTool === "ArrowAnnotate" ? annotation.data?.handles?.points[0] : annotation.data?.cachedStats?.[cacheKey]
|
const cachedStats = annotation.markTool === "ArrowAnnotate" ? annotation.data?.handles?.points[0] : annotation.data?.cachedStats?.[cacheKey]
|
||||||
const hasProp = cachedStats
|
const hasProp = cachedStats
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue