More lights, show plane

This commit is contained in:
Thomas Forgione 2024-06-22 21:32:44 +02:00
parent 0f424ad039
commit d7f5edc4bc
7 changed files with 70 additions and 13 deletions

View File

@ -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()

View File

@ -22,10 +22,18 @@
</div>
</div>
<div>
<label class="checkbox">
<input type="checkbox" id="show-lines">
Afficher les droites
</label>
<div>
<label class="checkbox">
<input type="checkbox" id="show-lines">
Afficher les directions de la lumière pour chaque sphère
</label>
</div>
<div>
<label class="checkbox">
<input type="checkbox" id="show-plane">
Afficher le plan contenant les sphères
</label>
</div>
</div>
</div>
</section>

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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<THREE.PlaneGeometry, THREE.MeshPhongMaterial>;
/** 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":

View File

@ -56,7 +56,7 @@ export class Led extends THREE.Mesh<THREE.SphereGeometry, THREE.MeshBasicMateria
this.lines.visible = false;
this.add(this.lines);
this.light = new THREE.PointLight(0xffffff, 100);
this.light = new THREE.PointLight(0xffffff, 1000);
this.light.visible = false;
this.add(this.light);
}

View File

@ -505,3 +505,20 @@ def estimate_light(normals, grey_levels, treshold=(0, 1)):
validity_mask = np.logical_and(grey_levels > 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