To retrieve information about the objects that lie behind each pixel, I have to cast rays into the scene for each pixel of a rendered frame.
My problem is that the ray directions which I calculate are not correct.
The eye rays that I generate do not match my image frame vertically (they either start/end outside of it, or too far inside).
For example here is the first direction(top left of the image space) that i calculate

And here is the last direction (bottom right of the image space)

I think that maybe my calculation of the vertical field of view might be off. But so far I have not been able to fix it.
#calculates the direction the ray has to take for a u, v coordinate
def get_ray_direction(u, v, position, direction, up, right, width, height):
#mapping the u and v coordinates into normalised image coordinates
x = ((2*u - width)/width)
y = ((2*v - height)/height)
direction = x * right + y * up + direction + position
return direction
s = bpy.data.scenes["Scene"]
cam = s.camera
camData = cam.data
view_direction = cam.matrix_world.to_quaternion() * Vector((0.0, 0.0, -1.0))
up = cam.matrix_world.to_quaternion() * Vector((0.0, 1.0, 0.0))
aspect_ratio = s.render.resolution_x / s.render.resolution_y
right = mathutils.Vector.cross(view_direction, up)
up = up.normalized()
right = right.normalized()
#For the FOV I have to use the focal length and sensor size as base values
#since I will be given these values and have to set the camera accordingly
#I took the formula from: http://paulbourke.net/miscellaneous/lens/
fov_v = 2 * math.atan((camData.sensor_height * 0.5) / camData.lens)
fov_h = 2 * math.atan((camData.sensor_width * 0.5) / camData.lens)
up = up * math.tan(fov_v/2)
right = right * math.tan(fov_h/2)
height = s.render.resolution_y/1.0
width = s.render.resolution_x/1.0
#Starting top left, going row by row
for i in reversed(range(s.render.resolution_y)):
for j in range(s.render.resolution_x):
dir = get_ray_direction(j, i, pos, view_direction, up, right, width, height)
ray_dir = dir * 10000
ray_result = s.ray_cast(cam.location, ray_dir);