You are on page 1of 10

01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

Antigoni Kaliontzopoulou, Dean Adams & Michael Collyer


30 March, 2019

This tutorial summarizes the basic steps of digitizing 2D GM data using the R-package StereoMorph, and then
importing them to geomorph. As StereoMorph uses Shiny to allow the user to digitize, it is interactive, so you
need to run the code to gain hands-on experience on the details of how digitizing proceeds.

You will need to install and load StereoMorph first.

install.packages("StereoMorph")

library(StereoMorph)
library(geomorph)

## Loading required package: RRPP

## Loading required package: rgl

First, let´s see how one can digitize fixed landmarks. These correspond to well-defined anatomical points on
your structure of interest. You will need a folder with the pictures you will digitize (Images, in our example) In this
script, digitized data are stored in another folder, called Shapes To digitize, e.g., five fixed landmarks, run:

digitizeImages(image.file='Images', shapes.file='Shapes',
landmarks.ref=paste("LM", c(1:5), sep=""))

To digitize for the first time:

Go to Landmarks tab to see list of landmarks


The first lm is in bold
In the image window, double-click on the desired anatomical location to digitize
The point is now selected, and can be edited, moved etc. (is highlighted in green)
Select the next lm name and repeat
Navigate between landmarks with “n” (next) and “p” (previous)
Select lm and press “d” to delete
Save before moving to the next picture (or select the automatic save option)

NOTE: one has the ability to copy all landmarks to each image, and then move them to the desired

1 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

locations. This can be useful so that landmarks remain in the correct order.

Important detail! Any specimen with missing data (e.g., a broken specimen) may still be digitized. In this case,
simply leave the missing landmarks BLANK. They will be treated as NA and can be estimated in subsequent
data-processing steps.

To scale landmark coordinates during superimposition and obtain accurate estimates of the relative size of the
studied objects, you need to define the scaling of the images used, i.e. to indicate the correspondence of picture
pixels with a “true” size measurement. For this:

Go to the scaling tab


Select the ruler points by double clicking (one can use >1 scaling intervals, and then an average is
calculated)
Introduce your reference interval and units
Save

The easiest way to obtain sliding semilandmarks to describe the shape of curves, is by first digitizing a curve in
StereoMorph and then sampling the desired number of points from it. Curves are digitized in StereoMorph using
a Bezier approximation. For this you need to:

1. Specify curve names and start/end landmarks (see example_curve.txt) NOTE: do not use spaces or
strings used to name landmarks when naming the curves
2. Re-open the digitizer to record the curves

digitizeImages(image.file='Images', shapes.file='Shapes',
landmarks.ref=paste("LM", c(1:5), sep=""),
curves.ref = "example.curves.txt")

You can then:

Add points to the curve by selecting an empty line (with “-”) and double clicking on the image
After the first point, you need to add control points two at a time, to keep the curve continuous
Navigate across points with “n” and “p” and move them to adjust the curve

Once the curve is digitized, you can subsample a desired number of semilandmarks from it. This is
accomplished easiest with the function, readland.shapes. This is a geomorph function that reads in data from a
class shapes object. (In geomorph, there are several readland.___ functions for different landmark file types.)
Before using readland.shapes , a shapes object must be created (a Stereomorph function).

shapes <- readShapes("Shapes")


shapesGM <- readland.shapes(shapes, nCurvePts = 10) # can change 10 to a different num
ber

# Perform GPA
Y.gpa <- gpagen(shapesGM, print.progress = FALSE)
plot(Y.gpa)

2 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

When one has completed a serious digitizing effort, the readland.shapes function offers extreme flexibility for
choosing the sets of landmarks to use as a definition of “shape”. It must be stated that for those of us who
have spent some years in GMM, this is profoundly amazing! Not too long ago, one must have had an a
priori definition of a landmark configuration and digitize every specimen according to a preformed plan. Now,
one can experiment and find an optimal landmark configuration, post-digitizing.

Too demonstrate this, let’s use a digitizing set with 11 landmarks and 9 curves. First we need to define how
many landmarks should be in each curve.

shapes <- readShapes("example.digitized")

# curves include eye, head, tail 1, tail end, tail 2, anal fin,
# pectoral fin, opercle, pre-opercle
curves.list <- c(20, 24, 24, 16, 12, 8, 8, 24, 16)

Then use readland.shapes to read the data into a useable format for geomorph.

shapesGM <- readland.shapes(shapes, nCurvePts = curves.list)

Every curve needs to have at least three landmarks (or it is not a curve). Other than that, one can vary the
number for every curve. The set chosen is hypothetical. Let’s see what it looks like following generalized
Procrustes Analysis (GPA).

3 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

Y.gpa <- gpagen(shapesGM, print.progress = FALSE)


plot(Y.gpa)

The density of semilandmarks might be a little too great. We can reduce it by 50%, for example, in one line of
code:

shapesGM <- readland.shapes(shapes, nCurvePts = 0.5 * curves.list)


Y.gpa <- gpagen(shapesGM, print.progress = FALSE)
plot(Y.gpa)

4 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

Later it might impress you that no arguments for gpagen are needed when reading data in with
readland.shapes . Class geomorphShapes objects also have various attributes that can be exported for other
uses.

class(shapesGM)

## [1] "geomorphShapes"

attributes(shapesGM)

## $names
## [1] "landmarks" "fixed" "sliders" "curves" "n" "p"
## [7] "k" "scaled"
##
## $class
## [1] "geomorphShapes"

shapesGM$fixed # which landmakrs are fixed

## [1] 1 2 3 4 5 6 7 8 9 10 11 12

5 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

shapesGM$curves # a curves matrix for gpagen - can be modified

6 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

## [,1] [,2] [,3]


## curveLM.13 12 13 14
## curveLM.14 13 14 15
## curveLM.15 14 15 16
## curveLM.16 15 16 17
## curveLM.17 16 17 18
## curveLM.18 17 18 19
## curveLM.19 18 19 20
## curveLM.20 19 20 12
## curveLM.21 1 21 22
## curveLM.22 21 22 23
## curveLM.23 22 23 24
## curveLM.24 23 24 25
## curveLM.25 24 25 26
## curveLM.26 25 26 27
## curveLM.27 26 27 28
## curveLM.28 27 28 29
## curveLM.29 28 29 30
## curveLM.30 29 30 2
## curveLM.31 2 31 32
## curveLM.32 31 32 33
## curveLM.33 32 33 34
## curveLM.34 33 34 35
## curveLM.35 34 35 36
## curveLM.36 35 36 37
## curveLM.37 36 37 38
## curveLM.38 37 38 39
## curveLM.39 38 39 40
## curveLM.40 39 40 3
## curveLM.41 3 41 42
## curveLM.42 41 42 43
## curveLM.43 42 43 44
## curveLM.44 43 44 45
## curveLM.45 44 45 46
## curveLM.46 45 46 4
## curveLM.47 4 47 48
## curveLM.48 47 48 49
## curveLM.49 48 49 50
## curveLM.50 49 50 5
## curveLM.51 5 51 52
## curveLM.52 51 52 6
## curveLM.53 7 53 54
## curveLM.54 53 54 8
## curveLM.55 9 55 56
## curveLM.56 55 56 57
## curveLM.57 56 57 58
## curveLM.58 57 58 59
## curveLM.59 58 59 60
## curveLM.60 59 60 61
## curveLM.61 60 61 62

7 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

## curveLM.62 61 62 63
## curveLM.63 62 63 64
## curveLM.64 63 64 10
## curveLM.65 11 65 66
## curveLM.66 65 66 67
## curveLM.67 66 67 68
## curveLM.68 67 68 69
## curveLM.69 68 69 70
## curveLM.70 69 70 10

shapesGM$landmarks[[1]] # specimen 1

8 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

## [,1] [,2]
## LM1 59.10605 -41.32745
## LM2 74.27244 -37.38964
## LM3 87.95729 -38.09143
## LM4 88.15223 -41.52239
## LM5 81.21233 -42.26316
## LM6 77.97632 -44.09561
## LM7 66.82570 -42.73102
## LM8 67.29356 -44.29055
## LM9 66.16291 -40.78161
## LM10 63.74564 -44.56347
## LM11 64.01856 -40.70364
## LM12 62.80992 -39.37804
## curveLM.13 63.35576 -40.20925
## curveLM.14 63.23879 -41.18580
## curveLM.15 62.56849 -41.91977
## curveLM.16 61.58884 -42.10721
## curveLM.17 60.79722 -41.57606
## curveLM.18 60.50962 -40.63789
## curveLM.19 60.90162 -39.76580
## curveLM.20 61.76877 -39.41703
## curveLM.21 60.09664 -40.23578
## curveLM.22 61.23111 -39.43632
## curveLM.23 62.59470 -38.96945
## curveLM.24 64.00739 -38.67625
## curveLM.25 65.44277 -38.38270
## curveLM.26 66.87240 -38.13042
## curveLM.27 68.38092 -38.01345
## curveLM.28 69.85046 -37.93548
## curveLM.29 71.32668 -37.74054
## curveLM.30 72.78007 -37.54560
## curveLM.31 75.48816 -37.55269
## curveLM.32 76.68105 -37.77086
## curveLM.33 77.89008 -38.00519
## curveLM.34 79.15621 -38.10168
## curveLM.35 80.41810 -38.20840
## curveLM.36 81.69189 -38.28637
## curveLM.37 82.98184 -38.24738
## curveLM.38 84.20719 -38.44232
## curveLM.39 85.39355 -38.20840
## curveLM.40 86.65119 -38.09143
## curveLM.41 88.78695 -38.10234
## curveLM.42 89.43884 -38.53892
## curveLM.43 89.63378 -39.32465
## curveLM.44 89.78973 -40.12653
## curveLM.45 89.59479 -40.91226
## curveLM.46 88.93127 -41.36644
## curveLM.47 86.70989 -41.56138
## curveLM.48 85.26756 -41.60037
## curveLM.49 83.89652 -41.75632

9 de 10 14-06-2019 8:41
01.1: Digitizing Landmarks in StereoMorph https://deanadams.github.io/2019-Chile/Labs/01.1-Digitizing-StereoMor...

## curveLM.50 82.52547 -41.91227


## curveLM.51 80.08798 -42.76370
## curveLM.52 79.00116 -43.35483
## curveLM.53 67.11477 -43.17604
## curveLM.54 67.33255 -43.69627
## curveLM.55 66.16291 -41.28582
## curveLM.56 66.16291 -41.79002
## curveLM.57 66.08580 -42.26229
## curveLM.58 66.00695 -42.73384
## curveLM.59 65.85100 -43.15060
## curveLM.60 65.63888 -43.56695
## curveLM.61 65.39263 -43.96915
## curveLM.62 65.06841 -44.29338
## curveLM.63 64.68945 -44.48549
## curveLM.64 64.23370 -44.60245
## curveLM.65 64.01856 -41.28233
## curveLM.66 64.01856 -41.86102
## curveLM.67 63.97957 -42.42357
## curveLM.68 63.94058 -42.98611
## curveLM.69 63.90159 -43.52582
## curveLM.70 63.86260 -44.08836

names(shapesGM$landmarks) # all specimen names

## [1] "P1000602" "P1000603" "P1000604" "P1000605" "P1000606" "P1000615"


## [7] "P1000616" "P1000617" "P1000618" "P1000619" "P1000647" "P1000648"
## [13] "P1000649" "P1000650" "P1000651" "P1000657" "P1000658" "P1000659"
## [19] "P1000660" "P1000661" "P1000670" "P1000671" "P1000672" "P1000673"
## [25] "P1000674" "P1000684" "P1000685" "P1000686" "P1000687" "P1000688"
## [31] "P1000696" "P1000697" "P1000698" "P1000699" "P1000700" "P1000708"
## [37] "P1000709" "P1000710" "P1000711" "P1000712" "P1000719" "P1000720"
## [43] "P1000721" "P1000722" "P1000723" "P1000731" "P1000732" "P1000733"
## [49] "P1000734" "P1000735" "P1000743" "P1000744" "P1000745" "P1000746"
## [55] "P1000747" "P1000755" "P1000756" "P1000757" "P1000758" "P1000759"

10 de 10 14-06-2019 8:41

You might also like