# Absolute Values for Depth Image

**URL:** https://discourse.vtk.org/t/absolute-values-for-depth-image/326
**Category:** Support
**Created:** [February 25, 2019, 9:05pm UTC](https://discourse.vtk.org/t/absolute-values-for-depth-image/326 "2019-02-25T21:05:00Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![banesullivan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/banesullivan/32/7143_2.png) [@banesullivan](https://discourse.vtk.org/u/banesullivan)
#### Post date: [February 25, 2019, 9:05pm UTC](https://discourse.vtk.org/t/absolute-values-for-depth-image/326/1 "2019-02-25T21:05:00Z")

</div>

When using the `vtk.vtkWindowToImageFilter` to produce a buffered image of the distances to the mesh in the rendering scene, is it possible to use the 0-1 depth ranges to recover the true distances from the camera to the mesh?

```python
... 
alg = vtk.vtkWindowToImageFilter()
alg.SetInput(ren_win)
alg.SetInputBufferTypeToZBuffer()
alg.ReadFrontBufferOff()
alg.Modified()
alg.Update()
image = alg.GetOutput()
...

```

I image I can use these 0-1 depth values and the camera projection angles to recover the true distances but exactly how would I approach this?

---

<div class="post-metadata">

### Author: ![ken-martin](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ken-martin/32/884_2.png) [@ken-martin](https://discourse.vtk.org/u/ken-martin)
#### Post date: [February 27, 2019, 3:43pm UTC](https://discourse.vtk.org/t/absolute-values-for-depth-image/326/2 "2019-02-27T15:43:57Z")

</div>

0 is the near clipping plane, 1 is that far clipping plane. The in between values depend on if you are in parallel or perspective mode. For parallel it is just linear between near/far. For perspective

```auto
zbuff = 0.5 + (near + far + 2*near*far/zval)/(2*(far - near))

zbuff - 0.5 = (near + far + 2*near*far/zval)/(2*(far - near))

(zbuff - 0.5) *2*(far - near) = near + far + 2*near*far/zval

(zbuff - 0.5) *2*(far - near) - near - far = 2*near*far/zval

((zbuff - 0.5) *2*(far - near) - near - far)/(2*near*far) = 1/zval

2*near*far/((zbuff - 0.5) *2*(far - near) - near - far) = zval

```

Where zbuff is between 0 and 1.0, near and far are the near and far clipping distances (always positive) and zval is the distance on the view plane normal from the camera (always negative values with VTK right handed coord system)

---

<div class="post-metadata">

### Author: ![banesullivan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/banesullivan/32/7143_2.png) [@banesullivan](https://discourse.vtk.org/u/banesullivan)
#### Post date: [February 27, 2019, 3:54pm UTC](https://discourse.vtk.org/t/absolute-values-for-depth-image/326/3 "2019-02-27T15:54:47Z")

</div>

What about if the view is set to perspective? Is there any functionality in VTK to assist in these calculations?

Currently, I’ve gotten myself down a rabbit hole where I think I may be close to the desired result:

```python
...# Got the image from the rendering scene as `img` NumPy image array
import numpy as np
import vtki
import matplotlib.pyplot as plt

plt.imshow(img)
plt.colorbar()
plt.show()

```

![download](https://discourse.vtk.org/uploads/default/original/1X/b1c61676d10ae594a434f79b6b132cb1a601ccb6.png)

Then I get a point cloud:

```python
def get_depth_pc(plotter,):
    ren_source = vtk.vtkRendererSource()
    ren_source.SetInput(plotter.renderer)
    ren_source.WholeWindowOff()
    ren_source.DepthValuesOn()
    ren_source.Update()
    pc = vtk.vtkDepthImageToPointCloud()
    pc.SetCamera(plotter.renderer.GetActiveCamera())
    pc.SetInputConnection(ren_source.GetOutputPort())
    pc.Update()
    return vtki.wrap(pc.GetOutput())

point_cloud = get_depth_pc(p)

```

Then I transform the points to the camera’s reference frame

```python
def get_numpy_mtx(mtx):
    vals = np.empty((3,3))
    for i in range(3):
        for j in range(3):
            vals[i,j] = mtx.GetElement(i, j)
    return vals

matrix = p.camera.GetModelViewTransformMatrix()
mtx = get_numpy_mtx(matrix)
points = point_cloud.points.dot(mtx)

```

Then I attempt to produce the depth mapped image… but it doesn’t look right:

```python
idx = np.argwhere(img.ravel() != 1.0).ravel()
depths = np.empty_like(img.ravel())
depths[:] = np.nan
depths[idx] = points[:,-1]
plt.imshow(depths.reshape(img.shape))
plt.colorbar()
plt.show()

```

![download](https://discourse.vtk.org/uploads/default/original/1X/51ea8a33cc719bf61a63cfb4642c40b22e90322e.png)

---

<div class="post-metadata">

### Author: ![ken-martin](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ken-martin/32/884_2.png) [@ken-martin](https://discourse.vtk.org/u/ken-martin)
#### Post date: [February 28, 2019, 1:15pm UTC](https://discourse.vtk.org/t/absolute-values-for-depth-image/326/4 "2019-02-28T13:15:46Z")

</div>

VTK also has

renderer-\>DisplayToWorld(x,y,z)  
renderer-\>GetWorldPoint()

---

<div class="post-metadata">

### Author: ![banesullivan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/banesullivan/32/7143_2.png) [@banesullivan](https://discourse.vtk.org/u/banesullivan)
#### Post date: [September 3, 2019, 10:51pm UTC](https://discourse.vtk.org/t/absolute-values-for-depth-image/326/5 "2019-09-03T22:51:30Z")

</div>

So I was looking back at this thread with a colleague as we’re implementing this depth mapping in PyVista as a part of a research project and we realized that I totally read your original post wrong… turns out you answered exactly what I was asking (only took ~6 months to realize it 🤦‍♂️).

For anyone who needs an elegant solution, check out this using PyVista (which will be updated in PyVista before long such the the `image_depth` attribute returns the image with depth to the camera like shown below):

```python
import numpy as np
import pyvista as pv
import matplotlib.pyplot as plt
from pyvista import examples

mesh = examples.load_random_hills()

pv.close_all()
p = pv.Plotter()
p.add_mesh(mesh, color=True)
p.show(auto_close=False)

near, far = p.camera.GetClippingRange()
zval = 2*near*far/((p.image_depth[:,:,0] - 0.5) *2*(far - near) - near - far)
zval[zval <= -far] = np.nan

plt.imshow(zval)
plt.colorbar(label='Distance to Camera')
plt.xlabel('X Pixel')
plt.ylabel('Y Pixel')

```

![download](https://discourse.vtk.org/uploads/default/original/1X/88084992542aafe35ee9acc0012d2b5e4d3473fb.png)

---

<div class="post-metadata">

### Author: ![pablospe](https://discourse.vtk.org/user_avatar/discourse.vtk.org/pablospe/32/3106_2.png) [@pablospe](https://discourse.vtk.org/u/pablospe)
#### Post date: [March 3, 2021, 9:30am UTC](https://discourse.vtk.org/t/absolute-values-for-depth-image/326/6 "2021-03-03T09:30:37Z")

</div>

How do you change the view using intrinsic/extrinsic camera parameters?

It seems that inside the function `get_image_depth()`

> <https://github.com/pyvista/pyvista/blob/641415bb80e2fcf3106d196936eba3a64b130e19/pyvista/plotting/plotting.py#L3087>

An example:  
[https://docs.pyvista.org/examples/02-plot/image\_depth.html](https://docs.pyvista.org/examples/02-plot/image_depth.html)

But I am still missing the transformation from intrinsic/extrinsic to vtk camera?

---

<div class="post-metadata">

### Author: ![pablospe](https://discourse.vtk.org/user_avatar/discourse.vtk.org/pablospe/32/3106_2.png) [@pablospe](https://discourse.vtk.org/u/pablospe)
#### Post date: [March 3, 2021, 8:21pm UTC](https://discourse.vtk.org/t/absolute-values-for-depth-image/326/7 "2021-03-03T20:21:47Z")

</div>

Ok, I have a working version for python and pyvista (VTK):

> <https://github.com/pyvista/pyvista/issues/1215>
>
> How to set camera view using intrinsic/extrinsic parameters (used for Computer Vision people)?
> intrinsic = \[f 0 cx
> 0 f cy
> 0...

I still have some questions regarding the offline rendering (off\_screen=true). My questions:

> <https://github.com/pyvista/pyvista/issues/1215#issuecomment-790026239>
>
> How to set camera view using intrinsic/extrinsic parameters (used for Computer Vision people)?
> intrinsic = \[f 0 cx
> 0 f cy
> 0...
