Working with pixel format data: pixeltest.m

Often imaging data is provided in pixel format. However, as ValoMC uses triangles as the basis elements, the data are not directly compatible. This example demonstrates how to move between the two formats.

Contents

Creating a 2d mesh for pixel data

To create a mesh that can be easily mapped to a pixel grid the function createGridMesh can be used

clear all;

x_arr = -2:0.01:2;
y_arr = -2:0.01:2;

vmcmesh = createGridMesh(x_arr, y_arr); % function provided by ValoMC

% createGridMesh will create a mesh with the following mapping between
% x_arr and y_arr
%
% The mesh that is created has the following structure
%
%  o-------o--------o
%  |       |        |
%  |   x2  |   x4   |c1
%  |       |        |
%  o-------o--------o
%  |       |        |
%  |   x1  |   x3   |
%  |       |        |
%  o-------o--------o
%
%  o = mesh coordinates
%  x = x_arr, y_arr point
%
%  The triangular mesh is constructed in the following fashion
%
%  3--b1---6--b2---9
%  | .  t6 | .  t8 |
%  b9  .   |   .   b4
%  | t2  . | t4  . |
%  2-------5-------8
%  | .  t5 | .  t7 |
%  b8  .   |   .   b5
%  | t1  . | t3  . |
%  1---b7--4---b6--7
%
%  t_i = triangle
%  b_i = boundary element
%  numbers = vertex indices
%
% Note that there are two triangles for each grid point (x_arr,y_arr)
% and the order of the triangle indices. This means that when using one
% dimensional indexing to assign values to the medium, the assignments must be
% repeated assign values to the lower triangles.

vmcmedium = createMedium(vmcmesh);

Accessing grid elements using one dimensional indexing

Create example data in pixel format

[X,Y] = meshgrid(x_arr,y_arr); % MATLAB function
F = ((X.*exp(-X.^2-Y.^2)) +1)*0.2-0.1;

% Note that since there are twice as many triangles as there are grid
% cells, medium.absorption_coefficient is twice as big as F

vmcmedium.scattering_coefficient = 0.1;
vmcmedium.absorption_coefficient = repmat(F(:),2,1); % repeat F twice
vmcmedium.scattering_anisotropy = 0.9;
vmcmedium.refractive_index = 1;

figure;

patch('Faces', vmcmesh.H, 'Vertices',vmcmesh.r, 'FaceVertexCData', ...
      vmcmedium.absorption_coefficient, 'FaceColor', 'flat', 'EdgeColor','none');
xlabel('[mm]');
ylabel('[mm]');
c = colorbar;                             % create a colorbar
c.Label.String = 'Absorption coefficient';

vmcboundary = createBoundary(vmcmesh, vmcmedium); % create a boundary for the mesh

% Create a light source

lightsource = findBoundaries(vmcmesh, 'direction', [0 0], [0 -5], 1);
vmcboundary.lightsource(lightsource) = {'cosinic'};

solution = ValoMC(vmcmesh, vmcmedium, vmcboundary);
                 ValoMC-2D
--------------------------------------------
  Version:  v1.0b-118-g853f111
  Revision: 131
  OpenMP enabled                     
  Using 16 threads
--------------------------------------------
Initializing MC2D...
Computing... 
...done

Done

Visualize the solution

figure;
patch('Faces', vmcmesh.H, 'Vertices',vmcmesh.r, 'FaceVertexCData', ...
      solution.element_fluence, 'FaceColor', 'flat', 'EdgeColor','none');
xlabel('[mm]');
ylabel('[mm]');
c = colorbar;                             % create a colorbar
c.Label.String = 'Fluence [W/mm2]';

Accessing elements using two dimensional indexing

To avoid having to perform all assignments two times, optionally the medium can be defined using two-dimensional indexing. If two dimensional indexing is used, ValoMC will assume that createGridMesh has been used to create the mesh. In addition to the solution.element_fluence, ValoMC will return solution.grid_fluence, which represents the fluence in each grid cell. It is calculated as an average of the the two triangles in a grid cell.

clear vmcmedium;        % destroy the previous medium structure
clear boundary;


vmcmedium.scattering_coefficient = 0.1;
vmcmedium.absorption_coefficient = F; % two dimensional array
vmcmedium.scattering_anisotropy = 0.9;
vmcmedium.refractive_index = 1;


vmcboundary = createBoundary(vmcmesh, vmcmedium);

lightsource = findBoundaries(vmcmesh, 'direction', [0 0], [0 -5], 1);
vmcboundary.lightsource(lightsource) = {'cosinic'};

solution = ValoMC(vmcmesh, vmcmedium, vmcboundary);
                 ValoMC-2D
--------------------------------------------
  Version:  v1.0b-118-g853f111
  Revision: 131
  OpenMP enabled                     
  Using 16 threads
--------------------------------------------
Initializing MC2D...
Computing... 
...done

Done

Visualize the solution as a pixel map

It is convenient to use imagesc to visualize the solution returned in grid_fluence.

figure
imagesc(x_arr, y_arr, (solution.grid_fluence), [min((solution.grid_fluence(:))) ...
        max((solution.grid_fluence(:)))]);

xlabel('[mm]');
ylabel('[mm]');
c = colorbar;                             % create a colorbar
c.Label.String = 'Fluence [J/mm^2]';