-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
5 changed files
with
205 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#--------------------------------------------------------- | ||
# # [Cone](@id 36-cone) | ||
#--------------------------------------------------------- | ||
|
||
#= | ||
This page illustrates the `Cone` shape in the Julia package | ||
[`ImagePhantoms`](https://github.com/JuliaImageRecon/ImagePhantoms.jl). | ||
This page was generated from a single Julia file: | ||
[36-cone.jl](@__REPO_ROOT_URL__/36-cone.jl). | ||
=# | ||
|
||
#md # In any such Julia documentation, | ||
#md # you can access the source code | ||
#md # using the "Edit on GitHub" link in the top right. | ||
|
||
#md # The corresponding notebook can be viewed in | ||
#md # [nbviewer](http://nbviewer.jupyter.org/) here: | ||
#md # [`36-cone.ipynb`](@__NBVIEWER_ROOT_URL__/36-cone.ipynb), | ||
#md # and opened in [binder](https://mybinder.org/) here: | ||
#md # [`36-cone.ipynb`](@__BINDER_ROOT_URL__/36-cone.ipynb). | ||
|
||
|
||
# ### Setup | ||
|
||
# Packages needed here. | ||
|
||
using ImagePhantoms: Object, phantom, radon, spectrum | ||
using ImagePhantoms: Cone, cone | ||
import ImagePhantoms as IP | ||
using ImageGeoms: ImageGeom, axesf | ||
using MIRTjim: jim, prompt, mid3 | ||
using FFTW: fft, fftshift, ifftshift | ||
using LazyGrids: ndgrid | ||
using Unitful: mm, unit, ° | ||
using Plots: plot, plot!, scatter!, default | ||
using Plots # gif @animate | ||
default(markerstrokecolor=:auto) | ||
|
||
|
||
# The following line is helpful when running this file as a script; | ||
# this way it will prompt user to hit a key after each figure is displayed. | ||
|
||
isinteractive() ? jim(:prompt, true) : prompt(:draw); | ||
|
||
|
||
# ### Overview | ||
|
||
#= | ||
A basic shape used in constructing 3D digital image phantoms | ||
is the cone, | ||
specified by its center, base radii, height, angle(s) and value. | ||
All of the methods in `ImagePhantoms` support physical units, | ||
so we use such units throughout this example. | ||
(Using units is recommended but not required.) | ||
Here are 3 ways to define a `Object{Cone}`, | ||
using physical units. | ||
=# | ||
|
||
center = (20mm, 10mm, -15mm) | ||
width = (25mm, 30mm, 35mm) # x radius, y radius, height | ||
ϕ0s = :(π/6) # symbol version for nice plot titles | ||
ϕ0 = eval(ϕ0s) | ||
angles = (ϕ0, 0, 0) | ||
Object(Cone(), center, width, angles, 1.0f0) # top-level constructor | ||
cone( 20mm, 10mm, 5mm, 25mm, 35mm, 15mm, π/6, 0, 0, 1.0f0) # 9 arguments | ||
ob = cone(center, width, angles, 1.0f0) # tuples (recommended use) | ||
|
||
|
||
#= | ||
### Phantom image using `phantom` | ||
Make a 3D digital image of it using `phantom` and display it. | ||
We use `ImageGeoms` to simplify the indexing. | ||
=# | ||
|
||
deltas = (1.0mm, 1.1mm, 0.9mm) | ||
dims = (2^8, 2^8+2, 49) # odd | ||
ig = ImageGeom( ; dims, deltas, offsets=:dsp) | ||
oversample = 3 | ||
img = phantom(axes(ig)..., [ob], oversample) | ||
p1 = jim(axes(ig), img; | ||
title="Cone, rotation ϕ=$ϕ0s", xlabel="x", ylabel="y") | ||
|
||
|
||
# The image integral should match the object volume: | ||
volume = IP.volume(ob) | ||
(sum(img)*prod(ig.deltas), volume) | ||
|
||
|
||
# Show middle slices | ||
jim(mid3(img), "Middle 3 planes") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#= | ||
cone.jl | ||
Right cone | ||
Base object is a cone with unit radius and unit height, | ||
with base at origin pointing up along z. | ||
=# | ||
|
||
|
||
export Cone, cone | ||
|
||
|
||
""" | ||
Cone <: AbstractShape{3} | ||
""" | ||
struct Cone <: AbstractShape{3} end | ||
|
||
|
||
# constructor | ||
|
||
|
||
""" | ||
cone(cx, cy, cz, wx, wy, wz, Φ, Θ, value::Number) | ||
cone(center::NTuple{3,RealU}, width::NTuple{3,RealU}, angle::NTuple{3,RealU}, v) | ||
Construct `Object{Cone}` from parameters; | ||
here `width` is the base radii for `wx` and `wy` and `wz` is the height. | ||
""" | ||
cone(args... ; kwargs...) = Object(Cone(), args...; kwargs...) | ||
|
||
|
||
# methods | ||
|
||
|
||
volume1(::Cone) = π/3 # volume of unit cone | ||
|
||
ℓmax1(::Cone) = 2 # max line integral through unit cone | ||
|
||
function ℓmax(ob::Object3d{Cone}) | ||
rmax = maximum(ob.width[1:2]) | ||
return max(2 * rmax, sqrt(rmax^2 + ob.width[3]^2)) | ||
end | ||
|
||
|
||
""" | ||
phantom1(ob::Object3d{Cone}, (x,y,z)) | ||
Evaluate unit cone at `(x,y,z)`, | ||
for unitless coordinates. | ||
""" | ||
function phantom1(ob::Object3d{Cone}, xyz::NTuple{3,Real}) | ||
z = xyz[3] | ||
r = sqrt(sum(abs2, xyz[1:2])) | ||
return (0 ≤ z ≤ 1) && r ≤ 1 - z | ||
end | ||
|
||
|
||
# radon | ||
|
||
|
||
# x-ray transform (line integral) of unit cone | ||
# `u,v` should be unitless | ||
#= | ||
function xray1( | ||
::Cone, | ||
u::Ru, | ||
v::Rv, | ||
ϕ::RealU, # azim | ||
θ::RealU; # polar | ||
) where {Ru <: Real, Rv <: Real} | ||
T = promote_type(Ru, Rv, Float32) | ||
# (sϕ, cϕ) = sincos(ϕ) | ||
# (sθ, cθ) = sincos(θ) | ||
throw("todo: cone radon not done") | ||
end | ||
=# | ||
|
||
|
||
# spectrum | ||
|
||
#= | ||
""" | ||
spectrum1(::Object3d{Cone}, (kx,ky,kz)) | ||
Spectrum of unit cone at `(kx,ky,kz)`, | ||
for unitless spatial frequency coordinates. | ||
""" | ||
function spectrum1(::Object3d{Cone}, kxyz::NTuple{3,Real}) | ||
throw("todo: cone spectrum not done") | ||
end | ||
=# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9c5daee
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JuliaRegistrator() register
9c5daee
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Registration pull request created: JuliaRegistries/General/70866
After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.
This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via: