Basic tutorial - QSM direct method

This tutorial goes over the example code main_qsm_direct.m provided along the GitHub repository, and demonstrates the very basic usage of the QSM direct method.

Initialization

The code starts by clearing the workspace (were the variables are stored), closing all open figures, and adding the paths to subdirectories required in this demo.

% Clear all variables from the workspace and close all open figures
clear, close all

% Add the current directory and all the subdirectories to search path
addpath(genpath(pwd))

Defining the QSM

The QSM used as a basis for leaf generation in this tutorial is the example QSM provided with the code repository of LeafGen. This is found in the example-data directory.

filename = "example-data/ExampleQSM.mat";
QSM = importdata(filename);

The example QSM is of the format given by TreeQSM, but the input QSM could also be a struct containing information of the QSM cylinders (see QSM direct method)

Defining leaf base geometry

The leaf base geometry is defined by setting the vertice points of the geometry and indicating the triangles with respect to the vertices. These values are assigned to the LeafProperties struct.

% Vertices of the leaf base geometry
LeafProperties.vertices = [0.0    0.0    0.0;
                           -0.04  0.02   0.0;
                           0.0    0.10   0.0;
                           0.04   0.02   0.0];

% Triangles of the leaf base geometry
LeafProperties.triangles = [1 2 3;
                            1 3 4];

In the LeafProperties.vertices matrix each row corresponds to a singe vertice point and in the LeafProperties.triangles each row contains the row indices of vertices used for the triangles. These matrices define a leaf geometry based on two triangles which looks like this:

The absolute dimensions of the leaf base geometry are not important, since the base geometry is scaled to the correct size in the LSD sampling phase. Only the shape of the base geometry is preserved.

Setting petiole length limits

The leaf petioles are sampled unifromly from the interval defined to the LeafProperties struct:

LeafProperties.petioleLengthLimits = [0.08 0.10];

The units of the length limits are meters, so in this case the petioles are sampled between 8 and 10 centimeters.

Defining target leaf distributions

The target distribution types and parameters for LADD, LOD, and LSD are defined in the TargetDistributions struct.

The LADD marginal distribution types and parameters with respect to the structural variables are defined as:

% LADD relative height
TargetDistributions.dTypeLADDh = 'beta';
TargetDistributions.pLADDh = [22 3];

% LADD relative branch distance
TargetDistributions.dTypeLADDd = 'weibull';
TargetDistributions.pLADDd = [3.3 2.8];

% LADD compass direction
TargetDistributions.dTypeLADDc = 'vonmises';
TargetDistributions.pLADDc = [5/4*pi 0.1];

Fields dTypeLADDh and pLADDh define the distribution type and parameters for the LADD marginal distribution on the relative height, in this case a beta distribution with parameters $\alpha$ = 22 and $\beta$ = 3. Similarly, dTypeLADDd and pLADDd define the relative branch distance marginal distribution as a truncated Weibull distribution with the scale parameter of $\lambda$ = 3.3 and the shape parameter of $k$ = 2.8, and dTypeLADDc and pLADDc define the compass direction marginal distribution as a von Mises distribution with the mean direction of $\mu = \frac{5\pi}{4}$ and the concentration parameter of $\kappa$ = 0.1.

The LOD marginal distribution types and parameters with respect to the inclination and azimuth angles of leaf normals are defined as:

% LOD inclination angle
TargetDistributions.dTypeLODinc = 'dewit';
TargetDistributions.fun_pLODinc = @(h,d,c) [1 2];

% LOD azimuth angle
TargetDistributions.dTypeLODaz = 'uniform';
TargetDistributions.fun_pLODaz = @(h,d,c) [];

The dTypeLODinc and fun_pLODinc fields define the distribution type for leaf inclination angle and the function for the distribution parameters, in this case a generalized de Wit’s distribution with parameters a = 1 and b = 2. The definition of distribution parameters, compared to LADD, is now done with a function, since the shape of LOD is allowed to change with respect to the structural variables. In this example, the parameters for inclination angle are set to be identical for the whole tree, so the field fun_pLODinc is set to be a handle for a constant function over all variable values. The dTypeLODaz and fun_pLODaz fields define the distribution type and parameters for the leaf azimuth angle, in this case a uniform distribution and thus an empty parameter function as no parameters are needed for uniform distribution on the azimuth angle (the distribution covers values from $0$ to $2\pi$ uniformly).

The LSD type and parameters, similarly to LOD, are defined as:

TargetDistributions.dTypeLSD = 'normal';
TargetDistributions.fun_pLSD = @(h,d,c) [0.004 0.00025^2];

The dTypeLSD and fun_pLSD fields define the distribution type and parameter function for the LSD, in this case a normal distribution with expected value of 40 square centimeters and a variance of 2.5$^2$ square centimeters.

The parameters of LOD inclination and azimuth angle distributions as well as LSD have to be given as function handles with three variables: relative height, relative branch distance, and compass direction. This holds even in the case they are constant or empty.

Setting target leaf area

The target leaf area is set in square meters to a variable named totalLeafArea:

totalLeafArea = 50;

The total leaf area can be essentially set to any positive value. In this case a total area of 50 square meters is chosen as the target. Larger values create larger foliage, which also increases the computational cost (mainly caused by the intersection prevention phase). If the value is too large the computation time can become very large as the overcrowding of leaves causes a lot of intersections. It is also possible that for too large total areas the target is not reached.

A realistic choice for the target leaf area can be derived, for example, by multiplying some realistic leaf area index (LAI) value with the ground projected area of the tree crown.

Generating foliage

The foliage is generated by calling the function generate_foliage_qsm_direct with the inputs defined above

[Leaves,QSMbc] = generate_foliage_qsm_direct(QSM,TargetDistributions, ...
                                             LeafProperties,totalLeafArea);

The first output Leaves contains a LeafModelTrianlge class object, which holds the transformation parameters of the generated leaves. The second output QSMbc contains the QSM as a QSMBCylindrical class object, which can be used to visualize and export the QSM.

Running this function can take some time if generating large or very dense foliage.

Visualizing the foliage in 3D

The generated foliage and the QSM can be visualized using class functions:

% Initialize figure
figure(1), clf, hold on

% Plot leaves
hLeaf = Leaves.plot_leaves();

% Set leaf color
set(hLeaf,'FaceColor',[0 150 0]./255,'EdgeColor','none');

% Plot QSM
hQSM = QSMbc.plot_model();

% Set bark color
set(hQSM,'FaceColor',[150 100 50]./255,'EdgeColor','none');

% Set figure properties
hold off;
axis equal;
xlabel('x')
ylabel('y')
zlabel('z')

This produces a 3D figure with green leaves and brown QSM.

Visualizing leaf distributions

The distributions of accepted leaves can be visualized with histograms.

LADD

The histograms of accepted leaf area with respect to each of the structural variables can be visualized alongside their target distributions with the following function calls:

plot_LADD_h_QSM(QSMbc,Leaves,TargetDistributions);
plot_LADD_d_QSM(QSMbc,Leaves,TargetDistributions);
plot_LADD_c_QSM(QSMbc,Leaves,TargetDistributions);

Here, again, h refers to relative height, d refers to relative branch distance, and c refers to compass direction.

LOD

The histograms of the inclination and azimuth angles of accepted leaves can be visualized with the following function calls:

plot_LOD_inc_QSM(QSMbc,Leaves);
plot_LOD_az_QSM(QSMbc,Leaves);

By default, these functions consider all leaves generated on the QSM, but they can be tuned to plot only specific intervals of the structural variables. In this tutorial the LOD for inclination and azimuth angles are stationary for the whole tree, so it makes sense to see the orientation histograms of all of the generated leaves.

LSD

The histogram of surface areas of accepted leaves can be visualized with the following function call:

plot_LSD_QSM(QSMbc,Leaves);

As with LOD, by default, this function considers all leaves generated on the QSM, but it can be tuned to plot only specific intervals of the structural variables. In this tutorial also the LSD is stationary for the whole tree, so it makes sense to see the leaf size histogram of the whole tree at once.

Exporting to OBJ files

The generated foliage and the QSM can be exported to Wavefront OBJ files using class functions.

% Precision parameter for export
precision = 5;

% Exporting to obj files
Leaves.export_geometry('OBJ',true,'leaves_export.obj',precision);
QSMbc.export('OBJ','qsm_export.obj','Precision',precision);

The precision parameter defines the number of digits used when writing the geometry to an OBJ file: higher values give more precise geometry but increase the file size, whereas small values reduce the file size but provide less accurate geometry.