[vtk-developers] minimum intensity projection technique

Alberto García Consuegra algarcon at gmail.com
Wed May 16 05:57:33 EDT 2007


Hi all.

I´m developing an application wich represents a set of slices using diferent
techniques, such as Volume Rendering, Surface Rendering (Using
contourFiltering), Maximum Intensity Projection(using
vtkVolumeRayCastMIPFunction) and Multiplanar Reconstruction(using
vtkImagePlaneWidget), but I need to use one more technique, called Minimum
Intensity Projection, the approach is the same employed in Maximum Intensity
Projection but getting voxels values with minimum intensity instead of
voxels values with maximum intensity of the projection ray. Taking a look to
vtkVolumeRayCastMIPFunction source code it was easy to modify it an adapt it
to Minimum Intensity Projection. I write the appropiate changes I wish you
considere to add them to a new version of VTK.I send you a diff file with
these changes. I think you should put a fuction where user can decide what
technique he want to use(like in volume rendering when you decide if you
want to interpolate first or classify first, or in volumeRayCastMIP when you
can maximize scalar values or opacity). As an example Maximum Intensity
option, Minimun Intensity option may be considered, other method wich
calculates the mean of voxel projection, or the sum (if you calculate the
sum of voxels you can obtain a simulated X-Ray Image, median, or standard
deviation). I try to do it myself but I need to do a Java Binding and it is
very problematic creating a C++ class and then doing the Java binding. I
provide you the proposed changes, would you create it in newer releases of
VTK in C++?, then I could compile the new version for using it with a Java
binding.
Thanks you a lot.

Alberto
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20070516/f44af19e/attachment.html>
-------------- next part --------------
### Eclipse Workspace Patch 1.0
#P VTK-5-0-3
Index: VolumeRendering/vtkVolumeRayCastMIPFunction.h
===================================================================
RCS file: /cvsroot/VTK/VTK/VolumeRendering/vtkVolumeRayCastMIPFunction.h,v
retrieving revision 1.1
diff -u -r1.1 vtkVolumeRayCastMIPFunction.h
--- VolumeRendering/vtkVolumeRayCastMIPFunction.h	5 Apr 2005 14:48:48 -0000	1.1
+++ VolumeRendering/vtkVolumeRayCastMIPFunction.h	3 May 2007 14:58:32 -0000
@@ -12,13 +12,13 @@
      PURPOSE.  See the above copyright notice for more information.
 
 =========================================================================*/
-// .NAME vtkVolumeRayCastMIPFunction - A maximum intensity projection ray caster for volumes
+// .NAME vtkVolumeRayCastMIPFunction - A minimum intensity projection ray caster for volumes
 //
 // .SECTION Description
-// vtkVolumeRayCastMIPFunction is a volume ray cast function that
-// computes the maximum value encountered along the ray. This is
-// either the maximum scalar value, or the maximum opacity, as
-// defined by the MaximizeMethod. The color and opacity returned
+// vtkVolumeRayCastMinIPFunction is a volume ray cast function that
+// computes the minimum value encountered along the ray. This is
+// either the minimum scalar value, or the minimum opacity, as
+// defined by the MinimizeMethod. The color and opacity returned
 // by this function is based on the color, scalar opacity, and
 // gradient opacity transfer functions defined in the vtkVolumeProperty
 // of the vtkVolume.
@@ -28,19 +28,19 @@
 // vtkVolumeRayCastCompositeFunction vtkVolumeRayCastIsosurfaceFunction
 // vtkVolume vtkVolumeProperty
 
-#ifndef __vtkVolumeRayCastMIPFunction_h
-#define __vtkVolumeRayCastMIPFunction_h
+#ifndef __vtkVolumeRayCastMinIPFunction_h
+#define __vtkVolumeRayCastMinIPFunction_h
 
 #include "vtkVolumeRayCastFunction.h"
 
-#define VTK_MAXIMIZE_SCALAR_VALUE 0
-#define VTK_MAXIMIZE_OPACITY      1
+#define VTK_MINIMIZE_SCALAR_VALUE 0
+#define VTK_MINIMIZE_OPACITY      1
 
-class VTK_VOLUMERENDERING_EXPORT vtkVolumeRayCastMIPFunction : public vtkVolumeRayCastFunction
+class VTK_VOLUMERENDERING_EXPORT vtkVolumeRayCastMinIPFunction : public vtkVolumeRayCastFunction
 {
 public:
-  static vtkVolumeRayCastMIPFunction *New();
-  vtkTypeRevisionMacro(vtkVolumeRayCastMIPFunction,vtkVolumeRayCastFunction);
+  static vtkVolumeRayCastMinIPFunction *New();
+  vtkTypeRevisionMacro(vtkVolumeRayCastMinIPFunction,vtkVolumeRayCastFunction);
   void PrintSelf( ostream& os, vtkIndent indent );
 
 
@@ -50,15 +50,15 @@
 
 
   // Description:
-  // Set the MaximizeMethod to either ScalarValue or Opacity.
-  vtkSetClampMacro( MaximizeMethod, int,
-        VTK_MAXIMIZE_SCALAR_VALUE, VTK_MAXIMIZE_OPACITY );
-  vtkGetMacro(MaximizeMethod,int);
-  void SetMaximizeMethodToScalarValue() 
-    {this->SetMaximizeMethod(VTK_MAXIMIZE_SCALAR_VALUE);}
-  void SetMaximizeMethodToOpacity() 
-    {this->SetMaximizeMethod(VTK_MAXIMIZE_OPACITY);}
-  const char *GetMaximizeMethodAsString(void);
+  // Set the MinimizeMethod to either ScalarValue or Opacity.
+  vtkSetClampMacro( MinimizeMethod, int,
+        VTK_MINIMIZE_SCALAR_VALUE, VTK_MINIMIZE_OPACITY );
+  vtkGetMacro(MinimizeMethod,int);
+  void SetMinimizeMethodToScalarValue() 
+    {this->SetMinimizeMethod(VTK_MINIMIZE_SCALAR_VALUE);}
+  void SetMinimizeMethodToOpacity() 
+    {this->SetMinimizeMethod(VTK_MINIMIZE_OPACITY);}
+  const char *GetMinimizeMethodAsString(void);
 
 //BTX
   void CastRay( vtkVolumeRayCastDynamicInfo *dynamicInfo,
@@ -67,10 +67,10 @@
 
 
 protected:
-  vtkVolumeRayCastMIPFunction();
-  ~vtkVolumeRayCastMIPFunction();
+  vtkVolumeRayCastMinIPFunction();
+  ~vtkVolumeRayCastMinIPFunction();
 
-  int MaximizeMethod;
+  int MinimizeMethod;
 
 //BTX
   void SpecificFunctionInitialize( vtkRenderer *ren,
@@ -80,8 +80,8 @@
 
 //ETX
 private:
-  vtkVolumeRayCastMIPFunction(const vtkVolumeRayCastMIPFunction&);  // Not implemented.
-  void operator=(const vtkVolumeRayCastMIPFunction&);  // Not implemented.
+  vtkVolumeRayCastMinIPFunction(const vtkVolumeRayCastMinIPFunction&);  // Not implemented.
+  void operator=(const vtkVolumeRayCastMinIPFunction&);  // Not implemented.
 };
 
 
-------------- next part --------------
### Eclipse Workspace Patch 1.0
#P VTK-5-0-3
Index: VolumeRendering/vtkVolumeRayCastMIPFunction.cxx
===================================================================
RCS file: /cvsroot/VTK/VTK/VolumeRendering/vtkVolumeRayCastMIPFunction.cxx,v
retrieving revision 1.1
diff -u -r1.1 vtkVolumeRayCastMIPFunction.cxx
--- VolumeRendering/vtkVolumeRayCastMIPFunction.cxx	5 Apr 2005 14:48:48 -0000	1.1
+++ VolumeRendering/vtkVolumeRayCastMIPFunction.cxx	3 May 2007 14:55:47 -0000
@@ -12,25 +12,25 @@
      PURPOSE.  See the above copyright notice for more information.
 
 =========================================================================*/
-#include "vtkVolumeRayCastMIPFunction.h"
+#include "vtkVolumeRayCastMinIPFunction.h"
 #include "vtkVolumeRayCastMapper.h"
 #include "vtkVolume.h"
 #include "vtkObjectFactory.h"
 
 #include <math.h>
 
-vtkCxxRevisionMacro(vtkVolumeRayCastMIPFunction, "$Revision: 1.1 $");
-vtkStandardNewMacro(vtkVolumeRayCastMIPFunction);
+vtkCxxRevisionMacro(vtkVolumeRayCastMinIPFunction, "$Revision: 1.1 $");
+vtkStandardNewMacro(vtkVolumeRayCastMinIPFunction);
 
 // This is the templated function that actually casts a ray and computes
-// the maximum value.  It is valid for unsigned char and unsigned short,
+// the minimum value.  It is valid for unsigned char and unsigned short,
 template <class T>
-void vtkCastMaxScalarValueRay( T *data_ptr, vtkVolumeRayCastDynamicInfo *dynamicInfo,
+void vtkCastMinScalarValueRay( T *data_ptr, vtkVolumeRayCastDynamicInfo *dynamicInfo,
                                vtkVolumeRayCastStaticInfo *staticInfo )
 {
-  float     triMax, triValue;
-  int       max = 0;;
-  float     max_opacity;
+  float     triMin, triValue;
+  int       min = 0;;
+  float     min_opacity;
   int       loop;
   int       xinc, yinc, zinc;
   int       voxel[3], prev_voxel[3];
@@ -44,7 +44,7 @@
   float     *ray_increment;
   float     *grayArray, *RGBArray;
   float     *scalarArray;
-  T         nnValue, nnMax;
+  T         nnValue, nnMin;
 
   num_steps = dynamicInfo->NumberOfStepsToTake;
   ray_increment = dynamicInfo->TransformedIncrement;
@@ -68,7 +68,7 @@
     voxel[2] = vtkRoundFuncMacro( ray_position[2] );
 
     // Access the value at this voxel location
-    nnMax = *(data_ptr + voxel[2] * zinc +
+    nnMin = *(data_ptr + voxel[2] * zinc +
               voxel[1] * yinc + voxel[0] );
 
     // Increment our position and compute our voxel location
@@ -86,10 +86,10 @@
       nnValue = *(data_ptr + voxel[2] * zinc +
                   voxel[1] * yinc + voxel[0] );
 
-      // If this is greater than the max, this is the new max.
-      if ( nnValue > nnMax )
+      // If this is smaller than the min, this is the new min.
+      if ( nnValue < nnMin )
         {
-        nnMax = nnValue;
+        nnMin = nnValue;
         }
       
       // Increment our position and compute our voxel location
@@ -100,7 +100,7 @@
       voxel[1] = vtkRoundFuncMacro( ray_position[1] );
       voxel[2] = vtkRoundFuncMacro( ray_position[2] );
       }
-    max = (int)nnMax;
+    min = (int)nnMin;
     }
   // We are using trilinear interpolation
   else if ( staticInfo->InterpolationType == VTK_LINEAR_INTERPOLATION )
@@ -177,10 +177,10 @@
       zoff = ray_position[2] - (float) voxel[2];
       vtkTrilinFuncMacro( triValue, xoff, yoff, zoff, A, B, C, D, E, F, G, H );
 
-      // If this value is greater than max, it is the new max
-      if ( triValue > triMax )
+      // If this value is smaller than min, it is the new min
+      if ( triValue < triMin )
         {
-        triMax = triValue;
+        triMin = triValue;
         }
 
       // Increment our position and compute our voxel location
@@ -191,35 +191,35 @@
       voxel[1] = vtkFloorFuncMacro( ray_position[1] );
       voxel[2] = vtkFloorFuncMacro( ray_position[2] );
       }
-    max = (int)triMax;
+    min = (int)triMin;
     }
 
-  if ( max < 0 ) 
+  if ( min < 0 ) 
     {
-    max = 0;
+    min = 0;
     }
-  else if ( max > staticInfo->Volume->GetArraySize() - 1 )
+  else if ( min > staticInfo->Volume->GetArraySize() - 1 )
     {
-    max = (int)(staticInfo->Volume->GetArraySize() - 1);
+    min = (int)(staticInfo->Volume->GetArraySize() - 1);
     }
 
-  dynamicInfo->ScalarValue = max;  
-  max_opacity = scalarArray[max];
+  dynamicInfo->ScalarValue = min;  
+  min_opacity = scalarArray[min];
   
   // Set the return pixel value.  
   if( staticInfo->ColorChannels == 1 )
     {
-    dynamicInfo->Color[0] = max_opacity * grayArray[max];
-    dynamicInfo->Color[1] = max_opacity * grayArray[max];
-    dynamicInfo->Color[2] = max_opacity * grayArray[max];
-    dynamicInfo->Color[3] = max_opacity;
+    dynamicInfo->Color[0] = min_opacity * grayArray[min];
+    dynamicInfo->Color[1] = min_opacity * grayArray[min];
+    dynamicInfo->Color[2] = min_opacity * grayArray[min];
+    dynamicInfo->Color[3] = min_opacity;
     }
   else if ( staticInfo->ColorChannels == 3 )
     {
-    dynamicInfo->Color[0] = max_opacity * RGBArray[max*3];
-    dynamicInfo->Color[1] = max_opacity * RGBArray[max*3+1];
-    dynamicInfo->Color[2] = max_opacity * RGBArray[max*3+2];
-    dynamicInfo->Color[3] = max_opacity;
+    dynamicInfo->Color[0] = min_opacity * RGBArray[min*3];
+    dynamicInfo->Color[1] = min_opacity * RGBArray[min*3+1];
+    dynamicInfo->Color[2] = min_opacity * RGBArray[min*3+2];
+    dynamicInfo->Color[3] = min_opacity;
     }
 
   dynamicInfo->NumberOfStepsTaken = num_steps;
@@ -227,15 +227,15 @@
 
 
 // This is the templated function that actually casts a ray and computes
-// the maximum value.  It is valid for unsigned char and unsigned short,
+// the minimum value.  It is valid for unsigned char and unsigned short,
 template <class T>
-void vtkCastMaxOpacityRay( T *data_ptr, vtkVolumeRayCastDynamicInfo *dynamicInfo,
+void vtkCastMinOpacityRay( T *data_ptr, vtkVolumeRayCastDynamicInfo *dynamicInfo,
                         vtkVolumeRayCastStaticInfo *staticInfo )
 {
-  float     max;
+  float     min;
   float     opacity;
   float     value;
-  int       max_value = 0;
+  int       min_value = 0;
   int       loop;
   int       xinc, yinc, zinc;
   int       voxel[3];
@@ -261,8 +261,8 @@
   grayArray = staticInfo->Volume->GetGrayArray();
   RGBArray = staticInfo->Volume->GetRGBArray();
 
-  // Set the max value.  This will not always be correct and should be fixed
-  max = -999999.0;
+  // Set the min value.  This will not always be correct and should be fixed
+  min = 999999.0;
 
   xinc = staticInfo->DataIncrement[0];
   yinc = staticInfo->DataIncrement[1];
@@ -302,11 +302,11 @@
 
       opacity = SOTF[(int)value];
  
-      // If this is greater than the max, this is the new max.
-      if ( opacity > max ) 
+      // If this is smaller than the min, this is the new min.
+      if ( opacity < min ) 
         {
-        max = opacity;
-        max_value = (int) value;
+        min = opacity;
+        min_value = (int) value;
         }
 
       // Increment our position and compute our voxel location
@@ -396,11 +396,11 @@
 
       opacity = SOTF[(int)value];
  
-      // If this is greater than the max, this is the new max.
-      if ( opacity > max ) 
+      // If this is minor than the min, this is the new min.
+      if ( opacity < min ) 
         {
-        max = opacity;
-        max_value = (int) value;
+        min = opacity;
+        min_value = (int) value;
         }
       
       // Increment our position and compute our voxel location
@@ -413,37 +413,37 @@
       }
     }
 
-  dynamicInfo->ScalarValue = max;  
+  dynamicInfo->ScalarValue = min;  
 
   // Set the return pixel value.  The depth value is currently useless and
   // should be fixed.
   if( staticInfo->ColorChannels == 1 )
     {
-    dynamicInfo->Color[0] = max * grayArray[max_value];
-    dynamicInfo->Color[1] = max * grayArray[max_value];
-    dynamicInfo->Color[2] = max * grayArray[max_value];
-    dynamicInfo->Color[3] = max;
+    dynamicInfo->Color[0] = min * grayArray[min_value];
+    dynamicInfo->Color[1] = min * grayArray[min_value];
+    dynamicInfo->Color[2] = min * grayArray[min_value];
+    dynamicInfo->Color[3] = min;
     }
   else if ( staticInfo->ColorChannels == 3 )
     {
-    dynamicInfo->Color[0] = max * RGBArray[max_value*3];
-    dynamicInfo->Color[1] = max * RGBArray[max_value*3+1];
-    dynamicInfo->Color[2] = max * RGBArray[max_value*3+2];
-    dynamicInfo->Color[3] = max;
+    dynamicInfo->Color[0] = min * RGBArray[min_value*3];
+    dynamicInfo->Color[1] = min * RGBArray[min_value*3+1];
+    dynamicInfo->Color[2] = min * RGBArray[min_value*3+2];
+    dynamicInfo->Color[3] = min;
     }
 
 
   dynamicInfo->NumberOfStepsTaken = steps_this_ray;
 }
 
-// Construct a new vtkVolumeRayCastMIPFunction 
-vtkVolumeRayCastMIPFunction::vtkVolumeRayCastMIPFunction()
+// Construct a new vtkVolumeRayCastMinIPFunction 
+vtkVolumeRayCastMinIPFunction::vtkVolumeRayCastMinIPFunction()
 {
-  this->MaximizeMethod = VTK_MAXIMIZE_SCALAR_VALUE;
+  this->MinimizeMethod = VTK_MINIMIZE_SCALAR_VALUE;
 }
 
-// Destruct the vtkVolumeRayCastMIPFunction
-vtkVolumeRayCastMIPFunction::~vtkVolumeRayCastMIPFunction()
+// Destruct the vtkVolumeRayCastMinIPFunction
+vtkVolumeRayCastMinIPFunction::~vtkVolumeRayCastMinIPFunction()
 {
 }
 
@@ -451,23 +451,23 @@
 // It uses the integer data type flag that is passed in to
 // determine what type of ray needs to be cast (which is handled
 // by a templated function. 
-void vtkVolumeRayCastMIPFunction::CastRay( vtkVolumeRayCastDynamicInfo *dynamicInfo,
+void vtkVolumeRayCastMinIPFunction::CastRay( vtkVolumeRayCastDynamicInfo *dynamicInfo,
                                            vtkVolumeRayCastStaticInfo *staticInfo)
 {
   void *data_ptr;
   
   data_ptr = staticInfo->ScalarDataPointer;
 
-  if ( this->MaximizeMethod == VTK_MAXIMIZE_SCALAR_VALUE )
+  if ( this->MinimizeMethod == VTK_MINIMIZE_SCALAR_VALUE )
     {
     switch ( staticInfo->ScalarDataType )
       {
       case VTK_UNSIGNED_CHAR:
-        vtkCastMaxScalarValueRay( (unsigned char *)data_ptr, dynamicInfo, 
+        vtkCastMinScalarValueRay( (unsigned char *)data_ptr, dynamicInfo, 
                                   staticInfo );
         break;
       case VTK_UNSIGNED_SHORT:
-        vtkCastMaxScalarValueRay( (unsigned short *)data_ptr, dynamicInfo, 
+        vtkCastMinScalarValueRay( (unsigned short *)data_ptr, dynamicInfo, 
                                   staticInfo );
         break;
       default:
@@ -480,10 +480,10 @@
     switch ( staticInfo->ScalarDataType )
       {
       case VTK_UNSIGNED_CHAR:
-        vtkCastMaxOpacityRay( (unsigned char *)data_ptr, dynamicInfo, staticInfo );
+        vtkCastMinOpacityRay( (unsigned char *)data_ptr, dynamicInfo, staticInfo );
         break;
       case VTK_UNSIGNED_SHORT:
-        vtkCastMaxOpacityRay( (unsigned short *)data_ptr, dynamicInfo, staticInfo );
+        vtkCastMinOpacityRay( (unsigned short *)data_ptr, dynamicInfo, staticInfo );
         break;
       default:
         vtkWarningMacro ( << "Unsigned char and unsigned short are the only supported datatypes for rendering" );
@@ -492,7 +492,7 @@
     }
 }
 
-float vtkVolumeRayCastMIPFunction::GetZeroOpacityThreshold( vtkVolume *vtkNotUsed(vol) )
+float vtkVolumeRayCastMinIPFunction::GetZeroOpacityThreshold( vtkVolume *vtkNotUsed(vol) )
 {
   return ( 1.0 );
 }
@@ -501,27 +501,27 @@
 // vtkDepthPARCMapper.cxx).  It allows the specific mapper type to
 // update any local caster variables.  In this case, nothing needs
 // to be done here
-void vtkVolumeRayCastMIPFunction::SpecificFunctionInitialize( 
+void vtkVolumeRayCastMinIPFunction::SpecificFunctionInitialize( 
                                  vtkRenderer *vtkNotUsed(ren), 
                                  vtkVolume *vtkNotUsed(vol),
                                  vtkVolumeRayCastStaticInfo *staticInfo,
                                  vtkVolumeRayCastMapper *vtkNotUsed(mapper) )
 {
-  staticInfo->MIPFunction = 1;
-  staticInfo->MaximizeOpacity = (this->MaximizeMethod == VTK_MAXIMIZE_OPACITY);
+  staticInfo->MinIPFunction = 1; //
+  staticInfo->MinimizeOpacity = (this->MinimizeMethod == VTK_MINIMIZE_OPACITY);
 }
 
 // Description:
-// Return the maximize method as a descriptive character string.
-const char *vtkVolumeRayCastMIPFunction::GetMaximizeMethodAsString(void)
+// Return the minimize method as a descriptive character string.
+const char *vtkVolumeRayCastMinIPFunction::GetMinimizeMethodAsString(void)
 {
-  if( this->MaximizeMethod == VTK_MAXIMIZE_SCALAR_VALUE )
+  if( this->MinimizeMethod == VTK_MINIMIZE_SCALAR_VALUE )
     {
-    return "Maximize Scalar Value";
+    return "Minimize Scalar Value";
     }
-  if( this->MaximizeMethod == VTK_MAXIMIZE_OPACITY )
+  if( this->MinimizeMethod == VTK_MINIMIZE_OPACITY )
     {
-    return "Maximize Opacity";
+    return "Minimize Opacity";
     }
   else
     {
@@ -529,11 +529,11 @@
     }
 }
 
-// Print method for vtkVolumeRayCastMIPFunction
-void vtkVolumeRayCastMIPFunction::PrintSelf(ostream& os, vtkIndent indent)
+// Print method for vtkVolumeRayCastMinIPFunction
+void vtkVolumeRayCastMinIPFunction::PrintSelf(ostream& os, vtkIndent indent)
 {
   this->Superclass::PrintSelf(os,indent);
 
-  os << indent << "Maximize Method: " << this->GetMaximizeMethodAsString()
+  os << indent << "Minimize Method: " << this->GetMinimizeMethodAsString()
      << "\n";
 }


More information about the vtk-developers mailing list