Professional Documents
Culture Documents
GEOSPATIAL INTELLIGENCE
MSC THESIS
2013
SUPERVISORS:
DR. NIKO GALIATSATOS
DR. STEPHEN ROBINSON
SEPTEMBER 2013
P RESCRIBED F ORM - D ISCLAIMER
This paper was written by a student on the GEOINT MSc course at the Royal
School of Military Survey. It has not been corrected or altered as a result of
assessment and it may contain errors or omissions. The views expressed in it,
together with any recommendations, are those of the author and not those of
the DISC, JFIG, Cranfield University, or individual members of its staff. This
document has been printed on behalf of the author by the JFIG, but it has no
official standing as an MOD, DISC, JFIG or Cranfield University document.
I certify that this is my own work and gives due credit to the contribution of
others through references.
Andrew R. Colpitts
Captain
Royal Canadian Engineers
CRANFIELD UNIVERSITY
MSc THESIS
Academic Supervisors:
Dr. Niko Galiatsatos
Dr. Stephen Robinson
September 2013
This thesis is submitted in partial fulfilment of the requirements for the Degree of
Master of Science.
© Crown Copyright, 2013. All rights reserved. No part of this publication may be
reproduced without the written permission of the copyright holder.
ABSTRACT
A BSTRACT
Using a technique called Structure from Motion (SfM), 3D geometry can be
reconstructed from overlapping images of a rigid scene. This technique has
been shown to be useful for military and geospatial purposes in its application
with automated terrain extraction, but the potential of SfM has not yet been fully
exploited in a defence or a defence geospatial context. While the concept of
SfM has been studied since before the 1980s, it is only now coming into
widespread availability due to advances in research, hardware capability and
the proliferation of free and commercial software and hardware such as the
Microsoft® Kinect. This research project summarises the theory of SfM and
investigates the effects of three distinct and pervasive factors on the quality of
3D reconstructions: focal length estimation technique, the number of images
supplied as input and the type of image feature detector. The methodology in
this research project is dependent on the existence of both accurate and dense
reference data and also on a sequence of images which represent the same
scene. Among the conclusions and recommendations drawn from this project is
that the SfM technique for 3D reconstruction lends itself to efficient scaling
between large and small tasks at the tactical to operational levels. In addition,
while there are other 3D model generation techniques available, few are as
tactically viable as SfM. Other findings include the empirical confirmation that
the specification of camera parameters yields consistently better results, and
that there exists a distinct ‘quality vs. effort’ ratio, both in the number of
reconstructed 3D points and their overall accuracy, dependent on the density of
the input data supplied.
I
A C K N OW L E D GE ME N T S
A CKNOWLEDGEMENTS
The author would like to gratefully acknowledge the support of the following
individuals and organisations:
My beautiful wife Kristin for her patience, love, faith and resolve in taking care of
our new son David, who was born in July 2013.
Pierre Simard and David Rowlands at the Mapping and Charting Establishment
(MCE) in Ottawa for effecting the provision of contextual data and support.
Dr. Nikolaos Galiatsatos and Dr. Stephen Robinson for their guidance, patience
and flexibility.
II
TABLE OF C ON TE N TS
T ABLE OF C ONTENTS
ABSTRACT I
ACKNOWLEDGEMENTS ........................................................................................... II
TABLE OF CONTENTS ............................................................................................ III
LIST OF FIGURES ...................................................................................................V
1 INTRODUCTION ................................................................................. 1-1
1.1 BACKGROUND .......................................................................... 1-1
1.2 MOTIVATION ............................................................................. 1-1
1.3 PROJECT AIM ........................................................................... 1-2
1.4 PROJECT OBJECTIVES .............................................................. 1-2
1.5 ABOUT THIS REPORT ................................................................ 1-3
2 LITERATURE REVIEW ......................................................................... 2-1
2.1 OVERVIEW ............................................................................... 2-1
2.2 THE CRUX OF SFM: IMAGE-IMAGE CORRESPONDENCES .............. 2-1
2.3 OTHER CRITICAL FACTORS ....................................................... 2-2
2.4 STRUCTURE FROM MOTION W ORKFLOW STAGES ........................ 2-3
2.5 STAGE ONE: FEATURE EXTRACTION.......................................... 2-5
2.6 STAGE TWO: FEATURE MATCHING .......................................... 2-16
2.7 STAGE THREE: 3D RECONSTRUCTION ..................................... 2-20
2.8 STAGE FOUR: BUNDLE ADJUSTMENT (BA) ............................... 2-21
2.9 STAGE FIVE: DENSE 3D POINT CLOUD GENERATION ................ 2-23
2.10 SFM SOFTWARE .................................................................... 2-25
2.11 POINT CLOUD QUALITY MEASURES AND COMPARISON
TECHNIQUES .......................................................................... 2-27
2.12 SUMMARY .............................................................................. 2-29
3 METHODOLOGY AND DATA ................................................................. 3-1
3.1 OVERVIEW ............................................................................... 3-1
3.2 PART ONE: METHODOLOGY ....................................................... 3-2
3.3 DATA PREPARATION ................................................................. 3-3
3.4 SURF FEATURES ..................................................................... 3-5
3.5 SIFT FEATURES ....................................................................... 3-7
3.6 RECONSTRUCTION .................................................................... 3-8
3.7 POINT CLOUD EVALUATION ....................................................... 3-9
3.8 PART TWO: DATA .................................................................. 3-12
3.9 SUMMARY .............................................................................. 3-16
4 RESULTS .......................................................................................... 4-1
4.1 OVERVIEW ............................................................................... 4-1
4.2 OVERALL PERFORMANCE STATISTICS ........................................ 4-1
4.3 INITIAL OBSERVATIONS ............................................................. 4-2
4.4 NUMBER OF INPUT IMAGES ........................................................ 4-3
4.5 KEY CHARTS ............................................................................ 4-4
4.6 SUMMARY ................................................................................ 4-9
5 ANALYSIS AND DISCUSSION ............................................................... 5-1
5.1 OVERVIEW ............................................................................... 5-1
III
TABLE OF C ON TE N TS
IV
LIST OF FIGURES
L IST OF F IGURES
FIGURE 1 – CORRESPONDENCES EXTRACTED USING THE AFFINE SCALE
INVARIANT FEATURE TRANSFORM (ASIFT).................................................. 2-1
FIGURE 2 – DIAGRAM OF THE SIFT EXTRACTION PROCESS. ................................... 2-8
FIGURE 3 – DOG LAYER OCTAVES (LOWE, 2004). ............................................... 2-8
FIGURE 4 - IDENTIFICATION OF LOCAL EXTREMA IN SCALE AND IMAGE
SPACE (X,Y,Σ) (LOWE, 2004). .................................................................... 2-9
FIGURE 5 - SIFT FEATURE DESCRIPTOR ORIENTATION (VEDALDI AND
FULKERSON, 2008). ................................................................................ 2-10
FIGURE 6 - BASIC SCHEMATIC DIAGRAM OF THE SURF EXTRACTION
PROCESS. ............................................................................................... 2-11
V
LIST OF FIGURES
VI
C H A P TE R 1: I N T R OD U C TI ON
1 I NTRODUCTION
1.1 B ACKGROUND
McGrath (2010) showed that through second-phase exploitation of full-motion
video, it is possible to extract three-dimensional (3D) information, such as digital
elevation models (DEMs) using structure from Motion (SfM) techniques and
proprietary commercial software. He also demonstrated a limited attempt to
quantitatively assess these DEMs for accuracy. In the past, methods for
objectively assessing elevation data have typically been limited to “2.5D”
datasets, wherein unique horizontal locations correspond to single elevation
value. These surface models are not as useful in complex environments, where
the retention of the full 3D point cloud may be beneficial in permitting visual and
topological layering, and enabling the creation of more complex, true-to-form
structure models. In addition, while there are several recent and ongoing SfM
research projects focusing on the large-scale application of SfM and on the
improvement of SfM time-cost measures, little research has been conducted
focusing on a more holistic approach to SfM and its applications in a defence
context.
1.2 M OTIVATION
1.2.1 S CENARIO
Consider the following scenario: A four-man reconnaissance patrol is tasked to
observe an objective and departs the hide. Upon arrival at the objective, the
patrol commander and another member observe the objective from several
different vantage points using a process called ‘clover-leafing.’ At each
observation point, in addition to the normal notes and observations, the patrol
takes a picture using a basic single-reflex lens (SLR) digital camera. Upon
returning to the headquarters several hours later, the images are turned over to
a geospatial analyst, who uses them to quickly construct a 3D model of the
objective area. The model is cleaned up and given surface colouration directly
from the photos. Annotations are made according to the recollections of the
patrol members, and the 3D model helps them to describe the objective to the
commander.
1-1
C H A P TE R 1: I N T R OD U C TI ON
The end result is a 3D planning product which can both assist the patrol in
conveying their observations and assist the commander to make decisions.
Later in the week, a deliberate operation is planned and executed using the 3D
model.
1.2.2 T HE B ENEFIT
In total, the application of the SfM technique has improved operational
effectiveness at the tactical level, improved situational awareness and
represented only a small increase in manpower and resource requirements.
1.3 P ROJECT A IM
The aim of this project is to investigate the effect of image metadata, frame
count and processing algorithms on the quality of 3D point clouds produced
using SfM techniques.
1-2
C H A P TE R 1: I N T R OD U C TI ON
1.4.2 O BJECTIVE T WO
Develop a methodological approach for production and geo-registration of point
clouds with open-source SfM software using three independent variables:
estimation of camera calibration parameters, image count and choice of feature
detector.
1-3
C H A P TE R 2: L I TE R A TU R E R E V I EW
2 L ITERATURE R EVIEW
2.1 O VERVIEW
This chapter is a review of some of the basic concepts of computer vision and
SfM. A discussion of the current research on the relevant subjects is organized
in terms of a common SfM workflow. The field of computer vision, and SfM
within it, is surprisingly complex, and in no measure is this literature review
intended to be a comprehensive analysis of the current research in every
subject area. It is, however, designed to provide a framework for the
understanding of the methodology, analysis and discussion presented in
subsequent chapters.
2-1
C H A P TE R 2: L I TE R A TU R E R E V I EW
2-2
C H A P TE R 2: L I TE R A TU R E R E V I EW
2-3
C H A P TE R 2: L I TE R A TU R E R E V I EW
2-4
C H A P TE R 2: L I TE R A TU R E R E V I EW
The detector locates and vets candidate features, while the descriptor attempts
to describe the feature and its surrounding region so that it can be reliably
matched. The reliability of matching of detected features depends equally upon
the accuracy of the detector as it does on the robustness and distinctiveness of
the descriptor. Robustness is the ability of the descriptor to be reliably matched
despite image deformations and noise. Distinctiveness is the descriptor’s ability
2-5
C H A P TE R 2: L I TE R A TU R E R E V I EW
In general, feature detectors fall into one of two different levels of complexity:
scale invariance and affine invariance. There are also versions of these which
are invariant only to rotation, such as local greyvalue invariants (Schmid and
Mohr, 1997). In addition, there are largely two different types of features which
can be extracted: blob features and corner features.
− (x )
G ( x, y , σ ) =
1 2
+ y 2 2σ 2
e
2πσ 2
Equation 1 - The Gaussian kernel used to explore the scale space of an image.
2-6
C H A P TE R 2: L I TE R A TU R E R E V I EW
2-7
C H A P TE R 2: L I TE R A TU R E R E V I EW
David Lowe (2004) explains SIFT in great detail, but a short explanation will be
provided here. Figure 2 displays a very basic flowchart for the SIFT extraction
process.
2-8
C H A P TE R 2: L I TE R A TU R E R E V I EW
Figure 4 - Identification of Local Extrema in Scale and Image Space (x,y,σ) (Lowe, 2004).
Next, maxima and minima in the image space and scale space are extracted by
examining the 26 nearest neighbours in the 3x3 adjacent pixels in the current
scale and two adjacent scales (see Figure 4). These candidates are then
subjected to a detailed fit using a quadratic curve in the three dimensions (x,y,σ)
to localise the extrema to sub-pixel accuracy. Next, the extrema with strong
edge responses, those which are poorly localised along image boundaries and
those which exhibit low contrast are eliminated. Each remaining keypoint is
given an orientation assignment based upon the local mean image gradient
direction in the region of the keypoint.
The last step in SIFT is the computation of the keypoint descriptor, which is a
128-dimension vector corresponding to 16 bins in a 4x4 grid centred around the
keypoint and oriented with regard to the keypoint’s assigned orientation. Each
bin contains 8 separate orientations, into which sample gradients are binned.
2-9
C H A P TE R 2: L I TE R A TU R E R E V I EW
2-10
C H A P TE R 2: L I TE R A TU R E R E V I EW
Lxx ( x, y, σ ) Lxy ( x, y, σ )
H ( x, y , σ ) =
Lxy ( x , y , σ ) L yy ( x , y , σ )
Equation 2 - The Hessian Matrix at scale σ and point (x,y) (Bay et al., 2008).
Where:
∂2
Lxy = I ( x, y ) ∗ G (σ )
∂x∂y
Equation 3 - Lxy is the convolution (*) on the image I(x,y) of the Gaussian second-order
partial derivative over x and y.
2-11
C H A P TE R 2: L I TE R A TU R E R E V I EW
Figure 7 - The discretized and cropped Gaussian second order partial derivative in the Lyy
direction (left) and the Lxy direction (right).
Figure 8 - Box filters approximating the Gaussian second-order partial derivative in Dyy
(left) and Dxy (right).
In contrast to SIFT, which uses overall image gradients at the interest point to
determine keypoint orientation, SURF uses the magnitude of the Haar wavelet
response – again taking full advantage of the integral images - in the x and y
directions to map a distribution of weighted responses in the a circular region of
radius 6σ around the keypoint. A rotating envelope of size π/3 is used to
2-12
C H A P TE R 2: L I TE R A TU R E R E V I EW
determine the orientation of the keypoint by taking the orientation with the
greatest sum of wavelet response within the envelope as in Figure 9.
The SURF descriptor is extracted from a square region of size 20σ, oriented
according to the keypoint’s orientation. Like in SIFT, this region is further
subdivided into a set of 4x4 squares. Whereas the SIFT descriptor is of length
128, the SURF descriptor is of length 64, where for each of the 16 sub-regions
the Haar wavelet response is recorded in four dimensions:
v= (∑ d ,∑ d , ∑ d , ∑ d )
x y x y
Equation 4 - The haar wavelet response vector is recorded for each of the 16 sub-regions
for each interest point, making the descriptor half as long as the SIFT desciptor.
2-13
C H A P TE R 2: L I TE R A TU R E R E V I EW
There are, however, a number of potential drawbacks to SURF which are not
fully discussed by Bay et al. (2008). Firstly, the implementation of SURF as a
fully discretized approximation means that it cannot be used to determine the
location of an interest point to sub-pixel accuracy. Depending on the resolution
and focal length of the input images, this has the potential to become a serious
hindrance on reconstruction accuracy. Secondly, the use by SURF of
extremely large descriptor regions has at least two drawbacks; while it may be
more robust for planar surfaces, more complex 3D scenes with discontinuities
will force keypoints located close to the discontinuity (such as the corner of a
building) to mismatch despite being an otherwise valid keypoint, even for
relatively small view angle shifts. This may make it difficult for the SfM
algorithms using SURF to correctly model sharp corners. The second
disadvantage to large descriptor regions means that a much greater percentage
of the image – anywhere near the edge of the image – becomes unusable for
feature extraction and matching. This effect will be more pronounced for small-
resolution images.
2-14
C H A P TE R 2: L I TE R A TU R E R E V I EW
the extreme intensity value of the MSER. MSER detection and matching is a
novel concept, but suffers from some of the same weaknesses as SURF.
Affine-SIFT (ASIFT) is one of the only truly affine invariant detection methods
because it functions by the complete exploration of affine space (Morel and Yu,
2009). As such, it boasts far superior performance under severe anisotropic
scaling of the image. Its major drawback is the prohibitive computational cost
(several seconds per image, vs. several images per second with SIFT) for both
feature detection and feature matching. Nonetheless, further experimentation
with ASIFT could explore the ability to construct 3D models from far fewer
images, which has many implications in the defence context.
2-15
C H A P TE R 2: L I TE R A TU R E R E V I EW
1
Putative: “Generally considered or reputed to be.” (Oxford Dictionaries Online, 2013)
2-16
C H A P TE R 2: L I TE R A TU R E R E V I EW
therefore, the time required to conduct full pairwise matching increases with the
square of the number of input images (Wu, 2013a). Clearly, for large sets of
input images – which can contain more than 2000 features each – the time
required for feature matching under this method becomes unmanageable. In
addition, Wu (2013a) points out that for typical large sets of images, up to 75%
to 98% of all possible image pairs do not match. For the above reasons, it
becomes prudent to consider alternative methods to performing feature
matching than full pairwise matching. Two of these methods, specified
matching and pre-emptive feature matching, are listed in the following sub-
sections.
2-17
C H A P TE R 2: L I TE R A TU R E R E V I EW
Yu, 2009). For data with lower dimensionality, use of a k-d tree for feature
matching can drastically reduce computational cost.
Figure 10 - K-D Tree Example for a dataset in two dimensions (The Mathworks, Inc.,
2013).
In a K-D Tree, the reference data is split into bins such that each bin has a set
maximum number of data points. In this way, the appropriate bin can first be
found, so that an exhaustive search only has to be done on a limited number of
possible points in the reference data. The KNN Search algorithm and K-D
Trees are important in several aspects of this research project, such as the
project’s implementation of the iterative closest point (ICP) algorithm. K-D
Trees in 3 dimensions are important for the iterative closest point (ICP)
algorithm, but when dataset dimensionality exceeds 10, K-D Trees offer little
improvement over brute force (exhaustive) searches.
2-18
C H A P TE R 2: L I TE R A TU R E R E V I EW
Table 1 - Overview of the RANSAC Algorithm. Adapted from Depanis (2010) to reflect the
calculation of the fundamental matrix F for an image pair with at least the minimum
number of putative matches.
Step Description
From the set of putative matches, randomly select the minimum number of
1
correspondences required to estimate F (7 or 8, depending on the method).
2 Solve for F.
Attempt to fit the remaining putative matches to F with the equation:
3 x'T Fx = v
Equation 5 – x’ ↔ x is an inlier match if the residual ν is less than some error
tolerance ε, which is a parameter of the RANSAC algorithm.
For any putative match which yields a residual v greater than the error tolerance ε, this
4
putative match is an outlier. Otherwise, it is considered an inlier match.
If the fraction of inliers to putative matches exceeds a threshold, then re-compute F
5
using all of the inlier matches and return F.
Otherwise, re-select the minimum number of putative matches and start again, a
6
maximum of N times
2-19
C H A P TE R 2: L I TE R A TU R E R E V I EW
2-20
C H A P TE R 2: L I TE R A TU R E R E V I EW
f (ω + ∂ω ) ≈ f (ω ) + g T ∂ω + ∂ω T H∂ω
1
2
Equation 6 - The quadratic Taylor series expansion of the error function in Equation 30
(Triggs et al., 2000).
Where:
g≡
df
(ω ) is the gradient vector and
dω
∂2 f ∂2 f
(ω ) L (ω )
∂ω1
2
∂ω1∂ωi
H ≡ M O M is the Hessian matrix.
∂ 2
∂ 2
∂ω ∂ω (ω ) L ∂ω ∂ω (ω )
f f
i 1 i i
By taking the derivative of the Taylor expansion and setting it to zero, the
variation in the parameters δω can be obtained:
2-21
C H A P TE R 2: L I TE R A TU R E R E V I EW
∂ω = − H −1 g
Equation 7 - The Newton step prediction.
H ≈ J TWJ
Equation 8 - Gauss-Newton approximation to the least-squares Hessian matrix H (Triggs
et al., 2000).
∂xˆ ij
J=
∂ω
Equation 9 - The Jacobian is the matrix of the change in the back-projected points in
terms of the change in the parameters ω (Triggs et al., 2000).
This version of the LM algorithm is not without its disadvantages. Like most
nonlinear least-squares estimation algorithms, the LM algorithm is susceptible
to local minima in the error function, and can falsely converge on a saddle point
(Triggs et al., 2000). Nonetheless, as long as the outlier control measures in
the RANSAC algorithm are well-calibrated and the view geometry is strong, the
LM algorithm is usually able to converge accurately (Triggs et al., 2000).
2-22
C H A P TE R 2: L I TE R A TU R E R E V I EW
This process involves using the internal and external camera parameters and
the set of reconstructed points to create image patches around each
reconstructed point. From these image patches, additional matches are found
and triangulated to vastly increase the density of the point cloud. One example
of a software tool that performs dense reconstruction is Fukurawa and Ponce’s
(2010) Patch-Based Multi-View Stereo Software (PMVS) and Clustering Views
for Multi-view Stereo (CMVS). Figure 11 displays an example of CMVS-PMVS
output for a sparse reconstruction made with 1000 images and the SIFT
detector, centred on the building studied in this research project.
2-23
C H A P TE R 2: L I TE R A TU R E R E V I EW
further for experimentation in this research project, and all experimentation and
testing will be conducted with regard to sparse reconstruction.
2-24
C H A P TE R 2: L I TE R A TU R E R E V I EW
2.10 S F M S OFTWARE
There are a number of open-source SfM software packages available for use in
SfM applications, and also a number of commercial and closed-source software
packages. This research project concentrates on open-source software, and in
the end only one package, VisualSFM, was selected for experimentation. The
following sub-sections describe a select few of the software packages that can
be used to conduct SfM 3D reconstructions.
2.10.2 M ATLAB
The newest releases of Matlab® come with built-in image processing libraries
so Matlab scripts may be written to process a sequence of images and perform
3D reconstruction on them. Matlab can also be used as an application
programming interface (API) for another open-source computer vision library
called VLFeat (Vedaldi and Fulkerson, 2008), which can be used on previous
releases of Matlab which do not have built-in image processing libraries.
Matlab is advantageous in that it is so versatile; visualizations of the output and
a complete understanding of the process can be obtained at each stage.
However, using Matlab in this manner has two distinct disadvantages. Firstly,
the use of Matlab is tantamount to writing a software package nearly from
scratch; in addition to data pre-processing, this would involve an enormous
amount of additional effort which is not in the scope or the focus of this research
project. Secondly, Matlab is, in its basic configuration, unable to take
advantage of certain computational exploits which are embedded into other SfM
implementations, such as the graphics processing unit (GPU) implementation of
2-25
C H A P TE R 2: L I TE R A TU R E R E V I EW
2.10.3 B UNDLER
Bundler is an SfM system for large, unordered image collections which creates
3D point clouds from input images in much the same way as VisualSFM
(Snavely, Seitz and Szeliski, 2006). Bundler has the disadvantage of being an
entirely command-line software package; no visual output is generated until the
output is opened in a separate viewer. In addition, Bundler doesn’t
automatically assume a starting focal length if focal lengths cannot be obtained
from EXIF tags. Finally, the default behaviour of Bundler is to perform full
pairwise matching on the input data, which for large sets of images, becomes
time-prohibitive. Figure 12 shows an example of camera pose estimation
output from Bundler (Snavely, Seitz and Szeliski, 2006).
Figure 12 - Example of Bundler Camera Pose Estimation (Snavely, Seitz and Szeliski,
2006).
2-26
C H A P TE R 2: L I TE R A TU R E R E V I EW
The Hausdorff distance is a maximin distance, that is, it is the maximum of the
set of minimum distances between two datasets, as seen in Equation 10.
{
h(a, b ) = max min{d (a, b )}
a∈A b∈B
}
Equation 10 - The Hausdorff distance (Grégoire and Bouillot, 1998).
The Hausdorff distance has several major disadvantages for use in this
research project. For example, the basic algorithm has no way of knowing
2-27
C H A P TE R 2: L I TE R A TU R E R E V I EW
2-28
C H A P TE R 2: L I TE R A TU R E R E V I EW
data. The kNN search algorithm runs very quickly due to the fact that the K-D
Tree search object for the reference dataset can be pre-computed once and
then stored. The nearest point distance is the chief quality statistic used during
this research project.
2.12 S UMMARY
In this chapter, a limited literature and conceptual review were offered as
foundation for the methodology, analysis and discussion found in later chapters.
At the beginning of this chapter, the key factors in SfM which are evaluated in
this research project were described with reference to the important theory in
Annex A. Next the important concepts in SfM were presented with regard to a
typical SfM workflow. Finally, the point cloud evaluation methods considered for
use in this research project were presented.
2-29
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
In the second part of this chapter, the input, reference and supporting data used
in this research project are described.
3-1
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3-2
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
In addition, in this phase the reference data was cleaned up to better represent
the shape of the building that would be seen from the aerial images. For
example, the reference data contained a number of points located in the interior
of the building which would not be seen in the aerial imagery. Were these
3-3
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
points left in the reference data, the iterative closest point (ICP) registration and
nearest distance calculations may have been adversely affected.
The full list of 276 cases used in this research project is available in Annex F.
Supplied with the list of cases, the image database was used to produce the
image lists required as input to VisualSFM.
3-4
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3-5
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3-6
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
The SIFT feature extraction phase is built into VisualSFM using Lowe’s (2004)
binary. Every step in this phase is as described in paragraph 0. A visual
depiction is shown in Figure 16. The only noteworthy points in this
implementation are that once a set of SIFT features and descriptors are
extracted, the file is stored to save time in the event of future use. The same is
true for the match indices for matched pairs.
3-7
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3.6 R ECONSTRUCTION
The reconstruction process using VisualSFM is fairly transparent to the user. In
this research project, reconstructions were performed using either SIFT or
SURF input as dictated by the current case. Internal settings within VisualSFM
were not modified from the original settings throughout the reconstruction
process.
3-8
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3-9
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3-10
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
LE90AbsMin, etc. The major results of these calculations are given in Chapter 4,
the complete set of charts in Annex G.
3-11
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3-12
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
The sensor in use was the medium-wavelength infrared (MWIR) sensor as part
of the BAE Systems joint multi-mission electro-optical sensor (JMMES) suite.
The resolution of each image is 640x480 pixels, and the focal length determined
to be a constant 6750 pixels, assumed to be isotropic as in Annex E (see Figure
20).
3-13
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
Figure 21 displays the trace of the flight path as it performs a single orbit around
the target building. The flight path information is taken from the supplied image
metadata.
3-14
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3-15
C H A P TE R 3: M E T H O D O L O G Y AND D A TA
3.9 S UMMARY
In this chapter, both the methodology and the data used in this research project
were presented. The methodology is a logical, nearly-linear sequence of
operations, but it was developed over several iterations to its present form. The
data used in this project can be divided into the three distinct categories of input
data, reference data and supporting data. The input data is merely a sequence
of images, meaning that the methodology used in this project can be applied to
any set of images for which there also exists similar reference data.
3-16
C H A P TE R : 4 R E S U L T S
4 R ESULTS
4.1 O VERVIEW
This chapter is designed to convey the most important initial observations and
global results from the experimentation described in Chapter 3. Detailed
discussion of the observations is deferred until Chapter 5. Firstly, the most
important overall performance statistics are described. The second part of this
chapter displays some of the charts in order to introduce the concepts
discussed in Chapter 5.
4-1
C H A P TE R : 4 R E S U L T S
least 10 reconstructed points within the trimmed area of interest. Models not
meeting both of these requirements were considered unsuccessful
reconstructions.
While Table 4is an interesting general tool, it does not convey any information
about the distribution of these statistics with regard to the research project’s
third independent variable: the number of input images.
4-2
C H A P TE R : 4 R E S U L T S
Table 5 - Relation of the Number of Input Images (n) to a Number of Other Factors
Linked
# Determination Significance
Factor
Mean view angle is a common
independent variable for tests of
Mean View
1 θ = n / 360° repeatability against Affine
Angle (θ)
transformations in feature detectors and
descriptors.
If Full Pairwise Matching is
used:
Number of Represents the number of ties each
m = 0.5 * (n – 1)
2 Pairs per image has – the potential for each image
If the standard 10% overlap
Image (m) to match other images.
is used:
m = n * 0.1
Because feature matching is so
computationally expensive, the total
Total Number
number of matched pairs used to
3 of Matched p=n*m
achieve a reconstruction is
Pairs (p)
representative of the total computational
effort required.
Matches per Represents the total number of matches
4 d = p / 360°
Unit Angle (d) scaled to a common factor.
From Table 5, is can be seen that the number of input images can be used to
directly determine a number of other factors. The charts relating to some of
these alternatives are available in Annex G.
4-3
C H A P TE R : 4 R E S U L T S
4.5 K EY C HARTS
4.5.1 N UMBER OF R ECONSTRUCTED P OINTS VS . N UMBER OF I MAGES
Two observations are immediately clear from Figure 24. Firstly, that the
number of reconstructed points is nearly linear with regard to the log10 of the
number of input images. Secondly, the SIFT-Specified scenario is not only
most reliable, but it also yields the highest performance out of the other
estimation methods. Another interesting observation is that other reconstruction
methods only appear to become somewhat reliable at 150+ input images, and
that no reconstruction is successfully done at less than 20 input images.
4-4
C H A P TE R : 4 R E S U L T S
4-5
C H A P TE R : 4 R E S U L T S
Clearly from Figure 26, the SIFT-Specified scenario is again not only the most
reliable reconstruction method, but it also appears to represent a lower bound
for the value of LE90AbsMin.
4-6
C H A P TE R : 4 R E S U L T S
Figure 27 and Figure 28 represent the vertical and total horizontal adjustments
obtained by combining the centroid translation values for both the coarse
registration and the ICP output. It can be seen that there is a clear bias present
in the vertical coordinates, but also that the SIFT-Specified reconstructions are
consistently adjusted down by approximately 60m.
4-7
C H A P TE R : 4 R E S U L T S
In Figure 28 it can be seen that while the other scenarios become more reliable
beyond 120+ images, the SURF-Shared and SURF-Individual scenarios remain
noisy in terms of horizontal adjustments throughout. This could be an indication
of poor model geometry or it could also indicate that these methods yield an
insufficient number of points for the rough registration techniques to converge in
a bracketing least-squares minimization.
4-8
C H A P TE R : 4 R E S U L T S
4.6 S UMMARY
In this brief chapter, the most important results and the key, initial observations
of the experiments conducted in this research project were shown. It is
immediately clear that the Specified calibration cases outperform the other
estimation techniques and that SIFT outperforms SURF. But there remain
several questions as to the potential causes and implications of these
observations. The basic observations made in this chapter will be discussed in
further detail in Chapter 5.
4-9
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
5-1
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
In addition, it is clear from Figure 30 that the majority of the gains in quality – as
measured purely by the number of reprojected points – occurs below 1000
matched pairs.
5-2
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
A deeper consideration of what occurs between 0 and 100 input images (or
1000 matched pairs at 10% overlap) may be necessary. Recall also from
Figure 24 that the reliability of the reconstruction from the SIFT-matched pairs is
poor until about 100 images or 1000 matched pairs. This means that in
general, the number of reconstructed points is likely more dependent at this
stage on the success of the model; more reconstructed points means more
points are available to tie images to the bundle of sparse reprojections.
But there is also a simpler explanation: the rate of change of the number of
reconstructed points is related to the amount of new information given by each
image. If there are 50 images, with a mean view angle of 7.2°, then adding one
more image adds more information than if there are already 100 images, with a
mean view angle of 3.6°.
5-3
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
angles. Unfortunately, explicitly recording this information for each case was
not part of the experimental design (see paragraph 5.3.5).
5-4
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
5-5
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
This is perhaps due to the increasing difficulty of fitting a more complex model
to the same reference data. If that were the case, however, one would expect
the minimum accuracy to approach and attain a certain limit. A better
explanation is that, while the number of images increases, the view angle
decreases, and therefore the stereo-depth ambiguity increases. While
5-6
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
5-7
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
5.3.5 R ECORD THE N UMBER OF D ETECTED F EATURES PER I MAGE AND THE
N UMBER OF M ATCHED F EATURES PER P AIR
A simple addition to the current methodology could include the recording of the
number of matched features per pair and the number of detected features per
image. With such precise figures, additional comparisons could be made
regarding the specific performance of SIFT and SURF (or any number of
feature detectors).
5-8
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
5-9
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
5-10
C H A P TE R : 5 A N A L YS I S AND D I S C U S S I ON
5.5 S UMMARY
In this chapter, the results in Chapter 4 were discussed in detail, yielding
several general findings which are likely to apply to a large number of SfM
applications. In addition, analysis of the results led to several suggested
improvements to the project methodology, most of which can be implemented
relatively quickly.
5-11
C H A P TE R 6: C O N C L U S I ON
6-1
C H A P TE R 6: C O N C L U S I ON
6-2
W OR D C O U N T
W ORD C OUNT
Word Count: 13,301
This word count excludes captions, titles, tables, quotes and annexes.
I
W OR K S C I TE D
W ORKS C ITED
Agarwal, S., Snavely, N., Seitz, S.M. and Szeliski, R. (2009) Building Rome in a
Day, ICCV.
Ager, T.P. (2004) An Analysis of Metric Accuracy Defnitions and Methods of
Computation, NIMA InnoVision.
Aspert, N., Santa-Cruz, D. and Ebrahimi, T. (2002) MESH: Measuring Error
between Surfaces using the Hausdorff Distance, IEEE International
Conference on Multimedia and Expo, 705-708.
BAE Systems (2009) SOCET SET User's Manual, 55th edition, BAE Systems.
BAE Systems (2012) JMMES Sensors Secifications, BAE Systems Spectral
Solutions LLC.
Bay, H., Ess, A., Tuytelaars, T. and Van Gool, L. (2008) Speeded-Up Robust
Features (SURF), Computer Vision and Image Understanding, vol. 110,
no. 3, pp. 346-359.
Byröd, M. and Åström, K. (2010) Conjugate Gradient Bundle Adjustment,
ECCV, vol. II, pp. 114-127.
Cignoni, P., Rocchini, C. and Scorpigno, R. (1996) Metro: Measuring Error of
Simplified Surfaces (Technical Report), Paris, France: Centre National de
la Recherche Scientifique, Paris.
Derpanis, K.G. (2010) Overview of the RANSAC Algorithm, 12th edition,
Unpublished.
ERDAS Inc. (2010) eATE User's Guide 2010, ERDAS, Inc.
Fischler, M.A. and Bolles, R.C. (1981) Random Sample Consensus: A
Paradigm for Model Fitting with Applications to Image Analysis and
Automated Cartography, Communications of the ACM, vol. 24, no. 6,
June, pp. 381-395.
Furukawa, Y. and Ponce, J. (2010) Accurate, Dense and Robust Multi-view
Stereopsis, IEEE Transactions on Pattern Analysis and Machine
Intelligence, vol. 32, pp. 1362-1376.
Gavin, H. (2011) The Levenberg-Marquardt method for nonlinear least squares
curve-fitting problems, Durham, NC: Duke University.
Girardeau-Montaut, D., Roux, M., Marc, R. and Thibault, G. (2005) Change
Detection on Points Cloud Data acquired with a Ground Laser Scanner,
ISPRS Workshop on Laser Scanning, Enshede, the Netherlands, 12-14.
Grégoire, N. and Bouillot, M. (1998) Hausdorff Distance Between Convex
Polygons, [Online], Available:
http://cgm.cs.mcgill.ca/~godfried/teaching/cg-
projects/98/normand/main.html [12 September 2013].
Hartley, R.I. and Zisserman, A. (2003) Multiple View Geometry in Computer
Vision, 2nd edition, Cambridge: Cambridge Univeristy Press.
II
W OR K S C I TE D
III
W OR K S C I TE D
IV
W OR K S C I TE D
Vedaldi, A. and Fulkerson, B. (2008) Vision Lab Features Library: An Open and
Portable Library of Computer Vision Algorithms, [Online], Available:
http://www.vlfeat.org/ [11 June 2011].
Wilm, J. (2010) Iterative Closest Point (Matlab Central), 30 May, [Online],
Available: http://www.mathworks.com/matlabcentral/fileexchange/27804-
iterative-closest-point [30 August 2013].
Wu, C. (2007) SiftGPU: A Graphics Processing Unit (GPU) Implementation of
Scale Invariant Feature Transform (SIFT), [Online], Available:
http://cs.unc.edu/~ccwu/siftgpu [11 June 2013].
Wu, C. (2013a) Towards Linear-time Incremental Structure from Motion, 3D
Vision.
Wu, C. (2013b) VisualSFM: A Visual Structure from Motion System, 19 Feb,
[Online], Available:
http://homes.cs.washington.edu/~ccwu/vsfm/doc.html#gui [09 Sep 2013].
Wu, C., Agarwal, S., Curless, B. and Seitz, S.M. (2011) Multicore Bundle
Adjustment, IEEE Computer Society Conference on Computer Vision and
Pattern Recognition, 3057-3064.
Wu, C., Agarwal, S., Curless, B. and Seitz, S.M. (2012) Schematic Surface
Reconstruction, IEEE Computer Society Conference on Computer Vision
and Pattern Recognition, Providence, RI, USA.
V
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
A.1.1 R EFERENCE
One of the most frequently-cited texts in SfM projects and applications is
Richard Hartley and Andrew Zisserman’s (2003) textbook, Multiple View
Geometry, 2nd Edition. This textbook is the principal source of the theory and
equations displayed in this annex.
A-1
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
ψ = PΨ
Equation 12 - A finite projective camera is represented in SfM theory as a 3x4 projection
matrix P with 11 degrees of freedom (Hartley and Zisserman, 2003: 157).
This notation is adapted from Hartley and Zisserman (2003: 158). Note also
that the projected point Ψ’ is [Ψx, Ψy,cf] in the camera coordinate system (the
camera focal length cf is negative to preserve the orientation of the image; see
Figure 33). When these coordinates are divided through by cf then the
projected point is represented in homogeneous coordinates. P can be
factorized into components as in Equation 13.
( )
P = K c R [I | −t ]
Equation 13 - Decomposition of a finite projective camera matrix P.
A-2
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
c
(
Ψ = cR o Ψ − cO )
Equation 14 – A point in the scene can be expressed in the coordinate system of the
camera by subtracting the coordinates of the camera centre and then applying a rotation.
A-3
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
p in the image coordinate system and one or more parameters describing the
radial distortion of the image. The principal point p is the point on the image
plane intersected by the camera’s principal axis. For cameras with digital image
sensors, it is helpful to express the focal length cf as well as the image
coordinates of the principal point [px,py] in terms of the number of pixels, where
φ is the focal length in pixels (also called the scale factor), [x0,y0] are the
coordinates of the principal point p in pixels and m is the spatial resolution of the
sensor in pixels per unit length. While infrequent, there is a possibility in some
digital sensors that mx ≠ my. This implies that φx ≠ φy as in Equation 15. It will
also affect the coordinates [x0 y0] in pixels of p as in Equation 16.
[ϕ x ϕ y
T
] = f ⋅ [m
c
x m y]T
Equation 15 - Expression of the scale factors in the x and y directions in terms of number
of pixels by multiplying by the sensor's resolution in pixels per unit length.
[x0 y0 ] = p x
T
[ py ] [m
T
x y m ]
Equation 16 - Expression of the coordinates of the principal point in the image
coordinate system in units of pixels.
In addition, if the sensor axes are not orthogonal, a skew factor s must be
accounted for. The internal parameters contribute to the construction of the
matrix 3x3 matrix K as in Equation 17.
ϕ x s x0
K = ϕy y0
1
Equation 17 - Construction of the camera calibration matrix K from the internal
parameters.
A-4
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
of the distorted pixel from the centre of radial distortion [xc,yc]. According to
Hartley and Zisserman (2003: 190-191), the centre of radial distortion need not
be exactly the principal point, although this is a usual assumption. The
corrected coordinates of each pixel [ẋ, ẏ] can be determined:
L(r ) = 1 + κ 1r + κ 2 r 2 + K + κ n r n
Equation 19 - Taylor series expansion of the radial distortion function (Keikkilä and
Silvén, 1997).
( )
L ( r ) = 1 + κ ⋅ ( x − xc ) + ( y − y c ) ≈ 1 + κ 2 ⋅ r 2
2 2
In addition, because the focal lengths used in this dissertation were relatively
long, the use of κ = 0 (i.e., a pinhole camera model) in the specified calibration
is justified, especially since the British Aerospace Engineering (BAE) Systems
joint multi-mission electro-optical sensor (JMMES) medium-wavelength infrared
(MWIR) camera is a military-grade surveillance sensor (BAE Systems, 2012).
A-5
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
A-6
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
Figure 34 displays some of the contrasts and similarities between SfM and
metric photogrammetry.
A-7
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
Any point captured by two cameras lies on a plane defined by the two camera
centres and the point. The baseline is the line connecting the two camera
centres. It intersects each image at the epipole. The epipoles are hence the
image of the opposite camera’s centre on each image. The epipolar plane is
projected onto each image as a line, connecting the epipole and the image of
the defining point, and all such epipolar lines intersect the epipole (Hartley and
Zisserman, 2003). The epipolar geometry can be shown to give rise to one of
the most important concepts in two-view geometry: There exists a unique, rank
2, 3x3 matrix F, such that for all corresponding points x’ ↔ x’’:
A-8
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
The matrix F is termed the fundamental matrix and has several unique
properties.
Where fij are the individual elements of F. A least-squares solution for the
elements of F can be obtained using the singular value decomposition (SVD) of
A:
A = UDV T
Equation 23 – The solution for fij which minimizes the sum of squared errors is the last
column of V in the SVD of A (Hartley and Zisserman, 2003: 280).
A-9
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
P = [I | 0]
Equation 25 – A Simple, canonical camera located at the origin.
[
P' = [e']× F + e' vT | λe' ]
Equation 26 – General formula for a camera matrix P' given the fundamental matrix F and
corresponding camera at the origin.
F T e' = 0
Equation 27 - e' is the right null-vector of FT and can be obtained by solving for the null
T
space e’ = F \ [0 0 0]
0 − e'3 e '2
[e']× = e'3 0 − e'1
− e'2 e'1 0
Equation 28 – Construction of a skew-symmetric matrix based on the epipole e' of P'.
A-10
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
2
∑ = ∑ Pˆ i Xˆ j − x ij
2
xˆ ij − x ij
ij ij
Equation 30 – The reprojection error is the sum of squared distances between the
reprojected image points and measured image points (Hartley and Zisserman, 2003: 434).
This is done by varying the camera matrices and the positions of the
reprojected points. Since the computational cost of adjusting both the camera
matrices and the positions of the reprojected points is prohibitive for large
collections of images and points, a number of less-costly solutions are offered
by Hartley and Zisserman (2003). The computational method used by Wu
(2013a) in VisualSFM is to interleave the BA. The actual solution is achieved
by using preconditioned conjugate gradient (PCG) bundle adjustment (Wu et
al., 2011), and camera calibration is refined as images are added to the
reconstruction.
A-11
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
λiui = KR[I | t ]X i
Equation 31 – Relation between the decomposition of a camera matrix, which is defined
up to scale, and a reprojected point.
The use of this formula on a single view is tranditionally called the P3P problem,
wherein the rotation R and translation t of a camera are sought, when the
camera calibration K is known. The inverse of this problem is to solve for K
when R and t are known. Since R, t, Xi, and ui are known for at least i = 1…3
when three projected points are known, then this equation can be solved for the
camera calibration matrix K, and the camera calibration refined from initial
assumptions.
A.4 T RANSFORMATIONS
The following paragraphs summarize conventions and properties for the
transformations discussed in this research project.
X Transformed = RX Original + t
Equation 32 – Common way of representing Euclidean 3D transformations.
Where R is a rotation about the origin of the coordinate system. This makes the
transformation difficult to intuitively grasp, especially if the centroid of the
dataset is far from the coordinate system’s origin. Instead, Euclidean
transformations R,t are presented in this research project as:
A-12
A N N E X A: S T R U C T U R E FR O M M O TI O N T H E O R Y
sR t
Similarity 7
0T 1 • The Absolute Conic, Ω∞
R t
Euclidean 6
0T 1
• Volume
A-13
A N N E X B: I MA GE D A TA B A S E VBA C OD E
countImagesTotal = 0
countImagesSkipped = 0
countImagesNotSkipped = 0
Err_Form_Load:
MsgBox ("There has been an error.")
'Error Handlers
Resume Exit_Form_Load
End Sub
B-1
A N N E X B: I MA GE D A TA B A S E VBA C OD E
Dim p, u As String
Dim fs As Object
Dim batchFile, outputListFile As Object
Dim strOptions, strInput, strOutput, strPathUserData As String
Set fs = CreateObject("Scripting.FileSystemObject")
Set batchFile = fs.CreateTextFile(folderProject & "\" & folderInput & "\" & nameBatchFile &
".bat")
Set outputListFile = fs.CreateTextFile(folderProject & "\" & folderInput & "\" & nameBatchFile &
"_OutputList" & ".txt")
p = "cd " & Chr(34) & folderProject & Chr(34)
batchFile.Writeline p
p = ""
batchFile.Writeline p
imageList = Format(caseNumber, "000") & "_" & caseDetector & "_" & caseEstimation & "_" &
Format(caseImages, "0000")
If caseSpecifiedMatching Then
imageList = imageList & "_" & Format(casePairing, "000")
Else
imageList = imageList & "_XXX"
End If
pairList = imageList & ".match.txt"
gcplist = imageList & ".txt.gcp"
'__________________________________________________________________
' Deal with the strOptions String
strOptions = "cmd /c VisualSFM sfm"
' If there aren't enough images to ensure that each image is matched with the minimum
number of neightbours,
' Then actually perform full pairwise matching.
' Otherwise, use the pairs list.
'If caseSpecifiedMatching Then
strOptions = strOptions & "+import"
'End If
If caseEstimation = "Spec" Then
strOptions = strOptions & "+k=" & fixedCalibration
ElseIf caseEstimation = "Est_Shared" Then
strOptions = strOptions & "+shared"
End If
strOptions = strOptions & "+sort+gcp"
'__________________________________________________________________
' Deal with the strInput String
strInput = imageList & ".txt"
'__________________________________________________________________
' Deal with the strOutput String
strOutput = folderProject & "\" & folderOutput & "\" & imageList & ".nvm"
'__________________________________________________________________
' Deal with the strPathUserData String
strPathUserData = pairList
B-2
A N N E X B: I MA GE D A TA B A S E VBA C OD E
'__________________________________________________________________
' Write a command to move the three list files to the VisualSFM directory.
p = "move /y " & folderProject & "\" & folderInput & "\" & imageList & "*.* " &
folderProject
batchFile.Writeline p
'__________________________________________________________________
' Write the line to the batch file.
p = strOptions & " " & strInput & " " & strOutput
'If caseSpecifiedMatching Then
p = p & " " & strPathUserData
'End If
batchFile.Writeline p
'__________________________________________________________________
' Write the line to the output list file.
u = strOutput
outputListFile.Writeline u
'__________________________________________________________________
' Write a command to move the three list files back to the Input directory.
p = "move /y " & folderProject & "\" & imageList & "*.* " & folderProject & "\" &
folderInput
batchFile.Writeline p
'Now Write the image List, Pairs List and gcp List to the Input Folder...
WriteLists
Else
'Do nothing for now.
End If
rsCases.MoveNext
Loop
rsCases.Close
p = "pause"
batchFile.Writeline p
outputListFile.Close
batchFile.Close
Exit_Btn_WriteFiles_Click:
MsgBox ("Starting the Exit Sub Routine.")
' Set all private variables to nothing now (if they still exist)
Set rsCases = Nothing
Exit Sub
Err_Btn_WriteFiles_Click:
MsgBox ("There has been an error.")
'Error Handlers
Resume Exit_Btn_WriteFiles_Click
End Sub
B-3
A N N E X B: I MA GE D A TA B A S E VBA C OD E
u = rsImages("ID")
imageListSimple.Writeline u
r = rsImages("ImageName") & " " & Format(rsImages("POINT_X"), "0.0000") & " " &
Format(rsImages("POINT_Y"), "0.0000") & " " & Format(rsImages("POINT_Z"), "0.0000") & " "
gcpListFile.Writeline r
imageNames(imagesListed) = q
imagesListed = imagesListed + 1
skipCounter = skipCounter - 1 + skipFactor
Else
'Exits the loop
Exit Do
End If
Else
skipCounter = skipCounter - 1
End If
rsImages.MoveNext
Loop
rsImages.Close
imageListSimple.Close
gcpListFile.Close
imageListFile.Close
If caseSpecifiedMatching Then
Set pairListFile = fs.CreateTextFile(folderProject & "\" & folderInput & "\" & pairList)
' For every image file listed in the previous files, take a few images before and after in
sequence. These are image pairs.
' The variable i represents the image being paired, and j is the rover pairing with a set
number of images before and after the
' current image.
For i = 0 To imagesListed - 1
s = imageNames(i)
For j = 1 To casePairing
If i + j >= imagesListed Then
t = imageNames(i - imagesListed + j)
Else
t = imageNames(i + j)
End If
pairListFile.Writeline s & " " & t & " "
Next j
Next i
pairListFile.Close
End If
Exit_WriteLists:
'MsgBox ("Starting the Exit Sub Routine.")
' Set all private variables to nothing now (if they still exist)
Set rsImages = Nothing
Exit Sub
Err_WriteLists:
MsgBox ("There has been an error.")
'Error Handlers
Resume Exit_WriteLists
End Sub
B-4
A N N E X B: I MA GE D A TA B A S E VBA C OD E
End If
Else
'MsgBox (" Skipped a record. k and l are: " & k & ", " & l)
End If
rsImages.MoveNext
Loop
rsImages.Close
Set rsImages = Nothing
Set fs = CreateObject("Scripting.FileSystemObject")
Set batchASIFT = fs.CreateTextFile("D:\Colpitts\Project\Software\demo_ASIFT\" & "Batch_RunASIFT"
& ".bat")
m = 0
For m = 0 To binMax - 1
u = Format(imageIndex(0, m), "0000")
v = Format(imageIndex(1, m), "0000")
batchASIFT.Writeline "ASIFT.exe .\png\" & u & ".png .\png\" & v & ".png vert.png horz.png
matchings.txt .\png\" & u & ".sift .\png\" & v & ".sift"
u = Format(imageIndex(2, m), "0000")
v = Format(imageIndex(3, m), "0000")
batchASIFT.Writeline "ASIFT.exe .\png\" & u & ".png .\png\" & v & ".png vert.png horz.png
matchings.txt .\png\" & u & ".sift .\png\" & v & ".sift"
u = Format(imageIndex(4, m), "0000")
v = Format(imageIndex(5, m), "0000")
batchASIFT.Writeline "ASIFT.exe .\png\" & u & ".png .\png\" & v & ".png vert.png horz.png
matchings.txt .\png\" & u & ".sift .\png\" & v & ".sift"
u = Format(imageIndex(6, m), "0000")
v = Format(imageIndex(7, m), "0000")
batchASIFT.Writeline "ASIFT.exe .\png\" & u & ".png .\png\" & v & ".png vert.png horz.png
matchings.txt .\png\" & u & ".sift .\png\" & v & ".sift"
Next m
batchASIFT.Writeline ""
batchASIFT.Writeline "pause"
batchASIFT.Close
End Sub
startnum = 1
chunksize = 100
chunkstart = startnum
chunkend = chunkstart + chunksize - 1
endnum = 7539
i = startnum
j = 1
Set fs = CreateObject("Scripting.FileSystemObject")
Set batchConvert = fs.CreateTextFile("D:\Colpitts\Project\Software\VisualSFM\Batch" &
Format(startnum, "0000") & "-" & Format(endnum, "0000") & "batchConvert" & ".bat")
batchConvert.Writeline "cd D:\Colpitts\Project\Software\VisualSFM\"
batchConvert.Writeline ""
B-5
A N N E X B: I MA GE D A TA B A S E VBA C OD E
Else
Exit For
End If
Next j
listfile.Close
batchConvert.Writeline "cmd /c VisualSFM sfm+nomatch+skipsfm " & Format(chunkstart, "0000") &
"-" & Format(chunkend, "0000") & ".txt output.nvm"
batchConvert.Writeline ""
batchConvert.Writeline "pause"
batchConvert.Close
End Sub
End Sub
B-6
A N N E X C: SURF F E A TU R E E X T R A C TI O N AND M A TC H I N G M A TL A B ® C O D E
C-1
A N N E X C: SURF F E A TU R E E X T R A C TI O N AND M A TC H I N G M A TL A B ® C O D E
load([pname_variable,fname_matcharray_done],'matcharray_done');
else matcharray_done = false(nimage_all); end
if exist_surfvect_reqr
disp('Loading the surfvect_reqr variable.');
load([pname_variable,fname_surfvect_reqr],'surfvect_reqr');
else surfvect_reqr = []; end
if exist_surfvect_done
disp('Loading the surfvect_done variable.');
load([pname_variable,fname_surfvect_done],'surfvect_done');
else surfvect_done = false(nimage_all,1); end
if exist_feature
disp('Loading the feature variable.');
load([pname_variable,fname_feature],'feature');
else feature = cell(nimage_all,1); end
if exist_validpoint
load([pname_variable,fname_validpoint],'validpoint');
else validpoint = cell(nimage_all,1); end
if exist_matchindex
disp('Loading the matchindex variable.');
load([pname_variable,fname_matchindex],'matchindex');
else matchindex = []; end
listcase.Case_Number = Buf{1,1};
listcase.Images = Buf{1,2};
listcase.Detector = Buf{1,3};
listcase.Focal_Estimation = Buf{1,4};
listcase.Matching = Buf{1,5};
listcase.Pair = Buf{1,6};
listcase.Name = Buf{1,7};
clear Buf;
if ~exist_matcharray_reqr
% Rebuild the matcharray_reqr variable
disp('Rebuilding the matcharray_reqr variable.');
ncase = size(listcase.Case_Number,1);
for i = 1:ncase
fname_list = listcase.Name{i,1};
[fid_list,Msg] = fopen([pname_list,fname_list],'rt');
if fid_list == -1, error(Msg); end
clear Msg;
listimg = textscan(fid_list,'%u\n');
fclose(fid_list);
listimg = listimg{1,1};
colsize = size(listimg,1);
if strcmp(listcase.Matching{i,1},'Full')
for j = 1:colsize
for k = 1:j
if listimg(j,1) == listimg(k,1)
% do nothing
else
matcharray_reqr(listimg(j,1),listimg(k,1)) = true;
matcharray_reqr(listimg(k,1),listimg(j,1)) = true;
end
end
end
else
% Build listimg into an array of matches, where the first column is
% the left match and the remaining columns are the right match.
for j = 2:listcase.Pair(i,1) + 1
nextcol = zeros(colsize,1);
C-2
A N N E X C: SURF F E A TU R E E X T R A C TI O N AND M A TC H I N G M A TL A B ® C O D E
nextcol(1:end-1,1) = listimg(2:end,j-1);
nextcol(end,1) = listimg(1,j-1);
listimg = [listimg,nextcol];
end
% Now cycle through the match list and set the image pairs in the
% matcharray_reqr to true
for j = 1:colsize
for k = 2:listcase.Pair(i,1) + 1
matcharray_reqr(listimg(j,1),listimg(j,k)) = true;
matcharray_reqr(listimg(j,k),listimg(j,1)) = true;
end
end
end
end
% Now save the matcharray_reqr variable
save([pname_variable,fname_matcharray_reqr],'matcharray_reqr');
end
fclose('all');
clear ans;
clear colsize;
clear fid_list;
clear listimg;
clear ncase;
clear nextcol;
C-3
A N N E X C: SURF F E A TU R E E X T R A C TI O N AND M A TC H I N G M A TL A B ® C O D E
exist_surf_reqr = false;
surfvect_done(i,1) = false;
end
end
end
if ~exist_surf_reqr
disp('There are also missing surf files.');
end
csurf = 0;
% Now perform the missing feature extractions
if ~((nsurf_pend == 0) && exist_surf_reqr && exist_surfvect_done && exist_feature &&
exist_validpoint)
for i = 1:nimage_all
if surfvect_reqr(i,1)
fname_image = [num2str(i,format_num),'.jpg'];
if ~surfvect_done(i,1)
csurf = csurf + 1;
disp(['SURF extraction # ',num2str(csurf),' of ',num2str(nsurf_pend),' on image:
',fname_image]);
pixel = rgb2gray(imread([pname_image,fname_image]));
point = detectSURFFeatures(pixel);
[feature{i,1},validpoint{i,1}] = extractFeatures(pixel,point);
if ~exist_surf_file(i,1)
fname_surf = [num2str(i,format_num),'.sift'];
npoint = size(validpoint{i,1},1);
[fid_surf] = fopen([pname_surf,fname_surf],'wt');
if fid_surf == -1, error(Msg); end
clear Msg;
fprintf(fid_surf,'%u\n',npoint);
fprintf(fid_surf,'%u\n',128);
for j = 1:npoint
% Remove these two corrections if they are found to not be necessary
% The first correction changes the image coordinate system to match
% Lowe's (2004) output.
% The second correction just ensures that the orientation is in the
% range -pi to pi
loc = validpoint{i,1}(j,1).Location;
loc_x = loc(1,1);
loc_y = loc(1,2);
fprintf(fid_surf,format_point,...
loc_x,...
loc_y,... % first correction
validpoint{i,1}(j,1).Scale,...
rem(validpoint{i,1}(j,1).Orientation+pi,2*pi)-pi); % corr 2
fprintf(fid_surf,format_feat,zeros_feat);
end
fclose(fid_surf);
end
surfvect_done(i,1) = true;
else
disp(['SURF extraction on image: ',fname_image,' is reported as complete.
Skipping.']);
end
end
end
% Now save the surfvect_done, feature and validpoint variables
disp('Saving the surfvect_done variable.');
save([pname_variable,fname_surfvect_done],'surfvect_done');
disp('Saving the feature variable.');
save([pname_variable,fname_feature],'feature');
disp('Saving the validpoint variable.');
save([pname_variable,fname_validpoint],'validpoint');
end
fclose('all');
clear ans;
clear csurf;
clear fid_surf;
clear loc;
clear loc_x;
clear loc_y;
clear pixel;
C-4
A N N E X C: SURF F E A TU R E E X T R A C TI O N AND M A TC H I N G M A TL A B ® C O D E
clear point;
cmatch = 0;
cmatch_bin = 0;
cmatch_binsize = 10000;
% Now actually perform the matching and output to an index
if (nmatch_pend > 0) && do_matching
for i = 1:nimage_all
if surfvect_reqr(i,1)
disp_line = true;
for j = 1:i
if matcharray_reqr(i,j)
cmatch = cmatch + 1;
cmatch_bin = cmatch_bin + 1;
if ~matcharray_done(i,j)
if disp_line
disp(['Match # ',num2str(cmatch),' of ',num2str(nmatch_reqr),' with images:
',num2str(i),' & ',num2str(j)]);
disp_line = false;
end
matchindex{cmatch,2} = matchFeatures(feature{i,1},feature{j,1},'Prenormalized',
true) - 1;
matchindex{cmatch,1} = [i,j,size(matchindex{cmatch,2},1)];
else
if disp_line
disp(['Match # ',num2str(cmatch),' of ',num2str(nmatch_reqr),' with images:
',num2str(i),' & ',num2str(j),' is already stored. Skipping']);
disp_line = false;
end
end
matcharray_done(i,j) = true;
if cmatch_bin >= cmatch_binsize
cmatch_bin = 0;
% Now back-up the matchindex and the matcharray_done
disp('Saving mathindex.');
save([pname_variable,fname_matchindex],'matchindex');
disp('Saving matcharray_done.');
save([pname_variable,fname_matcharray_done],'matcharray_done');
end
end
end
end
end
% Now save matchindex and matcharray_done
disp('Saving the mathindex variable.');
save([pname_variable,fname_matchindex],'matchindex');
disp('Saving matcharray_done variable.');
save([pname_variable,fname_matcharray_done],'matcharray_done');
end
clear cmatch;
clear do_matching;
clear cmatch_bin;
clear cmatch_binsize;
clear disp_line;
C-5
A N N E X C: SURF F E A TU R E E X T R A C TI O N AND M A TC H I N G M A TL A B ® C O D E
clear fname_image;
clear fname_list;
clear fname_match;
clear fname_matcharray_done;
clear fname_matcharray_reqr;
clear fname_matchindex;
clear fname_surf;
clear fname_ surfvect_done;
clear fname_surfvect_reqr;
clear fname_validpoint;
clear format_csv_field;
clear format_csv_header;
clear format_feat;
clear format_header;
clear format_imghead;
clear format_index;
clear format_point;
clear i;
clear j;
clear k;
clear match_reciprocal;
clear nimage_all;
clear nmatch_done;
clear nmatch_pend;
clear nmatch_reqr;
clear npoint;
clear nsurf_done;
clear nsurf_reqr;
clear overwrite_surf;
clear pname_csv;
clear rematch;
clear zerod_feat;
fclose('all');
clear ans;
C-6
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
disp('Set up parameters.')
[param] = setparam(element_ref);
% 1) Reads a list of filenames and paths to open nvm files and save plys
% also sets up the record structure for recording the performance of each
% model.
disp('Get List and set up record structure.')
[listcase,record] = setlist(param);
% <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
% Now open the loop:
disp('Open the loop.')
for i = 1:listcase.numcase
% Reset element_in
element_in = [];
record.glbl.point(i,1) = 0;
record.glbl.dirstat.mean.x(i,1) = 0;
record.glbl.dirstat.mean.y(i,1) = 0;
record.glbl.dirstat.mean.z(i,1) = 0;
record.glbl.dirstat.var.x(i,1) = 0;
record.glbl.dirstat.var.y(i,1) = 0;
D-1
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
record.glbl.dirstat.var.z(i,1) = 0;
record.glbl.adjust.offset_x(i,1) = 0;
record.glbl.adjust.offset_y(i,1) = 0;
record.glbl.adjust.offset_z(i,1) = 0;
record.glbl.adjust.icp.rmse.first(i,1) = 0;
record.glbl.adjust.icp.rmse.last(i,1) = 0;
if size(element_in.vertex.x,1) < 10
% Code to skip the rest of the loop.
disp('Reconstruction NOT successful.')
record.success(i,1) = false;
else
% 5) Reads the tie point vertical values from the reference data
% 6) Reads the tie point vertical values from the nvm file
% 8) Calculates the vertical offset and adjusts the nvm height values
disp('Get tie point height values.')
[param.tiepoint.in.coord_z{i,1},...
param.tiepoint.in.vect_logic{i,1}] = tiezval(element_in,param);
if any(param.tiepoint.in.vect_logic{i,1})
tiept_z = param.tiepoint.in.coord_z{i,1};
vect_logic = param.tiepoint.in.vect_logic{i,1};
% Find the overall offset by averageing the tie points
record.glbl.adjust.offset_z(i,1) = mean(...
param.tiepoint.ref.coord_z(vect_logic) - ...
tiept_z(vect_logic));
% Apply the height adjustment to the input data.
disp('Apply the height adjustment to the input data.')
element_in.vertex.z = ...
element_in.vertex.z + record.glbl.adjust.offset_z(i,1);
clear tiept_z;
clear vect_logic;
% Brute Force Horizontal Alignment
% This algorithm tries to align the model to the data in both the x
% and y directions at the same time. It starts with the x
% direction because that is typically worse than the y direction,
% then it moves to the y direction, in both cases moving the window
% before finding a local minima, adjusting the window size and then
% switching axes
disp('Attempting Brute Force Horizontal Bracketing Alignment.')
xguess = param.alignwindow.xguess;
xrange = param.alignwindow.xrange;
xprecis = param.alignwindow.xprecis;
yguess = param.alignwindow.yguess;
yrange = param.alignwindow.yrange;
yprecis = param.alignwindow.yprecis;
dist = zeros(3,1);
% This variable tells us whether the algorith is currently
% searching along the X direction or the y direction
x_or_y = true; % true for x, false for y
while (xrange > xprecis) || (yrange > yprecis)
% Starting positions for the x and y offsets
if x_or_y % true for x, false for y
yoffset = yguess;
str = sprintf(['The xguess is: ',num2str(xguess),'m. The xrange is:
',num2str(xrange),'m.']);
disp(str);
else
xoffset = xguess;
str = sprintf(['The yguess is: ',num2str(yguess),'m. The yrange is:
',num2str(yrange),'m.']);
disp(str);
end
for j = 1:3
if x_or_y % true for x, false for y
xoffset = xguess + (j - 2) * xrange;
else
yoffset = yguess + (j - 2) * yrange;
end
% Replicate element_in
element_br = element_in;
% Apply the current guess to the model.
element_br.vertex.x = element_br.vertex.x + xoffset;
element_br.vertex.y = element_br.vertex.y + yoffset;
% Trim and the element structure to the desired extents
element_br = meshtrim(element_br,param);
[~,distvect] = knnsearch(param.NS,...
[element_br.vertex.x,...
element_br.vertex.y,...
element_br.vertex.z],...
'K',1,'Distance','euclidean','IncludeTies',false);
D-2
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
distvect = distvect(1:len);
D-3
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
repmat(record.glbl.adjust.icp.vect_t{i,1},m,1) +...
repmat(model_bar,m,1);
element_in.vertex.x = model(:,1);
element_in.vertex.y = model(:,2);
element_in.vertex.z = model(:,3);
clear model;
clear m;
clear model_bar;
clear model_centred;
% Try to trim the mesh now; if there are no points in the mesh,
% then it's not successful;
element_tr = meshtrim(element_in,param);
if size(element_tr.vertex.x,1) < 10
% Code to skip the rest of the loop.
disp('Reconstruction NOT successful.')
record.success(i,1) = false;
end
if record.success(i,1)
% Trim and the nvm for the desired extents
disp('Trim the input mesh.')
element_in = meshtrim(element_in,param);
% Directional statistics
disp('Generate directional statistics.')
record.glbl.dirstat.mean.x(i,1) = mean(element_in.vertex.x);
record.glbl.dirstat.mean.y(i,1) = mean(element_in.vertex.y);
record.glbl.dirstat.mean.z(i,1) = mean(element_in.vertex.z);
record.glbl.dirstat.var.x(i,1) = var(element_in.vertex.x);
record.glbl.dirstat.var.y(i,1) = var(element_in.vertex.y);
record.glbl.dirstat.var.z(i,1) = var(element_in.vertex.z);
if record.success(i,1)
% Now write a new ply file, but with colours ranging from blue
% (close) to yellow (far) closest point distance.
vect_dist = [];
vect_logic_low = [];
vect_logic_high = [];
D-4
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
vect_red = [];
vect_green = [];
vect_blue = [];
rise_red = 255;
rise_green = 255;
rise_blue = -255;
run = high - low;
a_red = rise_red / run;
a_green = rise_green / run;
a_blue = rise_blue / run;
b_red = 0;
b_green = 0;
b_blue = 255;
vect_dist = neardist;
vect_logic_low = (vect_dist <= low);
vect_logic_high = (vect_dist >= high);
vect_logic_mid = ~any([vect_logic_low,vect_logic_high],2);
vect_red = element_in.vertex.diffuse_red;
vect_green = element_in.vertex.diffuse_green;
vect_blue = element_in.vertex.diffuse_blue;
% 16) Now write all RECORDS to an output CSV file with proper headers
D-5
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
format_field = [repmat('%s,',1,31),'%s\n'];
fprintf(fid_output_main,format_field,...
param.format.output.csv.main.fieldname{1,:});
clear format_field;
nrows = size(listcase.casenumber,1);
for j = 1:nrows
fprintf(fid_output_main,param.format.output.csv.main.data,...
listcase.casenumber(j,1),...
listcase.imagecount(j,1),...
listcase.detector{j,1},...
listcase.estimation{j,1},...
listcase.matching{j,1},...
listcase.pair(j,1),...
record.success(j,1),...
record.centroidcorr(j,1),...
record.glbl.point(j,1),...
record.glbl.dirstat.mean.x(j,1),...
record.glbl.dirstat.mean.y(j,1),...
record.glbl.dirstat.mean.z(j,1),...
record.glbl.dirstat.var.x(j,1),...
record.glbl.dirstat.var.y(j,1),...
record.glbl.dirstat.var.z(j,1),...
record.glbl.adjust.offset_x(j,1),...
record.glbl.adjust.offset_y(j,1),...
record.glbl.adjust.offset_z(j,1),...
record.glbl.adjust.icp.rmse.first(j,1),...
record.glbl.adjust.icp.rmse.last(j,1),...
record.glbl.adjust.icp.mat_r{j,1}(1,1),...
record.glbl.adjust.icp.mat_r{j,1}(1,2),...
record.glbl.adjust.icp.mat_r{j,1}(1,3),...
record.glbl.adjust.icp.mat_r{j,1}(2,1),...
record.glbl.adjust.icp.mat_r{j,1}(2,2),...
record.glbl.adjust.icp.mat_r{j,1}(2,3),...
record.glbl.adjust.icp.mat_r{j,1}(3,1),...
record.glbl.adjust.icp.mat_r{j,1}(3,2),...
record.glbl.adjust.icp.mat_r{j,1}(3,3),...
record.glbl.adjust.icp.vect_t{j,1}(1,1),...
record.glbl.adjust.icp.vect_t{j,1}(1,2),...
record.glbl.adjust.icp.vect_t{j,1}(1,3)...
);
end
fclose(fid_output_main);
clear nrows;
clear j;
clear fid_output_main;
% 16) Now write all dist vectors to an output CSV file with proper headers
% Obtain the format for the field name
for k = 1:(size(listcase.casenumber,1)-1)
param.format.output.csv.dist.fieldname = [...
param.format.output.csv.dist.fieldname,'%s,'];
param.format.output.csv.dist.data = [...
param.format.output.csv.dist.data,'%4.6f,'];
end
clear k;
param.format.output.csv.dist.fieldname = [...
param.format.output.csv.dist.fieldname,'%s\n'];
param.format.output.csv.dist.data = [...
param.format.output.csv.dist.data,'%4.6f\n'];
fprintf(fid_output_dist,param.format.output.csv.dist.fieldname,...
listcase.fname_load{:,1});
cell_casepoint = [];
cell_casepoint = mat2cell(record.glbl.point',[1],repmat([1],1,size(record.glbl.point,1)));
fprintf(fid_output_dist,param.format.output.csv.dist.data,...
cell_casepoint{1,:});
clear cell_casepoint;
D-6
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
ncol = size(record.glbl.point,1);
for i = 1:ncol
neardistlen(i,1) = size(record.glbl.qual.neardist{i,1},1);
end
nrow = max(neardistlen);
mat_out = zeros(nrow,ncol);
for i = 1:ncol
mat_out(1:neardistlen(i,1),i) = record.glbl.qual.neardist{i,1};
end
clear neardistlen;
for i = 1:nrow
fprintf(fid_output_dist,...
param.format.output.csv.dist.data,mat_out(i,:));
end
clear i;
clear nrow;
clear ncol;
clear mat_out;
fclose(fid_output_dist);
clear fid_output_dist;
end
% >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
param = setfield(param,'cpoly',[]);
param.cpoly = setfield(param.cpoly,'coord_x1',[]);
param.cpoly = setfield(param.cpoly,'coord_y1',[]);
param.cpoly = setfield(param.cpoly,'coord_x2',[]);
param.cpoly = setfield(param.cpoly,'coord_y2',[]);
D-7
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
param.cpoly = setfield(param.cpoly,'A',[]);
param.cpoly = setfield(param.cpoly,'B',[]);
param.cpoly = setfield(param.cpoly,'C',[]);
param = setfield(param,'alpha',[]);
param = setfield(param,'format',[]);
param.format = setfield(param.format,'list',[]);
param.format.list = setfield(param.format.list,'fieldname',[]);
param.format.list = setfield(param.format.list,'line',[]);
param.format = setfield(param.format,'output',[]);
param.format.output = setfield(param.format.output,'ply',[]);
param.format.output = setfield(param.format.output,'csv',[]);
param.format.output.csv = setfield(param.format.output.csv,'main',[]);
param.format.output.csv.main = setfield(param.format.output.csv.main,'fieldname',[]);
param.format.output.csv.main = setfield(param.format.output.csv.main,'data',[]);
param.format.output.csv.main = setfield(param.format.output.csv.main,'pname_save',[]);
param.format.output.csv.main = setfield(param.format.output.csv,'fname_save',[]);
param.format.output.csv = setfield(param.format.output.csv,'dist',[]);
param.format.output.csv.dist = setfield(param.format.output.csv.dist,'fieldname',[]);
param.format.output.csv.dist = setfield(param.format.output.csv.dist,'data',[]);
param.format.output.csv.dist = setfield(param.format.output.csv.dist,'pname_save',[]);
param.format.output.csv.dist = setfield(param.format.output.csv.dist,'fname_save',[]);
param = setfield(param,'alignwindow',[]);
param.alignwindow = setfield(param.alignwindow,'xguess',[]);
param.alignwindow = setfield(param.alignwindow,'xrange',[]);
param.alignwindow = setfield(param.alignwindow,'xprecis',[]);
param.alignwindow = setfield(param.alignwindow,'yguess',[]);
param.alignwindow = setfield(param.alignwindow,'yrange',[]);
param.alignwindow = setfield(param.alignwindow,'yprecis',[]);
param.alignwindow = setfield(param.alignwindow,'zguess',[]);
param.alignwindow = setfield(param.alignwindow,'zrange',[]);
param.alignwindow = setfield(param.alignwindow,'zprecis',[]);
param = setfield(param,'xsect',[]);
param.xsect = setfield(param.xsect,'stripwidth',[]);
param.xsect = setfield(param.xsect,'idw_pow',[]);
param.xsect = setfield(param.xsect,'changethresh',[]);
param.xsect = setfield(param.xsect,'xdir',[]);
param.xsect.xdir = setfield(param.xsect.xdir,'ycoord',[]);
param.xsect.xdir = setfield(param.xsect.xdir,'refsect',[]);
param.xsect.xdir = setfield(param.xsect.xdir,'refchange',[]);
param.xsect = setfield(param.xsect,'ydir',[]);
param.xsect.ydir = setfield(param.xsect.ydir,'xcoord',[]);
param.xsect.ydir = setfield(param.xsect.ydir,'refsect',[]);
param.xsect.ydir = setfield(param.xsect.ydir,'refchange',[]);
% param = setfield(param,'DT',[]); %Place holder for a Delaunay triangulation
% of the reference data.
param = setfield(param,'NS',[]); % Place holder for a KNN search object of
% the reference data.
param = setfield(param,'icp',[]);
param.icp = setfield(param.icp,'max_iter',[]);
param.icp = setfield(param.icp,'max_rmse_change',[]);
[param.tiepoint.ref.coord_z,...
param.tiepoint.ref.vect_logic] = tiezval(element_ref,param);
if ~all(param.tiepoint.ref.vect_logic)
error('Not all tie points contain reference data!!!')
end
% These are the points defining the lines on the convex polygon which is
% used to constrain the scope of the data.
param.cpoly.coord_x1 = ...
[432.281086999981;
520.916690999991;
D-8
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
447.045187000011;
358.409583];
param.cpoly.coord_y1 = ...
[32001.9688919996;
31961.6198899997;
31799.3447820004;
31839.6937840003];
param.format.output.csv.main.pname_save = ...
D-9
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
'D:\Colpitts\Project\Software\Matlab\readply\Output\';
param.format.output.csv.main.fname_save = ...
'output_main.csv';
param.format.output.csv.dist.pname_save = ...
'D:\Colpitts\Project\Software\Matlab\readply\Output\';
param.format.output.csv.dist.fname_save = ...
'output_dist.csv';
param.icp.max_iter = 100;
param.icp.max_rmse_change = 0.00005;
% Create a nearest-neighbours search object
ticID_SearchObject = tic;
disp('Create a nearest-neighbours search object.');
param.NS = createns(...
[element_ref.vertex.x,...
element_ref.vertex.y,...
element_ref.vertex.z],...
'NSMethod','kdtree',...
'Distance','euclidean',...
'BucketSize',50);
elapsedTime_SearchObject = toc(ticID_SearchObject);
disp(['Elapsed time: ',num2str(elapsedTime_SearchObject,2)]);
clear elapsedTime_SearchObject;
% param.xsect.xdir.ycoord = 31902;
% param.xsect.ydir.xcoord = 448;
% param.xsect.stripwidth = 2;
% param.xsect.idw_pow = 3;
% param.xsect.changethresh = 2;
% % Create the reference cross sections and the change section.
% ticID_RefSect = tic;
% disp('Get the reference sections.');
% elapsedTime_RefSect = toc(ticID_RefSect);
% disp(['Elapsed time: ',num2str(elapsedTime_RefSect,2)]);
param.alignwindow.xguess = 0;
param.alignwindow.xrange = 64;
param.alignwindow.xprecis = 0.25;
param.alignwindow.yguess = 0;
param.alignwindow.yrange = 64;
param.alignwindow.yprecis = 0.25;
param.alignwindow.zguess = -40;
param.alignwindow.zrange = 128;
param.alignwindow.zprecis = 0.25;
end
% >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
% Structure to store the list that will be read from the csv.
listcase = [];
listcase = setfield(listcase,'fieldname',[]);
listcase = setfield(listcase,'casenumber',[]);
listcase = setfield(listcase,'pname_load',[]);
listcase = setfield(listcase,'fname_load',[]);
listcase = setfield(listcase,'ftype_load',[]);
listcase = setfield(listcase,'pname_save',[]);
listcase = setfield(listcase,'fname_save',[]);
listcase = setfield(listcase,'pname_imagesave_top',[]);
listcase = setfield(listcase,'fname_imagesave_top',[]);
listcase = setfield(listcase,'imagecount',[]);
listcase = setfield(listcase,'detector',[]);
listcase = setfield(listcase,'estimation',[]);
listcase = setfield(listcase,'matching',[]);
listcase = setfield(listcase,'pair',[]);
listcase = setfield(listcase,'numcase',[]); % The total number of cases.
D-10
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
listcase.fieldname = textscan(...
fid_list,param.format.list.fieldname,1,'delimiter',',');
Buf = textscan(fid_list,param.format.list.line,'delimiter',',');
fclose(fid_list);
clear fid_list;
clear ans;
listcase.casenumber = Buf{1,1};
listcase.pname_load = Buf{1,2};
listcase.fname_load = Buf{1,3};
listcase.ftype_load = Buf{1,4};
listcase.pname_save = Buf{1,5};
listcase.fname_save = Buf{1,6};
listcase.pname_coloursave = Buf{1,7};
listcase.fname_coloursave = Buf{1,8};
listcase.imagecount = Buf{1,9};
listcase.detector = Buf{1,10};
listcase.estimation = Buf{1,11};
listcase.matching = Buf{1,12};
listcase.pair = Buf{1,13};
listcase.numcase = size(listcase.casenumber,1);
clear Buf;
record.glbl = setfield(record.glbl,'dirstat',[]);
record.glbl.dirstat = setfield(record.glbl.dirstat,'mean',[]);
record.glbl.dirstat.mean = setfield(record.glbl.dirstat.mean,'x',[]);
record.glbl.dirstat.mean = setfield(record.glbl.dirstat.mean,'y',[]);
record.glbl.dirstat.mean = setfield(record.glbl.dirstat.mean,'z',[]);
record.glbl.dirstat.mean = setfield(record.glbl.dirstat.mean,'neardist',[]);
record.glbl.dirstat = setfield(record.glbl.dirstat,'var',[]);
record.glbl.dirstat.var = setfield(record.glbl.dirstat.var,'x',[]);
record.glbl.dirstat.var = setfield(record.glbl.dirstat.var,'y',[]);
record.glbl.dirstat.var = setfield(record.glbl.dirstat.var,'z',[]);
record.glbl.dirstat.var = setfield(record.glbl.dirstat.var,'neardist',[]);
record.glbl = setfield(record.glbl,'adjust',[]);
record.glbl.adjust = setfield(record.glbl.adjust,'offset_x',[]);
record.glbl.adjust = setfield(record.glbl.adjust,'offset_y',[]);
record.glbl.adjust = setfield(record.glbl.adjust,'offset_z',[]);
record.glbl.adjust = setfield(record.glbl.adjust,'icp',[]);
record.glbl.adjust.icp = setfield(record.glbl.adjust.icp,'mat_r',[]);
record.glbl.adjust.icp = setfield(record.glbl.adjust.icp,'vect_t',[]);
record.glbl.adjust.icp = setfield(record.glbl.adjust.icp,'rmse',[]);
record.glbl.adjust.icp.rmse = setfield(record.glbl.adjust.icp.rmse,'first',[]);
record.glbl.adjust.icp.rmse = setfield(record.glbl.adjust.icp.rmse,'last',[]);
record.glbl = setfield(record.glbl,'qual',[]);
record.glbl.qual = setfield(record.glbl.qual,'neardist',[]);
record.glbl.qual = setfield(record.glbl.qual,'hausdorff',[]);
record = setfield(record,'section',[]);
record.section = setfield(record.section,'denscorr',[]);
record.section = setfield(record.section,'hausdorff',[]);
record = setfield(record,'visualize',[]);
record.visualize = setfield(record.visualize,'neardist',[]);
record.visualize.neardist = setfield(record.visualize.neardist,'lowval',[]);
record.visualize.neardist = setfield(record.visualize.neardist,'highval',[]);
end
D-11
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
% rotation and translation would you have to apply to a model about its
% own centroid such that the model best fit the data?
%
% model_new = (R * (model - model_bar) + t) + model_bar
%
% In this arguably more intuitive notation, the translation vector is
% simply the discrepancy between the model centroid and the data.
%
% Such that the error function:
%
% E = SUM( Wi * Di )
%
% is minimised, where Wi are the individual point weights and Di are the
% distances between the model points and the nearest data point.
%
% In order for the error function to represent the sum of SQUARED
% distance, I have chosen than Wi = Di so that each point is scaled again
% by its distance from the closest model point, yielding a sum-of-squares
% error function. This supposition appears to work well during the rough
% alignment.
% Initialisations
RT = eye(3);
tT = zeros(1,3);
rmse_vect = zeros(param.icp.max_iter,1);
model_orig = [element_in.vertex.x,...
element_in.vertex.y,...
element_in.vertex.z];
data_orig = [element_ref.vertex.x,...
element_ref.vertex.y,...
element_ref.vertex.z];
% Finds the model centroid and the deviations from the centroid These can
% be saved and used in subsequent interations
m_orig = size(model_orig,1);
model_bar_orig = mean(model_orig,1);
model_centred_orig = model_orig - repmat(model_bar_orig,m_orig,1);
i = 1;
stop_iter = false;
while ~stop_iter
element_iter = element_in;
model = [element_iter.vertex.x,...
element_iter.vertex.y,...
element_iter.vertex.z];
end
% Perform matching
[idx_ref,dist] = knnsearch(param.NS,model,...
'K',1,'Distance','euclidean','IncludeTies',false);
idx_model = true(size(model,1),1);
D-12
A N N E X D: P OI N T C L OU D A N A L Y S I S M A TL A B ® C O D E
else
rmse_first = rmse_vect(i,1);
end
model = model(idx_model,:);
% Finds the data_idx centroid and the centred data (around its centroid)
n = size(data_idx,1);
data_bar = mean(data_idx,1);
data_centred = data_idx - repmat(data_bar,n,1);
% Now solve for the rotation about the centroid and the translation
S = (model_centred .* repmat(dist,1,3))' * data_centred;
[U,~,V] = svd(S);
R = V * diag([1,1,det(V * U')]) * U';
t = data_bar - model_bar;
if i >= param.icp.max_iter
disp('Reached the maximum iterations. Stopping.');
stop_iter = true;
rmse_last = rmse_vect(param.icp.max_iter,1);
elseif ~stop_iter
disp(['Completed iteration number: ',num2str(i),'. The RMSE is: ',num2str(rmse_vect(i,1))]);
i = i + 1;
end
end
end
D-13
A N N E X E: A U X I L I A R Y C A L C U L A TI O N S
Sensor Widths
Focal Length f 12.7 mm 12.8 mm 12.9 mm
(θ)
FOVs
Possible
E-1
A N N E X E: A U X I L I A R Y C A L C U L A TI O N S
Focal Plane
f: Focal Length
θ: Field of View
X= 2·f·sin(θ/2)
X= 12.800 mm (Mean)
Image Dimensions:
W: Width = 640 pixels
H: Height = 480 pixels
fy = fx (See assumption 1)
fx = 6750 pixels
fy = 6750 pixels
Step Four: (Alternative to Step Three) Find the focal plane resolution of the sensor.
Focal Plane resolution is measured in pixels per (inch/cm)
I will use cm.
E-2
A N N E X E: A U X I L I A R Y C A L C U L A TI O N S
E-3
A N N E X F: C O M P L E T E L I S T OF CASES
F-1
A N N E X F: C O M P L E T E L I S T OF CASES
F-2
A N N E X F: C O M P L E T E L I S T OF CASES
F-3
A N N E X F: C O M P L E T E L I S T OF CASES
F-4
A N N E X F: C O M P L E T E L I S T OF CASES
F-5
A N N E X F: C O M P L E T E L I S T OF CASES
F-6
A N N E X G: C H A R TS
Annex G C HARTS
This annex contains the charts produced for this research project. Additional
charts can be found in the supporting Excel files which accompany this
research project.
G-1
A N N E X G: C H A R TS
G-2
A N N E X G: C H A R TS
G-3
A N N E X G: C H A R TS
G-4