天天看點

java讀取dcm影像檔案_DCM醫學影像檔案的格式與讀取方法分享

醫學影像DCM是個類似PNG的分塊格式,内涵豐富醫療資訊,由于應用領域較窄,OpenCV沒有提供對其加載支援,一般采用dcmtk庫進行加載。

部落客本着研究探索的精神寫了這段代碼,并分享出來,提供了解析DCM的DIB資料、寬高、窗寬窗位、像素間距的功能,支援反色DCM。

将來可以參考spec文檔進行擴充,可以在大架構中加入塊的處理,進而抽取更多感興趣的資訊,也可以加入壓縮DCM的支援。

// 輸入:檔案名

// 輸出:寬高 窗寬窗位 像素間距 dib

unsigned short* dcmLoadImage(char* fn, int& width, int& height, int& windowWidth, int& windowLevel, double& pixelSpacing)

{

// 讀取整個檔案到記憶體

FILE* f = fopen(fn, "rb");

fseek(f, 0, SEEK_END);

int dcmSize = ftell(f);

fseek(f, 0, SEEK_SET);

unsigned char* dcm = new unsigned char[dcmSize];

fread(dcm, dcmSize, 1, f);

fclose(f);

// 解析

width = -1;

height = -1;

windowWidth = -1;

windowLevel = -1;

pixelSpacing = 0.0;

bool invert = false;

unsigned short* dib = NULL;

int dibSize = -1;

int p = 132;

while( p

{

short group = *(short*)(dcm+p);

p+=2;

short element = *(short*)(dcm+p);

p+=2;

//cout<

if(group==0x0002)

{

if(element==0x0001)// 2,1

{

p+=10;

}

else// 2,*

{

char vr[3];

vr[0] = dcm[p++];

vr[1] = dcm[p++];

vr[2] = '\0';

short size = *(short*)(dcm+p);

p+=2;

p+=size;

}

}

else// *

{

int size = *(int*)(dcm+p);

p+=4;

if(size==-1)

size=0;

if(group==0x0028&&element==0x0010)

height = *(short*)(dcm+p);

if(group==0x0028&&element==0x0030)

pixelSpacing = atof((char*)dcm+p);

if(group==0x0028&&element==0x0004)

invert = !strncmp((char*)dcm+p, "MONOCHROME1", 11);

else if(group==0x0028&&element==0x0011)

width = *(short*)(dcm+p);

else if(group==0x0028&&element==0x1050)

windowLevel = atoi((char*)dcm+p);

else if(group==0x0028&&element==0x1051)

windowWidth = atoi((char*)dcm+p);

else if(group==0x7FE0&&element==0x0010)

{

dibSize = size;

dib = new unsigned short[dibSize];

memcpy(dib, dcm+p, dibSize);

}

p+=size;

}

}

assert(p==dcmSize);

assert(width!=-1);

assert(height!=-1);

assert(windowLevel!=-1);

assert(windowWidth!=-1);

assert(dib!=NULL);

assert(dibSize==width*height*2);

// 反圖做修正

if(invert)

{

for(int i=0; i

dib[i] ^= 0xFFFF;

windowLevel = 65535-windowLevel;

}

delete[] dcm;

return dib;

}

void dcmReleaseImage(unsigned short* dib)

{

delete[] dib;

}