Ghazi Bouabene

Ghazi Bouabene

I am a scientific collaborator at the mathematics and computer science department of the University of Basel and one of the developers of Scalismo: https://github.com/unibas-gravis/scalismo

Location Basel, Switzerland

Activity

  • @BehzadV Hi Behzad,

    The first one is creating a Discrete Gaussian Process from a set of discrete deformation fields, all defined over the same discrete domain. The other two perform a low rank approximation of an analytically defined GP. The difference between the two is simply in the approximation method, the first uses the Nystrom approximation while the...

  • Hi Behzad,
    getLandmarksOf() is intended to retrieve landmarks from the 3D scene. This allows you to click landmarks on a displayed mesh and retrieve them programmatically in the running ScalismoLab Instance. LandmarkIO, on the other hand, allows to load already defined landmarks.

    getLandmarksOf() is a method specific to Scalismo Lab. There is no other...

  • @BehzadV Hi Behzad, there is no predefined function in Scalismo to do this since the desired properties of the design GP change a lot from one shape family to another. The idea here is to define a kernel combination and compute a Low rank Gaussian process model as we did in step 4.6. Typically, for the femur project, one would use a combination of Gaussian...

  • @BehzadV in that case, we *design* a prior using the kernels presented in week 4 which allows us to fit a reference mesh to each aligned mesh. Assuming that the fits based on the designed prior are close enough, we would now have a series of meshes in correspondence (the reference warped to match each aligned mesh).

  • @AdrianSzatmari Hi Adrian,
    Regarding intelliJ not finding the SDK, that is strange. Usually one indicates the directory where it was installed which is sufficient for the project to run. Not sure whether your case is common enough to change the IDE tutorial.

    Regarding the tutorials and the IDE: if you copy the code snippets inside the main function (i.e...

  • Hi Mafalda,

    We can break it into smaller steps:

    val listOfPairs = modelPts zip noselessPts

    Here, we have zipped two collections together. listOfPairs will then be a list of Tuples of points. Let's look at its first elements as an example:

    val firstPair = listOfPairs.head
    //firstPair: (scalismo.geometry.Point[scalismo.geometry._3D],...

  • @AdrianSzatmari Hi Adrian,

    Are you in an IDE or are you using Scalismo **Lab**?
    (If you are in and IDE, the default mode should be one where the code is compiled.)

    Also, could you give us an idea why you found that Oracle jdk was required on your Ubuntu?

  • Hi Behzad,

    Yes there is. Once the fitting done you can use the methods in the MeshMetrics object (http://unibas-gravis.github.io/scalismo/0.10/api/index.html#scalismo.mesh.MeshMetrics$ ) to evaluate the mesh to mesh distance between the target and the model instance resulting as a fit.

    The average mesh distance and the Hausdorff distance are the usual...

  • Hi Behzad,

    Here, the ICP method finds candidate (i.e. potential) correspondences and uses them to perform rigid alignment. The hope is that these candidate correspondences will tend to get better and better the more we iterate (and rigidly align the shapes).

    After rigid alignment, one possible method to obtain correspondences for all of the points is to...

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise12.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise12.html")

  • Hi Clemens,

    Yes, that is exactly how I retrieved the point Id of the nose tip:

    val mesh : TriangleMesh = MeshIO.readMesh(new File("datasets/Paola.stl")).get

    show(mesh, "Paola")

    // now, in the GUI click a landmark on the nose tip, then:

    val landmarks = getLandmarksOf("Paola").get

    val noseTipPoint : Point[_3D] = landmarks.head.point

    val...

  • Hi Mikhail,

    Thank you for the nice feedback. Yes, starting with a new library is usually time consuming, let alone in a new language. We really try to make this introduction easy by providing ready-to-execute code and incremental tutorials. In fact the coding project was also thought such that one can stitch together previously seen parts of the code in...

  • Hi Chris,

    Thanks for the nice feedback.

    The summer school will be on a similar note to the online course, that is, a combination of theory and hands-on tutorials and project. Only this time, the tutors will be right there to help with any programming issues :).

    Regarding the project, the application scope will open up a bit to fitting models to images...

  • Hi Chris,

    It is true that the ICP method is very prone to local minima, independently whether the target is complete or not. That is why one should not rely on a single model fitting method but rather have a tool set to adapt to different cases.

    Other examples of model fitting methods include parametric registration (...

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise11.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise11.html")

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise10.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise10.html")

  • Hi Alan,
    The fact that the meshes have a different number of vertices means that they are not in correspondence. This in turn means that you cannot yet build a PCA model, as you deduced. At the stage where you are, you should now use the Gaussian Process model you computed in step 4.11 and fit it to each of the aligned femurs, using the method introduced in...

  • Hi Adrian,

    Yes, in the statistical mesh model, we are modelling the variations of all the vertices of the reference mesh. For any of pointID of the mesh, you can for example compute a marginal e.g. model.gp.marginal(PointId(0)) which would return a distribution of the deformations observed at that point.

  • Hi Adrian,
    Good question :). We did prepare a tutorial for this here

    https://unibas-gravis.github.io/scalismo-tutorial/ide.html

    This uses IntelliJ idea and the latest version of Scalismo. Once setup with the new environment, you can have a look at the updated tutorials (similar structures to those of Scalismo Lab) that should ease the transition to...

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise9.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise9.html")

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise8.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise8.html")

  • Hi Senerath,
    After downloading and unzipping the scalismoLab zip file, you should have a "datasets" directory into the unzipped directory.

  • Hi Miriam,
    Yes there is. You can sort the files by name on load as such:
    val files = new File("datasets/step2/meshes/").listFiles.sortBy(f => f.getName()).take(5)

  • Hi Natalia,

    Good question. One explanation could be that the order of the files resulting from:
    val files = new File("datasets/nonAlignedFaces/").listFiles
    is different, depending on the machine. Since we take the head of the list as a reference for the alignment, the meshes end up being aligned to a different reference if the order is different....

  • Hi Chris,

    Did you perform a low rank approximation of the GP before sampling?

    If not, please check the section entitled "Sampling on high resolution meshes" in the tutorial of step 4.6: https://www.futurelearn.com/courses/statistical-shape-modelling/4/steps/412751

  • Hi B (or is it V? :)),
    If the interpreter printed out the value of the variable "alignedSet", it means that the execution has successfully finished. So you should be able to proceed with the rest of the tutorial. This said, the execution should not have taken 15 min (more like 1 min). Could you please recheck whether the printout really takes that long (might...

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise7.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise7.html")

  • Hi B,
    "Interpolating a GP" is perhaps a language abuse in our API to describe exactly what you understood. If you look at the instance method of an "interpolated" GP (https://github.com/unibas-gravis/scalismo/blob/master/src/main/scala/scalismo/statisticalmodel/DiscreteLowRankGaussianProcess.scala#L314) you can see that we do exactly what you described above....

  • Hi Zhuye,

    Was the email address you used a temporary email address (random alphanumeric characters)? In that case, we have a tendency to reject the requests. Ideally, you should use an institutional email address, or an address that relates to your name. If however the email address you used is indeed your address, please resubmit your request and we will...

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise6.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise6.html")

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise5.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise5.html")

  • Hi Chris,
    You are right. Even though in the code you can now sample a deformation at any point in space, in practice, this does only make sense if you stay in the neighborhood of the original discrete domain. Otherwise, the sampled deformation fields will tend to be too rough and differ from the properties of the original discrete GP.

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise4.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise4.html")

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise3.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise3.html")

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise2.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise2.html")

  • Dear all,

    Thank you for reporting your measurement. All the reported measurements till Feb 22nd have been added to the previous years values. These are summarized in this spreadsheet: https://goo.gl/ZcbOF9 along with the parameters of the estimated normal distribution. We will be updating the spreadsheet with newly reported values in the coming days.

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise1.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise1.html")

  • Hi Alan,
    The resulting message of that execution is correct. What is the issue you are experiencing?

  • Hi Mafalda,

    Have you checked the sections "Iterating on collections" and "Reducing collections" in the Scala cheat sheet (Documents -> Full track -> Scala Cheat sheet) ?

    Please note that this exercise is only meant to familiarize you with the Scala notation that we might use during the tutorials. So do not let this discourage nor block you. We will also...

  • Hi Hassan, in this particular case, the MRI and the mesh data were already aligned. So, in this tutorial, we just read the data and displayed it. We will see next week how to perform such an alignment between 2 triangle meshes, which can also be applied for aligning a triangle mesh to an MRI.

  • Great, thanks for the feedback. The current version available for download now includes this fix.

  • HI Asim,

    Thank you for pointing this out.

    Try replacing
    %JAVA_HOME%\bin\java -jar -Xmx3g dist\scalismoLab.jar
    with
    "%JAVA_HOME%\bin\java" -jar -Xmx3g dist\scalismoLab.jar

    (i.e adding the quotes) in the .bat file and let me know if that helped.

    I will also upload a version with this fix shortly.

  • Hi Chad,

    Hair is a precious resource, please don't pull it out :)

    If you look at the formula of the covariance matrix, you will notice that it is a sum of m outer products.

    The rank of a matrix resulting from an outer product is always one, as each row of the matrix is simply a different scaling of the first row. Hence the covariance matrix is a sum...

  • @SteveLewis Hi Steve, I do not really get your question. For the case of the femur, the way we "tailor" the kernels and their parameters is by having some prior assumption on how much a femur can possibly deform. Based on this we can come up with a free-form deformation model (that is often too flexible) that we use to bring our shapes into correspondence....

  • Hi Vic,
    What do you get then? Do you ave an error message?

  • Hi Luke,

    This is a very important discussion for the future of Scalismo and should be perhaps continued on Scalismo's mailing list or as an issue on the Github repo afterwards. We are well aware that the choice of Scala as a language for the library can be inconvenient to teams that already invested in more mainstream languages such as Python, Java, C# or...

  • Hi Steve,

    To generate the Gaussian Process needed for registering all other shapes you need to follow the methods introduced in step 4.6. The idea there is to design a kernel that is a mixture of Gaussian kernels with parameters adapted to the flexibility of femur shapes.

    Once you have all meshes registered you can build a PCA model. This model is not...

  • Nice!

  • Hi Qida,

    After checking with the SMIR guys, it seems that you are not naming your files according to the indicated convention.

    For the 2 URLs you sent me, these were file names
    329078: QidaZhang.case_1.101147.stl
    329087: QidaZhang.case_10.101156.stl

    Please replace QidaZhang in the file name with VSD, as indicated in the upload instructions....

  • Hi Qida,

    As mentioned I forwarded your problem to the SMIR maintainers and would first wait for their response. If the problem however persists longer, then yes, as a plan B you could send me your data and I could run the evaluation script locally.

  • @QidaZhang

    Hi Qida,
    As we are not the developers nor the maintainers of the SMIR repository, I can only forward your problem to the SMIR guys. Could you give me one of the URLs you obtained after uploading the file? Yesterday we had a similar situation with a couple of students here and changing the browser seemed to do it.

  • Hi Luke,

    Unfortunately in the Scalismo UI version we used when filming the course, that is also the one used in scalismo lab, this was not possible. In the newer versions of Scalismo UI these operations are possible as can be seen in the following quickstart : https://github.com/unibas-gravis/scalismo-ui/blob/master/doc/quickstart.md

  • Hi Qida,

    Did the upload succeed (did it display a URL https://www.smir.ch/Objects/xxxx) ?
    If so, did you follow the file naming convention?

  • Hi Steve,
    As Marcel [mentioned already](https://www.futurelearn.com/courses/statistical-shape-modelling/3/comments/26887744), the solution to the project will be made available earliest after end of April as we use the course as a term project here at the University of Basel. In the meantime, have you given it a try? Any questions we can help you with?

  • Hi Qida,

    The head of the femur disappears since for every point on the femur head of the reference, we are tying to find a candidate correspondence on the incomplete target which is not there. Therefore, all the points of the femur head will collapse into the closest points on the target shape that they can find. To avoid this situation, you can change the...

  • In Scalismo you can clip a mesh based on any predicate of your definition
    http://unibas-gravis.github.io/scalismo/0.10/api/index.html#scalismo.mesh.Mesh$
    Any points where your predicate would return true would then be removed from the resulting mesh.

    You can for example use this to define "space regions" where all points lying in the region would be...

  • Hi Qida,

    Clicking landmarks for 200 points is of course not an option. The 200 correspondence points were actually obtained using a mesh to mesh registration method, similar to the non-rigid ICP method that we introduce in step 6.6. The example of the 200 points was just meant to exactly trigger this type of question you're having :)

    Regarding the femur...

  • Hi Luke,

    1) That should be the right call. Can you post the error you are getting? (it could be that you need to call it with aligned_landmark_seq.toIndexedSeq)

    2) These should be an optional description and an optional uncertainty value. In general, you can find the names of function arguments using the API...

  • You need to define that yourself, depending on your region of interest. In the case of the nose, I simply clicked a point on the reference's nose tip and kept all points of the mesh within a particular radius. For other regions more complicated mesh clipping (or labeling) might be needed.

  • rigid ICP: step 6.5
    non-rigid ICP: step 6.6

    The difference between the two is the operation performed once the candidate correspondences are found:

    rigid ICP: Procrustes analysis
    non-rigid ICP: Gaussian process regression

  • continuation of previous message ..

    6. Use the PCA model in one of the following applications (only an example subset): sampling, population analysis, image segmentation, shape completion ..

    + For the example of the shape completion, we can for example fit the PCA model to the observed parts of the shape (using for example non-rigid ICP). Given that...

  • continuation of previous message ..

    4. For each of the shapes in our dataset, we now fit the free-form deformation model to it using the *non-rigid* ICP method. The result is a deformed reference shape that ideally should resemble as much as possible our target shape. Since this result is simply a deformation of the reference, it is obviously in...

  • Hi Steve,

    Given a dataset of shapes our usual work-flow to build a statistical shape model is as follows:

    1. Pick one shape out of the dataset to be the reference shape

    2. Click corresponding landmarks on all of the shapes as well as on the reference, and align all shapes to the reference using the Procrustes method. At this stage, the shape are only...

  • Not sure if I understood the question. The region to marginalize on depends on the application. In our case, since we wanted to reconstruct the nose, we marginalized over the nose region. In some other application the region might be different or one might even not need to marginalize.

  • Hi Luke,

    In Scala, the expression

    val identity = SquareMatrix.eye[_3D]
    3.0 * identity

    is in fact a function call to the "*" function of the Double class:
    3.0.*(identity)

    This would require that the method below is implemented in the default Double class:
    *(mat: SquareMatrix[_3D]) {..}

    Given that SquareMatrix is a class defined in the...

  • Hi Luke,

    It should be indeed the case that the left and right eye are strongly correlated. In fact, the deformation vectors should be in most cases more or less mirrored around the sagittal plane.

    As the example model is a light-weight one learned from 10 examples, perhaps you need to sample a few more deformations for get this feeling.

  • @QidaZhang Dear Qida,

    The easiest way to think about this, is the example of applying a function to a collection that we have in the scala cheat sheet:

    val coll1 = IndexedSeq(0,1,2,3)
    def increment(x : Int) = { x + 1 }
    val newColl = coll1.map{ case x => increment(x) }

    By mapping the increment function on coll1, we obtain a new...

  • Hi Qida,

    Once you read the landmarks from file as you do in line 6 of your code (val datasetL = ..), you already have the landmarks .. meaning, there is no need to add them to the scene and retrieve them again using the getLandmarksOf() method .. you can directly use the set of landmarks in datasetL for the rigid alignment.

    An easy way to loop on both...

  • Hi Luke,

    Thanks for the positive feedback :)

    1) Yes there is a basic auto-completion in Scalismo Lab. You can access it using the Ctrl+Space

    However, since Scalismo Lab is meant as an educational tool, this functionality does not really compare to that available in a proper IDE (please check the Documents -> Readme for a bit more details). For bigger...

  • Hi Martin,
    In general, it is not such a good idea to combine both shape and pose optimizations at the same time, as quite often you would have some pose differences between the two shapes being compensated for by a too strong (unnatural) shape deformation. The best practice in my opinion is to alternate between the two: first optimize on the pose only until...

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise10.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise10.html")

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise11.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise11.html")

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise10.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise10.html")

  • Hi Qida,

    Yes, this is a common pitfall of aligning long bones with the rigid ICP algorithm. This inverted position is local minimum out of which the ICP algorithm does not come out. The best option for rigid alignment is usually clicking corresponding landmarks and using the Procrustes alignment, like we did in week 2. For the project's femur data, the...

  • Hi Stefan,

    The problem is that getLandmarksOf returns a scala.collection.Seq of Landmarks, while the write function expects a scala.collection.immutable.Seq of Landmarks.

    Try:
    LandmarkIO.writeLandmarksJson(getLandmarksOf("alignedFemur_1").get.toIndexedSeq, new File("smir/step2/landmarks_aligned/1.json"))

  • Hi Clinton,
    That is normal: 32 bits systems are not supported by Scalismo.

  • Hi Michael,
    That is exactly the reason why we augmented the model with the Gaussian kernel: to increase the range of shapes it can represent. You can easily try to use the littleModel instead (simply overwrite the model variable in scalismoLab: val model = littleModel) and compare the results you get.

  • Dear all,

    It seems that a technical problem on the SMIR repository has caused some of the requests to access the data to fail.

    In case you have submitted a request to access the project data and have not yet received your credentials, please report the issue in this comment section or by sending an email to ghazi.bouabene@unibas.ch

    In the meantime,...

  • Dear all,

    It seems that a technical problem on the SMIR repository has caused some of the requests to access the data to fail.

    In case you have submitted a request to access the project data and have not yet received your credentials, please report the issue in this comment section or by sending an email to ghazi.bouabene@unibas.ch

    In the meantime,...

  • Hi Martin,

    Please make sure to allocate enough heap memory by changing the -Xmx value in scalismoLab's launch script to a greater value that your system can afford.

    Also, saving the aligned meshes and aligned landmarks to file will be helpful for the further steps of the project as it will avoid you to compute the alignment each time.

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise9.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise9.html")

  • The solution for the exercises in the full track version can be found here:
    http://shapemodelling.cs.unibas.ch/solutions/Exercise8.html

    To access this solution document directly from within Scalismo Lab, execute the following line in the Scalismo Lab code pane window:

    goto("http://shapemodelling.cs.unibas.ch/solutions/Exercise8.html")

  • Hi Martin,
    The 300 points are used to approximate the basis functions of the low-rank decomposition.
    These basis functions are in turn evaluated on all the points of the domain (the mesh) when sampling a deformation.