diff --git a/applications/gui/src/camera.cpp b/applications/gui/src/camera.cpp
index a4880a550661c8225bb431c34acb06f11dfb60d4..de1518695bb7b96d8871f64c180c702e822062bb 100644
--- a/applications/gui/src/camera.cpp
+++ b/applications/gui/src/camera.cpp
@@ -268,7 +268,7 @@ void ftl::gui::Camera::_draw(ftl::rgbd::FrameSet &fs) {
 			pos /= pos[3];
 
 			auto name = fs.frames[i].get<std::string>("name");
-			ftl::overlay::drawPoseCone(state_.getLeft(), im1_, over_depth, pose, cv::Scalar(0,0,255,255), 0.2);
+			ftl::overlay::drawCamera(state_.getLeft(), im1_, over_depth, fs.frames[i].getLeftCamera(), pose, cv::Scalar(0,0,255,255), 0.2,screen_->root()->value("show_frustrum", false));
 			if (name) ftl::overlay::drawText(state_.getLeft(), im1_, over_depth, *name, pos, 0.5, cv::Scalar(0,0,255,255));
 		}
 	}
diff --git a/applications/gui/src/overlay.cpp b/applications/gui/src/overlay.cpp
index f38d1056f44f23d7bb0a3adc4755b11e08f4476f..f5460febc689584dcdca6dc24c5c12a3f9383081 100644
--- a/applications/gui/src/overlay.cpp
+++ b/applications/gui/src/overlay.cpp
@@ -110,6 +110,70 @@ void ftl::overlay::drawPoseCone(
     draw3DLine(cam, colour, depth, p110, origin, linecolour);
 }
 
+void ftl::overlay::drawCamera(
+        const ftl::rgbd::Camera &vcam,
+        cv::Mat &colour,
+        cv::Mat &depth,
+        const ftl::rgbd::Camera &camera,
+        const Eigen::Matrix4d &pose,
+        const cv::Scalar &linecolour,
+        double scale, bool frustrum) {
+
+    //double size2 = size;
+
+    const auto &params = camera;
+    double width = (static_cast<double>(params.width) / static_cast<double>(params.fx)) * scale;
+    double height = (static_cast<double>(params.height) / static_cast<double>(params.fx)) * scale;
+    double width2 = width / 2.0;
+    double height2 = height / 2.0;
+
+    double principx = (((static_cast<double>(params.width) / 2.0) + params.cx) / static_cast<double>(params.fx)) * scale;
+    double principy = (((static_cast<double>(params.height) / 2.0) + params.cy) / static_cast<double>(params.fx)) * scale;
+
+    Eigen::Vector4d p110 = pose.inverse() * Eigen::Vector4d(-width2,-height2,scale,1);
+    Eigen::Vector4d p100 = pose.inverse() * Eigen::Vector4d(-width2,height2,scale,1);
+    Eigen::Vector4d p010 = pose.inverse() * Eigen::Vector4d(width2,-height2,scale,1);
+    Eigen::Vector4d p000 = pose.inverse() * Eigen::Vector4d(width2,height2,scale,1);
+    Eigen::Vector4d origin = pose.inverse() * Eigen::Vector4d(principx,principy,0,1);
+
+    p110 /= p110[3];
+    p100 /= p100[3];
+    p010 /= p010[3];
+    p000 /= p000[3];
+    origin /= origin[3];
+
+    if (origin[2] < 0.1 || p110[2] < 0.1 || p100[2] < 0.1 || p010[2] < 0.1 || p000[2] < 0.1) return;
+
+    draw3DLine(vcam, colour, depth, p000, origin, linecolour);
+    draw3DLine(vcam, colour, depth, p000, p010, linecolour);
+    draw3DLine(vcam, colour, depth, p000, p100, linecolour);
+
+    draw3DLine(vcam, colour, depth, p010, origin, linecolour);
+    draw3DLine(vcam, colour, depth, p010, p110, linecolour);
+
+    draw3DLine(vcam, colour, depth, p100, origin, linecolour);
+    draw3DLine(vcam, colour, depth, p100, p110, linecolour);
+
+    draw3DLine(vcam, colour, depth, p110, origin, linecolour);
+
+    if (frustrum) {
+        const double fscale = 16.0;
+        Eigen::Vector4d f110 = pose.inverse() * Eigen::Vector4d(-width2*fscale,-height2*fscale,scale*fscale,1);
+        Eigen::Vector4d f100 = pose.inverse() * Eigen::Vector4d(-width2*fscale,height2*fscale,scale*fscale,1);
+        Eigen::Vector4d f010 = pose.inverse() * Eigen::Vector4d(width2*fscale,-height2*fscale,scale*fscale,1);
+        Eigen::Vector4d f000 = pose.inverse() * Eigen::Vector4d(width2*fscale,height2*fscale,scale*fscale,1);
+        draw3DLine(vcam, colour, depth, f000, p000, cv::Scalar(0,255,0,0));
+        draw3DLine(vcam, colour, depth, f010, p010, cv::Scalar(0,255,0,0));
+        draw3DLine(vcam, colour, depth, f100, p100, cv::Scalar(0,255,0,0));
+        draw3DLine(vcam, colour, depth, f110, p110, cv::Scalar(0,255,0,0));
+
+        draw3DLine(vcam, colour, depth, f000, f010, cv::Scalar(0,255,0,0));
+        draw3DLine(vcam, colour, depth, f000, f100, cv::Scalar(0,255,0,0));
+        draw3DLine(vcam, colour, depth, f010, f110, cv::Scalar(0,255,0,0));
+        draw3DLine(vcam, colour, depth, f100, f110, cv::Scalar(0,255,0,0));
+    }
+}
+
 void ftl::overlay::drawText(
         const ftl::rgbd::Camera &cam,
         cv::Mat &colour,
diff --git a/applications/gui/src/overlay.hpp b/applications/gui/src/overlay.hpp
index 336dee0be055d6ca092a2377c1a0a269554568b3..d9ce665724bbf94c9382bfe4b5b7e12c3307a093 100644
--- a/applications/gui/src/overlay.hpp
+++ b/applications/gui/src/overlay.hpp
@@ -3,7 +3,7 @@
 
 #include <opencv2/core/mat.hpp>
 #include <Eigen/Eigen>
-#include <ftl/rgbd/camera.hpp>
+#include <ftl/rgbd/frame.hpp>
 
 namespace ftl {
 namespace overlay {
@@ -44,6 +44,16 @@ void drawPoseCone(
     const cv::Scalar &linecolour,
     double size);
 
+void drawCamera(
+    const ftl::rgbd::Camera &cam,
+    cv::Mat &colour,
+    cv::Mat &depth,
+    const ftl::rgbd::Camera &camera,
+    const Eigen::Matrix4d &pose,
+    const cv::Scalar &linecolour,
+    double scale=1.0,
+    bool frustrum=false);
+
 }
 }