Learn R Programming

Morpho (version 2.12)

slider3d: slides Semilandmarks along curves and surfaces in 3D by minimising bending energy of a thin-plate spline deformation.

Description

slides Semilandmarks along curves and surfaces in 3D. The positions on the surface are sought which minimise bending energy (of a thin-plate spline deformation)

Usage

slider3d(
  dat.array,
  SMvector,
  outlines = NULL,
  surp = NULL,
  sur.path = NULL,
  sur.name = NULL,
  meshlist = NULL,
  ignore = NULL,
  sur.type = "ply",
  tol = 1e-05,
  deselect = FALSE,
  inc.check = TRUE,
  recursive = TRUE,
  iterations = 0,
  initproc = TRUE,
  fullGPA = FALSE,
  pairedLM = 0,
  bending = TRUE,
  stepsize = ifelse(bending, 1, 0.5),
  mc.cores = parallel::detectCores(),
  fixRepro = TRUE,
  missingList = NULL,
  use.lm = NULL,
  smoothnormals = FALSE,
  silent = FALSE
)

Value

dataslide

array containing slidden Landmarks in the original space - not yet processed by a Procrustes analysis

vn.array

array containing landmark normals

Arguments

dat.array

Input k x m x n real array, where k is the number of points, m is the number of dimensions, and n is the sample size. Ideally the dimnames[[3]] vector contains the names of the surface model (without file extension) - e.g. if the model is named "surface.ply", the name of the corresponding matrix of the array would be "surface"

SMvector

A vector containing the row indices of (semi-) landmarks on the curve(s) and surfaces that are allowed to slide

outlines

A vector (or if threre are several curves) a list of vectors (containing the rowindices) of the (Semi-)landmarks forming the curve(s) in the successive position on the curve - including the beginning and end points, that are not allowed to slide.

surp

integer vector containing the row indices of semi-landmarks positioned on surfaces.

sur.path

Path to the surface models (e.g. ply, obj, stl files)

sur.name

character vector: containing the filenames of the corresponding surfaces - e.g. if the dat.array[,,i] belongs to surface_i.ply, sur.name[i] would be surface_i.ply. Only necessary if dat.array does not contain surface names.

meshlist

list containing triangular meshes of class 'mesh3d', for example imported with mesh2ply or file2mesh in the same order as the specimen in the array (see examples below).

ignore

vector containing indices of landmarks that are to be ignored. Indices of outlines/surfaces etc will be updated automatically.

sur.type

character:if all surfaces are of the same file format and the names stored in dat.array, the file format will be specified here.

tol

numeric: Threshold for convergence in the sliding process

deselect

Logical: if TRUE, the SMvector is interpreted as those landmarks, that are not allowed to slide.

inc.check

Logical: if TRUE, the program stops when convergence criterion starts increasing and reports result from last iteration.

recursive

Logical: if TRUE, during the iterations of the sliding process, the outcome of the previous iteration will be used. Otherwise the original configuration will be used in all iterations.

iterations

integer: select manually the max. number of iterations that will be performed during the sliding process (usefull, when there is very slow convergence). 0 means iteration until convergence.

initproc

requests initial Procrustes fit before sliding.

fullGPA

Logical: if FALSE, only a partial procrustes fit will be performed.

pairedLM

A X x 2 numeric matrix with the indices of the rows containing paired Landmarks. E.g. the left column contains the lefthand landmarks, while the right side contains the corresponding right hand landmarks. - This will ideally create symmetric mean to get rid of assymetry.

bending

if TRUE, bending energy will be minimized, Procrustes distance otherwise.

stepsize

integer: dampening factor for the amount of sliding. Useful to keep semi-landmarks from sliding too far off the surface. The displacement is calculated as \(\Upsilon = \Upsilon^0 + stepsize * UT\). Default is set to 1 for bending=TRUE and 0.5 for bending=FALSE.

mc.cores

integer: determines how many cores to use for the computation. The default is autodetect. But in case, it doesn't work as expected cores can be set manually.

fixRepro

logical: if TRUE, fix landmarks will also be projected onto the surface. If you have landmarks not on the surface, select fixRepro=FALSE

missingList

a list of length samplesize containing integer vectors of row indices specifying missing landmars for each specimen. For specimens without missing landmarks enter numeric(0).

use.lm

indices specifying a subset of (semi-)landmarks to be used in the rotation step - only used if bending=FALSE.

smoothnormals

logical: if TRUE, tangent planes will be computed from locally smoothed normals

silent

logical: if TRUE, console output is suppressed.

Warning

Depending on the size of the suface meshes and especially the amount of landmarks this can use an extensive amount of your PC's resources, especially when running in parallel. As the computation time and RAM usage of matrix algebra involved is quadratic to the amount of landmarks used, doubling the amount of semi-landmarks will quadruple computation time and system resource usage. You can easily stall you computer with this function with inappropriate data.

Author

Stefan Schlager

References

Klingenberg CP, Barluenga M, and Meyer A. 2002. Shape analysis of symmetric structures: quantifying variation among individuals and asymmetry. Evolution 56(10):1909-1920.

Gunz, P., P. Mitteroecker, and F. L. Bookstein. 2005. Semilandmarks in Three Dimensions, in Modern Morphometrics in Physical Anthropology. Edited by D. E. Slice, pp. 73-98. New York: Kluwer Academic/Plenum Publishers.

Schlager S. 2012. Sliding semi-landmarks on symmetric structures in three dimensions. American Journal of Physical Anthropology, 147(S52):261. URL: http://dx.doi.org/10.1002/ajpa.21502.

Schlager S. 2013. Soft-tissue reconstruction of the human nose: population differences and sexual dimorphism. PhD thesis, Universitätsbibliothek Freiburg. URL: http://www.freidok.uni-freiburg.de/volltexte/9181/.

See Also

relaxLM, createMissingList

Examples

Run this code
if (FALSE) {
data(nose)
###create mesh for longnose
longnose.mesh <- tps3d(shortnose.mesh,shortnose.lm,longnose.lm,threads=1)
### write meshes to disk
mesh2ply(shortnose.mesh, filename="shortnose")
mesh2ply(longnose.mesh, filename="longnose")

## create landmark array
data <- bindArr(shortnose.lm, longnose.lm, along=3)
dimnames(data)[[3]] <- c("shortnose", "longnose")

# define fix landmarks
fix <- c(1:5,20:21)
# define surface patch by specifying row indices of matrices
# all except those defined as fix
surp <- c(1:nrow(shortnose.lm))[-fix]

slide <- slider3d(data, SMvector=fix, deselect=TRUE, surp=surp,
                  sur.path=".",iterations=1,mc.cores=1)
                  # sur.path="." is the current working directory

# now one example with meshes in workspace

meshlist <- list(shortnose.mesh,longnose.mesh)

slide <- slider3d(data, SMvector=fix, deselect=TRUE, surp=surp,
                  iterations=1, meshlist=meshlist,
                  mc.cores=1,fixRepro=FALSE)
require(rgl)
## visualize sliding
deformGrid3d(slide$dataslide[,,1],shortnose.lm,ngrid = 0)
## these are fix
spheres3d(slide$dataslide[fix,,1],col=4,radius=0.7)

###finally an example with missing landmarks:
## we assume that coordinates 185:189, 205:209 and 225:229 are in the second config are missing
missingList <- createMissingList(2)
missingList[[2]] <- c(185:189,205:209,225:229)
slideMissing <- slider3d(data, SMvector=fix, deselect=TRUE, surp=surp,
                  iterations=1, meshlist=meshlist,
                  mc.cores=1,fixRepro=FALSE,missingList=missingList)

## example with two curves
## Example with surface semilandmarks and two curves
fix <- c(1:5,20:21)
outline1 <- c(304:323)
outline2 <- c(604:623)
outlines <- list(outline1,outline2)
surp <- c(1:623)[-c(fix,outline1,outline2)]
slideWithCurves <- slider3d(data, SMvector=fix, deselect=TRUE, surp=surp,
                            meshlist=meshlist,iterations=1,mc.cores=1,outlines=outlines)
deformGrid3d(slideWithCurves$dataslide[,,1],shortnose.lm,ngrid = 0)
plot(slideWithCurves)

## finally an example with sliding without meshes by estimating the surface from the
## semi-landmarks

slideWithCurvesNoMeshes <- slider3d(data, SMvector=fix, deselect=TRUE, surp=surp,
                            iterations=1,mc.cores=1,outlines=outlines)
## compare it to the data with surfaces
deformGrid3d(slideWithCurves$dataslide[,,1],slideWithCurvesNoMeshes$dataslide[,,1],ngrid = 0)
## not too bad, only lonely surface semi-landmarks are a bit off

}

Run the code above in your browser using DataLab