diff --git a/calibration.py b/calibration.py
index c24b025..c1c3bb9 100755
--- a/calibration.py
+++ b/calibration.py
@@ -92,7 +92,8 @@ def calibrate(input_dir: str):
# Calculate the positions of the light sources
light_positions = utils.lines_intersections(sphere_centers, estimated_lights)
- print(estimated_lights)
+ # Calculate plane parameters from the sphere centers and intersect camera rays with the plane
+ plane_normal, plane_alpha = utils.plane_parameters_from_points(sphere_centers)
# Return value as dictionnary
return {
@@ -102,6 +103,10 @@ def calibrate(input_dir: str):
'directions': estimated_lights[i].tolist(),
} for i, (name, position) in enumerate(zip(image_names, light_positions))],
'spheres': sphere_centers.tolist(),
+ 'plane': {
+ 'normal': plane_normal.tolist(),
+ 'alpha': plane_alpha.tolist(),
+ }
}
@@ -115,8 +120,6 @@ def main():
with open('data/calibration.json', 'w') as f:
json.dump(calib, f, indent=4)
- print(calib)
-
if __name__ == '__main__':
main()
diff --git a/templates/calibration.html b/templates/calibration.html
index b785b26..f0e20fa 100644
--- a/templates/calibration.html
+++ b/templates/calibration.html
@@ -22,10 +22,18 @@
diff --git a/ts/Calibration.ts b/ts/Calibration.ts
index e7d418c..49a5dc6 100644
--- a/ts/Calibration.ts
+++ b/ts/Calibration.ts
@@ -17,6 +17,17 @@ export interface Led {
directions: Vector3[];
}
+/**
+ * A 3D plane.
+ */
+export interface Plane {
+ /** The normal of the plane. */
+ normal: Vector3;
+
+ /** The offset of the plane. */
+ alpha: number;
+}
+
/**
* Type for the calibration data.
*/
@@ -26,4 +37,7 @@ export interface Calibration {
/** Position of the spheres. */
spheres: Vector3[];
+
+ /** The coordinates of the plane that best fit the spheres. */
+ plane: Plane;
}
diff --git a/ts/CameraObject.ts b/ts/CameraObject.ts
index 3ab834c..cc24c89 100644
--- a/ts/CameraObject.ts
+++ b/ts/CameraObject.ts
@@ -31,7 +31,7 @@ export default class CameraObject extends THREE.Object3D {
// Faces
{
- let material = new THREE.MeshPhongMaterial({color: 0xffffff});
+ let material = new THREE.MeshPhongMaterial({color: 0x00ff00});
material.transparent = true;
material.opacity = 0.8;
@@ -117,7 +117,7 @@ export default class CameraObject extends THREE.Object3D {
*/
hover(): void {
this.mesh.material.opacity = 1;
- this.lines.material.color.setHex(0xff0000);
+ this.lines.material.color.setHex(0xffffff);
}
/**
@@ -125,7 +125,7 @@ export default class CameraObject extends THREE.Object3D {
*/
unHover(): void {
this.mesh.material.opacity = 0.8;
- this.lines.material.color.setHex(0x990000);
+ this.lines.material.color.setHex(0x999999);
}
}
diff --git a/ts/Engine.ts b/ts/Engine.ts
index 9a31eba..8abf411 100644
--- a/ts/Engine.ts
+++ b/ts/Engine.ts
@@ -46,12 +46,15 @@ export class Engine {
/** HTML element on which the renderer will be added. */
domElement: HTMLElement;
- /** Checkbox indicating whether wants to show the lines from the spheres to the lights. */
+ /** Checkbox indicating whether the user wants to show the lines from the spheres to the lights. */
showLinesCheckbox: HTMLInputElement;
/** HTML span where we will show the name of the current selected led. */
selectedObject: HTMLElement;
+ /** HTML element indicating whether the user wants to show the plane containing all spheres. */
+ showPlaneCheckbox: HTMLInputElement;
+
/** HTML image where we will show the real photo corresponding to the selected led. */
ledView: HTMLImageElement;
@@ -73,6 +76,9 @@ export class Engine {
/** Object containing all the representations of the spheres (white). */
spheres: THREE.Object3D;
+ /** The plane that approximates the plane containing the spheres. */
+ plane: THREE.Mesh;
+
/** Axes that will be shown to help the visualisation of the scene. */
axes: THREE.AxesHelper;
@@ -123,6 +129,7 @@ export class Engine {
*/
initHtml(): void {
this.showLinesCheckbox = getInputElementById('show-lines');
+ this.showPlaneCheckbox = getInputElementById('show-plane');
this.selectedObject = getElementById('selected-object');
this.ledView = getImageElementById('led-view');
}
@@ -152,10 +159,17 @@ export class Engine {
}
this.scene.add(this.spheres);
+ let normal = new THREE.Vector3(-calibration.plane.normal[1], -calibration.plane.normal[0], calibration.plane.normal[2]);
+ this.plane = new THREE.Mesh(new THREE.PlaneGeometry(20, 20), new THREE.MeshPhongMaterial({ color: 0x0000ff, side: THREE.DoubleSide, transparent: true, opacity: 0.5 }));
+ this.plane.lookAt(normal);
+ this.plane.position.set(0, 0, -calibration.plane.alpha / calibration.plane.normal[2]);
+ this.plane.visible = this.showPlaneCheckbox.checked;
+ this.scene.add(this.plane);
+
this.axes = new THREE.AxesHelper(10);
this.scene.add(this.axes);
- this.ambientLight = new THREE.AmbientLight(0xffffff, 0.15);
+ this.ambientLight = new THREE.AmbientLight(0xffffff, 1);
this.scene.add(this.ambientLight);
this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
@@ -186,6 +200,7 @@ export class Engine {
window.addEventListener('pointermove', (e) => this.onPointerMove(e));
window.addEventListener('pointerup', () => this.onPointerUp());
this.showLinesCheckbox.addEventListener('change', () => this.leds.setShowLines(this.showLinesCheckbox.checked));
+ this.showPlaneCheckbox.addEventListener('change', () => this.plane.visible = this.showPlaneCheckbox.checked);
document.addEventListener('keyup', (e) => {
switch (e.code) {
case "ArrowDown":
diff --git a/ts/Led.ts b/ts/Led.ts
index a857bb9..774687a 100644
--- a/ts/Led.ts
+++ b/ts/Led.ts
@@ -56,7 +56,7 @@ export class Led extends THREE.Mesh treshold[0], grey_levels < treshold[1])
lights = weighted_least_squares(normals, grey_levels, validity_mask)
return lights
+
+
+def plane_parameters_from_points(points):
+ """Computes the parameters of a plane from a set of points.
+
+ Args:
+ points (Array ..., dim): Coordinates of the points used to define the plane.
+
+ Returns:
+ Array ..., dim: Normal vector to the plane.
+ Array ...: Plane constant alpha.
+ """
+ homogeneous = to_homogeneous(points)
+ E = np.einsum('...ki,...kj->...ij', homogeneous, homogeneous)
+ L = matrix_kernel(E)
+ n, alpha = L[..., :-1], L[..., -1]
+ return n, alpha