Hi Federica,
A good starting point for a fitting with MCMC could be the following snippet. Of course the proposals and evaluators which are the most interesting parts, i left out. The proposals should not change much depending on which information you have, landmarks or not. But you will need an adapted evaluator.
I do not get your point of sampling points when you do not have landmarks. Landmarks are an instance of the concept of point-to-point correspondence and are therefore very well defined on the model and the target. Just random sampling would not give you point pairs in correspondence. Or did I understand you wrong? Is it impossible to define landmarks?
If you have well-aligned shapes you could maybe directly start with a likelihood similar to the average shape distance. Then you would not need landmarks. If they are not well aligned, consider first to adapt only the pose, so only use pose proposals first. Then when you have well-aligned shapes, you could mix shape and pose proposals for a second step where you then calculate the shape fitting as non-rigid registration. For both phases, you could use the same evaluator based on average shape distance.
I hope this gives you additional input on how to approach the fitting with MCMC.
Best, Andreas
object MCMCFitting extends App {
case class FitParameter(translationParameters: EuclideanVector[_3D],
pitchRotation: Double,
yawRotation: Double,
rollRotation: Double,
modelCoefficients: DenseVector[Double],
center: Point[_3D])
scalismo.initialize()
implicit val rng = Random(1024l)
val init: FitParameter = ???
val ssm: StatisticalMeshModel = ???
val target: TriangleMesh[_3D] = ???
val proposal: ProposalGenerator[FitParameter] with TransitionProbability[FitParameter] = ???
val evaluator: DistributionEvaluator[FitParameter] = ???
val chain = MetropolisHastings(proposal,evaluator)
val sampleIterator = chain.iterator(init)
val samples = sampleIterator.take(1000).toIndexedSeq
val maximumAPosterioriSample = samples.maxBy( s => evaluator.logValue(s))
val finalRigidTransformation = RigidTransformation(
TranslationTransform(maximumAPosterioriSample.translationParameters),
RotationTransform(
maximumAPosterioriSample.pitchRotation,maximumAPosterioriSample.yawRotation,maximumAPosterioriSample.rollRotation,
maximumAPosterioriSample.center)
)
val finalShape = ssm.instance(maximumAPosterioriSample.modelCoefficients).transform(finalRigidTransformation)
}