Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example for setting camera intrinsics in VTK using python
import vtk
import numpy as np
from vtk.util import numpy_support
import cv2
class Camera_VTK():
"""
Example class showing how to project a 3D world coordinate onto a 2D image plane using VTK
"""
def __init__(self, w, h, P, K):
self.w = w
self.h = h
self.P = P # position of 3D sphere
self.K = K # Camera matrix
self.f = np.array( [K[0,0], K[1,1]] ) # focal lengths
self.c = K[:2,2] # principal point
# projection of 3D sphere center onto the image plane
self.p_im = np.dot(self.K,P.reshape(3,1)).flatten()
self.p_im /= self.p_im[-1]
self.init_vtk()
def getImage(self):
"""
Render a sphere using VTK into an image, and plot the projection of that sphere onto the image plane. They should coincide
"""
# Set basic camera parameters in VTK
cam = self.renderer.GetActiveCamera()
near = 0.1
far = 1000.0
cam.SetClippingRange(near, far)
# Position is at origin, looking in z direction with y down
cam.SetPosition(0, 0, 0)
cam.SetFocalPoint(0, 0, 1)
cam.SetViewUp(0, -1, 0)
w,h = self.w, self.h
# Set window center for offset principal point
wcx = -2.0*(self.c[0] - self.w / 2.0) / self.w
wcy = 2.0*(self.c[1] - self.h / 2.0) / self.h
cam.SetWindowCenter(wcx, wcy)
# Set vertical view angle as a indirect way of setting the y focal distance
angle = 180 / np.pi * 2.0 * np.arctan2(self.h / 2.0, self.f[1])
cam.SetViewAngle(angle)
# Set the image aspect ratio as an indirect way of setting the x focal distance
m = np.eye(4)
aspect = self.f[1]/self.f[0]
m[0,0] = 1.0/aspect
t = vtk.vtkTransform()
t.SetMatrix(m.flatten())
cam.SetUserTransform(t)
# Render the scene into a numpy array for openCV processing
self.renWin.Render()
winToIm = vtk.vtkWindowToImageFilter()
winToIm.SetInput(self.renWin)
winToIm.Update()
vtk_image = winToIm.GetOutput()
width, height, _ = vtk_image.GetDimensions()
vtk_array = vtk_image.GetPointData().GetScalars()
components = vtk_array.GetNumberOfComponents()
arr = cv2.flip(numpy_support.vtk_to_numpy(vtk_array).reshape(height, width, components), 0)
arr = cv2.cvtColor(arr, cv2.COLOR_BGR2RGB)
# Draw a circle at the projected place of the 3D sphere onto the image plane
cv2.circle(arr,(int(self.p_im[0]),int(self.p_im[1])),5,(0,0,255),1)
return arr
def init_vtk(self):
"""
Initialize VTK actors and rendering pipeline
"""
self.shpereSource = vtk.vtkSphereSource()
self.shpereSource.SetCenter(self.P[0],self.P[1],self.P[2])
self.shpereSource.SetRadius(1.0)
self.shperemapper = vtk.vtkPolyDataMapper()
self.shperemapper.SetInputConnection(self.shpereSource.GetOutputPort())
self.shpereactor = vtk.vtkActor()
self.shpereactor.SetMapper(self.shperemapper)
self.renderer = vtk.vtkRenderer()
self.renWin = vtk.vtkRenderWindow()
self.renWin.SetOffScreenRendering(1)
self.renderer.AddActor(self.shpereactor)
self.renderer.SetBackground(0.1, 0.2, 0.4)
self.renderer.ResetCamera()
self.renWin.AddRenderer(self.renderer)
self.renWin.SetSize(self.w, self.h)
self.renWin.Render()
if __name__ == '__main__':
fx = 500.0
fy = 400.0
cx = 395.0
cy = 275.0
w = 760
h = 570
K = np.array( [ [fx, 0., cx],
[ 0. ,fx, cy],
[0.,0.,1.]])
P = np.array([ 11.14230157 , 11.23046172 , 28.56272345])
test = Camera_VTK(w,h,P,K)
arr = test.getImage()
cv2.imshow("test", arr)
cv2.waitKey(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.