What I am trying to do is extract the bounding box location of a spherical object in the camera frame, in terms of pixels. Using the function:

world_to_camera = bpy_extras.object_utils.world_to_camera_view(scene, camera, tracked_actual_location)

The outputs of this function are:

world_to_camera[0] -> X-location from 0-1
world_to_camera[1] -> Y-location from 0-1
world_to_camera[2] -> Depth on the view axis 

My first question that I can't verify is: Is world_to_camera[2] the actual distance between the camera plane and the tracked_object plane? If so, the following code calculates what I want:

apparent_size = (actual_size * focal_length)/world_to_camera[2]
x_resolution = scene.render.resolution_x
pixel_pitch_x = focal_length/x_resolution
width_in_pixels = apparent_size/pixel_pitch_x

I have reason to believe it is not correct because for my object configuration I am getting a result of width_in_pixels = 0.83, whereas zooming at the rendered image it has a width and height of 3 pixels. Any clarification will be appreciated.


1 Answer 1


Ok, I think I found my mistake. The output from world_to_camera[2] is the actual planar distance that should be used for the calculation. However, instead of using the focal length of the camera to calculate the pixel pitch, the camera sensor width should be used instead such that:

sensor_width = camera.data.sensor_width/1000
pixel_pitch_x = sensor_width/x_resolution # [m]

The output for my previous configuration is now 1.006 pixels, which also explains why the rendered image fills 3 pixels. The way I see it, the resolution of the camera is not fine enough and therefore it interpolates the 0.006/2 pixels in each direction by filing them with a lower pixel intensity value.

The link to the reference that got me to use the sensor width instead of the focal length: http://www.robsphotography.co.nz/crop-factor-advantage-appendix-2.html


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .