c++如何实现对硬盘的操作_放疗趣味操作——如何实现“放疗剂量”绘画

d97a65f0d02d7abf2ac449d519a1b584.png

指导老师: 曾彪  湖南省肿瘤医院 

0925e5587a0492a9e89d7522ef492a67.png

f182e6c725a4790264db2ae2c448a3dc.png

   肿瘤放射治疗已经经历了100多年的发展历程,放射治疗始终追求着一个明确的目标:肿瘤组织接受最佳剂量,危及器官尽可能接受最低的剂量。当前,放射治疗已经从传统的“常规照射”(大面积照射、精准度不高)时代进入到成熟的“精准制导”(三维精准定位、靶区精准勾画、实施精准打击)时代。我们不仅仅实现了靶区精准勾画,而且已经可以进行“放疗剂量雕刻”,最大限度的实现临床医生的诊疗思路,做出一个满意的放疗计划方案,进而达到即可以保证肿瘤完全被高剂量覆盖,又可降低周边组织器官的放疗剂量,从而尽量减少健康组织的损害,又实现肿瘤的精准打击和长期控制。

   同时,放射治疗作为恶性肿瘤的三大治疗手段之一,相比于手术、化疗更依赖于医学数字影像信息技术。在放疗实施过程中会遇到许多困难(设备众多、流程复杂、数据繁多、管理不便),因此在放疗处方剂量给予、放疗计划设计、治疗实施、质量保证、质量控制中需要一个统一规范的的协议标准。这个标准就是DICOM RT协议。DICOM RT协议作为DICOM协议的标准补充,专门用于处理放射治疗设备间的数据处理与传输。下面,本文将演示利用DICOM RT,实现放疗剂量雕刻功能,绘出“蒙娜丽莎的微笑”画像和“情满杏林,疫去春回”的艺术字。

一、DICOM 以及DICOM RT的数据结构

1983年美国ACR和NEMA组织联合成立DICOM(Digital Imaging and Communications in Medicine)标准委员会,并于1985年发布DICOM标准第一版,主要用于规范医学影像通信和存储的格式问题。1997-1999年,DICOM标准委员会批准了五个DICOM RT(Radiation Therapy)对象标准:RT结构集(RT Structure set)、RT计划(RT Plan)、RT剂量(RT Dose)和RT图像(RT lmage)、RT治疗记录(RT Records)。

DICOM标准文件包含头文件(File Meta Information)和数据集(Data Set),头文件中包含标识数据集合的相关信息,数据集是DICOM中的主要组成部分,不仅包括医学图像数据,还包括了许多和医学图像相关信息。在数据集中以dataElement为单元数据进行储存,其中每个单元数据包括:tag(标签),VR(数据类型),VL(数据长度),VF(数据值)。其中tag以两组16进制的数据分别表示的组号和元素号,dataElement以tag在DICOM文件中从小到大依次排列,如下图。

 0b5cef8e30748434e3f743487536fafa.png

根据DICOM的IOD(informationobject definition)可以将dataElement进行归类,以RT结构集(RT Structure set)为例,如下表。

RT结构集IOD模型描述表

患者Patient

患者Patient

检查Study

患者检查Patient Study

常规检查General Study

序列Series

RT序列(RT Series)

设备Equipment

常规设备General Equipment

结构集Structure Set

结构及Structure Set

感兴趣轮廓ROI Contour

RT感兴趣观察RT ROI Observations

批准Approval

语音audio

服务对象说明SOP Common

二、工具

目前可用的DICOM查看、编辑工具有很多,如:DicomEdit、dicompyler等。这里推荐使用dicompyler,可以查看DICOM RT中的图像、结构、DVH图等,但是由于软件中数据统计结果与商用TPS中相关数据结果有所差异,建议仅供参考。

编程语言对应的DICOM工具包也很齐全,如:Python工具包Pydicom、Java框架dcm4che等。本文中使用Python编程语言,借助Pydicom工具包对DICOM RT文件数据进行个人趣味操作,不涉及临床治疗数据。

使用Monaco TPS进行DICOM数据接收和蒙娜丽莎画像的计划设计。

三、思路与方法
3.1 图片灰度到剂量梯度

图片的画面层次是通过像素点不同灰度值和颜色的明暗对比体现出来的,灰度是指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0,在计算机中用一个字节的八位二进制数表示。故黑白图片也称灰度图,在医学、图像识别等领域有很广泛的应用。如下图,不同的灰度值对应的黑白颜色深浅。

4f1ab70db680d8f8ca376735f2c49057.png

     那如何在TPS中实现蒙娜丽莎画像中的明暗对比?这就需要DICOM 图像上勾勒出特定的轮廓,并在TPS中赋予特定的结构轮廓颜色、透明度和剂量梯度,进而得到蒙娜丽莎的结构画像和剂量画像。

 3.2 灰度划分和轮廓抽取

首先将梦娜丽莎画像抠除背景、转换灰度图。考虑到在TPS中轮廓颜色、透明度设置和剂量梯度设置,想要呈现出原始图片中0-255个连续的灰度级变化是不现实的,因此进行一定程度的简化。将原始图片的灰度值划分为4个等级:25,100,150,200,利用python中的opencv工具包进行原始图片像素灰度值的阈值操作,生成下图中右侧四个素材图片。

3926fa87fba7a6ba715f15da6b396ef9.png

然后使用opencv工具包中的轮廓抽取功能从四个灰度划分素材图片中抽取轮廓,并保存坐标数据,用于后续写入DICOM RT结构集。如下图,抽取轮廓图。

370e59340a8a93cbf9356cef7866d8a3.png

3.3 DICOM RT结构集数据处理

首先复制一套带有RTss 结构数据的CT序列,对序列下每一个DICOM CT图像文件修改像素数据,对应的标签tag为(7fe0,0010)。原始CT文件尺寸为640*640,修改像素值后生成一个尺寸400*600的CT图像作为画像底板,如下图。

3f44540d46637b30a43fbae9b82aca08.png

     然后将上文得到的四个轮廓数据追加写入到RTss结构集文件中,对应的tag标签为(3006,0010)、(3006,0020)、(3006,0039)、(3006,0080),如下图。

d330059a280a0e38cc6e1a8b2f876a0d.png

3.4 Monaco TPS 蒙娜丽莎画像计划设计

将DICOM CT序列和RTss结构文件导入Monaco TPS后,勾画外轮廓并设置结构颜色和三维显示透明度,就可以完成TPS中的蒙娜丽莎结构画像的显示,如下图。

  e7b90f1dd0585a86c302b8c5a871f565.png

       考虑在TPS中设计画像全身结构的计划,一些精细地方的剂量难以控制,比如眉毛、嘴唇等。因此进行一定的简化,只针对画像头部进行计划设计。采用9个射野,床角270度和机架90度,小机头等差20度。射野参数如下图。

2130a9bb231d4b50c97820f36b27136d.png

     对四个灰度划分的轮廓数据给予不同的处方剂量,原始画像中灰度越高的部分对应的处方剂量也越高。配合剂量线颜色设置,根据处方剂量值采用不同灰度的黑白颜色,完成TPS中的蒙娜丽莎剂量画像图。如下图。

 647386a2e921fa078d5c809248c861f7.png

类似画像写入的操作,也可以在DICOM RT中写入书法字体数据,如下图。

71d683e4f327d6f4c6c9d9c5afaa8b46.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华睿相机和Basler相机都有自己的SDK,这里分别介绍一下它们的C++开发例子。 华睿相机SDK开发例子: 1. 首先需要安装华睿相机的SDK,并且添加SDK头文件和库文件到工程中。 2. 在代码中包含SDK的头文件,并且初始化SDK: ```c++ #include "MvCameraControl.h" int main() { // 初始化SDK MV_CC_DEVICE_INFO_LIST stDeviceList; memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST)); MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList); if (stDeviceList.nDeviceNum == 0) { printf("No device found!\n"); return -1; } return 0; } ``` 3. 打开相机并设置相机参数: ```c++ // 打开相机 MV_CC_DEVICE_INFO* pstDeviceInfo = stDeviceList.pDeviceInfo[0]; void* handle = NULL; MV_CC_CreateHandle(&handle, pstDeviceInfo); MV_CC_OpenDevice(handle); // 设置相机参数 MV_CC_SetPixelFormat(handle, PixelType_Gvsp_RGB8_Packed); MV_CC_SetTriggerMode(handle, MV_TRIGGER_MODE_OFF); MV_CC_SetExposureTime(handle, 1000); ``` 4. 开始采集图像并保存: ```c++ // 开始采集图像 MV_CC_StartGrabbing(handle); MV_FRAME_OUT_INFO_EX stImageInfo = { 0 }; unsigned char* pData = NULL; MV_CC_GetImageForRGB(handle, pData, 1000, &stImageInfo); // 保存图像 cv::Mat matImage = cv::Mat(stImageInfo.nHeight, stImageInfo.nWidth, CV_8UC3, pData).clone(); cv::imwrite("image.jpg", matImage); ``` 5. 最后需要释放资源并关闭相机: ```c++ // 停止采集图像 MV_CC_StopGrabbing(handle); // 关闭相机并释放资源 MV_CC_CloseDevice(handle); MV_CC_DestroyHandle(handle); ``` Basler相机SDK开发例子: 1. 首先需要安装Basler相机的SDK,并且添加SDK头文件和库文件到工程中。 2. 在代码中包含SDK的头文件,并且初始化系统: ```c++ #include <pylon/PylonIncludes.h> int main() { // 初始化系统 Pylon::PylonAutoInitTerm autoInitTerm; return 0; } ``` 3. 获取相机并设置相机参数: ```c++ // 获取第一个相机 Pylon::CInstantCamera camera(Pylon::CTlFactory::GetInstance().CreateFirstDevice()); // 设置相机参数 camera.Open(); camera.PixelFormat.SetValue(Pylon::PixelType_RGB8packed); camera.TriggerMode.SetValue(Pylon::TriggerMode_Off); camera.ExposureTime.SetValue(1000); ``` 4. 开始采集图像并保存: ```c++ // 开始采集图像 camera.StartGrabbing(Pylon::GrabStrategy_LatestImageOnly); Pylon::CGrabResultPtr ptrGrabResult; camera.RetrieveResult(1000, ptrGrabResult, Pylon::TimeoutHandling_ThrowException); // 保存图像 cv::Mat matImage = cv::Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t*)ptrGrabResult->GetBuffer()).clone(); cv::imwrite("image.jpg", matImage); ``` 5. 最后需要释放资源并关闭相机: ```c++ // 停止采集图像 camera.StopGrabbing(); // 关闭相机并释放资源 camera.Close(); ``` 以上是华睿相机SDK和Basler相机SDK的C++开发例子,具体实现还需要根据自己的需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值