体积渲染:如何将.raw文件转换为opengl友好的isosurface?

时间:2012-02-20 19:30:00

标签: opengl textures volume-rendering

我想使用行进四面体创建.raw体积医疗数据集的3D可视化器。

我发现this implementation on GPL license看起来不错,并且基于Paul Bourke的信息,但我不知道如何使用.raw文件,我发现people load as a 3d texture

//assuming that the data at hand is a 256x256x256 unsigned byte data
int XDIM=256, YDIM=256, ZDIM=256;
const int size = XDIM*YDIM*ZDIM;
bool LoadVolumeFromFile(const char* fileName) {

    FILE *pFile = fopen(fileName,"rb");
   if(NULL == pFile) {
    return false;
   }

   GLubyte* pVolume=new GLubyte[size]; //<- here pVolume is a 1D byte array 
   fread(pVolume,sizeof(GLubyte),size,pFile);
   fclose(pFile);

   // now pVolume is passed to a 3d texture 

    //load data into a 3D texture


glGenTextures(1, &textureID);
   glBindTexture(GL_TEXTURE_3D, textureID);

   // set the texture parameters
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

   glTexImage3D(GL_TEXTURE_3D,0,GL_INTENSITY,XDIM,YDIM,ZDIM,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,pVolume);
   delete [] pVolume;
   return true;




}

我不知道我是否应该: a)直接从pValue访问值 b)将它们加载到3D纹理后访问它们

我不知道我应该如何索引pVolume以获得每个x,y,z的等值面强度。如果pVolume是一维数组。我知道x,y坐标是使用除法和模块从1D数组映射的,但是我如何映射x,y,z?

另一方面,如果我将.raw文件加载为3d纹理

  

glTexCoord3f

给出给定x,y,z的等值?

澄清:问题不在于“OpenGL可以直接从中绘制等值面吗?”问题是如何索引.raw几何上的等级,这是正确评估每个四面体所需要的。在图像上可以看出,每个四面体情况都是根据等值面是在其上方还是下方来标记的。 isosurface在.raw文件的x,y,z坐标上编制索引,如何在数据集上为每个x,y,z访问它? glTexCoord3f会给出我在给定的x,y,z上的强度吗?是否更好地直接从pVolume数组进行x,y,z转换?

enter image description here

2 个答案:

答案 0 :(得分:1)

我认为你在这里混淆了一些事情。 OpenGL不是图像处理库。这是一个光栅化器API。 3D纹理并不意味着您将数据加载到任意内容并获得任意访问权限。您可以加载3D纹理以将它们映射到曲面上,或者在直接体积渲染中使用它们。

提取isosurfaces超出了OpenGL的范围。

RAW文件只是意味着没有标题,您必须先知道数据布局才能使用它。你需要知道

  • 宽度
  • 高度
  • 深度
  • 每个值
  • 个字节 然后可以在数据偏移

    处找到x,y,z处的值

    (宽*高* z +宽* y + z)*(字节)

Isovalue只表示数据集中的所有像素都等于给定值。通常情况下,您对像素的感兴趣,这些像素与isovalue下方和上方的每个像素相邻。为了有效确定,首先确定每个像素的标量场的梯度。然后,如果它们位于等值的上方或下方,则沿渐变测试相邻像素。这里没有涉及OpenGL!

答案 1 :(得分:1)

  

isosurface在.raw文件的x,y,z坐标上编入索引,如何在数据集上为每个x,y,z访问它?

将图像加载为3D阵列并将其编入索引。不要将其加载为OpenGL纹理。

  

glTexCoord3f会给出我在给定的x,y,z上的强度吗?

没有。作为the documentation statesglTexCoord3f只是为要发布的下一个顶点提供一组纹理坐标。它什么都不返回,它不会导致任何事情发生。它只是在OpenGL中设置状态。

  

直接从pVolume数组进行x,y,z转换是否更好?

是。 OpenGL中的信息通常应该朝着一个方向传播:从用户到屏幕。您可以使用OpenGL函数提供将用于渲染内容的OpenGL信息。这就是OpenGL如何发挥最佳效果。

任何类型的反向跟踪(将图像读回CPU等)都是一条缓慢的路径。