Converting Multiple 2D Files Into One 3D File

From VisItusers.org

Jump to: navigation, search

Sometimes you'll want to take several 2D data files and convert them into a 3D model for visualization. For example, you might have CT slices of a model that you want to view in 3D as a volume rendering. This page provides a couple of methods for converting 2D data into 3D data that can be viewed with VisIt.

[edit] Combining plain text spreadsheets into a volume

VisIt does not have a method for combining plain text spreadsheet files into a 3D volume so some data reorganization is required. You can use the following Python script to read in your ASCII spreadsheet files and write them out as a 3D dataset that VisIt can plot and manipulate in 3D.

###############################################################################
# Usage: python plaintext.py files
#
# Purpose:
#   This program takes a set of plaintext files on the command line and glues
#   them together into a BOV file that can be plotted using VisIt.
#
# Notes:      The input files must be plain text and contain only columns
#             of numbers. All input files must have the same number of rows and
#             columns.
#
# Programmer: Brad Whitlock
# Date:       Fri Feb  3 16:12:53 PST 2012
#
# Modifications:
#
###############################################################################
import sys, string, struct
 
# Read one input file and return its data as a list.
def readslice(filename):
    f = open(filename, "rt")
    lines = f.readlines()
    f.close()
 
    data = []
    nrows = 0
    for line in lines:
        toks = string.split(line, " ")
        vals = []
        for t in toks:
            try:
                v = float(t)
                vals = vals + [v]
            except:
                pass
        if nrows == 0:
            ncols = len(vals)
        for v in vals:
            data = data + [v]
        nrows = nrows + 1
    print data
    return data,ncols,nrows
 
# Insert the data from one slice into the overall 3D array.
def insertslice(data, slice, k, nx, ny):
    index2 = 0
    for j in xrange(ny):
        for i in xrange(nx):
            # Note the reversal in j here to make the data look the same 
            # as the input text file.
            index3 = k * nx*ny + (ny-1-j)*nx + i
            data[index3] = slice[index2]
            index2 = index2 + 1
 
# Write the 3D array out to a BOV file.
def saveBOV(filename, data, varname, nx, ny, nz):
    f = open(filename + ".dat", "wb")
    for d in data:
        f.write(struct.pack('f', d))
    f.close()
 
    f = open(filename + ".bov", "wt")
    f.write("TIME: 0\n")
    f.write("DATA_FILE: %s.dat\n" % filename)
    f.write("DATA_SIZE: %d %d %d\n" % (nx,ny,nz))
    f.write("DATA_FORMAT: FLOAT\n")
    f.write("VARIABLE: %s\n" % varname)
    f.write("DATA_ENDIAN: LITTLE\n")
    f.write("CENTERING: zonal\n")
    f.close()
 
# Create some test data.
def write_test_data():
    NX,NY,NZ = 3,4,5
    idx = 0
    for k in xrange(NZ):
        filename = "input%02d.txt" % k
        f = open(filename, "wt")
        for j in xrange(NY):
            line = ""
            for i in xrange(NX):
                line = line + "%d " % idx
                idx = idx + 1
            f.write("%s\n" % line)
        f.close()
 
# Iterate over the filenames that were passed on the command line and
# glue them together into BOV.
def main():
    nx = 0
    ny = 0
    nz = len(sys.argv[1:])
    data = []
 
    k = 0
    for filename in sys.argv[1:]:
        slice,dimx,dimy = readslice(filename)
        if k == 0:
            nx,ny = dimx,dimy
            data = [0] * (nx * ny * nz)
        insertslice(data, slice, k, nx, ny)
        k = k + 1
    print data
    saveBOV("output", data, "var", nx, ny, nz)
 
# Call it.
#write_test_data()
main()

[edit] Combining images into a volume

VisIt can read several input images into a single 3D dataset by using imgvol files. An imgvol file is a simple text file that has the names of the slice images in it along with a couple of optional keywords to specify Z-origin and Z-spacing. Each image corresponds to one slice through the 3D volume in the Z dimension. An example imgvol file:

Z_START: 0.
Z_STEP: 1.25
image001.jpg
image002.jpg
image003.jpg
image004.jpg
image005.jpg

The final volume will be sized according to the number of pixels in the source images and the number of slices used in the Z dimension. The variables to be plotted will consist of the usual image color variables: red, green, blue, intensity. The intensity variable is a combination of the red, green, blue components from the image and can be useful as a proxy for density, though the variable range will be different.

You can always make some adjustments to the dataset:

  • Apply a Transform operator to scale the dataset from pixels to a known coordinate system.
  • Create an expression involving the color component variables to derive a variable such as density.
  • Export the modified dataset to a Silo file or BOV file so further analysis will be done on the 3D dataset, skipping any additional processing that was needed to make the data more suitable for analysis. This will make VisIt faster.

You can make a Pseudocolor plot and apply an Isovolume operator to extract a volume bounded by minimum and maximum values. The following image extracts higher density bone values from a stack of images using the Isovolume operator.

Skeleton extracted from set of 2D image slices
Skeleton extracted from set of 2D image slices
Personal tools