Pic2World is a toolbox for inferring Real World Information such as distances from Pictures and Camera Intrinsics. It also offers a set of Geometry and Image Manipulation tools, that help to deal with Homographies and Perspective while maintaining the Real World coherence.
You can install Pic2World via pip, by running the following command:
pip install pic2world
Pic2World includes 4 main modules:
pic2world.camera_utils
: Tools based on Thin-Lens Equation that allow to transform Pixel Measures into Real World Distances, when the intrinsic parameters of the camera (Inclination, Focal Length and Pixel Size) and the scene (one of Real Object Lenght or Distance to Object) are known.pic2world.homographies
: Tools based on Homographies that help to deal with Perspective Correction. Designed to produce visualizations coherent with the Real World inferred information.pic2world.geometry
: Geometry tools that help to deal with N-Dimensional polygon transformations.pic2world.interactive
: Interactive Tools, based on matplotlib, that can be used for asking information about the image to the user. For example, it include functions to let the user define or confirm a polygon over the image.
Camera Utils include two main classes, pic2world.camera_utils.camera
and pic2world.camera_utils.ruler
.
-
Camera
is used to model the Camera. It receives its intrinsics through the constructor ( Pixel Size, Focal Length and, optionally, Sensor Shape), and internally calculates and store the rest of intrinsics. For example, if we would want to analize images taken from a Canon EOS R6 mounting a 50 mm lens, we would set it as follows:from pic2world.camera_utils.camera import Camera # Build the Intrinsics of a Canon R6 CANON_EOS_R6_CAMERA = Camera( pixel_size_mm=8.18/1000.0, # Pixel size of the camera sensor. 8.18 μm focal_length_mm=50, # Focal length of the mounted lens sensor_shape_px=(5472, 3648)) # (width, height) of the sensor. Default: None. Only used for inclinations close to 0º.
There are some preset camera models that can be exported from
pic2world.camera_utils.config
-
Ruler
is the object used to transform Pixel Measures to Real World Distances using a definedCamera
and some of the Scene Intrinsics. Let's build an example using the following image:That's the information we know for this image:
- Camera: Canon EOS R6.
- 3 DIN-A4 Height: 3*30 cm.
- Distance from lens to first DIN-A4: 140 cm.
- Angle of the camera: 60 degrees.
First, we create the Ruler object
from pic2world.camera_utils.ruler import Ruler
# Create a Ruler object
ruler = Ruler(camera=CANON_EOS_R6_CAMERA)
Then, knowing how many pixels does the 3 DIN-A4 occuppy in our image we can make the following inferences:
# Let's assume that we don't know the distance between the lens and the object and calculate it.
distance_lens_to_object = ruler.distance_to_object_cm(object_length_px=1969, # Height of the object to measure in pixels
real_object_length_cm=3*30.0, # Real heigth of the 3 DIN-A4 papers.
angle_degrees=60) # Angle of the camera (0º would mean zenith).
object_height = ruler.object_length_in_cm(object_length_px=1969, # Height of the object to measure in pixels.
distance_to_object_cm=140.0, # Distance between the object and the camera lens.
angle_degrees=60) # Angle of the camera (0º would mean zenith).
Output:
>>> distance_lens_to_object: Calculated: 139.6958 cm - Real Distance: ≈ 140 cm
>>> object_height: Calculated: 90.1959 - Real Height: 90 cm
Homographies are included in the pic2world.homographies.homography_utils
module. This functions need, as input, the angle of the camera, and the bbox surrounding the object to isolate. It includes an interactive option to let the user define the bbox when it is not known.
Let's see an example with the same image used in the Camera Utils:
from pic2world.homographies.homography_utils import correct_perspective
correct_polygon_perspective(img=None,
origin_polygon=None, # We are not providing an input polygon because we want the user to define it.
interactive=True, # Ask the user to define the polygon.
angle_degrees=60 # Angle with which the image was originaly taken.
output_shape=(600, 300), # Output shape we want
pad= 0.05) # Padding between the limits of the rectangle and the border of the output image.
This library is a work in progress. It is not yet complete, and it is not meant to be used in production yet.