使用Marching Cubes和OPENGL显示多帧DICOM图像时的未定义结果

时间:2013-01-19 11:31:36

标签: c++ opengl 3d dicom cubes

好吧,我已经和DICOM合作了一段时间,现在我遇到了一些问题,显示了MULTIFRAME CT图像。我正在使用行进立方体(当然)构建表面然后opengl(在Qt 4.8.1下)来显示它。 这段代码是我用来逐帧读取的。我有一个8位*宽度,高度,number_of_frames *我从dicom文件的标题中得到它们

if (samplesPerPixel == 1 &&  bitsAllocated == 8)
{

    pixel_8=( byte*)malloc(numPixels);


    for(int f=0;f<number_of_frames;f++)
    {
        fread(pixel_8,1,numPixels,dicom_file);
        for(int i=0;i<height;i++)
        {
            for(int j=0;j<width;j++)
            {
                int il=(i*width)+j;
                unsig=pixel_8[il];
                buff[j*3]=unsig;
                buff[(j*3)+1]=unsig;
                buff[(j*3)+2]=unsig;
                MCPoint *vert=&mcPoints[f][i][j]; 

                vert->x=f;
                vert->y=i;
                vert->z=j;
                vert->val = unsig;  
            }
        }
    }
}

MCPoint具有以下结构

struct MCPoint { 
float x, y, z; 
float val; 
 }; 

我还尝试将提取的帧保存为.jpg图像,它可以实现。但是当我尝试将生成的矩阵 pixel_8 发送到行进立方体函数时,我得到了一些奇怪的东西(我将在下面添加一张图片)

阅读框架后,我正在使用以下代码调用行进立方体:

MarchingCubeObject = new CMarchingCubes(width, height, number_of_frames, 200, mcPoints);
MCTriangles=MarchingCubeObject->getTriangles();
gl_widget=new CGlWidget(NULL,MarchingCubeObject->getNumTraingle(),MCTriangles,0);
gl_widget->show();

这里是Marching cube Class(我不认为MC的代码有什么问题,因为我从一个受信任的地方得到它:))我只更改了第3步< /强>

CMarchingCubes::CMarchingCubes(int ncellsX, int ncellsY, int ncellsZ, float minValue, MCPoint *** points)
{
TRIANGLE * triangles = new TRIANGLE[3*ncellsX*ncellsY*ncellsZ];
numTriangles = int(0);

int YtimeZ = (ncellsY+1)*(ncellsZ+1);
//go through all the points
for(int k=0; k < ncellsZ; k++)          //x axis
    for(int j=0; j < ncellsY; j++)      //y axis
        for(int i=0; i < ncellsX; i++)  //z axis
        {
            //initialize vertices
            mp4Vector verts[8];

            int ind = i*YtimeZ + j*(ncellsZ+1) + k;
            /*(step 3)*/ 
            verts[0]=construct_vert_from_pt(points[k  ][j  ][i  ]); 
            verts[1] = construct_vert_from_pt(points[k][j  ][i+1  ]);
            verts[2] = construct_vert_from_pt(points[k+1][j  ][i+1]); 
            verts[3] =  construct_vert_from_pt(points[k+1  ][j  ][i+1]); 
            verts[4] = construct_vert_from_pt(points[k  ][j+1][i  ]); 
            verts[5] = construct_vert_from_pt(points[k][j+1][i+1  ]); 
            verts[6] =construct_vert_from_pt(points[k+1][j+1][i+1]);   
            verts[7] =construct_vert_from_pt(points[k+1  ][j+1][i]);


            //get the index
            int cubeIndex = int(0);
            for(int n=0; n < 8; n++) /*(step 4)*/       
                if(verts[n].val >= minValue) cubeIndex |= (1 << n);

            //check if its completely inside or outside
            /*(step 5)*/
            if(!edgeTable[cubeIndex]) continue;

            //get intersection vertices on edges and save into the array
            mpVector intVerts[12];
            /*(step 6)*/ 
            if(edgeTable[cubeIndex] & 1) intVerts[0] = LinearInterp(verts[0], verts[1], minValue);
            if(edgeTable[cubeIndex] & 2) intVerts[1] = LinearInterp(verts[1], verts[2], minValue);
            if(edgeTable[cubeIndex] & 4) intVerts[2] = LinearInterp(verts[2], verts[3], minValue);
            if(edgeTable[cubeIndex] & 8) intVerts[3] = LinearInterp(verts[3], verts[0], minValue);
            if(edgeTable[cubeIndex] & 16) intVerts[4] = LinearInterp(verts[4], verts[5], minValue);
            if(edgeTable[cubeIndex] & 32) intVerts[5] = LinearInterp(verts[5], verts[6], minValue);
            if(edgeTable[cubeIndex] & 64) intVerts[6] = LinearInterp(verts[6], verts[7], minValue);
            if(edgeTable[cubeIndex] & 128) intVerts[7] = LinearInterp(verts[7], verts[4], minValue);
            if(edgeTable[cubeIndex] & 256) intVerts[8] = LinearInterp(verts[0], verts[4], minValue);
            if(edgeTable[cubeIndex] & 512) intVerts[9] = LinearInterp(verts[1], verts[5], minValue);
            if(edgeTable[cubeIndex] & 1024) intVerts[10] = LinearInterp(verts[2], verts[6], minValue);
            if(edgeTable[cubeIndex] & 2048) intVerts[11] = LinearInterp(verts[3], verts[7], minValue);

            //now build the triangles using triTable
            for (int n=0; triTable[cubeIndex][n] != -1; n+=3) {
                /*(step 7)*/    
                triangles[numTriangles].p[0] = intVerts[triTable[cubeIndex][n+2]];
                triangles[numTriangles].p[1] = intVerts[triTable[cubeIndex][n+1]];
                triangles[numTriangles].p[2] = intVerts[triTable[cubeIndex][n]];
                /*(step 8)*/    
                    triangles[numTriangles].norm = ((triangles[numTriangles].p[1] - 
                    triangles[numTriangles].p[0]).Cross(triangles[numTriangles].p[2] - 
                    triangles[numTriangles].p[0])).Normalize();
                numTriangles++;
            }

        }   //END OF FOR LOOP

        //free all the wasted space
        retTriangles = new TRIANGLE[numTriangles];
        for(int i=0; i < numTriangles; i++)
            retTriangles[i] = triangles[i];
        delete [] triangles;


}


CMarchingCubes::~CMarchingCubes(void)
{
}

mpVector CMarchingCubes::LinearInterp( mp4Vector p1, mp4Vector p2, float value )
{
    mpVector p;
    if(p1.val != p2.val)
        p = (mpVector)p1 + ((mpVector)p2 - (mpVector)p1)/(p2.val - p1.val)*(value - p1.val);
    else 
        p = (mpVector)p1;
    return p;
}

TRIANGLE * CMarchingCubes::getTriangles()
{
    return retTriangles;
}

mp4Vector CMarchingCubes::construct_vert_from_pt( MCPoint p )
{
    return mp4Vector(p.x,p.y,p.z,p.val );
}

int CMarchingCubes::getNumTraingle()
{
    return numTriangles;
}

这里也是TRIANGLE结构

typedef struct {
mpVector p[3];
mpVector norm;
} TRIANGLE;

基本上我正在从dicom文件中读取矩阵,然后将其发送到Marching cube,就像我说的那样,在发送它之前我还有什么要改变它的颜色???或者

之后我用这个功能来显示我得到的东西(我除以200,因为实际值我有一个空黑屏,所以我试图缩放它们):

    glViewport(0,0,700,700);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
glBegin(GL_TRIANGLES);

for(int i=0; i < numOfTriangles; i++){
    glNormal3f(MCTriangles[i].norm.x, MCTriangles[i].norm.y, MCTriangles[i].norm.z);
    for(int j=0; j < 3; j++)                            
        glVertex3f(MCTriangles[i].p[j].x/200,MCTriangles[i].p[j].y/200,MCTriangles[i].p[j].z/200);
}

glEnd();

这是我在尝试显示结果三角形时得到的: 链接到图像: Marching Cube result

这些是我将它们保存为JPG后在DICOM文件中的16帧:

链接到图片:16 extracted jpg pictures from the dicom file

0 个答案:

没有答案