### Install CameraTransform from Repository Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/installation.md Execute this command after cloning the repository to install the package. ```bash python setup.py install ``` -------------------------------- ### Install CameraTransform with pip Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/installation.md Use this command for the standard installation of the package. ```bash pip install cameratransform ``` -------------------------------- ### Install CameraTransform in Development Mode Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/installation.md Use this command for development to link the installed package to the source files. ```bash python setup.py develop ``` -------------------------------- ### Setup OrbitControls and Scene Elements Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/coordinate_systems.md Initializes OrbitControls for camera interaction and creates 3D text labels for X, Y, and Z axes. This setup is useful for visualizing the orientation of objects in a 3D scene. ```javascript const controls = new OrbitControls(camera_extern, renderer.domElement); //controls.maxPolarAngle = Math.PI * 0.5; //controls.minDistance = 10; //controls.maxDistance = 50; console.log("Hi"); const color = 0xA0A6A9; const matDark = new THREE.LineBasicMaterial( { color: color, side: THREE.DoubleSide } ); const shapes_y = font.generateShapes( "y", 0.5 ); const geometry_y = new THREE.ShapeGeometry( shapes_y ); const text_y = new THREE.Mesh( geometry_y, matDark ); text_y.position.y = 2.5; scene.add( text_y); const shapes_x = font.generateShapes( "x", 0.5 ); const geometry_x = new THREE.ShapeGeometry( shapes_x ); const text_x = new THREE.Mesh( geometry_x, matDark ); text_x.position.x = 2.5; scene.add( text_x); const shapes_z = font.generateShapes( "z", 0.5 ); const geometry_z = new THREE.ShapeGeometry( shapes_z ); const text_z = new THREE.Mesh( geometry_z, matDark ); text_z.position.z = 2.5; text_z.rotateX(90*Math.PI/180); text_z.rotateY(90*Math.PI/180); scene.add( text_z); ``` -------------------------------- ### Initialize RectilinearProjection with image from numpy array Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection using a numpy array of an example image to infer dimensions. Requires matplotlib for reading the image. ```python >>> import matplotlib.pyplot as plt >>> im = plt.imread("test.jpg") >>> projection = ct.RectilinearProjection(focallength_px=3863.64, image=im) ``` -------------------------------- ### Clone CameraTransform Repository Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/installation.md Clone the repository to get the latest development version. ```bash git clone https://github.com/rgerum/cameratransform.git ``` -------------------------------- ### Font Loading and Scene Creation Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/coordinate_systems.md Loads a font asynchronously and then calls main functions to create and render scenes with the loaded font. This handles asynchronous asset loading before scene setup. ```javascript const loader = new THREE.FontLoader(); var font = undefined; loader.load( 'https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function ( f ) { font = f; console.log("font", font); main("#c"); main2("#c2", font); setCamParameter(cam_params); } ); ``` -------------------------------- ### Get camera rays from multiple image points Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Obtain the rays in camera coordinates for multiple points in the image coordinate system simultaneously. ```python >>> proj.getRay([[1968, 2291], [1650, 2189]]) ``` -------------------------------- ### cameratransform.moveDistance(start, distance, bearing) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/gps.md Calculates a new GPS point by moving a specified distance from a starting point along a given bearing. Supports batch processing for multiple starting points, distances, or bearings. ```APIDOC ## cameratransform.moveDistance(start, distance, bearing) ### Description Calculates a target GPS point by moving a specified distance from a starting point in a given direction (bearing). ### Parameters * **start** (*ndarray*) – The starting GPS point (latitude, longitude). Can be a single point or a batch of points. * **distance** (*float* or *ndarray*) – The distance to move in meters. Can be a single value or a batch of distances. * **bearing** (*float* or *ndarray*) – The bearing angle in degrees, specifying the direction of movement. Can be a single value or a batch of bearings. ### Returns * **target** (*ndarray*) – The calculated target GPS point(s) (latitude, longitude). ### Examples ```pycon >>> import cameratransform as ct >>> ct.moveDistance([52.51666667, 13.4], 503926, -164) array([48.14444416, 11.52952357]) >>> ct.moveDistance([[52.51666667, 13.4], [49.597854, 11.005092]], [10, 20], -164) array([[52.51658022, 13.39995926], [49.5976811 , 11.00501551]]) >>> ct.moveDistance([52.51666667, 13.4], [503926, 103926], [-164, -140]) array([[48.14444416, 11.52952357], [51.79667095, 12.42859387]]) ``` ``` -------------------------------- ### Transform Points Using Optimized Camera Group Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/stereo.ipynb Defines starting and ending points in the first camera's view and prepares to transform them using the optimized camera group. This is a precursor to projecting points or performing other 3D operations. ```python points1_start = np.array([[4186.75025841, 1275.33146571], [2331.92641872, 1019.27786453], [2001.20914719, 644.51861935], [1133.13081198, 1109.00803712], [ 900.20742144, 1016.83613865], [3287.47982902, 882.47189246], [3965.52607095, 693.78282123], [2689.04269923, 1033.94065467], [2889.82546079, 1144.44899631]]) points1_end = np.array([[3833.11271185, 1441.03505624], [2234.96105241, 1095.94815417], [2141.25664041, 614.81157533], [1797.43541128, 705.61811479], [1594.1321895 , 630.02825115], [4107.48373669, 942.87002974], [3238.54411195, 640.438481 ], [2868.55390207, 951.44851233], [3070.37430064, 1053.65575788]]) ``` -------------------------------- ### Batch Process GPS Movement Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/gps.md Efficiently calculates multiple target GPS positions by moving from various start points with specified distances and bearings. Useful for large datasets. ```python import cameratransform as ct ct.moveDistance([[52.51666667, 13.4], [49.597854, 11.005092]], [10, 20], -164) ``` -------------------------------- ### Get Ray from Image Point Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/camera.md Calculates the ray originating from the camera's position in space that corresponds to a given point in the image coordinate system. This is useful because the image-to-space transformation is not unique. The offset (camera origin) and the ray direction are returned. ```python offset, ray = cam.getRay([1968, 2291])) ``` ```python offset, ray, cam.getRay([[1968, 2291], [1650, 2189]]) ``` -------------------------------- ### Get camera ray from image point Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Obtain the ray in camera coordinates that corresponds to a given point in the image coordinate system. This is useful because image points map to rays, not unique 3D points. ```python >>> import cameratransform as ct >>> proj = ct.RectilinearProjection(focallength_px=3729, image=(4608, 2592)) >>> proj.getRay([1968, 2291]) ``` -------------------------------- ### Reconstruct 3D Points from Stereo Images Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/stereo.ipynb Use `spaceFromImages` to convert corresponding 2D points from two cameras into 3D world coordinates. This method requires the 2D points from both cameras and assumes a calibrated stereo camera setup. The output is an array of 3D points. ```python points_start_3D = cam_group.spaceFromImages(points1_start, points2_start) points_end_3D = cam_group.spaceFromImages(points1_end, points2_end) ``` -------------------------------- ### Move a GPS Position by Distance and Bearing Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/gps.md Use `moveDistance` to calculate a new GPS coordinate after moving a specified distance in meters and a given bearing in degrees from a starting point. Supports single or batch operations. ```python import cameratransform as ct ct.moveDistance([52.51666667, 13.4], 503926, -164) ``` -------------------------------- ### Initialize Camera and Transform Space to Image Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/api.md Sets up a camera with specific focal length and image dimensions, then transforms a single point from space coordinates to image coordinates. ```python >>> import cameratransform as ct >>> cam = ct.Camera(ct.RectilinearProjection(focallength_px=3729, image=(4608, 2592)), >>> ct.SpatialOrientation(elevation_m=15.4, tilt_deg=85)) ``` ```python >>> cam.imageFromSpace([-4.17, 45.32, 0.]) [1969.52 2209.73] ``` -------------------------------- ### Main Scene Initialization Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/coordinate_systems.md Initializes the WebGL renderer, creates the scene and camera, and sets up the initial render function. This is the entry point for setting up the 3D environment. ```javascript function main(id) { const canvas = document.querySelector(id); const renderer = new THREE.WebGLRenderer({canvas}); renderer.setSize( image_size[0], image_size[1] ); const [camera, scene] = createScene(100); var ctx = canvas.getContext("2d"); scene.render = () => { renderer.render(scene, camera); } scene.render(); scene.renderer = renderer; } ``` -------------------------------- ### Camera.rotateSpace Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/api.md Rotates the entire camera setup clockwise by a specified number of degrees. ```APIDOC ## Camera.rotateSpace ### Description Rotates the whole camera setup, this will turn the heading and rotate the camera position (pos_x_m, pos_y_m) around the origin. ### Method `rotateSpace(delta_heading: Number)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters #### Path Parameters * **delta_heading** (number) - The number of degrees to rotate the camera clockwise. ### Request Example ```python import cameratransform as ct cam = ct.Camera() cam.rotateSpace(45) ``` ### Response #### Success Response (200) None (modifies the camera object in place). #### Response Example None ``` -------------------------------- ### Initialize Camera Parameters and Event Listeners Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/coordinate_systems.md Sets up initial camera parameters and attaches event listeners to HTML input elements for updating camera properties and switching between angle systems. This script requires THREE.js and OrbitControls. ```javascript import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/build/three.module.js'; import {OrbitControls} from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'; let image_size = [300, 200]; let cam_params = {image_width_px:300, image_height_px:200, view_x_deg: 72, pos_x_m: 0, pos_y_m: -1, elevation_m: 2, heading_deg: 0, tilt_deg: 40, roll_deg: 0} document.getElementById("pos_x_m").oninput = function() {setCamParameter({pos_x_m: this.value}); this.nextSibling.innerText = this.value} document.getElementById("pos_y_m").oninput = function() {setCamParameter({pos_y_m: this.value}); this.nextSibling.innerText = this.value} document.getElementById("elevation_m").oninput = function() {setCamParameter({elevation_m: this.value}); this.nextSibling.innerText = this.value} document.getElementById("tilt-heading-roll").oninput = function() { console.log("1"); document.getElementById("angles1").style.display = ""; document.getElementById("angles2").style.display = "none"; } document.getElementById("yaw-pitch-roll").oninput = function() {console.log(2); document.getElementById("angles1").style.display = "none"; document.getElementById("angles2").style.display = ""; } document.getElementById("heading_deg").oninput = function() { setCamParameter({heading_deg: this.value}); this.nextSibling.innerText = this.value document.getElementById("yaw_deg").value = this.value; document.getElementById("yaw_deg").nextSibling.innerText = this.value; } document.getElementById("tilt_deg").oninput = function() { setCamParameter({tilt_deg: this.value}); this.nextSibling.innerText = this.value; document.getElementById("pitch_deg").value = this.value*1-90; document.getElementById("pitch_deg").nextSibling.innerText = this.value*1-90; } document.getElementById("roll_deg").oninput = function() { setCamParameter({roll_deg: this.value}); this.nextSibling.innerText = this.value; document.getElementById("roll_deg2").value = -this.value; document.getElementById("roll_deg2").nextSibling.innerText = -this.value; } document.getElementById("yaw_deg").oninput = function() { setCamParameter({heading_deg: this.value}); this.nextSibling.innerText = this.value document.getElementById("heading_deg").value = this.value; document.getElementById("heading_deg").nextSibling.innerText = this.value; } document.getElementById("pitch_deg").oninput = function() { console.log("pitch_deg", this.value, "tilt", this.value+90); ``` -------------------------------- ### Initialize Camera Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/api.md Initializes a camera object with default parameters. ```python >>> import cameratransform as ct >>> cam = ct.Camera() ``` -------------------------------- ### Initialize Camera with Projection and Orientation Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/camera.md Initializes a Camera object with specified projection and spatial orientation. Ensure the projection and orientation objects are correctly defined before instantiation. ```python import cameratransform as ct cam = ct.Camera(ct.RectilinearProjection(focallength_px=3729, image=(4608, 2592)), ct.SpatialOrientation(elevation_m=15.4, tilt_deg=85)) ``` -------------------------------- ### Import cameratransform library Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Import the necessary library for camera transformations. ```python >>> import cameratransform as ct ``` -------------------------------- ### cameratransform.getBearing(point1, point2) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/gps.md Calculates the bearing angle in degrees from a starting GPS point to an ending GPS point. It supports both single coordinate pairs and batches of coordinates. ```APIDOC ## cameratransform.getBearing(point1, point2) ### Description Calculates the bearing angle relative to the north direction between two GPS points. ### Parameters * **point1** (*ndarray*) – The first point (latitude, longitude) from which to calculate the bearing. Can be a single point or a batch of points. * **point2** (*ndarray*) – The second point (latitude, longitude) to which to calculate the bearing. Can be a single point or a batch of points. ### Returns * **bearing** (*float* or *ndarray*) – The bearing angle in degrees. The dimensions will match the input if a batch is provided. ### Examples ```pycon >>> import cameratransform as ct >>> ct.getBearing([85.3205556, 4.52777778], [-66.66559128, 140.02233212]) 53.34214977328738 >>> ct.getBearing([[85.3205556, 4.52777778], [65.3205556, 7.52777778]], [[-66.66559128, 140.02233212], [-60.66559128, 80.02233212]]) array([ 53.34214977, 136.82109976]) ``` ``` -------------------------------- ### Initialize Camera Models Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/stereo.ipynb Initializes two camera models with identical rectilinear projection parameters and then creates a CameraGroup. The projection is defined by focal length and image dimensions. ```python import cameratransform as ct cam1 = ct.Camera(ct.RectilinearProjection(focallength_px=3863.64, image=[4608, 2592])) cam2 = ct.Camera(cam1.projection) cam_group = ct.CameraGroup(cam1.projection, (cam1.orientation, cam2.orientation)) ``` -------------------------------- ### Initialize Camera and Set GPS Position Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/gps.md Initialize a Camera object and set its GPS position using floating-point latitude and longitude values. ```python import cameratransform as ct cam = ct.Camera() cam.setGPSpos(-66.66, 140.00, 19) ``` -------------------------------- ### Multiple Movements from a Single GPS Position Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/gps.md Calculates multiple destination GPS coordinates from a single starting point by applying different distances and bearings. Demonstrates flexibility for varied scenarios. ```python import cameratransform as ct ct.moveDistance([52.51666667, 13.4], [503926, 103926], [-164, -140]) ``` -------------------------------- ### Initialize SpatialOrientation Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/spatial.md Create a SpatialOrientation object with camera elevation and tilt. This sets up the coordinate system transformation. ```python import cameratransform as ct orientation = ct.SpatialOrientation(elevation_m=15.4, tilt_deg=85) ``` -------------------------------- ### Get Ray for a Single Image Point Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/api.md Calculates the ray originating from the camera's optical center that passes through a given point in the image. Returns the camera's origin and the ray vector. ```python offset, ray = cam.getRay([1968, 2291])) print(offset) print(ray) ``` -------------------------------- ### Initialize RectilinearProjection with focal length in mm and sensor size Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection by providing focal length in millimeters, sensor dimensions (width, height), and image dimensions. ```python >>> projection = ct.RectilinearProjection(focallength_mm=14, sensor=(17.3, 9.731), image=(4608, 3456)) ``` -------------------------------- ### Load and Apply Optimization Trace Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/stereo.ipynb Loads a previously saved optimization trace from a CSV file using pandas and applies it to the CameraGroup. This allows for resuming or analyzing previous optimization results. ```python import pandas as pd trace = pd.read_csv("trace_stereo.csv") cam_group.set_trace(trace) ``` -------------------------------- ### Initialize RectilinearProjection with image dimensions (width, height) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection by providing focal length in pixels and image dimensions as separate width and height values. ```python >>> projection = ct.RectilinearProjection(focallength_px=3863.64, image_width_px=4608, image_height_px=3456) ``` -------------------------------- ### Initialize RectilinearProjection with central point (tuple) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection by specifying the central point (optical axis) as a tuple (x, y) along with focal length and image dimensions. ```python >>> projection = ct.RectilinearProjection(focallength_px=3863.64, center=(2304, 1728), image=(4608, 3456)) ``` -------------------------------- ### Create Three.js Scene and Camera Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/coordinate_systems.md Initializes a Three.js scene, including a perspective camera, a cube mesh, grid lines, and a directional light. It sets up event listeners for camera updates. ```javascript function createScene(depth) { const camera = new THREE.PerspectiveCamera(75, image_size[0]/image_size[1], 0.1, depth); camera.position.set(0, 0, 20); camera.last_rot = [0, 0, 0]; addEventListener('cam_update', (e) => { if(scene.renderer !== undefined) scene.renderer.setSize( cam_params.image_width_px, cam_params.image_height_px ); camera.aspect = cam_params.image_width_px/cam_params.image_height_px; camera.fov = cam_params.view_x_deg; camera.updateProjectionMatrix(); camera.position.set(cam_params.pos_x_m, cam_params.pos_y_m, cam_params.elevation_m); console.log([cam_params.roll_deg, cam_params.tilt_deg, cam_params.heading_deg], camera.last_rot) camera.rotateZ(-camera.last_rot[0]*Math.PI/180); camera.rotateX(-camera.last_rot[1]*Math.PI/180); camera.rotateZ(-camera.last_rot[2]*Math.PI/180); camera.rotateZ(-cam_params.heading_deg*Math.PI/180); camera.rotateX(cam_params.tilt_deg*Math.PI/180); camera.rotateZ(cam_params.roll_deg*Math.PI/180); camera.last_rot = [cam_params.roll_deg, cam_params.tilt_deg, -cam_params.heading_deg]; scene.render() }, false); const scene = new THREE.Scene(); const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshPhongMaterial({color: 0x44aa88}); // greenish blue const cube = new THREE.Mesh(geometry, material); cube.position.set(0, 0, 0.5) scene.add(cube); const material_line = new THREE.LineBasicMaterial( { color: 0x404040 } ); scene.material_line = material_line; const points = []; for(let x = -10; x<=10 ; x+=2) { points.push( new THREE.Vector3(x, -10, 0 ) ); points.push( new THREE.Vector3(x, 10, 0 ) ); if(x<10) { points.push(new THREE.Vector3(x + 1, 10, 0)); points.push(new THREE.Vector3(x + 1, -10, 0)); } } const geometry_line = new THREE.BufferGeometry().setFromPoints( points ); const line = new THREE.Line( geometry_line, material_line ); scene.add( line ); const points2 = []; for(let y = -10; y<=10 ; y+=2) { points2.push( new THREE.Vector3(-10, y, 0 ) ); points2.push( new THREE.Vector3( 10, y, 0 ) ); if(y< 10) { points2.push( new THREE.Vector3( 10, y+1, 0 ) ); points2.push( new THREE.Vector3(-10, y+1, 0 ) ); } } const geometry_line2 = new THREE.BufferGeometry().setFromPoints( points2); const line2 = new THREE.Line( geometry_line2, material_line ); scene.add( line2 ); { const color = 0xFFFFFF; const intensity = 1; const light = new THREE.DirectionalLight(color, intensity); light.position.set(1, -2, 4); scene.add(light); } return [camera, scene]; } function main2(id, font) { const canvas = document.querySelector(id); const renderer = new THREE.WebGLRenderer({canvas}); const [camera, scene] = createScene(1); camera.near = 0.9; scene.add(camera) const camera_extern = new THREE.PerspectiveCamera(75, 1, 0.1, 5000); renderer.setSize( 300, 300 ); //camera_extern.rotateX(45*Math.PI/180); //camera_extern.rotateZ(90*Math.PI/180); ``` -------------------------------- ### Initialize RectilinearProjection with image dimensions (tuple) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection by providing focal length in pixels and image dimensions as a tuple (width, height). ```python >>> projection = ct.RectilinearProjection(focallength_px=3863.64, image=(4608, 3456)) ``` -------------------------------- ### Initialize Camera with Intrinsic and Spatial Parameters Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/getting_started.ipynb Initializes a camera object with rectilinear projection and spatial orientation. This is useful for setting up a camera model with specific focal length, sensor size, image resolution, elevation, and tilt. ```python import cameratransform as ct # intrinsic camera parameters f = 6.2 # in mm sensor_size = (6.17, 4.55) # in mm image_size = (3264, 2448) # in px # initialize the camera cam = ct.Camera(ct.RectilinearProjection(focallength_mm=f, sensor=sensor_size, image=image_size), ct.SpatialOrientation(elevation_m=10, tilt_deg=45)) ``` -------------------------------- ### Initialize RectilinearProjection with field of view (x-axis) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection by providing the horizontal field of view in degrees and image dimensions. ```python >>> projection = ct.RectilinearProjection(view_x_deg=61.617, image=(4608, 3456)) ``` -------------------------------- ### Camera Class Initialization Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/camera.md Initializes a Camera object with projection, orientation, and optional lens distortion. ```APIDOC ## class cameratransform.Camera(projection: CameraProjection, orientation: SpatialOrientation = None, lens: LensDistortion = None) ### Description This class is the core of the CameraTransform package and represents a camera. Each camera has a projection (subclass of `CameraProjection`), a spatial orientation (`SpatialOrientation`) and optionally a lens distortion (`LensDistortion`). ``` -------------------------------- ### Handle Points Behind Camera in ImageFromSpace Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/api.md Demonstrates that points behind the camera in space-to-image transformation return NaN values. ```python >>> cam.imageFromSpace([-4.17, -10.1, 0.]) [nan nan] ``` -------------------------------- ### Initialize Camera with Rectilinear Projection Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/getting_started.ipynb Initializes a camera object with rectilinear projection. Requires 'CameraImage2.jpg' and specifies the focal length in pixels. ```python import cameratransform as ct import numpy as np import matplotlib.pyplot as plt im = plt.imread("CameraImage2.jpg") camera = ct.Camera(ct.RectilinearProjection(focallength_px=3863.64, image=im)) ``` -------------------------------- ### Configure and Add Camera Helper Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/coordinate_systems.md Sets the position and rotation for an external camera and adds a CameraHelper to visualize its frustum. This is useful for debugging camera perspectives. ```javascript camera_extern.position.set(6, 0, 3); //camera_extern.rotateX(45*Math.PI/180); camera_extern.rotateZ(90*Math.PI/180); camera_extern.rotateX(80*Math.PI/180); camera.updateProjectionMatrix() const cameraPerspectiveHelper = new THREE.CameraHelper(camera); scene.add(cameraPerspectiveHelper); camera.updateProjectionMatrix() cameraPerspectiveHelper.update() cameraPerspectiveHelper.visible = true; renderer.render(scene, camera_extern); scene.render = () => renderer.render(scene, camera_extern); ``` -------------------------------- ### Initialize RectilinearProjection with tuple focal length in pixels Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection with different focal lengths for x and y axes in pixels, suitable for non-square sensor pixels, along with image dimensions. ```python >>> projection = ct.RectilinearProjection(focallength_px=(3772, 3774), image=(4608, 3456)) ``` -------------------------------- ### Camera.load Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/api.md Loads camera parameters from a JSON file. ```APIDOC ## Camera.load ### Description Loads the camera parameters from a json file. ### Method `load(filename: str)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters #### Path Parameters * **filename** (str) - The filename of the file to load. ### Request Example ```python import cameratransform as ct ct.Camera.load('camera_params.json') ``` ### Response #### Success Response (200) - **Camera** - A Camera object with loaded parameters. #### Response Example ```json ``` ``` -------------------------------- ### Display Top View of Image Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/getting_started.ipynb Loads an image and displays its top-down view using the camera transform. Ensure 'CameraImage.jpg' is in the correct directory. ```python import matplotlib.pyplot as plt im = plt.imread("CameraImage.jpg") top_im = cam.getTopViewOfImage(im, [-150, 150, 50, 300], scaling=0.5, do_plot=True) plt.xlabel("x position in m") plt.ylabel("y position in m"); ``` -------------------------------- ### Initialize RectilinearProjection with field of view (y-axis) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection by providing the vertical field of view in degrees and image dimensions. ```python >>> projection = ct.RectilinearProjection(view_y_deg=48.192, image=(4608, 3456)) ``` -------------------------------- ### Handle Points Behind Camera Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/camera.md Demonstrates how points that are behind the camera (for RectilinearProjection) are handled, resulting in NaN entries in the output. This helps in identifying and managing points outside the camera's view frustum. ```python cam.imageFromSpace([-4.17, -10.1, 0.]) ``` -------------------------------- ### Initialize RectilinearProjection with central point (x, y) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Initialize a projection by specifying the central point's x and y coordinates separately, along with focal length and image dimensions. ```python >>> projection = ct.RectilinearProjection(focallength_px=3863.64, center_x_px=2304, center_y_px=1728, image=(4608, 3456)) ``` -------------------------------- ### Set Camera Extrinsic Parameters Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/stereo.ipynb Configures the orientation (tilt, heading, roll) and position (x, y, elevation) for both camera 1 and camera 2. Camera 2 is offset by the defined baseline along the x-axis. ```python cam1.tilt_deg = 90 cam1.heading_deg = 35 cam1.roll_deg = 0 cam1.pos_x_m = 0 cam1.pos_y_m = 0 cam1.elevation_m = 0 cam2.tilt_deg = 90 cam2.heading_deg = -18 cam2.roll_deg = 0 cam2.pos_x_m = baseline cam2.pos_y_m = 0 cam2.elevation_m = 0 ``` -------------------------------- ### Set GPS Position using String Format Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/gps.md Set the camera's GPS position using a string representation of latitude and longitude. ```python cam.setGPSpos("66°39'53.4"S 140°00'34.8"") ``` -------------------------------- ### Plot Optimization Trace Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/stereo.ipynb Visualizes the optimization trace, showing the evolution of fitted parameters over the course of the optimization process. This helps in understanding the convergence and stability of the optimization. ```python cam_group.plotTrace() ``` -------------------------------- ### Camera Save/Load Functions Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/camera.md Functions to save and load camera parameters to/from JSON files. ```APIDOC ## Save/Load Functions #### Camera.save(filename: str) Saves the camera parameters to a json file. * **Parameters:** **filename** (*str*) – the filename where to store the parameters. ``` ```APIDOC #### Camera.load(filename: str) Load the camera parameters from a json file. * **Parameters:** **filename** (*str*) – the filename of the file to load. ``` ```APIDOC ### cameratransform.load_camera(filename: str) -> Camera Create a [`Camera`](#cameratransform.Camera) instance with the parameters from the file. * **Parameters:** **filename** (*str*) – the filename of the file to load. * **Returns:** **camera** – the camera with the given parameters. * **Return type:** [`Camera`](#cameratransform.Camera) ``` -------------------------------- ### Set GPS Position and Add Landmark Information Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/getting_started.ipynb Sets the camera's GPS position and adds landmark information. This involves converting GPS coordinates to a 3D space representation and associating them with pixel coordinates. ```python camera.setGPSpos("66°39'53.4\"S 140°00'34.8\"") lm_points_px = np.array([[2091.300935, 892.072126], [2935.904577, 824.364956]]) lm_points_gps = ct.gpsFromString([("66°39'56.12862''S 140°01'20.39562''", 13.769), ("66°39'58.73922''S 140°01'09.55709''", 21.143)]) lm_points_space = camera.spaceFromGPS(lm_points_gps) camera.addLandmarkInformation(lm_points_px, lm_points_space, [3, 3, 5]) ``` -------------------------------- ### Estimate Camera Parameters using Metropolis Algorithm Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/getting_started.ipynb Estimates camera parameters (elevation, tilt, heading, roll) using the Metropolis algorithm. This process involves defining parameter ranges and running a specified number of iterations. ```python trace = camera.metropolis([ ct.FitParameter("elevation_m", lower=0, upper=100, value=20), ct.FitParameter("tilt_deg", lower=0, upper=180, value=80), ct.FitParameter("heading_deg", lower=-180, upper=180, value=90), ct.FitParameter("roll_deg", lower=-180, upper=180, value=0) ], iterations=1e4) ``` -------------------------------- ### Load Stereo Images Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/stereo.ipynb Loads stereo images using matplotlib. Ensure 'StereoLeft.jpg' and 'StereoRight.jpg' are in the same directory. ```python import matplotlib.pyplot as plt imA = plt.imread("StereoLeft.jpg") imB = plt.imread("StereoRight.jpg") ``` -------------------------------- ### Project Image to Top View Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/api.md Projects an image onto a top-down plane. This function can optionally plot the result and allows for custom extent and scaling parameters. ```python projected_image = cam.getTopViewOfImage(image, extent=[x_min, x_max, y_min, y_max], scaling=scaling, do_plot=True, alpha=0.5, Z=0.0, skip_size_check=False, hide_backpoints=True) ``` -------------------------------- ### Transform camera coordinates to image coordinates (multiple points) Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Convert multiple points from camera coordinates (3D) to image coordinates (2D) simultaneously using an initialized projection. ```python >>> proj.imageFromCamera([[-0.09, -0.27, -1.00], [-0.18, -0.24, -1.00]]) ``` -------------------------------- ### CameraProjection.getRay Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/projections.md Maps image points to rays in the camera coordinate system. ```APIDOC ## CameraProjection.getRay(points, normed=False) ### Description As the transformation from the **image** coordinate system to the **camera** coordinate system is not unique, **image** points can only be uniquely mapped to a ray in **camera** coordinates. ### Method CameraProjection.getRay ### Parameters #### Path Parameters - **points** (ndarray) - Required - the points in **image** coordinates for which to get the ray, dimensions (2), (Nx2) - **normed** (bool) - Optional - Whether to return normalized rays. ### Returns - **rays** (ndarray) - the rays in the **camera** coordinate system, dimensions (3), (Nx3) ### Request Example ```python import cameratransform as ct proj = ct.RectilinearProjection(focallength_px=3729, image=(4608, 2592)) # get the ray of a point in the image: proj.getRay([1968, 2291]) # or the rays of multiple points in the image: proj.getRay([[1968, 2291], [1650, 2189]]) ``` ``` -------------------------------- ### Plot Camera Trace Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/getting_started.ipynb Displays the trace of the camera's path. Use this to visualize the camera's trajectory in a 3D space. ```python camera.plotTrace() plt.tight_layout() ``` -------------------------------- ### Add Object Height Information Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/getting_started.ipynb Adds information about object heights to the camera model. This requires pixel coordinates of feet and heads, and the camera object must be initialized. ```python feet = np.array([[1968.73191418, 2291.89125757], [1650.27266115, 2189.75370951], [1234.42623164, 2300.56639535], [ 927.4853119 , 2098.87724083], [3200.40162013, 1846.79042709], [3385.32781138, 1690.86859965], [2366.55011031, 1446.05084045], [1785.68269333, 1399.83787022], [ 889.30386193, 1508.92532749], [4107.26569943, 2268.17045783], [4271.86353701, 1889.93651518], [4007.93773879, 1615.08452509], [2755.63028039, 1976.00345458], [3356.54352228, 2220.47263494], [ 407.60113016, 1933.74694958], [1192.78987735, 1811.07247163], [1622.31086201, 1707.77946355], [2416.53943619, 1775.68148688], [2056.81514201, 1946.4146027 ], [2945.35225814, 1617.28314118], [1018.41322935, 1499.63957113], [1224.2470045 , 1509.87120351], [1591.81599888, 1532.33339856], [1701.6226147 , 1481.58276189], [1954.61833888, 1405.49985098], [2112.99329583, 1485.54970652], [2523.54106057, 1534.87590467], [2911.95610793, 1448.87104305], [3330.54617013, 1551.64321531], [2418.21276457, 1541.28499777], [1771.1651859 , 1792.70568482], [1859.30409241, 1904.01744759], [2805.02878512, 1881.00463747], [3138.67003071, 1821.05082989], [3355.45215983, 1910.47345815], [ 734.28038607, 1815.69614796], [ 978.36733356, 1896.36507827], [1350.63202232, 1979.38798787], [3650.89052382, 1901.06620751], [3555.47087822, 2332.50027861], [ 865.71688784, 1662.27834394], [1115.89438493, 1664.09341647], [1558.93825646, 1671.02167477], [1783.86089289, 1679.33599881], [2491.01579305, 1707.84219953], [3531.26955813, 1729.08486338], [3539.6318973 , 1776.5766387 ], [4150.36451427, 1840.90968707], [2112.48684812, 1714.78834459], [2234.65444134, 1756.17059266]]) heads = np.array([[1968.45971142, 2238.81171866], [1650.27266115, 2142.33767714], [1233.79698528, 2244.77321846], [ 927.4853119 , 2052.2539967 ], [3199.94718145, 1803.46727222], [3385.32781138, 1662.23146061], [2366.63609066, 1423.52398752], [1785.68269333, 1380.17615549], [ 889.30386193, 1484.13026407], [4107.73533808, 2212.98791584], [4271.86353701, 1852.85753597], [4007.93773879, 1586.36656606], [2755.89171994, 1938.22544024], [3355.91105749, 2162.91833832], [ 407.60113016, 1893.63300333], [1191.97371829, 1777.60995028], [1622.11915337, 1678.63975025], [2416.31761434, 1743.29549618], [2056.67597009, 1910.09072955], [2945.35225814, 1587.22557592], [1018.69818061, 1476.70099517], [1224.55272475, 1490.30510731], [1591.81599888, 1510.72308329], [1701.45016126, 1460.88834824], [1954.734384 , 1385.54008964], [2113.14023137, 1465.41953732], [2523.54106057, 1512.33125811], [2912.08384338, 1428.56110628], [3330.40769371, 1527.40984208], [2418.21276457, 1517.88006678], [1770.94524662, 1761.25436746], [1859.30409241, 1867.88794433], [2804.69006305, 1845.10009734], [3138.33130864, 1788.53351052], [3355.45215983, 1873.21402971], [ 734.49504829, 1780.27688131], [ 978.1022294 , 1853.9484135 ], [1350.32991656, 1938.60371039], [3650.89052382, 1863.97713098], [3556.44897343, 2278.37901052], [ 865.41437575, 1633.53969555], [1115.59187284, 1640.49747358], [1558.06918395, 1647.12218082], [1783.86089289, 1652.74740383], [2491.20950909, 1677.42878081], [3531.11177814, 1696.89774656], [3539.47411732, 1745.49398176], [4150.01023142, 1803.35570469], [2112.84669376, 1684.92115685], [2234.65444134, 1724.86402238]]) camera.addObjectHeightInformation(feet, heads, 0.75, 0.03) ``` -------------------------------- ### Camera.getRay Source: https://github.com/rgerum/cameratransform/blob/main/docs/source/camera.md Maps image points to rays in the space coordinate system. ```APIDOC #### Camera.getRay(points: ArrayLike, normed: bool = False) -> Tuple[ArrayLike, ArrayLike] As the transformation from the **image** coordinate system to the **space** coordinate system is not unique, **image** points can only be uniquely mapped to a ray in **space** coordinates. * **Parameters:** **points** (*ndarray*) – the points in **image** coordinates for which to get the ray, dimensions (2), (Nx2) * **Returns:** * **offset** (*ndarray*) – the origin of the camera (= starting point of the rays) in **space** coordinates, dimensions (3) * **rays** (*ndarray*) – the rays in the **space** coordinate system, dimensions (3), (Nx3) ### Examples ```pycon >>> import cameratransform as ct >>> cam = ct.Camera(ct.RectilinearProjection(focallength_px=3729, image=(4608, 2592)), >>> ct.SpatialOrientation(elevation_m=15.4, tilt_deg=85)) ``` get the ray of a point in the image: ```pycon >>> offset, ray = cam.getRay([1968, 2291])) >>> offset [0.00 0.00 15.40] >>> ray [-0.09 0.97 -0.35] ``` or the rays of multiple points in the image: ```pycon >>> offset, ray, cam.getRay([[1968, 2291], [1650, 2189]]) >>> offset [0.00 0.00 15.40] >>> ray [[-0.09 0.97 -0.35] [-0.18 0.98 -0.33]] ``` ```