|
|
A recent post by user 'yesbird' described using a .df3 media-density file made
from a medical CT scan, and rendered in POV-ray...
https://news.povray.org/povray.advanced-users/thread/%3C66f2f986%40news.povray.org%3E/?mtop=444143
I was inspired by that to try a different method, just to see if it would work:
skipping the CT-scan-to-.df3 conversion step and instead using the 'stack' of
multiple CT-scan images themselves as the media density, for the full 3-D
volume.
[I had to use one of the 3.8 betas for this test, because of a limitation in
'official' 3.7.0 of a maximum 256 entries in a pigment_map.]
For the test, I used a CT scan of my own, acquired from a recent visit to my
dentist (for a 'root canal' procedure-- which was painless, I am happy to say!)
In one of the file folders on the CD, I found the original numbered grayscale
image 'slices' that make up the scan-- 358 of them, at 523 X 523 pixel
resolution. Unfortunately, those 16-bit images were in a .dcm file format that
POV-ray cannot directly read as image_maps, so I batch-converted them to .png
files in Irfanview. (That app has a built-in dcm-to-png conversion filter,
although it is not turned on by default.) The one drawback is that the resulting
files were 'down-converted' to 8-bit grayscale...but that was adequate for my
test. The CT scan itself was of rather low-quality anyway.
Image_maps (or 'pigments' in general) cannot be used directly as media density--
but a *function* of the image_maps can. The trick was to get all of the 358
images loaded into a single pigment_map, for conversion to a function; I used an
automated 'string' set-up to do that, in a #for loop. (A typical pigment_map
uses index values between 0.0 and 1.0, which corresponds to 1 unit in z-space by
default. The 358 images fill that volume.)
pigment{
gradient z
pigment_map{
#for(i,1,358)
[i/358
image_map{
png concat("3DSlice",str(i,0,0),".png") gamma 3 interpolate 2 once
}
]
// a higher than normal gamma has the effect of increasing the
// image contrast
#end
.....
It produces the same result as laboriously specifying the individual images
themselves:
[1/358 image_map{png "3DSlice1.png" gamma 3 interpolate 2 once]
[2/358 image_map{png "3DSlice2.png" gamma 3 interpolate 2 once]
.....
[357/358 image_map{png "3DSlice357.png" gamma 3 interpolate 2 once]
[358/358 image_map{png "3DSlice358.png" gamma 3 interpolate 2 once]
(Just a reminder: The images need to be in a file folder location that POV-ray
can find; an additional Library_Path can be added to your master povray.ini
file if needed.)
To be honest, I was not sure *what* the end result of this media scheme would
look like, because of the image_maps being 'stacked together' in z, AND with
small gaps between their z-spacing. (They are just 2-D images.) But in effect,
they produce a kind of 'fake' .df3 appearance-- with a .df3's 'voxel depth'
being replaced by each image's media inbetween the image slices. Apparently,
each image's z-depth media extends only until the next image_map is
encountered-- instead of creating one ugly media blur in the enclosing box.
In the media code, a color_map can be used to give different colors to the
different 'densities'-- meaning, the varying grayscale values of the image_maps.
And the map's colors and index values can be played with to get interesting
effects, like supressing certain densities while accentuating others.
I will also post an animation of the rotating media box, at p.b.f. animations
in the newsgroups.
----
The one unknown value was the 'spacing' of the individual images in the CT
scan-- the CT machine's spatial resolution as the x-ray slices progressed
through my teeth! I just assumed that a 1-unit cube (a box) would suffice as the
full 'depth', more or less. (I actually used <523,523,358>/523 for the scaling)
----
My code:
#version 3.8;
global_settings{assumed_gamma 1.0}
// #default{finish{ambient .05 emission 0 diffuse .9}}
camera {
perspective
location <0, 0, -1.1>
look_at <0, 0, 0>
right x*image_width/image_height
angle 67
}
#declare PIG_SLICES =
function{
pigment{
gradient z
pigment_map{
#for(i,1,358) // 358 images
[i/358
image_map{png concat("3DSlice",str(i,0,0),".png") gamma 3 interpolate 2 once}
]
#end
} // end of pigment_map
} // end of pigment
} // end of function
box{0,.999 translate .0005
hollow
pigment{rgbt 1}
interior{
media{
emission 4
//absorption...
//scattering...
method 3 intervals 1 samples 60 aa_level 4
density{
function{PIG_SLICES(x,y,z).gray} // or .red or .green or .blue
color_map{
[0 transmit 1]
[.01 transmit 1]
[.1 rgb <0,0,1>]
[.2 rgb <0,1,0>]
[.5 rgb <0,1,0>]
[.5 rgb <1,0,0>]
[1 rgb <1,0,0>]
}
} // end of density
} // end of media
} // end of interior
translate -.5
scale <523,523,358>/523
//rotate...
}
Post a reply to this message
Attachments:
Download 'ct_scan_to_media_density_1_kw_10_2024.jpg' (226 KB)
Preview of image 'ct_scan_to_media_density_1_kw_10_2024.jpg'
|
|