From aee8ba5c99afe8c554b8b70e207d8eab149bb05d Mon Sep 17 00:00:00 2001 From: Russ Fish <fish@flux.utah.edu> Date: Fri, 18 Mar 2005 22:25:25 +0000 Subject: [PATCH] Simple camera simulator, including cosine distortion. --- robots/vmcd/cam-sim.awk | 103 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100755 robots/vmcd/cam-sim.awk diff --git a/robots/vmcd/cam-sim.awk b/robots/vmcd/cam-sim.awk new file mode 100755 index 0000000000..e8351ff494 --- /dev/null +++ b/robots/vmcd/cam-sim.awk @@ -0,0 +1,103 @@ +#! /usr/bin/awk -f +# +# cam-sim.awk - Simulate imaging of a floor grid into an overhead wide-angle camera. +# The default output is rows and then columns of grid points for gnuplot. +# An optional output simulates file_dumper grid points. +# A blank line separates the points along a row or column from the next one. +# +# Option vars, set with -v var=arg: +# -v floor=1 - Output floor coordinates for the grid in meters. +# -v warp=1 - Apply a radial distortion to warp the ccd coords. +# Value is the warp factor, 1.0 is a simple cosine. +# -v mm=1 - Output ccd coords in mm from the optical axis instead of in pixels. +# -v pts=1 - Output just the grid points in row-major order. +# -v fd=1 - file_dumper output, grid points in pixels plus world coords in meters. +# +# Commands: shell gnuplot +# cam-sim.awk -v floor=1 > grid.data plot "grid.data" with lines +# cam-sim.awk > nowarp.data plot "nowarp.data" with lines +# cam-sim.awk -v warp=1 > warp1.data plot "warp1.data" with lines +# cam-sim.awk -v warp=1.414 > warp2.data plot "warp2.data" with lines + +BEGIN { + # Assumptions: + # Floor units are meters, CCD units are pixels or millimeters. + # The grid origin is under the camera at the center. + # The CCD origin is at the lower left pixel of the image. + + # Do everything with matching aspect ratios for slight simplicity. + aspectX = 4; aspectY = 3; aspectRatio = aspectX / aspectY; + + # The floor grid, with the camera above its center point. + floorX = 3.000; floorY = floorX / aspectRatio; gridStep = 0.250; + halfX = floorX / 2; halfY = floorY / 2; + + # The optical center of the camera lens in meters above the floor. + ocHeight = 2.500; + + # The CCD image sensor is 1/3 inch diagonal 640x480 with a 4x3 aspect ratio. + ccdDiag = 1/3 * 25.4; xPix = 640; yPix = 480; + diagAngle = atan2(aspectY, aspectX); + ccdX = ccdDiag * cos(diagAngle); ccdY = ccdDiag * sin(diagAngle); + if ( !fd ) print "# ccdDiag", ccdDiag, "ccdX", ccdX, "ccdY", ccdY; + ## ccdDiag 8.46667 ccdX 6.77333 ccdY 5.08 + + # The lens is a varifocal wide-angle, with a focal length of 2.8 to 6 mm. + # Calculate a focal length to give a field-of-view that covers the whole grid. + focalLength = (ccdX/2) * ocHeight / halfX; + if ( !fd ) print "# focalLength", focalLength; + + # Put a grid line crossing directly under the camera. + stepsHalfX = int(halfX/gridStep); stepsHalfY = int(halfY/gridStep); + ptsX = 2 * stepsHalfX + 1; ptsY = 2 * stepsHalfY + 1; + if ( !fd ) print "# rows(ptsY)", ptsY, "cols(ptsX)", ptsX; + + # Visit the grid points. + if ( !fd ) print "# warp", warp; + for ( i = 0; i < ptsY; i++ ) { # Rows of the grid. + for ( j = 0; j < ptsX; j++ ) + point(i,j); + print ""; # Blank line separator. + } + if ( ! pts && !fd ) for ( j = 0; j < ptsX; j++ ) { # Columns of the grid. + for ( i = 0; i < ptsY; i++ ) + point(i,j); + print ""; + } +} + +function point(i,j) { + gridX = (j - stepsHalfX)*gridStep; + gridY = (i - stepsHalfY)*gridStep; + + if ( floor ) { + print gridX, gridY; + return; + } + + pixXmm = focalLength * gridX / ocHeight; + pixYmm = focalLength * gridY / ocHeight; + + if ( warp ) { + # Model barrel lens distortion as the cosine of the off-axis angle. + f = cos(warp * atan2(sqrt(gridX^2+gridY^2), ocHeight)); + pixXmm = pixXmm * f; + pixYmm = pixYmm * f; + } + + pixX = pixXmm * xPix/ccdX + xPix/2; + pixY = pixYmm * yPix/ccdY + yPix/2; + + if ( fd ) { # Simulate file_dumper output. + printf "\n+++\nsection: (%.3f, %.3f)\n", gridX, gridY; + frames++; + printf "frame %d (timestamp 1109888759.935184):\n", frames; + printf "a(%.6f,%.6f) b(%.6f,%.6f) -- wc(%.6f,%.6f,%.6f)\n+++\n", + pixX, pixY+6, pixX, pixY-6, gridX, gridY, 0.0; + } + else if ( mm ) + print pixXmm, pixYmm; + else { + print pixX, pixY; + } +} -- GitLab