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<dcmSize ) { short group = *(short*)(dcm+p); p+=2; short element = *(short*)(dcm+p); p+=2; //cout<<setfill(0)<<hex<<setw(4)<<group<<","<<setw(4)<<element<<setfill( )<<dec<<endl; 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] = ; 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<width*height; i++) dib[i] ^= 0xFFFF; windowLevel = 65535-windowLevel; } delete[] dcm; return dib; } void dcmReleaseImage(unsigned short* dib) { delete[] dib; }
上一篇:
IDEA上Java项目控制台中文乱码