Ok, then my first question is, within the previous code that I got to help compare my code to, which no longer works because of similar problems the import function:
import scalismo.geometry.{Landmark, Point3D, Vector, _3D} no longer works because Vector is no longer available. Therefore, when I use the val gauss = GaussianProcess[_3D, Vector[_3D]](changepointkernel), I cannot generate the proper gaussian process. I do not understand whether I should now be using DiscreteLowRankGaussianProcess as in:
val faceGP : DiscreteLowRankGaussianProcess[_3D, TriangleMesh, EuclideanVector[_3D]] = faceModel.gp from the tutorial on Gaussian Processes or whether I should be using the process from Shape modelling with Gaussian kernels:
val gp = GaussianProcess3D[EuclideanVector[_3D]](zeroMean, matrixValuedGaussianKernel) to build it, in which case, why is it necessary to start with a zeromean gaussian kernel?
Also, within this code:
def doRegistration(
lowRankGP: LowRankGaussianProcess[_3D, EuclideanVector[_3D]],
referenceMesh: TriangleMesh[_3D],
targetmesh: TriangleMesh[_3D],
registrationParameters: RegistrationParameters,
initialCoefficients: DenseVector[Double]
): DenseVector[Double] = {
val transformationSpace = GaussianProcessTransformationSpace(lowRankGP)
val fixedImage = referenceMesh.operations.toDistanceImage
val movingImage = targetMesh.operations.toDistanceImage
val sampler = FixedPointsUniformMeshSampler3D(
referenceMesh,
registrationParameters.numberOfSampledPoints
)
val metric = MeanSquaresMetric(
fixedImage,
movingImage,
transformationSpace,
sampler
)
val optimizer = LBFGSOptimizer(registrationParameters.numberOfIterations)
val regularizer = L2Regularizer(transformationSpace)
val registration = Registration(
metric,
regularizer,
registrationParameters.regularizationWeight,
optimizer
)
val registrationIterator = registration.iterator(initialCoefficients)
val visualizingRegistrationIterator = for ((it, itnum) <- registrationIterator.zipWithIndex) yield {
println(s"object value in iteration $itnum is ${it.value}")
it
}
val registrationResult = visualizingRegistrationIterator.toSeq.last
registrationResult.parameters
}
Is the registrationResult value the registered triangle mesh from the Parametric, non-rigid registration tutorial? if so, how do I get the triangle mesh from this in orer to save the non-rigid registered sample from this line: val finalCoefficients = registrationParameters.foldLeft(initialCoefficients)((modelCoefficients, regParameters) =>
doRegistration(lowRankGP, referenceMesh, targetMesh, regParameters, modelCoefficients)
)? Is this how you would actually run the registration?
for ((targetMeshFile, targetMesh, targetLandmarkFile, targetLandmarks) <- meshAndLandmarkPairs) {
println("registering mesh " + targetMeshFile.getName)
ui.find[TriangleMeshView](
targetGroup, (tv : TriangleMeshView) => true).foreach(v => v.remove())
val targetView =
ui.show(
targetGroup, targetMesh, "target")
targetView.color = Color.
RED
val pointPairsForPosterior = for ((refLm, targetLm) <-
referenceLandmarks.zip(targetLandmarks)) yield {
(refLm.point, targetLm.point - refLm.point)
}
val posteriorGP =
lowRankGP.posterior(pointPairsForPosterior.toIndexedSeq, sigma2 = 9.0)
val initialCoefficients = DenseVector.zeros[Double](lowRankGP.rank)
val registrationParameters = Seq(
RegistrationParameters(regularizationWeight = 1e-1, numberOfIterations = 20, numberOfSampledPoints = 1000),
RegistrationParameters(regularizationWeight = 1e-2, numberOfIterations = 30, numberOfSampledPoints = 1000),
RegistrationParameters(regularizationWeight = 1e-4, numberOfIterations = 40, numberOfSampledPoints = 2000),
RegistrationParameters(regularizationWeight = 1e-6, numberOfIterations = 50, numberOfSampledPoints = 4000)
)
val registeredMesh = doRegistration(posteriorGP, referenceMesh, targetMesh, registrationParameters, iniitalcoefs)
MeshIO.writeMesh(registeredMesh, new File(outputMeshDir, targetMeshFile.getName))
}