当前位置: 首页 > news >正文

基于cornerstone3D的dicom影像浏览器 第五章 在Displayer四个角落显示信息

先看效果

dicom四个角落显示信息

1.在displayer.vue文件中引入对应的依赖

import { vec3 } from "gl-matrix";
import {RenderingEngine,getRenderingEngine,Enums,utilities as csUtils,
} from "@cornerstonejs/core";
const { IMAGE_RENDERED, CAMERA_MODIFIED } = Enums.Events;
import { utilities } from "@cornerstonejs/tools";
const { getOrientationStringLPS, invertOrientationStringLPS } =utilities.orientation;

2.监听事件

mounted() {...this.$refs.displayer.addEventListener(IMAGE_RENDERED, this.onImageRendered);this.$refs.displayer.addEventListener(CAMERA_MODIFIED,this.onCameraModified);...},

3.相关函数

methods:{onImageRendered() {if (!this.state.series) return;this.drawText();},onCameraModified(event) {if (!this.state.series) return;const markers = this.getOrientationMarkers({image: this.state.image,camera: event.detail.camera,rotation: event.detail.rotation,});this.orientation.top = markers.top;this.orientation.bottom = markers.bottom;this.orientation.left = markers.left;this.orientation.right = markers.right;},drawText() {const canvas = this.$refs.displayer.querySelector(".cornerstone-canvas");const context = canvas.getContext("2d");const cvs_w = canvas.clientWidth;const cvs_h = canvas.clientHeight;const mtx = context.getTransform();context.resetTransform();context.font = "14px Arial";context.fillStyle = "white";context.textAlign = "left";context.textBaseline = "top";const idx = this.state.viewport.getCurrentImageIdIndex();const imageId = this.state.imageIds[idx];const image = this.state.series.GetImageById(imageId);let x = 5;let y = 5;let h = 17;let val;// 左上角 left-top// 姓名val = image.PatientName;context.fillText(val, x, y);y += h;// PatientIdval = image.PatientID;context.fillText(val, x, y);y += h;// 年龄(或者生日)+性别val = image.AgeAndSex;if (val) {context.fillText(val, x, y);y += h;}// Image Commentsval = image.ImageComments;if (val) {context.fillText(val, x, y);y += h;}// 左下角 left-bottomy = cvs_h - h;// 医院名val = image.HospitalName;if (val) {context.fillText(val, x, y);y -= h;}// 图像时间val = image.ContentDate + " " + image.ContentTime;if (val) {context.fillText(val, x, y);y -= h;}// Study Descriptionval = image.StudyDesc;if (val) {context.fillText(val, x, y);y -= h;}//series Descriptionval = image.SeriesDesc;if (val) {context.fillText(val, x, y);y -= h;}//患者方向val = image.PatientPosition;if (val) {context.fillText(val, x, y);y -= h;}// 右上角 right-topconst rmargin = 5;y = 5;const range = this.state.viewport.getProperties().voiRange || {lower: -1024,upper: 1024,};const wwwl = csUtils.windowLevel.toWindowLevel(range.lower, range.upper);val = "WL:" + wwwl.windowCenter.toFixed(0);val += " WW:" + wwwl.windowWidth.toFixed(0);x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y += h;// Image No-Countval = "Im:" + (idx + 1) + "/" + this.state.series.GetCount();x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y += h;// Series Noval = image.SeriesNo;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y += h;}// modalityval = image.DeviceName;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);}// 右下角 right-bottomy = cvs_h - h;// Thickness-Locationval = image.ThicknessLocation;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y -= h;}// 曝光参数val = image.Exposure;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y -= h;}// 拍片参数val = image.TrTe;if (val) {x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);y -= h;}// Zoomconst imageData = this.state.viewport.getImageData();const camera = this.state.viewport.getCamera();let spacing = [1, 1, 1];if (imageData) {spacing = imageData.spacing;}const t = cvs_h * spacing[1] * 0.5;const scale = t / camera.parallelScale;val = "Zoom:" + scale.toFixed(2);x = cvs_w - rmargin - context.measureText(val).width;context.fillText(val, x, y);context.setTransform(mtx);},getOrientationMarkers({ camera, rotation }) {// const { rotation, previousCamera, camera } = detail;let flipVertical = camera.flipVertical || false;let flipHorizontal = camera.flipHorizontal || false;let newRotation = rotation || 0;let rowCosines, columnCosines;const { viewUp, viewPlaneNormal } = camera;const viewRight = vec3.create();vec3.cross(viewRight, viewUp, viewPlaneNormal);columnCosines = [-viewUp[0], -viewUp[1], -viewUp[2]];rowCosines = viewRight;const rowString = getOrientationStringLPS(rowCosines);const columnString = getOrientationStringLPS(columnCosines);const oppositeRowString = invertOrientationStringLPS(rowString);const oppositeColumnString = invertOrientationStringLPS(columnString);const markers = {top: oppositeColumnString,left: oppositeRowString,right: rowString,bottom: columnString,};// If any vertical or horizontal flips are applied, change the orientation strings ahead of// the rotation applicationsif (flipVertical) {markers.top = invertOrientationStringLPS(markers.top);markers.bottom = invertOrientationStringLPS(markers.bottom);}if (flipHorizontal) {markers.left = invertOrientationStringLPS(markers.left);markers.right = invertOrientationStringLPS(markers.right);}// Swap the labels accordingly if the viewport has been rotated// This could be done in a more complex way for intermediate rotation values (e.g. 45 degrees)if (newRotation === 90 || newRotation === -270) {return {top: markers.left,left: invertOrientationStringLPS(markers.top),right: invertOrientationStringLPS(markers.bottom),bottom: markers.right, // left};} else if (newRotation === -90 || newRotation === 270) {return {top: invertOrientationStringLPS(markers.left),left: markers.top,bottom: markers.left,right: markers.bottom,};} else if (newRotation === 180 || newRotation === -180) {return {top: invertOrientationStringLPS(markers.top),left: invertOrientationStringLPS(markers.left),bottom: invertOrientationStringLPS(markers.bottom),right: invertOrientationStringLPS(markers.right),};}return markers;},
}


文章转载自:

http://dZgrRrBh.kqcqr.cn
http://ObczKNk7.kqcqr.cn
http://Reho7xaL.kqcqr.cn
http://PKETFvaP.kqcqr.cn
http://26UBJaEb.kqcqr.cn
http://qLoC5Aeg.kqcqr.cn
http://V35awC6y.kqcqr.cn
http://8U1PdR61.kqcqr.cn
http://fpIj2JVo.kqcqr.cn
http://exa9BfCD.kqcqr.cn
http://gKS4xOJy.kqcqr.cn
http://2xXxPHGA.kqcqr.cn
http://mevhWBVQ.kqcqr.cn
http://3MGRqaLZ.kqcqr.cn
http://o0A13mZ1.kqcqr.cn
http://XT58QQdM.kqcqr.cn
http://7YJoZ0ZQ.kqcqr.cn
http://xFUSYpVY.kqcqr.cn
http://cyqsI1xg.kqcqr.cn
http://DtRnSW5S.kqcqr.cn
http://HAGc0jm5.kqcqr.cn
http://2veYDfgG.kqcqr.cn
http://ft4axc6d.kqcqr.cn
http://wwthXuYl.kqcqr.cn
http://kUNuZhqZ.kqcqr.cn
http://k7lycqpv.kqcqr.cn
http://AO3o9DSP.kqcqr.cn
http://2406ngo4.kqcqr.cn
http://aXr6Jdqh.kqcqr.cn
http://0f48ooQd.kqcqr.cn
http://www.dtcms.com/a/368846.html

相关文章:

  • 3Ds Max Gamma值完全指南:问题识别与正确设置解析
  • Chrome 插件开发入门指南:从基础到实践
  • 《sklearn机器学习——聚类性能指标》调整兰德指数、基于互信息(mutual information)的得分
  • Bug排查日记:高效记录与解决之道
  • [TryHackMe]Wordpress: CVE-2021-29447(wp漏洞利用-SSRF+WpGetShell)
  • Chrome 插件开发入门:打造个性化浏览器扩展
  • 今天一天三面,明天加油DW!!!
  • Java基础篇02:基本语法
  • 当前的大部分的AI,可能已经分到了传统那桌了!Causal AI:颠覆传统机器学习的下一代人工智能技术,让AI真正理解“为什么“!
  • Firefox Window 开发流程(二)
  • 树莓派传感器扩展板资料
  • setup函数相关【3】
  • 基于单片机坐姿提醒系统/久坐提醒设计
  • 请求超过Spring线程池的最大线程(处理逻辑)
  • 使用buildroot交叉编译swupdate 记录
  • PyTorch 中的循环神经网络 (RNN/LSTM):时序数据处理实战指南
  • Preprocessing Model in MPC 7 - Matrix Triples and Convolutions Lookup Tables
  • 职场突围:我的转岗反思录
  • Nature Electronics 用于解码疲劳水平的眼睑软体磁弹性传感器
  • 【AI产品思路】AI 原型设计工具横评:产品经理视角下的 v0、Bolt 与 Lovable
  • 如何使用宝塔API批量操作Windows目录文件:从获取文件列表到删除文件的完整示例
  • 极大似然估计与概率图模型:统计建模的黄金组合
  • K8S删除命名空间卡住一直Terminating状态
  • 【清爽加速】Windows 11 Pro 24H2-Emmy精简系统
  • Overleaf教程+Latex教程
  • 获取DLL动态库的版本信息(dumpbin.exe)
  • AI时代企业获取精准流量与实现增长的GEO新引擎
  • 基于单片机老人居家环境健康检测/身体健康检测设计
  • Qt---字节数据处理QByteArray
  • 无字母数字命令执行