这篇文章是放射物理相关文章。
1 放射治疗中的两个重点
在肿瘤的放射治疗中,我们最关心的两个问题中的第一个是剂量的计算准确性,另一个是照射位置的准确性。剂量的计算等我们以后说,我们先说说怎么保证照射位置的准确性。
在放射治疗的历史发展中,为了确定照射位置的准确性,医生和物理师们做出了很多贡献。1895年伦琴发现了X射线后,接下来几年,X射线就被用来治疗肿瘤了。
一开始由于射线能量比较低,只能治疗表浅肿瘤。后来居里夫人等发现了放射性核素,核素放射出来的射线能量就高了很多了,可以治疗更深的肿瘤了。一开始,对于表浅肿瘤,医生在患者的皮肤表面画好标记,然后让技师进行照射。后来随着计算机的发明,放射治疗进行了质的提升。70年代CT机的出现,更是带来了破天荒的突破。可以对肿瘤和正常组织扫面,3D重建,可以完全在CT图像中确定肿瘤的位置、大小和形状。3D适型计划系统的出现,可以准确的计算剂量,同时还可以使用CT模拟机进行精确的定位。
最早,确定肿瘤位置的方法是采用拍摄正位和侧位胶片的方法,来确定肿瘤和铅挡块的位置,从而保证照射时位置的准确。随着EPID的出现,可以使用EPID进行正侧位照片的拍摄,完全电子化,快速方便。随着Cone Beam CT在加速器上的安装,可以在治疗前对患者进行CT扫描,重建,更加准确的确定肿瘤的位置,为精准放射治疗提供可能。
2 Elekta CBCT图像的获取
医科达加速器配备的CBCT,扫描后的图像是HIS格式。扫描时,使用kV射线(80-140kV)进行旋转扫描,探测器也是EPID板(可以采集kV射线)。根据设定,每隔0.5度左右吧(根据_Frames.xml数据推算)获取一张透射图像。然后根据图像的位置信息将获取到的600+张图像进行重建(FDK算法)。
3 单张HIS图像的读取
单张HIS图像的内容是什么呢?到底是什么格式?因此本篇文章就是研究怎么读取单张HIS文件,并将它显示出来。
首先查看_Frames.xml文件
<DicomUID>1.3.12.2.1107.5.1.4.92303.30000019060503011740200000028</DicomUID>
</Treatment>
<Field>
<Id>***KV-IMAGES***</Id>
<Description></Description>
</Field>
<Image>
<kV>100</kV>
<mA>40</mA>
<ms>40</ms>
<AcquisitionPresetName>Head and Neck S20 CW</AcquisitionPresetName>
<Width>512</Width>
<Height>512</Height>
<Depth>16</Depth>
<ReadoutOrientation>V</ReadoutOrientation>
<DicomUID>1.3.46.423632.337391202112324925803.1</DicomUID>
<CTDIvol>1.0</CTDIvol>
<CTDIPhantomType>Head Phantom (Length 15cm)</CTDIPhantomType>
<AbsoluteTableLatPosIEC1217_MM>15.6</AbsoluteTableLatPosIEC1217_MM>
<AbsoluteTableLongPosIEC1217_MM>234.3</AbsoluteTableLongPosIEC1217_MM>
<AbsoluteTableVertPosIEC1217_MM>-132.1</AbsoluteTableVertPosIEC1217_MM>
</Image>
<Frames>
<Frame>
<Seq>1</Seq>
<DeltaMs>0</DeltaMs>
<HasPixelFactor>False</HasPixelFactor>
<PixelFactor>0</PixelFactor>
<GantryAngle>-175.103530884</GantryAngle>
<Exposed>True</Exposed>
<MVOn>False</MVOn>
<UCentre>1.224934578</UCentre>
<VCentre>0.268885463</VCentre>
<Inactive>False</Inactive>
</Frame>
我们看到了,图像的维度是512x512,16位图。
然后上C++代码,使用的文件在这里:https://download.csdn.net/download/kangdehua/16490699
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
using namespace std;
int main(int,char* [])
{
string fileName="../data/test.1.his";
// 读取文件,已二进制模式读取
fstream input(fileName.c_str(),ios::binary|ios::in);
char buffer[100]; // read function can only get 1 Byte every time.
input.read(buffer,100); // read 100 Bytes every time.
// 因为我偷偷的知道了文件头有100个字节(哈哈)
// use vector store the header information.
vector<unsigned short> header; // 因为我们已经知道文件数据是16位数据了,所以使用 16位类型保存数据
for(int i=0;i<50;++i){
unsigned short p=buffer[2*i+1]<<8|buffer[2*i+0]; // use the little Endian.
header.push_back(p);
}
// Display the header
for(vector<unsigned short>::iterator it=header.begin();it!=header.end();++it){
cout<<*it<<endl;
}
unsigned short row,col;
row=header[8];
col=header[9];
cout<<"The row and column are: "<<row<<","<<col<<endl;
// Read the data in the his file.
input.seekg(100,ios::beg); // 跳过前面100个字节的文件头
int size=512*512; //262144 double is 524288
unsigned short pixel[size];
char data[size*2];
input.read(data,size*2); // 读取后面的所有图像像素数据
for(int i=0;i<size;++i){
pixel[i]=data[2*i+1]<<8|data[2*i+0]; //小端字节序
}
// Display the image using OpenCV
// 借用OpenCV,方便。
cv::Mat image=cv::Mat(col,row,CV_16UC1,pixel);
cv::normalize(image,image,0,255,cv::NORM_MINMAX,CV_8UC1);
cv::imshow("His Image",image);
cv::waitKey();
return 0;
}
这里面的关键点是字节写的读取方法,注意16位数据按照顺序读取后,需要按照小端字节序还原成原来的数据。
显示结果:
图1 Elekta CBCT单张HIS图像
标签:HIS,读取,Elekta,include,CBCT,图像,100,肿瘤 From: https://blog.csdn.net/kangdehua/article/details/142930613