这是一段解析DICOM格式图像的C++代码。DICOM是医学影像领域中常用的图像格式,该代码可以读取DICOM格式图像,并将其转化为OpenCV中的Mat类型。以下是代码的详细解释:

  1. 头文件和命名空间声明:
#include "highgui.h"
using namespace cv;
using namespace std;

其中,"highgui.h"是OpenCV中用于图像显示和用户交互的头文件。

  1. 结构体和枚举类型定义:
struct TagValue
{
    unsigned short tag1;
    unsigned short tag2;
};

enum E_SourcePixelType
{ 
    ESourcePixelType_U16, // USHORT
    ESourcePixelType_I16, // SHORT
};

TagValue结构体用于存储DICOM文件中的Tag值,包括一个16位的Tag1和一个16位的Tag2。ESourcePixelType枚举类型用于表示原始像素类型,包括USHORT和SHORT两种。

  1. 主函数:
int main()
{
    bool isVR=true;
    bool isLitteEndian=true;
    int file_length=0;
    char VR[3];

    unsigned int pixDataLen=0;
    unsigned int pixDataOffset=0;
    unsigned short channle=0;
    unsigned short rows=0;
    unsigned short cols=0;
    unsigned short dataLen=0;
    unsigned short validLen=0;

    E_SourcePixelType pixelType;

    int windowsWidth=0;
    int windowsCenter=0;

    bool ZeroIsBlack=true;
    float RescaleSlope =0.06;
    float RescaleIntercept=0;

    FILE *fp;
    fp=fopen("11.dcm","rb");
    if(fp==NULL)
    {
        printf("can not open file!");
        return 0;
    }
    ...

主函数开始时,定义了一系列变量用于存储读取DICOM文件时需要的信息。其中,isVR表示是否使用VR模式读取文件,isLitteEndian表示文件的字节序(小端序或大端序),pixDataLen表示像素数据的长度,pixDataOffset表示像素数据在文件中的偏移量,channle表示图像通道数,rows和cols表示图像的行数和列数,dataLen表示像素数据的长度(以字节为单位),validLen表示像素数据的有效长度(以位为单位),ZeroIsBlack表示0是否表示黑色,RescaleSlope和RescaleIntercept用于线性重采样。

  1. 读取DICOM文件头:
fseek(fp,128,SEEK_SET);

char headchar[5];
memset(headchar,0,5);
int read_num = fread(headchar,1,4,fp);
if(read_num!=4)
{
    fclose(fp);
    return 0;
}

if(strcmp(headchar,"DICM"))
{
    fclose(fp);
    printf("File is not DICM");
    return 0;
}

while(ftell(fp)+6<file_length)
{
    TagValue tag;
    unsigned int len;
    memset(VR,0,3);
    fread(&tag,sizeof(TagValue),1,fp);
    int index=ftell(fp);

    if(tag.tag1==0x02)
    {
        fread(VR,1,2,fp);
        if(!strcmp(VR,"OB")||!strcmp(VR,"OW")||!strcmp(VR,"SQ"))
        {
            fseek(fp,2,SEEK_CUR);
            fread(&len,sizeof(unsigned int),1,fp);
        }
        else
        {
            unsigned short l;
            int ss = fread(&l,sizeof(unsigned short),1,fp);
            int a=ftell(fp);
            len =(unsigned int)l ;
        }
    }
    else if(tag.tag1==0xfffe)
    {
        if(tag.tag2==0xe000||tag.tag2==0xe00d||tag.tag2==0xe0dd)
        {
            fread(&len,sizeof(unsigned int),1,fp);
        }
    }
    else if(isVR==true)
    {
        fread(VR,1,2,fp);
        int a= ftell(fp);
        if(!strcmp(VR,"OB")||!strcmp(VR,"OW")||!strcmp(VR,"SQ"))
        {
            fseek(fp,2,SEEK_CUR);
            fread(&len,sizeof(unsigned int),1,fp);
        }
        else
        {
            unsigned short l;
            l=sizeof(unsigned short);
            fread(&l,sizeof(unsigned short),1,fp);
            a= ftell(fp);
            len =(unsigned int)l ;
        }
    }
    else if(isVR==false)
    {
        fread(&len,sizeof(unsigned int),1,fp);
    }

    if(tag.tag1==0x02&&tag.tag2==0x10)
    {
        char msg[124];
        memset(msg,0,124);
        fread(msg,1,len,fp);

        if(!strcmp(msg,"1.2.840.10008.1.2.1"))
        {
            isLitteEndian=true;
            isVR=true;
        }
        else if(!strcmp(msg,"1.2.840.10008.1.2.2"))
        {
            isLitteEndian=false;
            isVR=true;
        }
        else if(!strcmp(msg,"1.2.840.10008.1.2"))
        {
11111cpp 定义控制台应用程序的入口点。#include opencv2opencvhpp#include highguih#pragma commentlib opencv_core2411dlib#pragma commentlib opencv_imgproc2411dlib#pragma commentlib opencv_highgui2411dlibusing namespac

原文地址: http://www.cveoy.top/t/topic/bGG0 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录