### Create a 3D Translation Parametric Transformation in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/transformations.md Instantiates a 3D translation transformation using a specified Euclidean vector. This is an example of a parametric transformation, which is defined by a finite set of parameters. ```Scala val translation = Translation3D(EuclideanVector3D(1, 3, 0.5)) translation.parameters ``` -------------------------------- ### Get Inverse of Rigid Transformation in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/transformations.md Calculates the inverse of a rigid transformation, specifically demonstrating the inverse of a RotationThenTranslation transformation. ```Scala val rinv : TranslationThenRotation[_3D] = RotationThenTranslation(rotation, translation).inverse ``` -------------------------------- ### Get Derivative of a Differentiable 3D Transformation in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/transformations.md Calculates the derivative of a transformation with respect to its position. This is possible if the transformation implements the CanDifferentiateWRTPosition trait. ```Scala val tDifferentiable : Transformation[_3D] with CanDifferentiateWRTPosition[_3D] = Translation3D(EuclideanVector3D(1, 0, 0)) val tDerivative : Point[_3D] => SquareMatrix[_3D] = tDifferentiable.derivativeWRTPosition ``` -------------------------------- ### Get Inverse of an Invertible 3D Transformation in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/transformations.md Retrieves the inverse transformation for a transformation that supports inversion, such as a translation. This requires the transformation to have the CanInvert trait. ```Scala val tInvertible : Transformation[_3D] with CanInvert[_3D, Transformation] = Translation3D(EuclideanVector3D(1, 0, 0)) val tinv : Translation[_3D] = tInvertible.inverse ``` -------------------------------- ### Initialize Scalismo and Load Meshes Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Initializes Scalismo's native libraries and loads a 'noseless' mesh from an STL file. It then displays the mesh with a specific color in the UI. ```Scala scalismo.initialize() val ui = ScalismoUI() val noseless = MeshIO.readMesh(new File("datasets/noseless.stl")).get val targetGroup = ui.createGroup("noseless") val targetView = ui.show(targetGroup, noseless, "noseless") targetView.color = Color.PINK ``` -------------------------------- ### Initialize Scalismo UI and Load Models Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Initializes the Scalismo environment and loads 3D mesh data and statistical models from files. It demonstrates how to organize objects into groups within the UI for visualization. ```scala scalismo.initialize() val ui = ScalismoUI() val targetGroup = ui.createGroup("noseless") val noseless = MeshIO.readMesh(new File("datasets/noseless.stl")).get val targetView = ui.show(targetGroup, noseless, "noseless") targetView.color = Color.PINK val littleModelGroup = ui.createGroup("littleModel group") val littleModel = StatismoIO.readStatismoMeshModel(new File("datasets/model.h5")).get val littleModelView = ui.show(littleModelGroup, littleModel, "littleModel") littleModelView.meshView.color = Color.ORANGE ``` -------------------------------- ### Write 3D Triangle Mesh with Scalismo Source: https://context7.com/unibas-gravis/scalismo/llms.txt Shows how to create a triangle mesh programmatically and save it to disk. The output format is automatically determined by the file extension provided in the File object. ```scala import scalismo.io.MeshIO import scalismo.mesh.{TriangleMesh3D, TriangleCell, TriangleList} import scalismo.common.{PointId, UnstructuredPoints} import scalismo.geometry.{Point, Point3D, _3D} import java.io.File val points = IndexedSeq( Point3D(0.0, 0.0, 0.0), Point3D(1.0, 0.0, 0.0), Point3D(0.5, 1.0, 0.0), Point3D(0.5, 0.5, 1.0) ) val triangles = IndexedSeq( TriangleCell(PointId(0), PointId(1), PointId(2)), TriangleCell(PointId(0), PointId(1), PointId(3)), TriangleCell(PointId(1), PointId(2), PointId(3)), TriangleCell(PointId(0), PointId(2), PointId(3)) ) val mesh = TriangleMesh3D(points, TriangleList(triangles)) MeshIO.writeMesh(mesh, new File("output.vtk")) MeshIO.writeMesh(mesh, new File("output.stl")) MeshIO.writeMesh(mesh, new File("output.ply")) ``` -------------------------------- ### Manage Scalismo UI Groups and Landmarks Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Demonstrates how to create UI groups and display models or landmarks within them. This replaces older global show methods with explicit group management. ```scala val modelGroup = ui.createGroup("model group") ui.show(modelGroup, model, "model") val lms = LandmarkIO.readLandmarksJson[_3D](new File("datasets/noseFittingLandmarks.json")).get ui.show(targetGroup, lms, "noseless") ``` -------------------------------- ### Write Discrete Images to VTK and NIfTI Source: https://context7.com/unibas-gravis/scalismo/llms.txt Demonstrates creating a 3D discrete image domain and writing the resulting image data to VTK or NIfTI file formats. This process requires a defined image domain and voxel data. ```scala import scalismo.io.ImageIO import scalismo.image.{DiscreteImage, DiscreteImageDomain, DiscreteImageDomain3D} import scalismo.geometry.{Point3D, EuclideanVector3D, IntVector3D, _3D} import java.io.File val origin = Point3D(0.0, 0.0, 0.0) val spacing = EuclideanVector3D(1.0, 1.0, 1.0) val size = IntVector3D(64, 64, 64) val domain = DiscreteImageDomain3D(origin, spacing, size) val image = DiscreteImage[_3D, Short](domain, pt => { val dist = math.sqrt(pt.x * pt.x + pt.y * pt.y + pt.z * pt.z) if (dist < 20) 1000.toShort else 0.toShort }) ImageIO.writeVTK(image, new File("sphere.vtk")) ImageIO.writeNifti(image, new File("sphere.nii")) ``` -------------------------------- ### Read Statistical Shape Models Source: https://context7.com/unibas-gravis/scalismo/llms.txt Illustrates loading a Point Distribution Model (PDM) from an HDF5 file. It covers accessing the mean shape, generating random samples, and creating specific instances using PCA coefficients. ```scala import scalismo.io.StatisticalModelIO import scalismo.statisticalmodel.PointDistributionModel import scalismo.mesh.TriangleMesh import scalismo.geometry._3D import java.io.File import scala.util.Success val modelFile = new File("face_model.h5") val modelResult = StatisticalModelIO.readStatisticalTriangleMeshModel3D(modelFile) modelResult match { case Success(model) => println(s"Model rank: ${model.rank}") val meanShape = model.mean implicit val rng = scalismo.utils.Random(42L) val randomSample = model.sample() import breeze.linalg.DenseVector val coeffs = DenseVector.zeros[Double](model.rank) coeffs(0) = 2.0 val specificShape = model.instance(coeffs) case _ => println("Failed to load model") } ``` -------------------------------- ### Manage Discrete Images and Interpolation Source: https://context7.com/unibas-gravis/scalismo/llms.txt Explains how to create discrete 3D image domains, populate them with values, and perform interpolation to continuous representations. It also covers resampling and domain rotation. ```scala import scalismo.image.{DiscreteImage, DiscreteImageDomain3D} import scalismo.geometry.{Point3D, EuclideanVector3D, IntVector3D, IntVector, _3D} import scalismo.common.Field import scalismo.common.interpolation.BSplineImageInterpolator3D val origin = Point3D(0.0, 0.0, 0.0) val spacing = EuclideanVector3D(1.0, 1.0, 1.0) val size = IntVector3D(100, 100, 100) val domain = DiscreteImageDomain3D(origin, spacing, size) val image = DiscreteImage[_3D, Float](domain, pt => (pt.x + pt.y + pt.z).toFloat) val voxelValue = image(IntVector(50, 50, 50)) val continuousImage: Field[_3D, Float] = image.interpolate(BSplineImageInterpolator3D(degree = 3)) val valueAtPoint = continuousImage(Point3D(50.5, 50.5, 50.5)) val newSize = IntVector3D(50, 50, 50) val newDomain = DiscreteImageDomain3D(domain.boundingBox, size = newSize) val resampledImage = continuousImage.discretize(newDomain, outsideValue = 0.0f) ``` -------------------------------- ### Read 3D Triangle Mesh with Scalismo Source: https://context7.com/unibas-gravis/scalismo/llms.txt Demonstrates how to load a 3D triangle mesh from VTK, STL, or PLY files. The function returns a Try object to handle potential IO errors gracefully. ```scala import scalismo.io.MeshIO import scalismo.mesh.TriangleMesh import scalismo.geometry._3D import java.io.File import scala.util.{Success, Failure} val meshFile = new File("face.vtk") val meshResult = MeshIO.readMesh(meshFile) meshResult match { case Success(mesh) => println(s"Loaded mesh with ${mesh.pointSet.numberOfPoints} points") println(s"Number of triangles: ${mesh.triangulation.triangles.size}") println(s"Bounding box: ${mesh.boundingBox}") case Failure(ex) => println(s"Failed to load mesh: ${ex.getMessage}") } val stlMesh = MeshIO.readMesh(new File("model.stl")) val plyMesh = MeshIO.readMesh(new File("scan.ply")) ``` -------------------------------- ### Perform 3D Geometric Transformations in Scalismo Source: https://context7.com/unibas-gravis/scalismo/llms.txt Demonstrates how to apply translation, rotation, and scaling transformations in 3D space. It also shows how to compose these transformations and use transformation spaces to generate them from parameters. ```scala import scalismo.transformations._ import scalismo.geometry.{Point3D, EuclideanVector3D, _3D} import breeze.linalg.DenseVector val translation = Translation3D(EuclideanVector3D(10.0, 20.0, 30.0)) val translatedPoint = translation(Point3D(0.0, 0.0, 0.0)) val center = Point3D(0.0, 0.0, 0.0) val rotation = Rotation3D(phi = Math.PI / 4, theta = 0.0, psi = 0.0, center = center) val rotatedPoint = rotation(Point3D(0.0, 1.0, 0.0)) val scaling = Scaling3D(2.0) val scaledPoint = scaling(Point3D(1.0, 1.0, 1.0)) val rigidTransform = TranslationAfterRotation3D(translation, rotation) val similarityTransform = TranslationAfterScalingAfterRotation3D(translation, scaling, rotation) val inverseRigid = rigidTransform.inverse val translationSpace = TranslationSpace3D val params = DenseVector(5.0, 10.0, 15.0) val translationFromParams = translationSpace.transformationForParameters(params) val rotationSpace = RotationSpace3D(center) val compositeSpace = ProductTransformationSpace(translationSpace, rotationSpace) ``` -------------------------------- ### Geometric Primitives: Point and EuclideanVector in Scala Source: https://context7.com/unibas-gravis/scalismo/llms.txt Illustrates the usage of Point and EuclideanVector for 1D, 2D, and 3D geometric entities. It covers creation, arithmetic operations, vector manipulations like normalization and dot product, and conversions to/from breeze vectors. ```Scala import scalismo.geometry._ // Create points in different dimensions val p1d = Point(5.0) val p2d = Point(3.0, 4.0) val p3d = Point(1.0, 2.0, 3.0) // Convenience constructors val point2D = Point2D(10.0, 20.0) val point3D = Point3D(1.0, 2.0, 3.0) // Create vectors val v2d = EuclideanVector2D(1.0, 0.0) val v3d = EuclideanVector3D(1.0, 2.0, 3.0) // Point-vector arithmetic val translated = point3D + v3d // Point3D(2.0, 4.0, 6.0) val displacement = point3D - Point3D.origin // EuclideanVector3D(1.0, 2.0, 3.0) // Vector operations val scaled = v3d * 2.0 // EuclideanVector3D(2.0, 4.0, 6.0) val normalized = v3d.normalize // Unit vector val length = v3d.norm // Euclidean norm val dot = v3d.dot(EuclideanVector3D(1.0, 0.0, 0.0)) // Dot product // 3D-specific operations val cross = v3d.crossproduct(EuclideanVector3D(0.0, 1.0, 0.0)) // Create from polar/spherical coordinates val fromPolar = Point.fromPolar(1.0, Math.PI / 4) // 2D point val fromSpherical = Point.fromSpherical(1.0, Math.PI / 4, Math.PI / 2) // 3D point // Convert to/from breeze vectors for linear algebra val breezeVec = point3D.toBreezeVector val backToPoint = Point.fromBreezeVector[_3D](breezeVec) ``` -------------------------------- ### Manipulate PointDistributionModel in Scalismo Source: https://context7.com/unibas-gravis/scalismo/llms.txt Demonstrates how to load a statistical shape model, sample random shapes, generate instances from coefficients, project target meshes, and compute posterior models based on observations. It requires a pre-trained model file and standard Scalismo geometry and IO imports. ```scala import scalismo.statisticalmodel.PointDistributionModel import scalismo.io.{StatisticalModelIO, MeshIO} import scalismo.geometry.{Point3D, _3D} import scalismo.common.PointId import breeze.linalg.DenseVector import java.io.File val model = StatisticalModelIO.readStatisticalTriangleMeshModel3D(new File("face_model.h5")).get val meanShape = model.mean implicit val rng = scalismo.utils.Random(42L) val randomShape1 = model.sample() val randomShape2 = model.sample() val coefficients = DenseVector.zeros[Double](model.rank) coefficients(0) = 2.0 coefficients(1) = -1.0 val specificShape = model.instance(coefficients) val targetMesh = MeshIO.readMesh(new File("target.vtk")).get val projectedShape = model.project(targetMesh) val reconstructionCoeffs = model.coefficients(targetMesh) val observations = IndexedSeq((PointId(100), Point3D(10.0, 20.0, 30.0)), (PointId(200), Point3D(15.0, 25.0, 35.0))) val posteriorModel = model.posterior(observations, sigma2 = 1.0) val posteriorSample = posteriorModel.sample() val reducedModel = model.truncate(newRank = 10) ``` -------------------------------- ### Create Training Data from Paired Landmarks Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Combines paired model and noseless landmarks to create training data for a statistical model. It associates points and adds a small noise factor. ```Scala val trainingData2 = (modelLandmarks zip noselessLandmarks).map { case (mLm, nLm) => (model.mean.pointSet.findClosestPoint(mLm.landmark.point).id, nLm.landmark.point, littleNoise) } ``` -------------------------------- ### Write Statistical Shape Models Source: https://context7.com/unibas-gravis/scalismo/llms.txt Demonstrates how to save a trained Point Distribution Model to an HDF5 file. This assumes the model has been created from a data collection of registered meshes. ```scala import scalismo.io.{StatisticalModelIO, MeshIO} import scalismo.statisticalmodel.PointDistributionModel import scalismo.statisticalmodel.dataset.DataCollection import scalismo.mesh.TriangleMesh import scalismo.geometry._3D import java.io.File val referenceMesh = MeshIO.readMesh(new File("reference.vtk")).get val trainingMeshes = (1 to 10).map(i => MeshIO.readMesh(new File(s"training_$i.vtk")).get ) val dataCollection = DataCollection.fromTriangleMesh3DSequence(referenceMesh, trainingMeshes) val model = PointDistributionModel.createUsingPCA(dataCollection) StatisticalModelIO.writeStatisticalTriangleMeshModel3D(model, new File("trained_model.h5")) ``` -------------------------------- ### Create Discrete Images in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/images.md Instantiates a discrete image by providing an image domain and a function that maps each point in the domain to a value, or by supplying an array of values. ```scala val image = DiscreteImage3D(imageDomain, p => 0.toShort) ``` ```scala val image2 = DiscreteImage3D(imageDomain, Array.fill(imageDomain.pointSet.numberOfPoints)(0.toShort)) ``` ```scala val image3 = DiscreteField3D(imageDomain, p => 0.toShort) ``` -------------------------------- ### Create and Manipulate TriangleMesh3D in Scala Source: https://context7.com/unibas-gravis/scalismo/llms.txt Demonstrates the creation of a 3D triangle mesh from points and triangles, accessing its properties like area and normals, and performing transformations. It utilizes the TriangleMesh3D class for representing triangulated surfaces. ```Scala import scalismo.mesh.{TriangleMesh3D, TriangleCell, TriangleList} import scalismo.common.{PointId, UnstructuredPoints} import scalismo.geometry.{Point3D, EuclideanVector3D, _3D} // Create a simple tetrahedron mesh val points = IndexedSeq( Point3D(0.0, 0.0, 0.0), Point3D(1.0, 0.0, 0.0), Point3D(0.5, 0.866, 0.0), Point3D(0.5, 0.289, 0.816) ) val triangles = IndexedSeq( TriangleCell(PointId(0), PointId(1), PointId(2)), TriangleCell(PointId(0), PointId(1), PointId(3)), TriangleCell(PointId(1), PointId(2), PointId(3)), TriangleCell(PointId(0), PointId(2), PointId(3)) ) val mesh = TriangleMesh3D(points, TriangleList(triangles)) // Access mesh properties println(s"Number of points: ${mesh.pointSet.numberOfPoints}") println(s"Number of triangles: ${mesh.triangulation.triangles.size}") println(s"Total surface area: ${mesh.area}") println(s"Bounding box: ${mesh.boundingBox}") // Compute normals val vertexNormals = mesh.vertexNormals val cellNormals = mesh.cellNormals // Transform the mesh val translatedMesh = mesh.transform(p => p + EuclideanVector3D(10.0, 0.0, 0.0)) // Access mesh operations for advanced functionality val ops = mesh.operations val closestPoint = ops.closestPointOnSurface(Point3D(0.5, 0.5, 0.5)) println(s"Closest point on surface: ${closestPoint.point}") ``` -------------------------------- ### Model Deformations with GaussianProcess in Scala Source: https://context7.com/unibas-gravis/scalismo/llms.txt Shows how to define and use Gaussian Processes for modeling continuous fields, such as deformation fields. It covers creating kernels, defining a GP with a mean and covariance, sampling from it, and performing regression by conditioning on observations. ```Scala import scalismo.statisticalmodel.GaussianProcess import scalismo.kernels.{GaussianKernel, DiagonalKernel} import scalismo.geometry.{Point, Point3D, EuclideanVector, EuclideanVector3D, _3D} import scalismo.common.{Field, EuclideanSpace} // Create a Gaussian kernel for smooth deformations val gaussianKernel = GaussianKernel3D(sigma = 50.0, scaleFactor = 10.0) // Create a diagonal kernel for vector-valued GP (3D deformation field) val vectorKernel = DiagonalKernel(gaussianKernel, 3) // Create a zero-mean GP for deformation modeling val gp = GaussianProcess3D[EuclideanVector[_3D]](vectorKernel) // Sample from the GP at specific points implicit val rng = scalismo.utils.Random(42L) val samplePoints = IndexedSeq( Point3D(0.0, 0.0, 0.0), Point3D(10.0, 0.0, 0.0), Point3D(0.0, 10.0, 0.0) ) val domain = scalismo.common.UnstructuredPointsDomain3D.Create.create(samplePoints) val sampledField = gp.sampleAtPoints(domain) // Compute marginal distribution at a point val marginalDist = gp.marginal(Point3D(5.0, 5.0, 5.0)) println(s"Mean at point: ${marginalDist.mean}") println(s"Covariance: ${marginalDist.cov}") // Condition GP on observations (regression) val observations = IndexedSeq( (Point3D(0.0, 0.0, 0.0), EuclideanVector3D(1.0, 0.0, 0.0)), (Point3D(20.0, 0.0, 0.0), EuclideanVector3D(-1.0, 0.0, 0.0)) ) val posteriorGP = gp.posterior(observations, sigma2 = 1.0) ``` -------------------------------- ### Define Discrete Image Domains in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/images.md Creates a domain for discrete images, representing a rectangular grid of points. It can be initialized using structured points, or directly with origin, spacing, size, and optional rotation. ```scala val imageDomain = DiscreteImageDomain3D(StructuredPoints3D(origin, spacing, size)) ``` ```scala val imageDomain2 = DiscreteImageDomain3D(origin, spacing, size) ``` ```scala val imageDomain3 = DiscreteImageDomain3D(origin, spacing, size, yaw, pitch, roll) ``` ```scala val boundingBox : BoxDomain[_3D] = imageDomain.boundingBox val imageDomain4 = DiscreteImageDomain3D(boundingBox, spacing = spacing) ``` ```scala val imageDomain5 = DiscreteImageDomain3D(boundingBox, size = size) ``` -------------------------------- ### Extract Landmark Points from UI Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Shows how to filter landmark views from a specific UI group and extract the underlying point data for model fitting. ```scala val modelLandmarkViews = ui.filter(modelGroup, (lv: LandmarkView) => true) val modelPts: Seq[Point[_3D]] = modelLandmarkViews.map(lv => lv.landmark.point) ``` -------------------------------- ### Load and Display Statistical Mesh Model Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Loads a statistical mesh model from an H5 file and displays it in the Scalismo UI with a distinct color. This represents a base shape model. ```Scala val littleModel = StatismoIO.readStatismoMeshModel(new File("datasets/model.h5")).get val littleModelGroup = ui.createGroup("littleModel group") val littleModelView = ui.show(littleModelGroup, littleModel, "littleModel") littleModelView.meshView.color = Color.ORANGE ``` -------------------------------- ### MeshIO.writeMesh API Source: https://context7.com/unibas-gravis/scalismo/llms.txt Writes a 3D triangle mesh to disk in various formats (VTK, STL, PLY, H5). The format is automatically determined by the file extension. ```APIDOC ## MeshIO.writeMesh ### Description Writes a 3D triangle mesh to disk in various formats (VTK, STL, PLY, H5). The format is automatically determined by the file extension. ### Method POST (conceptual, as it writes to a file) ### Endpoint N/A (File-based operation) ### Parameters #### Path Parameters - **mesh** (TriangleMesh[_3D]) - Required - The 3D triangle mesh to write. - **file** (File) - Required - The file object representing the destination path and filename. ### Request Example ```scala import scalismo.io.MeshIO import scalismo.mesh.{TriangleMesh3D, TriangleCell, TriangleList} import scalismo.common.{PointId, UnstructuredPoints} import scalismo.geometry.{Point, Point3D, _3D} import java.io.File // Create a simple triangle mesh programmatically val points = IndexedSeq( Point3D(0.0, 0.0, 0.0), Point3D(1.0, 0.0, 0.0), Point3D(0.5, 1.0, 0.0), Point3D(0.5, 0.5, 1.0) ) val triangles = IndexedSeq( TriangleCell(PointId(0), PointId(1), PointId(2)), TriangleCell(PointId(0), PointId(1), PointId(3)), TriangleCell(PointId(1), PointId(2), PointId(3)), TriangleCell(PointId(0), PointId(2), PointId(3)) ) val mesh = TriangleMesh3D(points, TriangleList(triangles)) // Write to different formats MeshIO.writeMesh(mesh, new File("output.vtk")) // VTK format MeshIO.writeMesh(mesh, new File("output.stl")) // STL format MeshIO.writeMesh(mesh, new File("output.ply")) // PLY format ``` ### Response #### Success Response (200) Indicates that the mesh was successfully written to the specified file. #### Response Example N/A (Operation is side-effecting, no explicit return value for success other than completion.) ``` -------------------------------- ### Metropolis-Hastings Sampling with Scalismo Source: https://context7.com/unibas-gravis/scalismo/llms.txt Implements a Metropolis-Hastings sampling algorithm for shape parameters. It defines a proposal distribution (Gaussian) and a prior (Gaussian prior on coefficients), then sets up and runs the Markov chain to generate samples. The analysis includes calculating the mean of the sampled coefficients. Dependencies include Scalismo, Breeze for linear algebra, and a Random number generator. ```Scala import scalismo.sampling._ import scalismo.sampling.proposals._ import scalismo.sampling.evaluators._ import scalismo.utils.Random // Define a simple state type case class ShapeParameters(coefficients: breeze.linalg.DenseVector[Double]) // Create a proposal generator class GaussianProposal(stddev: Double)(implicit rng: Random) extends ProposalGenerator[ShapeParameters] with SymmetricTransitionRatio[ShapeParameters] { override def propose(current: ShapeParameters): ShapeParameters = { val noise = breeze.linalg.DenseVector.rand(current.coefficients.length, breeze.stats.distributions.Gaussian(0, stddev)) ShapeParameters(current.coefficients + noise) } } // Create a likelihood evaluator class GaussianPriorEvaluator extends DistributionEvaluator[ShapeParameters] { override def logValue(sample: ShapeParameters): Double = { // Standard normal prior on coefficients -0.5 * sample.coefficients.dot(sample.coefficients) } } // Set up Metropolis-Hastings chain implicit val rng = Random(42L) val proposal = new GaussianProposal(0.1) val prior = new GaussianPriorEvaluator() // Create MH proposal generator val mhGenerator = MHProposalGenerator(proposal, prior) // Create Markov chain val chain = new MarkovChain[ShapeParameters] { override def next(current: ShapeParameters): ShapeParameters = { val proposed = proposal.propose(current) val acceptRatio = math.exp(prior.logValue(proposed) - prior.logValue(current)) if (rng.scalaRandom.nextDouble() < acceptRatio) proposed else current } } // Run sampling val initial = ShapeParameters(breeze.linalg.DenseVector.zeros[Double](10)) val samples = chain.iterator(initial).take(1000).toIndexedSeq // Analyze samples val meanCoeffs = samples.map(_.coefficients).reduce(_ + _) / samples.length.toDouble ``` -------------------------------- ### Perform Landmark Registration in Scalismo Source: https://context7.com/unibas-gravis/scalismo/llms.txt Shows how to compute rigid and similarity transformations between sets of corresponding 3D landmarks using SVD-based least squares estimation. The registration results can be applied to points or meshes to align source data with target coordinates. ```scala import scalismo.registration.LandmarkRegistration import scalismo.geometry.{Point, Point3D, Landmark, _3D} import scalismo.transformations.{TranslationAfterRotation, TranslationAfterScalingAfterRotation} val sourceLandmarks = Seq(Landmark[_3D]("p1", Point3D(0.0, 0.0, 0.0)), Landmark[_3D]("p2", Point3D(1.0, 0.0, 0.0)), Landmark[_3D]("p3", Point3D(0.0, 1.0, 0.0)), Landmark[_3D]("p4", Point3D(0.0, 0.0, 1.0))) val targetLandmarks = Seq(Landmark[_3D]("p1", Point3D(10.0, 10.0, 10.0)), Landmark[_3D]("p2", Point3D(11.0, 10.0, 10.0)), Landmark[_3D]("p3", Point3D(10.0, 11.0, 10.0)), Landmark[_3D]("p4", Point3D(10.0, 10.0, 11.0))) val center = Point3D(0.0, 0.0, 0.0) val rigidTransform: TranslationAfterRotation[_3D] = LandmarkRegistration.rigid3DLandmarkRegistration(sourceLandmarks, targetLandmarks, center) val transformedPoint = rigidTransform(Point3D(0.5, 0.5, 0.5)) val similarityTransform: TranslationAfterScalingAfterRotation[_3D] = LandmarkRegistration.similarity3DLandmarkRegistration(sourceLandmarks, targetLandmarks, center) val pointPairs = Seq((Point3D(0.0, 0.0, 0.0), Point3D(10.0, 10.0, 10.0)), (Point3D(1.0, 0.0, 0.0), Point3D(11.0, 10.0, 10.0)), (Point3D(0.0, 1.0, 0.0), Point3D(10.0, 11.0, 10.0))) val rigidFromPairs = LandmarkRegistration.rigid3DLandmarkRegistration(pointPairs, center) ``` -------------------------------- ### Load and Display 3D Landmarks from JSON Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Loads 3D landmarks from a JSON file and displays them using the Scalismo UI. This is useful for preparing landmark data for statistical shape analysis. ```Scala val modelLMs = LandmarkIO.readLandmarksJson[_3D](new File("datasets/modelLandmarks.json")).get ui.show(modelGroup, modelLMs, "model") val noselessLMs = LandmarkIO.readLandmarksJson[_3D](new File("datasets/noselessLandmarks.json")).get ui.show(targetGroup, noselessLMs, "noseless") ``` -------------------------------- ### Read and Write Anatomical Landmarks Source: https://context7.com/unibas-gravis/scalismo/llms.txt Shows how to read landmarks from JSON files and write them back to disk in both JSON and CSV formats. Includes handling of uncertainty information and descriptive metadata. ```scala import scalismo.io.LandmarkIO import scalismo.geometry.{Landmark, Point, Point3D, _3D} import java.io.File import scala.util.Success val landmarksResult = LandmarkIO.readLandmarksJson3D(new File("landmarks.json")) landmarksResult match { case Success(landmarks) => landmarks.foreach { lm => println(s"${lm.id}: ${lm.point}") lm.description.foreach(d => println(s" Description: $d")) lm.uncertainty.foreach(u => println(s" Has uncertainty information")) } case _ => println("Failed to load landmarks") } val landmarks = Seq( Landmark[_3D]("nasion", Point3D(0.0, 50.0, 30.0), Some("Nose bridge")), Landmark[_3D]("left_eye", Point3D(-15.0, 45.0, 25.0), Some("Left eye center")), Landmark[_3D]("right_eye", Point3D(15.0, 45.0, 25.0), Some("Right eye center")), Landmark[_3D]("chin", Point3D(0.0, 0.0, 20.0), Some("Chin point")) ) LandmarkIO.writeLandmarksJson(landmarks, new File("face_landmarks.json")) LandmarkIO.writeLandmarksCsv(landmarks, new File("face_landmarks.csv")) ``` -------------------------------- ### Define Gaussian Process Covariance Kernels Source: https://context7.com/unibas-gravis/scalismo/llms.txt Shows how to define and manipulate covariance kernels for Gaussian processes, including RBF kernels, diagonal kernels for vector fields, and kernel composition. ```scala import scalismo.kernels._ import scalismo.geometry.{Point3D, _3D} val gaussianKernel = GaussianKernel3D(sigma = 50.0, scaleFactor = 10.0) val point1 = Point3D(0.0, 0.0, 0.0) val point2 = Point3D(10.0, 0.0, 0.0) val kernelValue = gaussianKernel(point1, point2) val vectorKernel = DiagonalKernel(gaussianKernel, outputDim = 3) val matrixValue = vectorKernel(point1, point2) val fineKernel = GaussianKernel3D(sigma = 10.0, scaleFactor = 5.0) val coarseKernel = GaussianKernel3D(sigma = 100.0, scaleFactor = 20.0) val multiScaleKernel = fineKernel + coarseKernel val scaledKernel = gaussianKernel * 2.0 val bsplineKernel = BSplineKernel[_3D](order = 3, scale = 2) ``` -------------------------------- ### Create a 3D Translation Space and Transformations in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/transformations.md Initializes a TranslationSpace3D object, which acts as a factory for creating translation transformations. It can generate transformations from parameters or provide the identity transformation. ```Scala import breeze.linalg.DenseVector val translationSpace = TranslationSpace3D val parameters = DenseVector(1.0, 0.0, 3.0) val translationFromParameters = translationSpace.transformationForParameters(parameters) val ident = translationSpace.identityTransformation ``` -------------------------------- ### Update and Display Posterior Model Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Calculates a new posterior model using the generated training data and displays it in the Scalismo UI. This refines the statistical model based on new data. ```Scala val betterPosterior = model.posterior(trainingData2.toIndexedSeq) val betterPosteriorGroup = ui.createGroup("better posterior") ui.show(betterPosteriorGroup, betterPosterior, "betterPosterior") ``` -------------------------------- ### Create Structured Points for Image Grids in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/images.md Defines a grid of points in 3D space, used as the basis for discrete images. It allows specifying the origin, spacing, size, and optional rotation of the grid. ```scala val origin = Point3D(10.0, 15.0, 7.0) val spacing = EuclideanVector3D(0.1, 0.1, 0.1) val size = IntVector3D(32, 64, 92) val points = StructuredPoints3D(origin, spacing, size) ``` ```scala val yaw = Math.PI / 2 val pitch = 0.0 val roll = Math.PI val points2 = StructuredPoints3D(origin, spacing, size, yaw, pitch, roll) ``` -------------------------------- ### Filter Landmarks using Scalismo UI Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Filters landmarks displayed in the Scalismo UI based on a given predicate. This allows for selective visualization and processing of landmark data. ```Scala val modelLandmarks = ui.filter(modelGroup, (lv: LandmarkView) => true) val noselessLandmarks = ui.filter(targetGroup, (lv: LandmarkView) => true) ``` -------------------------------- ### Interpolate and Discretize Images in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/images.md Converts a discrete image to a continuous representation using interpolation (e.g., BSpline) and then back to a discrete image with a potentially different domain and resolution. ```scala val continuousImage : Field[_3D, Short] = image.interpolate(BSplineImageInterpolator3D(degree = 3)) ``` ```scala val newDomain = DiscreteImageDomain3D(image.domain.boundingBox, size=IntVector(32, 32, 32)) val resampledImage : DiscreteImage[_3D, Short] = continuousImage.discretize(newDomain, outsideValue = 0.toShort) ``` -------------------------------- ### Create a Product Transformation Space in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/transformations.md Defines a composite transformation space by combining individual transformation spaces, such as TranslationSpace3D and RotationSpace3D. It can generate a composite transformation from a combined set of parameters. ```Scala import breeze.linalg.DenseVector val compositeSpace = ProductTransformationSpace(TranslationSpace3D, RotationSpace3D(Point3D(0, 0, 0))) val ct : CompositeTransformation[_3D, Translation, Rotation] = compositeSpace.transformationForParameters(DenseVector(0.0 ,0.0 ,0.0, 0.0, 0.0, 0.0)) ``` -------------------------------- ### MeshIO.readMesh API Source: https://context7.com/unibas-gravis/scalismo/llms.txt Reads a 3D triangle mesh from various file formats including VTK, STL, and PLY. The function automatically detects the file format based on the extension and returns a TriangleMesh[_3D] wrapped in a Try for error handling. ```APIDOC ## MeshIO.readMesh ### Description Reads a 3D triangle mesh from various file formats including VTK, STL, and PLY. The function automatically detects the file format based on the extension and returns a `TriangleMesh[_3D]` wrapped in a `Try` for error handling. ### Method GET (conceptual, as it reads from a file) ### Endpoint N/A (File-based operation) ### Parameters #### Path Parameters - **file** (File) - Required - The file object representing the mesh file to read. ### Request Example ```scala import scalismo.io.MeshIO import scalismo.mesh.TriangleMesh import scalismo.geometry._3D import java.io.File import scala.util.{Success, Failure} // Read a mesh from a VTK file val meshFile = new File("face.vtk") val meshResult = MeshIO.readMesh(meshFile) meshResult match { case Success(mesh) => println(s"Loaded mesh with ${mesh.pointSet.numberOfPoints} points") case Failure(ex) => println(s"Failed to load mesh: ${ex.getMessage}") } ``` ### Response #### Success Response (200) - **TriangleMesh[_3D]** - The loaded 3D triangle mesh. - **Try[TriangleMesh[_3D]]** - A Try monad wrapping the mesh, allowing for error handling. #### Response Example ```scala // Example of a successful result Success(mesh: TriangleMesh[_3D]) // Example of a failure Failure(new Exception("File not found")) ``` ``` -------------------------------- ### Read 3D Scalar Image with Scalismo Source: https://context7.com/unibas-gravis/scalismo/llms.txt Reads 3D scalar images from NIfTI or VTK files. It supports generic voxel types and handles coordinate system transformations internally. ```scala import scalismo.io.ImageIO import scalismo.image.DiscreteImage import scalismo.geometry._3D import java.io.File import scala.util.{Success, Failure} val imageFile = new File("ct_scan.nii") val imageResult = ImageIO.read3DScalarImage[Short](imageFile) imageResult match { case Success(image) => println(s"Image dimensions: ${image.domain.pointSet.size}") println(s"Spacing: ${image.domain.pointSet.spacing}") println(s"Origin: ${image.domain.pointSet.origin}") val centerVoxel = image.domain.pointSet.size.map(_ / 2) val value = image(scalismo.geometry.IntVector(centerVoxel(0), centerVoxel(1), centerVoxel(2))) println(s"Center voxel value: $value") case Failure(ex) => println(s"Failed to load image: ${ex.getMessage}") } val floatImage = ImageIO.read3DScalarImageAsType[Float](imageFile) ``` -------------------------------- ### Augment Statistical Model with Low-Rank GP Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Augments a statistical mesh model with a low-rank Gaussian process approximation. This enhances the model's ability to capture variations by using a sampler and approximating the GP. ```Scala val sampler = UniformMeshSampler3D(littleModel.referenceMesh, 500) val lowRankGP = LowRankGaussianProcess.approximateGP(gp, sampler, 50) val model = StatisticalMeshModel.augmentModel(littleModel, lowRankGP) ``` -------------------------------- ### Define Custom X-Mirrored Kernel Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Creates a custom kernel that mirrors the input kernel across the X-axis. This is used in constructing symmetric kernels for shape models. ```Scala case class XmirroredKernel(ker: PDKernel[_3D]) extends PDKernel[_3D] { override def k(x: Point[_3D], y: Point[_3D]): Double = ker(Point(x(0) * -1f ,x(1), x(2)), y) } ``` -------------------------------- ### ImageIO.read3DScalarImage API Source: https://context7.com/unibas-gravis/scalismo/llms.txt Reads a 3D scalar image from VTK or NIfTI file formats. Supports various voxel types including Byte, Short, Int, Float, and Double. For NIfTI files, the library handles coordinate system transformations between RAS and LPS automatically. ```APIDOC ## ImageIO.read3DScalarImage ### Description Reads a 3D scalar image from VTK or NIfTI file formats. Supports various voxel types including Byte, Short, Int, Float, and Double. For NIfTI files, the library handles coordinate system transformations between RAS and LPS automatically. ### Method GET (conceptual, as it reads from a file) ### Endpoint N/A (File-based operation) ### Parameters #### Path Parameters - **file** (File) - Required - The file object representing the image file to read. - **Implicit Type Parameter** (VoxelType) - Required - The type of the scalar values in the image (e.g., `Short`, `Float`). ### Request Example ```scala import scalismo.io.ImageIO import scalismo.image.DiscreteImage import scalismo.geometry._3D import java.io.File import scala.util.{Success, Failure} // Read a 3D image with Short voxel type val imageFile = new File("ct_scan.nii") val imageResult = ImageIO.read3DScalarImage[Short](imageFile) imageResult match { case Success(image) => println(s"Image dimensions: ${image.domain.pointSet.size}") // Access voxel values val centerVoxel = image.domain.pointSet.size.map(_ / 2) val value = image(scalismo.geometry.IntVector(centerVoxel(0), centerVoxel(1), centerVoxel(2))) println(s"Center voxel value: $value") case Failure(ex) => println(s"Failed to load image: ${ex.getMessage}") } // Read with automatic type conversion to Float val floatImage = ImageIO.read3DScalarImageAsType[Float](imageFile) ``` ### Response #### Success Response (200) - **DiscreteImage[_3D, VoxelType]** - The loaded 3D scalar image. - **Try[DiscreteImage[_3D, VoxelType]]** - A Try monad wrapping the image, allowing for error handling. #### Response Example ```scala // Example of a successful result Success(image: DiscreteImage[_3D, Short]) // Example of a failure Failure(new Exception("Invalid file format")) ``` ``` -------------------------------- ### Define a 3D Transformation from a Function in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/transformations.md Creates a 3D transformation by providing a function that maps a 3D point to another 3D point and optionally specifying its domain. If the domain is not specified, it defaults to the entire Euclidean space. ```Scala import scalismo.common._ import scalismo.geometry._ import scalismo.transformations._ val domain : Domain[_3D] = EuclideanSpace[_3D] Transformation3D(domain, p => p + EuclideanVector3D(1, 0, 0)) ``` -------------------------------- ### Compute Posterior Model Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Approximates a Gaussian Process, augments a statistical model, and computes the posterior based on landmark correspondences between the model and the target mesh. ```scala val sampler = UniformMeshSampler3D(littleModel.referenceMesh, 500) val lowRankGP = LowRankGaussianProcess.approximateGP(gp, sampler, 50) val model = StatisticalMeshModel.augmentModel(littleModel, lowRankGP) val trainingData = (modelPts zip noselessPts).map{ case (mPt, nPt) => (model.mean.pointSet.findClosestPoint(mPt).id, nPt, littleNoise) } val posterior = model.posterior(trainingData.toIndexedSeq) ``` -------------------------------- ### Create a 3D Rotation Parametric Transformation in Scala Source: https://github.com/unibas-gravis/scalismo/blob/main/docs/transformations.md Defines a 3D rotation transformation by specifying Euler angles and a rotation center. This demonstrates another type of parametric transformation. ```Scala val rotation = Rotation3D(0, 0.1, 0.3, Point3D(0, 0, 0)) ``` -------------------------------- ### Marginalize Posterior Model Source: https://github.com/unibas-gravis/scalismo/wiki/revisions.html Filters points based on distance to a reference point and creates a marginal model from the posterior. ```scala val nosePtIDs = model.referenceMesh.pointSet.pointIds.filter { id => (model.referenceMesh.pointSet.point(id) - model.referenceMesh.pointSet.point(PointId(8152))).norm <= 42 } val posteriorNoseModel = betterPosterior.marginal(nosePtIDs.toIndexedSeq) ```