分割对象的体素统计以及长短径计算优化、分割组添加状态
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
72d0494baa
commit
307c02725f
|
|
@ -399,4 +399,12 @@ export function getReadingQuestionTrialById(params) {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
// 修改分割组保存状态
|
||||||
|
export function changeSegmentationSavedStatus(data) {
|
||||||
|
return request({
|
||||||
|
url: `/Segmentation/changeSegmentationSavedStatus`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -276,7 +276,6 @@ export default {
|
||||||
let imageId = imageIds[0]
|
let imageId = imageIds[0]
|
||||||
let volume = cache.getVolume(this.volumeId)
|
let volume = cache.getVolume(this.volumeId)
|
||||||
let spacing = volume ? volume.spacing : []
|
let spacing = volume ? volume.spacing : []
|
||||||
console.log(spacing, 'spacing')
|
|
||||||
// if (this.series.orientation === 'AXIAL') imageId = viewport.getCurrentImageId()
|
// if (this.series.orientation === 'AXIAL') imageId = viewport.getCurrentImageId()
|
||||||
if (imageId && volume) {
|
if (imageId && volume) {
|
||||||
this.$emit('setMPRInfo', { type: this.series.orientation, key: "imageNum", value: detail.numberOfSlices })
|
this.$emit('setMPRInfo', { type: this.series.orientation, key: "imageNum", value: detail.numberOfSlices })
|
||||||
|
|
@ -501,7 +500,6 @@ export default {
|
||||||
DicomEvent.$emit("isloaded", {})
|
DicomEvent.$emit("isloaded", {})
|
||||||
}
|
}
|
||||||
}]).then(r => {
|
}]).then(r => {
|
||||||
console.log(this.imageInfo.zoom, 'this.imageInfo.zoom')
|
|
||||||
if (data.isLocation || !this.imageInfo.zoom) {
|
if (data.isLocation || !this.imageInfo.zoom) {
|
||||||
setTimeout(() => { csUtils.jumpToSlice(viewport.element, { imageIndex: data.SliceIndex }); })
|
setTimeout(() => { csUtils.jumpToSlice(viewport.element, { imageIndex: data.SliceIndex }); })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2041,14 +2041,8 @@ export default {
|
||||||
},
|
},
|
||||||
setCrosshairsToolLineColor(viewportId) {
|
setCrosshairsToolLineColor(viewportId) {
|
||||||
let colors = [
|
let colors = [
|
||||||
'#0ca8df',
|
|
||||||
'#ffd10a',
|
'#ffd10a',
|
||||||
'#b6d634',
|
'#b6d634',
|
||||||
'#3fbe95',
|
|
||||||
'#785db0',
|
|
||||||
'#5070dd',
|
|
||||||
'#505372',
|
|
||||||
'#ff994d',
|
|
||||||
'#fb628b',
|
'#fb628b',
|
||||||
]
|
]
|
||||||
let index = viewportId.split("-").pop()
|
let index = viewportId.split("-").pop()
|
||||||
|
|
@ -2534,6 +2528,14 @@ export default {
|
||||||
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].resetOrientationMarkers()
|
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].resetOrientationMarkers()
|
||||||
viewport.resetCamera({ resetPan: true, resetZoom: true, resetToCenter: true })
|
viewport.resetCamera({ resetPan: true, resetZoom: true, resetToCenter: true })
|
||||||
viewport.resetProperties()
|
viewport.resetProperties()
|
||||||
|
if (this.isMPR) {
|
||||||
|
let volume = cache.getVolume(this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].volumeId)
|
||||||
|
const voi = metaData.get('voiLutModule', volume._imageIds[Math.ceil((volume._imageIds.length - 1) / 2)])
|
||||||
|
const lower = voi.windowCenter[0] - voi.windowWidth[0] / 2
|
||||||
|
const upper = voi.windowCenter[0] + voi.windowWidth[0] / 2 - 1
|
||||||
|
console.log(lower, upper)
|
||||||
|
viewport.setProperties({ voiRange: { upper: upper, lower: lower } })
|
||||||
|
}
|
||||||
viewport.render()
|
viewport.render()
|
||||||
renderingEngine.render()
|
renderingEngine.render()
|
||||||
if (this.readingTool === 3) {
|
if (this.readingTool === 3) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form ref="segmentForm" :model="form" label-width="120px" label-position="left">
|
<el-form ref="segmentForm" :model="form" label-width="120px" label-position="left" :rules="rules">
|
||||||
<!-- 检查名称 -->
|
<!-- 检查名称 -->
|
||||||
<el-form-item :label="$t('segment:form:label:studyName')" prop="taskBlindName">
|
<el-form-item :label="$t('segment:form:label:studyName')" prop="taskBlindName">
|
||||||
<el-select v-model="form.studyId" clearable @change="(e) => handleChange(e, 'study')">
|
<el-select v-model="form.studyId" clearable @change="(e) => handleChange(e, 'study')">
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 分割组名称 -->
|
<!-- 分割组名称 -->
|
||||||
<el-form-item :label="$t('segment:form:label:segmentGroupName')" prop="taskBlindName">
|
<el-form-item :label="$t('segment:form:label:segmentGroupName')" prop="segmentGroupId">
|
||||||
<el-select v-model="form.segmentGroupId" clearable @change="(e) => handleChange(e, 'segmentGroup')">
|
<el-select v-model="form.segmentGroupId" clearable @change="(e) => handleChange(e, 'segmentGroup')">
|
||||||
<el-option v-for="item in segmentGroupList" :key="item.Id" :label="item.SegmentationName"
|
<el-option v-for="item in segmentGroupList" :key="item.Id" :label="item.SegmentationName"
|
||||||
:value="item.Id" />
|
:value="item.Id" />
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
<!-- 取消 -->
|
<!-- 取消 -->
|
||||||
<el-button size="mini" @click="handleCancel">{{ $t('common:button:cancel') }}</el-button>
|
<el-button size="mini" @click="handleCancel">{{ $t('common:button:cancel') }}</el-button>
|
||||||
<!-- 确认 -->
|
<!-- 确认 -->
|
||||||
<el-button type="primary" size="mini" @click="handleSave">
|
<el-button type="primary" size="mini" @click="handleSave" :disabled="!form.segmentId">
|
||||||
{{ $t('common:button:confirm') }}</el-button>
|
{{ $t('common:button:confirm') }}</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
@ -65,7 +65,26 @@ export default {
|
||||||
segmentGroupList: [],
|
segmentGroupList: [],
|
||||||
segmentList: [],
|
segmentList: [],
|
||||||
segmentionList: [],
|
segmentionList: [],
|
||||||
series: {}
|
series: {},
|
||||||
|
rules: {
|
||||||
|
segmentGroupId: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (value) {
|
||||||
|
// callback(new Error('请再次输入密码'));
|
||||||
|
let segmentGroup = this.segmentGroupList.find(item => item.Id === value)
|
||||||
|
if (!segmentGroup.IsSaved) {
|
||||||
|
callback(new Error(this.$t('segment:confirm:message:segmentGroupIsNotSave')));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}, trigger: ['blur', 'change']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// mounted() {
|
// mounted() {
|
||||||
|
|
@ -126,7 +145,9 @@ export default {
|
||||||
handleCancel() {
|
handleCancel() {
|
||||||
this.$emit("update:visible", false)
|
this.$emit("update:visible", false)
|
||||||
},
|
},
|
||||||
handleSave() {
|
async handleSave() {
|
||||||
|
let validate = await this.$refs.segmentForm.validate()
|
||||||
|
if (!validate) return false
|
||||||
let segment = this.segmentList.find(item => item.Id === this.form.segmentId)
|
let segment = this.segmentList.find(item => item.Id === this.form.segmentId)
|
||||||
if (segment.SegmentJson) {
|
if (segment.SegmentJson) {
|
||||||
let obj = JSON.parse(segment.SegmentJson)
|
let obj = JSON.parse(segment.SegmentJson)
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,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" v-if="SegmentConfig.InactiveSegmentations.show">
|
<!-- <div class="SegmentConfig" v-if="SegmentConfig.InactiveSegmentations.show">
|
||||||
<span>{{ $t('trials:reading:Segmentations:title:Opacity') }}</span>
|
<span>{{ $t('trials:reading:Segmentations:title:Opacity') }}</span>
|
||||||
|
|
@ -130,28 +130,38 @@
|
||||||
</div>
|
</div>
|
||||||
<template v-if="segmentList.length > 0">
|
<template v-if="segmentList.length > 0">
|
||||||
<div class="SegmentGroupBox">
|
<div class="SegmentGroupBox">
|
||||||
<el-popover placement="left" width="40" trigger="click">
|
<div style="display: flex;align-items: center;">
|
||||||
<div class="SegmentGroupBtnBox">
|
<el-popover placement="left" width="40" trigger="click">
|
||||||
<div class="SegmentGroupBtn" @click.stop="addSegmentGroup">
|
<div class="SegmentGroupBtnBox">
|
||||||
{{ $t('trials:reading:Segmentations:button:addSegmentGroup') }}
|
<div class="SegmentGroupBtn" @click.stop="addSegmentGroup">
|
||||||
|
{{ $t('trials:reading:Segmentations:button:addSegmentGroup') }}
|
||||||
|
</div>
|
||||||
|
<div class="SegmentGroupBtn" @click.stop="rename('segmentGroup')">
|
||||||
|
{{ $t('trials:reading:Segmentations:button:renameSegmentGroup') }}
|
||||||
|
</div>
|
||||||
|
<div class="SegmentGroupBtn" @click.stop="exportSegmentGroup">
|
||||||
|
{{ $t('trials:reading:Segmentations:button:exportSegmentGroup') }}
|
||||||
|
</div>
|
||||||
|
<div class="SegmentGroupBtn" @click.stop="delSegmentGroup">
|
||||||
|
{{ $t('trials:reading:Segmentations:button:deleteSegmentGroup') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="SegmentGroupBtn" @click.stop="rename('segmentGroup')">
|
<i slot="reference" class="el-icon-more" style="cursor: pointer;color:#fff" />
|
||||||
{{ $t('trials:reading:Segmentations:button:renameSegmentGroup') }}
|
</el-popover>
|
||||||
</div>
|
<el-select v-model="segmentationId" placeholder="" @change="selectSegmentGroup">
|
||||||
<div class="SegmentGroupBtn" @click.stop="exportSegmentGroup">
|
<el-option v-for="item in segmentList" :key="`${item.segmentationId}`"
|
||||||
{{ $t('trials:reading:Segmentations:button:exportSegmentGroup') }}
|
:label="item.name" :value="item.segmentationId">
|
||||||
</div>
|
</el-option>
|
||||||
<div class="SegmentGroupBtn" @click.stop="delSegmentGroup">
|
</el-select>
|
||||||
{{ $t('trials:reading:Segmentations:button:deleteSegmentGroup') }}
|
</div>
|
||||||
</div>
|
<div style="float: right;">
|
||||||
</div>
|
<i class="el-icon-warning-outline" style="color:red;margin-right: 5px;"
|
||||||
<i slot="reference" class="el-icon-more" style="cursor: pointer;color:#fff" />
|
:title="$t('trials:reading:Segmentations:tip:segmentationIsNotSave')"
|
||||||
</el-popover>
|
v-if="!curSegmentGroup.isSaved"></i>
|
||||||
<el-select v-model="segmentationId" placeholder="" @change="selectSegmentGroup">
|
<el-button type="success" size="small" @click="saveSegmentGroup([curSegmentGroup])">
|
||||||
<el-option v-for="item in segmentList" :key="`${item.segmentationId}`" :label="item.name"
|
{{ $t("common:button:save") }}
|
||||||
:value="item.segmentationId">
|
</el-button>
|
||||||
</el-option>
|
</div>
|
||||||
</el-select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="addSegmentBox" @click.stop="addSegment"
|
<div class="addSegmentBox" @click.stop="addSegment"
|
||||||
style="display: flex;align-items: center;justify-content: space-between;">
|
style="display: flex;align-items: center;justify-content: space-between;">
|
||||||
|
|
@ -191,7 +201,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">{{ index + 1 }}</div>
|
<div class="serialNum" slot="reference">{{ index + 1 }}</div>
|
||||||
|
|
@ -234,12 +244,12 @@
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
<div class="saveBtnBox">
|
<div class="saveBtnBox">
|
||||||
<el-button type="success" size="small" @click="saveSegmentGroup()">{{ $t("common:button:save")
|
<el-button type="success" size="small" @click="saveSegmentGroup()">{{ $t("common:button:save")
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getSegmentationList, addOrUpdateSegmentation, deleteSegmentation, getSegmentList, addOrUpdateSegment, deleteSegment, getSegmentBindingList, saveSegmentBindingAndAnswer, getReadingTableQuestionTrialById, getReadingQuestionTrialById } from '@/api/reading'
|
import { changeSegmentationSavedStatus, getSegmentationList, addOrUpdateSegmentation, deleteSegmentation, getSegmentList, addOrUpdateSegment, deleteSegment, getSegmentBindingList, saveSegmentBindingAndAnswer, getReadingTableQuestionTrialById, getReadingQuestionTrialById } from '@/api/reading'
|
||||||
import * as cornerstoneTools from '@cornerstonejs/tools';
|
import * as cornerstoneTools from '@cornerstonejs/tools';
|
||||||
import * as cornerstone from "@cornerstonejs/core";
|
import * as cornerstone from "@cornerstonejs/core";
|
||||||
import dcmjs from '@/utils/dcmUpload/dcmjs'
|
import dcmjs from '@/utils/dcmUpload/dcmjs'
|
||||||
|
|
@ -352,7 +362,7 @@ export default {
|
||||||
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'], //
|
||||||
statsKey: [],
|
statsKey: [],
|
||||||
drawing: false, // 是否正在分割
|
drawing: false, // 是否正在分割
|
||||||
isDel: false,
|
// isDel: false,
|
||||||
digitPlaces: 2,
|
digitPlaces: 2,
|
||||||
isloaded: false,
|
isloaded: false,
|
||||||
popoverId: null
|
popoverId: null
|
||||||
|
|
@ -462,7 +472,9 @@ export default {
|
||||||
this.actionConfiguration.contourBidirectional.data.segmentationId = segmentationId
|
this.actionConfiguration.contourBidirectional.data.segmentationId = segmentationId
|
||||||
this.actionConfiguration.contourBidirectional.data.segmentIndex = segmentIndex
|
this.actionConfiguration.contourBidirectional.data.segmentIndex = segmentIndex
|
||||||
},
|
},
|
||||||
addTip(item) {
|
async addTip(item) {
|
||||||
|
let segmentGroup = this.segmentList.filter(item => i.segmentationId === i.segmentationId)
|
||||||
|
await this.saveSegmentGroup(segmentGroup, false)
|
||||||
this.calculateStatistics([item.segmentIndex], item.segmentationId, 'individual');
|
this.calculateStatistics([item.segmentIndex], item.segmentationId, 'individual');
|
||||||
this.getBidirectional([item])
|
this.getBidirectional([item])
|
||||||
|
|
||||||
|
|
@ -633,6 +645,7 @@ export default {
|
||||||
lockSegment(item, lock) {
|
lockSegment(item, lock) {
|
||||||
segmentation.segmentLocking.setSegmentIndexLocked(item.segmentationId, item.segmentIndex, lock)
|
segmentation.segmentLocking.setSegmentIndexLocked(item.segmentationId, item.segmentIndex, lock)
|
||||||
item.lock = lock
|
item.lock = lock
|
||||||
|
if (!lock) this.changeSegmentationSavedStatus(item.segmentationId, lock)
|
||||||
},
|
},
|
||||||
selectSegment(item) {
|
selectSegment(item) {
|
||||||
this.segmentationId = item.segmentationId;
|
this.segmentationId = item.segmentationId;
|
||||||
|
|
@ -659,6 +672,7 @@ export default {
|
||||||
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,
|
segmentationId: null,
|
||||||
|
isSaved: false,
|
||||||
segments: []
|
segments: []
|
||||||
}
|
}
|
||||||
let segmentationId = await this.addOrUpdateSegmentation({ name: obj.name })
|
let segmentationId = await this.addOrUpdateSegmentation({ name: obj.name })
|
||||||
|
|
@ -693,6 +707,7 @@ export default {
|
||||||
let obj = {
|
let obj = {
|
||||||
name: this.$t('trials:reading:Segmentations:name:SegmentGroup') + 1,
|
name: this.$t('trials:reading:Segmentations:name:SegmentGroup') + 1,
|
||||||
view: true,
|
view: true,
|
||||||
|
isSaved: false,
|
||||||
segments: []
|
segments: []
|
||||||
}
|
}
|
||||||
let segmentationId = await this.addOrUpdateSegmentation({ name: obj.name })
|
let segmentationId = await this.addOrUpdateSegmentation({ name: obj.name })
|
||||||
|
|
@ -820,7 +835,7 @@ export default {
|
||||||
this.selectSegment(this.segmentList[groupIndex].segments[0])
|
this.selectSegment(this.segmentList[groupIndex].segments[0])
|
||||||
}
|
}
|
||||||
this.$emit('resetQuestion')
|
this.$emit('resetQuestion')
|
||||||
this.saveSegmentGroup([this.segmentList[groupIndex]])
|
this.saveSegmentGroup([this.segmentList[groupIndex]], false)
|
||||||
|
|
||||||
},
|
},
|
||||||
resetViewport(passive = true) {
|
resetViewport(passive = true) {
|
||||||
|
|
@ -995,7 +1010,7 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (segment.bidirectional && segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata;
|
if (segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (labelmap3D.metadata.length <= 0) {
|
if (labelmap3D.metadata.length <= 0) {
|
||||||
|
|
@ -1207,12 +1222,6 @@ export default {
|
||||||
},
|
},
|
||||||
segmentationModifiedCallback(evt) {
|
segmentationModifiedCallback(evt) {
|
||||||
const { detail } = evt;
|
const { detail } = evt;
|
||||||
// console.log(detail)
|
|
||||||
if (detail.segmentIndex === 0) {
|
|
||||||
this.drawing = true
|
|
||||||
this.isDel = true
|
|
||||||
}
|
|
||||||
// || !detail.segmentIndex
|
|
||||||
if (!detail || detail.segmentIndex === 255) {
|
if (!detail || detail.segmentIndex === 255) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1271,31 +1280,24 @@ export default {
|
||||||
this.timeoutId = setTimeout(() => {
|
this.timeoutId = setTimeout(() => {
|
||||||
this.timeoutId = null;
|
this.timeoutId = null;
|
||||||
this.drawing = false;
|
this.drawing = false;
|
||||||
if (!this.isDel) {
|
let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
|
||||||
this.calculateStatistics([this.segmentIndex], this.segmentationId, 'individual');
|
if (segmentGroup && segmentGroup.segments && segmentGroup.segments.length > 0) {
|
||||||
let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
|
let segmentIndexs = []
|
||||||
let segment = segmentGroup ? segmentGroup.segments.find(item => item.segmentIndex === this.segmentIndex) : null
|
segmentGroup.segments.forEach(item => {
|
||||||
if (segment) this.getBidirectional([segment])
|
segmentIndexs.push(item.segmentIndex)
|
||||||
} else {
|
item.bidirectional = null
|
||||||
let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
|
item.stats = null
|
||||||
if (segmentGroup && segmentGroup.segments && segmentGroup.segments.length > 0) {
|
})
|
||||||
let segmentIndexs = []
|
annotation.state.getAllAnnotations().forEach(i => {
|
||||||
segmentGroup.segments.forEach(item => {
|
if (i.metadata.segmentationId === this.segmentationId && i.metadata.toolName === "SegmentBidirectional") {
|
||||||
segmentIndexs.push(item.segmentIndex)
|
annotation.state.removeAnnotation(i.annotationUID)
|
||||||
})
|
}
|
||||||
annotation.state.getAllAnnotations().forEach(i => {
|
})
|
||||||
if (i.metadata.segmentationId === this.segmentationId && i.metadata.toolName === "SegmentBidirectional") {
|
this.calculateStatistics(segmentIndexs, this.segmentationId, 'individual');
|
||||||
annotation.state.removeAnnotation(i.annotationUID)
|
this.resetViewport(false)
|
||||||
}
|
// this.getBidirectional(segmentGroup.segments)
|
||||||
})
|
|
||||||
this.calculateStatistics(segmentIndexs, this.segmentationId, 'individual');
|
|
||||||
this.getBidirectional(segmentGroup.segments)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
this.isDel = false
|
|
||||||
|
|
||||||
}, 500);
|
}, 500);
|
||||||
},
|
},
|
||||||
// 获取当前任务分割标记与问题绑定关系
|
// 获取当前任务分割标记与问题绑定关系
|
||||||
|
|
@ -1331,51 +1333,28 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 保存整个分组
|
// 保存整个分组
|
||||||
async saveSegmentGroup(list = null) {
|
async saveSegmentGroup(list = null, saveSegment = true) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
let segmentList = list ? list : this.segmentList
|
let segmentList = list ? list : this.segmentList
|
||||||
if (segmentList.length <= 0) return false
|
if (segmentList.length <= 0) return false
|
||||||
this.$emit("setToolsPassive")
|
this.$emit("setToolsPassive")
|
||||||
let questionNeedChange = false;
|
let questionNeedChange = false;
|
||||||
let bindingList = []
|
if (saveSegment) {
|
||||||
for (let i = 0; i < segmentList.length; i++) {
|
for (let i = 0; i < segmentList.length; i++) {
|
||||||
let segmentGroup = segmentList[i]
|
let segmentGroup = segmentList[i]
|
||||||
let data = {
|
let data = {
|
||||||
SegmentationId: segmentGroup.segmentationId
|
SegmentationId: segmentGroup.segmentationId
|
||||||
}
|
|
||||||
let res = await this.getSegmentBindingList(data)
|
|
||||||
if (res && res.length > 0) questionNeedChange = true
|
|
||||||
for (let j = 0; j < res.length; j++) {
|
|
||||||
let item = res[j]
|
|
||||||
let segment = segmentGroup.segments.find(d => d.id === item.SegmentId)
|
|
||||||
let question = await this.getQuestionConfig(item.TableQuestionId ? item.TableQuestionId : item.QuestionId, !!item.TableQuestionId);
|
|
||||||
let imageToolAttribute = question.ImageToolAttribute
|
|
||||||
let answer = ''
|
|
||||||
if (imageToolAttribute === 'length' || imageToolAttribute === 'width') {
|
|
||||||
let s = {
|
|
||||||
length: "maxMajor",
|
|
||||||
width: 'maxMinor'
|
|
||||||
}
|
|
||||||
answer = segment.bidirectional && segment.bidirectional[s[imageToolAttribute]] ? Number(segment.bidirectional[s[imageToolAttribute]]).toFixed(this.digitPlaces) : ''
|
|
||||||
} else {
|
|
||||||
answer = segment.stats && segment.stats[imageToolAttribute] ? Number((segment.stats[imageToolAttribute]).value).toFixed(this.digitPlaces) : ''
|
|
||||||
}
|
}
|
||||||
let o = {
|
let res = await this.getSegmentBindingList(data)
|
||||||
Answer: answer,
|
if (res && res.length > 0) {
|
||||||
QuestionId: item.QuestionId,
|
questionNeedChange = true
|
||||||
RowId: item.RowId,
|
break
|
||||||
SegmentId: item.SegmentId,
|
|
||||||
SegmentationId: item.SegmentationId,
|
|
||||||
TableQuestionId: item.TableQuestionId,
|
|
||||||
VisitTaskId: this.visitInfo.VisitTaskId,
|
|
||||||
}
|
}
|
||||||
bindingList.push(o)
|
|
||||||
}
|
}
|
||||||
}
|
if (questionNeedChange) {
|
||||||
if (questionNeedChange) {
|
let confirm = await this.$confirm(this.$t("segment:confirm:questionNeedChange"))
|
||||||
let confirm = await this.$confirm(this.$t("segment:confirm:questionNeedChange"))
|
if (!confirm) return false
|
||||||
if (!confirm) return false
|
}
|
||||||
}
|
}
|
||||||
this.$emit("update:globalLoading", true)
|
this.$emit("update:globalLoading", true)
|
||||||
this.$emit("update:loadingText", this.$t("segment:loadingText:saveSegmentation"))
|
this.$emit("update:loadingText", this.$t("segment:loadingText:saveSegmentation"))
|
||||||
|
|
@ -1387,6 +1366,7 @@ export default {
|
||||||
})
|
})
|
||||||
// 生成文件路径
|
// 生成文件路径
|
||||||
let blob = this.exportSegmentation(segmentGroup.segmentationId, segmentGroup)
|
let blob = this.exportSegmentation(segmentGroup.segmentationId, segmentGroup)
|
||||||
|
console.log(blob, 'blob')
|
||||||
// if (!blob) return false
|
// if (!blob) return false
|
||||||
if (blob) {
|
if (blob) {
|
||||||
let path = `/${this.$route.query.trialId}/Segment/${this.visitInfo.SubjectId
|
let path = `/${this.$route.query.trialId}/Segment/${this.visitInfo.SubjectId
|
||||||
|
|
@ -1397,17 +1377,126 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 => {
|
this.changeSegmentationSavedStatus(segmentGroup.segmentationId, saveSegment)
|
||||||
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 })
|
if (saveSegment) {
|
||||||
})
|
await this.getBidirectionalSaveSegment(list)
|
||||||
|
this.syncBindingAnswer(list)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (bindingList.length > 0) this.saveSegmentBindingAndAnswer(bindingList)
|
|
||||||
this.$emit("update:globalLoading", false)
|
this.$emit("update:globalLoading", false)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 获取长短径并提交分割段
|
||||||
|
async getBidirectionalSaveSegment(list) {
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
let segmentGroup = list[i]
|
||||||
|
if (segmentGroup.segments && segmentGroup.segments.length > 0) {
|
||||||
|
for (let j = 0; j < segmentGroup.segments.length; j++) {
|
||||||
|
let segment = segmentGroup.segments[j]
|
||||||
|
let res = await Promise.race([this.getBidirectionalToSegment([segment]), this.setDelay(300000)])
|
||||||
|
if (res) {
|
||||||
|
this.addOrUpdateSegment({ name: segment.SegmentLabel, color: segment.color, segmentIndex: segment.segmentIndex, segmentationId: segment.segmentationId, segmentJson: JSON.stringify({ stats: segment.stats, bidirectional: segment.bidirectional }), id: segment.id })
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
getBidirectionalToSegment(list) {
|
||||||
|
return new Promise(async (reslove, reject) => {
|
||||||
|
list.forEach(item => {
|
||||||
|
this.createSegmentConfiguration(item.segmentIndex, item.segmentationId);
|
||||||
|
})
|
||||||
|
|
||||||
|
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||||
|
const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
|
||||||
|
const viewport = renderingEngine.getViewport(viewportId);
|
||||||
|
[viewport.element].forEach(async (element) => {
|
||||||
|
const bidirectionalData =
|
||||||
|
await CStUtils.segmentation.getSegmentLargestBidirectional({
|
||||||
|
segmentationId: list[0].segmentationId,
|
||||||
|
segmentIndices: list.map(item => item.segmentIndex),
|
||||||
|
});
|
||||||
|
console.log(bidirectionalData)
|
||||||
|
if (bidirectionalData.length <= 0) {
|
||||||
|
list.forEach(item => {
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
item.bidirectional = null
|
||||||
|
})
|
||||||
|
this.resetViewport(false)
|
||||||
|
return reslove(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
let bidirectional = bidirectionalData[0]
|
||||||
|
const { segmentIndex } = bidirectional;
|
||||||
|
const { majorAxis, minorAxis, maxMajor, maxMinor } = bidirectional;
|
||||||
|
let item = list.find(i => i.segmentIndex === segmentIndex)
|
||||||
|
SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], {
|
||||||
|
segmentIndex,
|
||||||
|
segmentationId: item.segmentationId,
|
||||||
|
});
|
||||||
|
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
|
||||||
|
if (an) {
|
||||||
|
annotation.locking.setAnnotationLocked(an.annotationUID, true)
|
||||||
|
annotation.visibility.setAnnotationVisibility(an.annotationUID, item.bidirectionalView)
|
||||||
|
}
|
||||||
|
item.bidirectional = bidirectional
|
||||||
|
reslove(true)
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
setDelay(time) {
|
||||||
|
return new Promise(async (reslove, reject) => {
|
||||||
|
setTimeout(() => { reslove(true) }, time)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async syncBindingAnswer(segmentList) {
|
||||||
|
let bindingList = []
|
||||||
|
for (let i = 0; i < segmentList.length; i++) {
|
||||||
|
let segmentGroup = segmentList[i]
|
||||||
|
let data = {
|
||||||
|
SegmentationId: segmentGroup.segmentationId
|
||||||
|
}
|
||||||
|
let res = await this.getSegmentBindingList(data)
|
||||||
|
if (res && res.length > 0) questionNeedChange = true
|
||||||
|
for (let j = 0; j < res.length; j++) {
|
||||||
|
let item = res[j]
|
||||||
|
let segment = segmentGroup.segments.find(d => d.id === item.SegmentId)
|
||||||
|
let question = await this.getQuestionConfig(item.TableQuestionId ? item.TableQuestionId : item.QuestionId, !!item.TableQuestionId);
|
||||||
|
let imageToolAttribute = question.ImageToolAttribute
|
||||||
|
let answer = ''
|
||||||
|
if (imageToolAttribute === 'length' || imageToolAttribute === 'width') {
|
||||||
|
let s = {
|
||||||
|
length: "maxMajor",
|
||||||
|
width: 'maxMinor'
|
||||||
|
}
|
||||||
|
answer = segment.bidirectional && segment.bidirectional[s[imageToolAttribute]] ? Number(segment.bidirectional[s[imageToolAttribute]]).toFixed(this.digitPlaces) : ''
|
||||||
|
} else {
|
||||||
|
answer = segment.stats && segment.stats[imageToolAttribute] ? Number((segment.stats[imageToolAttribute]).value).toFixed(this.digitPlaces) : ''
|
||||||
|
}
|
||||||
|
let o = {
|
||||||
|
Answer: answer,
|
||||||
|
QuestionId: item.QuestionId,
|
||||||
|
RowId: item.RowId,
|
||||||
|
SegmentId: item.SegmentId,
|
||||||
|
SegmentationId: item.SegmentationId,
|
||||||
|
TableQuestionId: item.TableQuestionId,
|
||||||
|
VisitTaskId: this.visitInfo.VisitTaskId,
|
||||||
|
}
|
||||||
|
bindingList.push(o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bindingList.length > 0) this.saveSegmentBindingAndAnswer(bindingList)
|
||||||
|
},
|
||||||
// 新增或修改分割组
|
// 新增或修改分割组
|
||||||
async addOrUpdateSegmentation(item) {
|
async addOrUpdateSegmentation(item) {
|
||||||
let { name, id, url } = item
|
let { name, id, url } = item
|
||||||
|
|
@ -1458,6 +1547,7 @@ export default {
|
||||||
name: item.SegmentationName,
|
name: item.SegmentationName,
|
||||||
view: true,
|
view: true,
|
||||||
segUrl: item.SEGUrl,
|
segUrl: item.SEGUrl,
|
||||||
|
isSaved: item.IsSaved,
|
||||||
segments: []
|
segments: []
|
||||||
}
|
}
|
||||||
this.segmentList.push(obj)
|
this.segmentList.push(obj)
|
||||||
|
|
@ -1593,6 +1683,23 @@ export default {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 修改分割组状态
|
||||||
|
async changeSegmentationSavedStatus(Id, IsSaved) {
|
||||||
|
try {
|
||||||
|
let params = {
|
||||||
|
IsSaved,
|
||||||
|
Id
|
||||||
|
}
|
||||||
|
let res = await changeSegmentationSavedStatus(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
let segmentGroup = this.segmentList.find(item => item.segmentationId === Id)
|
||||||
|
if (segmentGroup) segmentGroup.isSaved = IsSaved
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
hex2Rgb(hexValue, alpha = 1) {
|
hex2Rgb(hexValue, alpha = 1) {
|
||||||
const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||||
const hex = hexValue.replace(rgx, (m, r, g, b) => r + r + g + g + b + b);
|
const hex = hexValue.replace(rgx, (m, r, g, b) => r + r + g + g + b + b);
|
||||||
|
|
@ -1712,6 +1819,7 @@ export default {
|
||||||
|
|
||||||
.BidirectionalBtn {
|
.BidirectionalBtn {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.num {
|
.num {
|
||||||
|
|
@ -1836,6 +1944,7 @@ export default {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
i {
|
i {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue