📄 dicom.cpp
字号:
/////////
// Dicom.cpp: implementation of the Dicom class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Dicom.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define KK 10
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
int Dicom::frame_number = 0;
Dicom::Dicom()
{
/////////////module0:给链表及链表中的char分配空间/////////
p_DcmData = (struct DcmData*)malloc(sizeof(struct DcmData));
p_DcmData->pNext = NULL;
p_DcmData->slice_location = 0;
p_DcmData->window_center = NULL;
p_DcmData->window_width = NULL;
p_DcmData->pixelx_spacing = NULL;
p_DcmData->pixely_spacing = NULL;
p_DcmData->manufacture = NULL;
p_DcmData->rescale_intercept = NULL;
p_DcmData->rescale_slope = NULL;
p_DcmData->rows = 0;
p_DcmData->columns = 0;
p_DcmData->transfer = NULL;
p_DcmData->image_orderID = 0;
///////////////module0:end/////////////////////////////
}
Dicom::~Dicom()
{
}
////////////////////读取DCM文件begin//////////////////////////
Dicom::readDcmfile(CString filename)
{
int image_tempID;
DcmData* pTemp;
DcmData* pTemp2;
CFile dcmfile;
if (!dcmfile.Open(filename,CFile::modeRead))
return FALSE;
/////////////////////module1:判断DICM文件//////////////
dcmfile.Seek(128,CFile::begin);
char* dcm;
dcm = new char(5);
dcmfile.Read(dcm,4);dcm[4]=0;
if (strcmp(dcm,"DICM"))
{
return FALSE;
}
frame_number++;//dicm图片的总数DICOM::frame_number;
////////////////////module1:end//////////////////////
/////////////////////DcmData链表指到末尾///////////////
image_tempID = 1;
for(pTemp2=p_DcmData;pTemp2->pNext!=NULL;pTemp2=pTemp2->pNext)
image_tempID++;
if (Dicom::frame_number!=1)
{
pTemp = (struct DcmData*)malloc(sizeof(struct DcmData));
pTemp->pNext = NULL;
pTemp->slice_location = 0;
pTemp->window_center = NULL;
pTemp->window_width = NULL;
pTemp->pixelx_spacing = NULL;
pTemp->pixely_spacing = NULL;
pTemp->manufacture = NULL;
pTemp->rescale_intercept = NULL;
pTemp->rescale_slope = NULL;
pTemp->rows = 0;
pTemp->columns = 0;
pTemp->transfer = NULL;
pTemp->image_orderID = 0;
pTemp2->pNext = pTemp;
pTemp->image_orderID = image_tempID+1;
}
else
{
pTemp = pTemp2;
pTemp->image_orderID = image_tempID;
}
/////////////////////////////////end/////////////////////
///////////////////module2:读取传输语法//////////////
unsigned short int gtag,etag;
unsigned int len;
BOOL len_ObOwSq;
len=0;
len_ObOwSq = FALSE;
do
{
dcmfile.Seek(len,CFile::current);
dcmfile.Read(>ag,2);
dcmfile.Read(&etag,2);
dcmfile.Seek(2,CFile::current);
dcmfile.Read(&len,2);
}while((gtag != TRANSFER_GROUP)||(etag != TRANSFER_ELEMENT));
pTemp->transfer = new char[len+1];
dcmfile.Read(pTemp->transfer,len);
pTemp->transfer[len] = 0;
///////////////////module2:end///////////////////////
//////////////////module3:根据传输语法读数据/////////
char vr[3];
if (!strcmp(pTemp->transfer,EXVR_LENDIAN))
{
len=0;gtag=0;etag=0;
do
{
dcmfile.Read(>ag,2);
dcmfile.Read(&etag,2);
dcmfile.Read(vr,2);
vr[2] = 0;
if (!strcmp(vr,"OB")||(!strcmp(vr,"OW"))||(!strcmp(vr,"SQ")))
{
dcmfile.Seek(2,CFile::current);
dcmfile.Read(&len,4);
}
else
{
dcmfile.Read(&len,2);
}
switch(gtag)
{
case SLICE_LOCATION_GROUP://image plane module
switch(etag)
{
case SLICE_LOCATION_ELEMENT:
pTemp->slice_location = new char[len+1];
dcmfile.Read(pTemp->slice_location,len);
pTemp->slice_location[len] = 0;
break;
case STUDY_NUMBER_ELEMENT:
pTemp->study_number = new char[len+1];
dcmfile.Read(pTemp->study_number,len);
pTemp->study_number[len] = 0;
break;
default:
dcmfile.Seek(len,CFile::current);
break;
}
break;
case CT_DATA_GROUP: //ct值
switch(etag)
{
case CT_DATA_ELEMENT:
dcmfile.Read(&pTemp->ct,len);
break;
default:
dcmfile.Seek(len,CFile::current);
break;
}
break;
case IMAGE_GROUP://image pixel module
switch(etag)
{
case WINDOW_CENTER_ELEMENT:
pTemp->window_center = new char[len+1];
dcmfile.Read(pTemp->window_center,len);
pTemp->window_center[len] = 0;
break;
case WINDOW_WIDTH_ELEMENT:
pTemp->window_width = new char[len+1];
dcmfile.Read(pTemp->window_width,len);
pTemp->window_width[len] = 0;
break;
case PIXEL_SPACING_ELEMENT:
char* temp;
int i,k;
temp = new char[len+1];
dcmfile.Read(temp,len);
temp[len] = 0;
for (i=0;temp[i]!=92;i++);
pTemp->pixelx_spacing = new char[i+1];
pTemp->pixely_spacing = new char[len-i];
for (k=0;k<i;k++)
{
pTemp->pixelx_spacing[k] = temp[k];
}
pTemp->pixelx_spacing[i] = 0;
for (k=0;k<len-i-1;k++)
{
pTemp->pixely_spacing[k] = temp[k+i+1];
}
pTemp->pixely_spacing[len-i-1] = 0;
break;
case RESCALE_INTERCEPT_ELEMENT:
pTemp->rescale_intercept = new char[len+1];
dcmfile.Read(pTemp->rescale_intercept,len);
pTemp->rescale_intercept[len] = 0;
break;
case RESCALE_SLOPE_ELEMENT:
pTemp->rescale_slope = new char[len+1];
dcmfile.Read(pTemp->rescale_slope,len);
pTemp->rescale_slope[len] = 0;
break;
case ROWS_ELEMENT:
dcmfile.Read(&pTemp->rows,len);
break;
case COLUMNS_ELEMENT:
dcmfile.Read(&pTemp->columns,len);
break;
default:
dcmfile.Seek(len,CFile::current);
break;
}
break;
case MANUFACTURE_GROUP://general equipment module
switch(etag)
{
case MANUFACTURE_ELEMENT:
pTemp->manufacture = new char[len+1];
dcmfile.Read(pTemp->manufacture,len);
pTemp->manufacture[len] = 0;
break;
case STUDY_DATA_ELEMENT:
pTemp->study_data = new char[len+1];
dcmfile.Read(pTemp->study_data,len);
pTemp->study_data[len] = 0;
break;
default:
dcmfile.Seek(len,CFile::current);
break;
}
break;
default:
dcmfile.Seek(len,CFile::current);
break;
}
}while((gtag != CT_DATA_GROUP)||(etag != CT_DATA_ELEMENT));
}
//////////////////module3:end////////////////////////
//////////////////module4:计算窗宽窗位begin///////////////
int max,min,i,j;
min = 1001;
max = -1001;
for(i=0;i<256;i++)
for(j=0;j<256;j++)
{
min = pTemp->ct[i][j]<min?pTemp->ct[i][j]:min;
max = pTemp->ct[i][j]>max?pTemp->ct[i][j]:max;
}
pTemp->window_width = intTOstr(max-min);
pTemp->window_center = intTOstr((max-min)/2);
ctTOpixel(pTemp);//ct值到pixel值的转换
/////////////////module4:end///////////////////////
BmpInfor();//初始bmp文件头数据
dcmfile.Close();
return TRUE;
}
//////////////////////读取DCM文件end////////////////////////////////////
////////////////////////ct值到象素值的转换begin//////////////////////////////
void Dicom::ctTOpixel(DcmData* p_Temp)
{
int i,j;
int min,max;
int pixel;
double intercept,slope;
if (p_Temp->rescale_intercept==NULL)
intercept = 0;
else intercept = strTOdouble(p_Temp->rescale_intercept);
if (p_Temp->rescale_slope==NULL)
slope = 1;
else slope = strTOdouble(p_Temp->rescale_slope);
for(i=0;i<256;i++)
for(j=0;j<256;j++)
{
min = (2*strTOdouble(p_Temp->window_center) - strTOdouble(p_Temp->window_width))/2.0 + 0.5;
max = (2*strTOdouble(p_Temp->window_center) + strTOdouble(p_Temp->window_width))/2.0 + 0.5;
pixel = (p_Temp->ct[i][j]*slope+intercept-min)*255.0/(double)(max - min);
p_Temp->pixel[i][j] = pixel;
if (pixel>255)
p_Temp->pixel[i][j] = 255;
if (pixel<0)
p_Temp->pixel[i][j] = 0;
}
}
////////////////////////ct值到象素值的转换end//////////////////////////////
////////////////////////字符到双精度的转换begin///////////////////////////////
double Dicom::strTOdouble(char* str)
{
int i;
char* pTemp;
pTemp = str;
double lalala;
lalala = 0;
for(i=0;(*pTemp!=46)&&(*pTemp!=0);pTemp++,i++);
pTemp = str;
for(;*pTemp!=0;pTemp++,i--)
{
int k;
double d;
d =0;
if(i>0)
{
d = (*pTemp-48);
for(k=i-1;k!=0;k--)
d = d*10;
}
if(i<0)
{
d = (*pTemp-48);
for(k=i;k!=0;k++)
d = d*0.1;
}
lalala = lalala+d;
}
return (lalala);
}
/////////////////////////////字符到双精度的转换end/////////////////////////////////
/////////////////////////////整形到字符的转换begin////////////////////////////////
char* Dicom::intTOstr(int itemp)
{
int b,temp;
char* pctemp;
temp = itemp;
for(b=0;temp!=0;temp/=10,b++)
pctemp = new char[b+1];
pctemp[b] = 0;
temp = itemp;
for(;b>0;b--)
{
pctemp[b-1] = 48+temp%10;
temp/=10;
}
return pctemp;
}
/////////////////////////////整形到字符的转换摁钉end////////////////////////////////
//////////////////////////////module5:给bmp信息赋值/////////////
void Dicom::BmpInfor()
{
bmphead.bfType = 0x4D42;
bmphead.bfSize = 66614;
bmphead.bfReserved = 0;
bmphead.bfOffBits = 0x436;
bmphead.biSize = 0x28;
bmphead.biWidth = 256;
bmphead.biHeight = 256*frame_number;
bmphead.biPlanes = frame_number;
bmphead.biBitCount = 8;
bmphead.biCompression = 0;
bmphead.biSizeImage = 65536*frame_number;
bmphead.biXPelsPerMeter = (int)1000/strTOdouble(p_DcmData->pixelx_spacing);
bmphead.biYPelsPerMeter = (int)1000/strTOdouble(p_DcmData->pixely_spacing);
bmphead.biClrUsed = 256;
bmphead.biClrImportant = 0;
int i;
for (i=0;i<256;i++)
{
bmphead.bmiColors[i].rgbBlue = i;
bmphead.bmiColors[i].rgbGreen = i;
bmphead.bmiColors[i].rgbRed = i;
bmphead.bmiColors[i].rgbReserved = 0;
}
}
///////////////////////////////module5:给bmp信息赋值/////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -