MP3 2022
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
MP3
2022
1 Ray Marching
In this activity, you will march rays through a VTK render to implement various transfer and composite functions.
The outline of this activity will be: 1. Implementing a grayscale transfer function with the max
intensity operator 2. Implementing an alpha transfer function with the over operator Starter Code:
#grade (DO NOT DELETE THIS LINE)
import random, os, gzip, numpy, vtk
from vtk.util import numpy_support as VN
from PIL import Image
VTK_FILE = "./HeadCT.vtk"
def compositeKeepA(a,b):
return a
def getVolumeScalars(volume):
scalars = VN.vtk_to_numpy(volume.GetPointData().GetArray("scalars")) return scalars.reshape(volume.GetDimensions(),order="F")
def volumeRender(displaySlice, volume, transfer, composite, yval=-1):
#get the dimensions of the volume array
xsize, ysize, zsize = volume.GetDimensions()
#get the min and max values of the scalars for volume
srange = volume.GetScalarRange()
#get the scalars themselves
scalars = getVolumeScalars(volume)
#determine if we're just taking a single y slice or compositing it somehow
ymin = ymax = yval
if yval == -1:
ymin = 0
ymax = ysize
#loop over every element on the z and x axes
for z in range(zsize):
for x in range(xsize):
#do transfer and composite for y values across the entire range
a = transfer(scalars[x,ymin,z],srange)
for y in range(ymin,ymax):
a = composite(a,transfer(scalars[x,y,z],srange))
ra,ga,ba,aa = a
#update displaySlice appropriately
displaySlice.SetScalarComponentFromFloat(x, z, 0, 0, ra*aa)
displaySlice.SetScalarComponentFromFloat(x, z, 0, 1, ga*aa)
displaySlice.SetScalarComponentFromFloat(x, z, 0, 2, ba*aa)
def saveSliceToImage(displaySlice,fname):
xs,zs,_ = displaySlice.GetDimensions()
scalars = VN.vtk_to_numpy(displaySlice.GetPointData().GetArray(0))
scalars = (255*scalars).astype(numpy.uint8)
scalars = scalars.reshape((xs,zs,3),order="F")
scalars = numpy.rot90(scalars,1)
im = Image.fromarray(scalars)
im.save(fname)
display(im)
def decompressVtkData(ifname,ofname):
if not os.path.exists(ofname):
if os.path.exists(ifname):
with gzip.GzipFile(ifname, 'rb ') as fin:
with open(ofname, 'wb') as fout:
fout.write(fin.read())
#transfer = transfer function to pass to volumeRender()
#composite = composite function to pass to volumeRender()
#ymin = y value to pass to volumeRender
def render(transfer,composite,fname,yval=-1):
decompressVtkData(VTK_FILE+".gz",VTK_FILE)
reader = vtk.vtkStructuredPointsReader()
reader.SetFileName(VTK_FILE)
reader.Update()
volume = reader.GetOutput()
xsize, ysize, zsize = volume.GetDimensions()
displaySlice = vtk.vtkImageData()
displaySlice.SetExtent(0,xsize-1,0,zsize-1,0,0);
displaySlice.AllocateScalars(vtk.VTK_FLOAT,3);
volumeRender(displaySlice,volume,transfer,composite,yval)
displaySlice.Modified()
2 Part 1: Maximum intensity projection
Implement transferGrayscale():
• function should return an (r,g,b,a) tuple
• r, g, and b components should be equal to the linear interpolation of scalar between the min and max values in srange, normalized to (0,1)
• a component should always be 1
[ ]: #grade (DO NOT DELETE THIS LINE)
def transferGrayscale(scalar, srange):
###BEGIN STUDENT SOLUTION
pass
###END REFERENCE SOLUTION
Test transferGrayscale()
[ ]: #unit tests for transferGrayscale()
r = [4,7]
scalars = [5,6,5.5,6.5]
grays = [2/6,4/6,3/6,5/6]
for i in range(len(scalars)):
numpy .testing .assert_allclose(transferGrayscale(scalars[i],r)[0],grays[i],␣ ,→rtol=1e-2)
numpy .testing .assert_allclose(transferGrayscale(scalars[i],r)[1],grays[i],␣ ,→rtol=1e-2)
numpy .testing .assert_allclose(transferGrayscale(scalars[i],r)[2],grays[i],␣ ,→rtol=1e-2)
numpy .testing .assert_allclose(transferGrayscale(scalars[i],r)[3],1,␣ ,→rtol=1e-2)
Test render using transferGrayscale() [ ]: render(transferGrayscale,compositeKeepA,"test .png",200)
Your image should look like this:
Implement compositeMax():
• a and b are both rgba tuples of the form (red,green,blue,alpha)
• return value should be the max of a and b using standard ordering operators (e.g., compare red, then green, then blue, then alpha)
[ ]: #grade (DO NOT DELETE THIS LINE)
def compositeMax(a,b):
###BEGIN STUDENT SOLUTION
pass
###END REFERENCE SOLUTION
Test compositeMax()
[ ]: #unit tests for compositeMax()
for i in range(1000):
a = tuple([random .random() for _ in range(4)])
b = tuple([random .random() for _ in range(4)])
if a > b:
assert(compositeMax(a,b) == a)
else:
assert(compositeMax(a,b) == b)
Test render using compositeMax() [ ]: render(transferGrayscale,compositeMax,"part1 .png")
Your image should look like this:
3 Part 2: “X-ray” projection
Implement transferAlpha():
• function should return an (r,g,b,a) tuple
• r, g, and b components should always be 1
• a component should be equal to the linear interpolation of scalar between the min and max values in srange, normalized to (0,1), and multiplied by the constant 0.0125
[ ]: #grade (DO NOT DELETE THIS LINE)
def transferAlpha(scalar, srange):
###BEGIN STUDENT SOLUTION
pass
###END REFERENCE SOLUTION
Test transferAlpha()
[ ]: #unit tests for transferAlpha()
r = [4,7]
scalars = [5,6,5.5,6.5]
alphas = [0.004167,0.008333,0.00625,0.010417]
for i in range(len(scalars)):
numpy .testing .assert_allclose(transferAlpha(scalars[i],r)[0],1, rtol=1e-2)
numpy .testing .assert_allclose(transferAlpha(scalars[i],r)[1],1, rtol=1e-2)
numpy .testing .assert_allclose(transferAlpha(scalars[i],r)[2],1, rtol=1e-2)
numpy .testing .assert_allclose(transferAlpha(scalars[i],r)[3],alphas[i],␣ ,→rtol=1e-2)
Implement compositeOver():
• a and b are both rgba tuples of the form (red,green,blue,alpha)
• return value should be the tuple (ro,go,bo,ao), or the rgba color resulting from the appli- cation of the over operator for a over b
• see image below and https://en.wikipedia.org/wiki/Alpha_compositing#Description for over operator computation reference
[ ]: #grade (DO NOT DELETE THIS LINE)
def compositeOver(a,b):
###BEGIN STUDENT SOLUTION
pass
###END REFERENCE SOLUTION
Test compositeOver()
[ ]: #unit tests for compositeOver()
a = (0.4,0.7,0.2,0.5)
b = (0.1,0.9,0.8,0.6)
aoverb = compositeOver(a,b)
numpy.testing.assert_allclose(aoverb[0],0.2875, rtol=1e-2)
numpy.testing.assert_allclose(aoverb[1],0.7775, rtol=1e-2)
numpy.testing.assert_allclose(aoverb[2],0.425, rtol=1e-2)
numpy.testing.assert_allclose(aoverb[3],0.8, rtol=1e-2)
bovera = compositeOver(b,a)
numpy.testing.assert_allclose(bovera[0],0.175, rtol=1e-2)
numpy.testing.assert_allclose(bovera[1],0.85, rtol=1e-2)
numpy.testing.assert_allclose(bovera[2],0.65, rtol=1e-2)
numpy.testing.assert_allclose(bovera[3],0.8, rtol=1e-2)
Test render using transferAlpha() and compositeOver()
[ ]: render(transferAlpha,compositeOver,"part2.png")
Your image should look like this:
[ ]:
2022-07-12