How to get accurate Z depth? I‘m struggling to render accurate depth maps of different 3D models using Cycles and was wondering  if anybody has/had similar problems and how she/he resolved them. I would greatly apprichiate help! :)

I attempted two different methods to obtain depth maps: 
1) Via a camera node, exporting raw Z depth.
2) By rendering the Z pass and later convert them to paralell depths as in 1). 
In both cases, I store the depth as OpenEXR files. It is my understanding that this is the go-to format in such cases as it is designed to store linear data and, thus, should not distort my Z depth information.

However, in both cases I run into the same problem: I still have inaccurate depth values. I experimented with a simple scene - just a flat plane that is fronto-paralell to the camera. On top of this plane I put a ramp. When rendering this simple scene, e.g. in case of 1), these inacuraccies manifest as staircase artefacts on the ramp. 

The thing is, I need accurate Z depths to test my algorithms on this data. So I can't turn on anti-aliasing, since that would also smooth the depth boundaries between fore- and background objects.

EDIT: 
blend-exchange.giantcowfilms.com/b/6241 &amp; imgur.com/a/mj3JeTR

Any thoughts?

Thanks,
Nici
If you want depth values that are parallel to the image plane, change the camera to orthographic projection. This will give accurate values in the Z-pass.



Edit:

Your error was having the file output node set to Float (Half) instead of Float (Full). Each file output node as its own settings! The reduced bit width resulted in the loss of precision.

Here is a little script for checking the values and displaying the normalized image. It requires OpenCV.

import cv2
import argparse

def image_values(path):
    """
    Print the pixel values of the column at the image center and display the normalized image.
    :param path: Path to image
    """
    print(path)
    img = cv2.imread(path, cv2.IMREAD_ANYDEPTH)
    (h, w) = img.shape
    print("image ({}, {})".format(h, w))
    img2 = cv2.normalize(img, None, 0., 1., cv2.NORM_MINMAX)
    for y in range(h):
            print("({},{}): {}".format(int(w/2), y, img[y, int(w/2)]))
    cv2.imshow('image', img2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Analyze image values")
    parser.add_argument("--src", type=str, help="Image to load.", required=True)
    args = parser.parse_args()
    image_values(args.src)