-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2065278
commit 8ab66aa
Showing
12 changed files
with
523 additions
and
198 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
using Makie | ||
using MultipleViewGeometry, Test, Random | ||
using MultipleViewGeometry.ModuleCostFunction | ||
using MultipleViewGeometry.ModuleTypes | ||
using MultipleViewGeometry.ModuleConstraints | ||
using MultipleViewGeometry.ModuleConstruct | ||
using MultipleViewGeometry.ModuleDraw | ||
using MultipleViewGeometry.ModuleMove | ||
using LinearAlgebra | ||
using StaticArrays | ||
using GeometryTypes | ||
using Test | ||
|
||
π³ = [Point3D(x,y,rand(50:100)) for x = -100:5:100 for y = -100:5:100] | ||
π³ = π³[1:50:end] | ||
X = reshape(reinterpret(Float64,π³),(3,length(π³))) | ||
|
||
# Specify the coordinate systems of the world, the camera frame and the picture | ||
# plane. | ||
world_basis = (Vec(1.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(0.0, 0.0, 1.0)) | ||
camera_basis = (Point(0.0, 0.0, 0.0), Vec(-1.0, 0.0, 0.0), Vec(0.0, -1.0, 0.0), Vec(0.0, 0.0, 1.0)) | ||
picture_basis = (Point(0.0, 0.0), Vec(-1.0, 0.0), Vec(0.0, -1.0)) | ||
|
||
# The focal length for both cameras is one. | ||
f = 1 | ||
image_width = 640 / 10 | ||
image_height = 480 / 10 | ||
|
||
cameraβ = Pinhole(image_width, image_height, f, camera_basis..., picture_basis...) | ||
cameraβ = Pinhole(image_width, image_height, f, camera_basis..., picture_basis...) | ||
|
||
# Rotate and translate camera one. | ||
πβ = Matrix{Float64}(I,3,3) | ||
πβ = [-50.0, -2.0, 0.0] | ||
relocate!(cameraβ, πβ, πβ) | ||
|
||
# Rotate and translate camera two. | ||
πβ = Matrix{Float64}(I,3,3) | ||
πβ = [50.0, 2.0, 0.0] | ||
relocate!(cameraβ, πβ, πβ) | ||
|
||
|
||
scale = 20.0f0 | ||
x = Vec3f0(0); baselen = 0.2f0 * scale ; dirlen = 1f0 * scale | ||
# create an array of differently colored boxes in the direction of the 3 axes | ||
rectangles = [ | ||
(HyperRectangle(Vec3f0(x), Vec3f0(dirlen, baselen, baselen)), RGBAf0(1,0,0,1)), | ||
(HyperRectangle(Vec3f0(x), Vec3f0(baselen, dirlen, baselen)), RGBAf0(0,1,0,1)), | ||
(HyperRectangle(Vec3f0(x), Vec3f0(baselen, baselen, dirlen)), RGBAf0(0,0,1,1)) | ||
] | ||
meshes = map(GLNormalMesh, rectangles) | ||
|
||
|
||
scene = mesh(merge(meshes)) | ||
scatter!(scene, X[1,:],X[2,:], X[3,:], markersize = 3, color = :red) | ||
draw!(cameraβ, scene) | ||
draw!(cameraβ, scene) | ||
|
||
|
||
|
||
πββ², πββ² = ascertain_pose(cameraβ, world_basis... ) | ||
πββ² = obtain_intrinsics(cameraβ, CartesianSystem()) | ||
πββ², πββ² = ascertain_pose(cameraβ, world_basis... ) | ||
πββ² = obtain_intrinsics(cameraβ, CartesianSystem()) | ||
|
||
# Camera projection matrices. | ||
πβ = construct(ProjectionMatrix(),πββ²,πββ²,πββ²) | ||
πβ = construct(ProjectionMatrix(),πββ²,πββ²,πββ²) | ||
|
||
|
||
# Set of corresponding points. | ||
β³ = project(cameraβ,πβ,π³) | ||
β³ΚΉ = project(cameraβ,πβ,π³) | ||
|
||
# Estimate of the fundamental matrix and the true fundamental matrix. | ||
π = estimate(FundamentalMatrix(), DirectLinearTransform(), (β³, β³ΚΉ)) | ||
|
||
#π β = construct(FundamentalMatrix(), πβ, πβ) | ||
π β = construct(FundamentalMatrix(), πββ²,πββ²,-πββ²,πββ²,πββ²,-πββ²) | ||
|
||
# Ensure the estimated and true matrix have the same scale and sign. | ||
π = π / norm(π ) | ||
π = π / sign(π [3,1]) | ||
π β = π β / norm(π β) | ||
π β = π β / sign(π β[3,1]) | ||
|
||
@test π β π β | ||
|
||
# Check that the fundamental matrix satisfies the corresponding point equation. | ||
npts = length(β³) | ||
residual = zeros(Float64,npts,1) | ||
for correspondence in zip(1:length(β³),β³, β³ΚΉ) | ||
i, m , mΚΉ = correspondence | ||
π¦ = hom(m) | ||
π¦ΚΉ = hom(mΚΉ) | ||
residual[i] = (π¦ΚΉ'*π *π¦) | ||
end | ||
|
||
@test isapprox(sum(residual), 0.0; atol = 1e-7) | ||
|
||
|
||
# Test the Fundamental Numerical Scheme on the Fundamental matrix problem. | ||
Ξβ = [SMatrix{3,3}(Matrix(Diagonal([1.0,1.0,0.0]))) for i = 1:length(β³)] | ||
Ξβ = [SMatrix{3,3}(Matrix(Diagonal([1.0,1.0,0.0]))) for i = 1:length(β³)] | ||
π β = estimate(FundamentalMatrix(),DirectLinearTransform(), (β³, β³ΚΉ)) | ||
π = estimate(FundamentalMatrix(), | ||
FundamentalNumericalScheme(vec(π β), 5, 1e-10), | ||
(Ξβ,Ξβ), (β³, β³ΚΉ)) | ||
|
||
|
||
# Ensure the estimated and true matrix have the same scale and sign. | ||
π = π / norm(π ) | ||
π = π / sign(π [3,1]) | ||
|
||
@test π β π β | ||
|
||
# Test the Bundle Adjustment estimator on the Fundamental matrix problem. | ||
π , lsqFit = estimate(FundamentalMatrix(), | ||
BundleAdjustment(vec(π β), 5, 1e-10), | ||
(β³, β³ΚΉ)) | ||
π = π / norm(π ) | ||
π = π / sign(π [3,1]) | ||
@test π β π β |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
function estimate(entity::HomographyMatrix, method::DirectLinearTransform, π::Tuple{AbstractArray, Vararg{AbstractArray}}) | ||
β³, β³ΚΉ = π | ||
N = length(β³) | ||
if (N != length(β³ΚΉ)) | ||
throw(ArgumentError("There should be an equal number of points for each view.")) | ||
end | ||
πͺ, π = transform(HomogeneousCoordinates(),CanonicalToHartley(),β³) | ||
πͺΚΉ, πΚΉ = transform(HomogeneousCoordinates(),CanonicalToHartley(),β³ΚΉ) | ||
π = moments(HomographyMatrix(), (πͺ, πͺΚΉ)) | ||
Ξ», h = smallest_eigenpair(Symmetric(π)) | ||
π = reshape(h,(3,3)) | ||
π = SMatrix{3,3,Float64,9}(π / norm(π)) | ||
# Transform estimate back to the original (unnormalised) coordinate system. | ||
inv(πΚΉ)*π*π | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module ModuleSyntheticData | ||
using MultipleViewGeometry.ModuleOperators, MultipleViewGeometry.ModuleMathAliases | ||
using LinearAlgebra, StaticArrays | ||
export generate_planar_points | ||
include("synthetic_data.jl") | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Generates a random point on the plane centered around a point on the plane | ||
# that is closest to the origin. | ||
function generate_planar_points(π§::AbstractArray, d::Real, extent::Real, N::Int) | ||
# Generate vector π° on a plane through the origin with normal vector π§. | ||
first(π§) == 0 ? π° = cross(π§,SVector(1.0,0.0,0.0)) : π° = cross(π§,SVector(0.0,0.0,1.0)) | ||
points = Array{SVector{3,Float64},1}(undef,N) | ||
for n = 1:N | ||
# Rotate π° randomly around the axis π§. | ||
ΞΈ = rand() * 2*pi | ||
π€ = π§ / norm(π§) | ||
π― = π°*cos(ΞΈ) + cross(π€,π°)*sin(ΞΈ) + π€*dot(π€,π°)*(1-cos(ΞΈ)) | ||
# Scale the vector so that it lies in the interval [0, extent) | ||
π― = (rand() * extent) * π― | ||
# Translate the vector so that it lies on the plane parametrised by π§ and d. | ||
π― = π― + d*(π§/norm(π§)^2) | ||
points[n] = π― | ||
end | ||
points | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.