Calibrate a Camera

To calibrate a camera, you can use the classical example of a chessboard. The chessboard is often used because the geometry makes it a good test case for detection and processing.

Prerequisites

The calibration code uses the numpy and opencv-python packages. To follow along, install the libraries:

pip3 install numpy
pip3 install opencv-python

Instructions

  1. Print out the checkerboard and attach it to a flat surface that doesn’t distort the checkerboard. Good surfaces are completely flat like a table, an non-textured wall or an acrylic plate. Do not hold the image in the air with your hands or tape it to a textured surface such as a textured wall, cardboard, or folder.

  2. Take images of the checkerboard with your camera from various angles and distances that show the entire image, including the edges. Ensure the image is well and thoroughly lit to avoid distortions affecting the vision algorithms. You can use the Export screenshot button on the camera panel of your machine’s CONTROL tab in the Viam app. Save between 10 - 15 images (see examples).

    Example of good images: Example of good images

  3. Save cameraCalib.py

  4. Run python3 cameraCalib.py YOUR_PICTURES_DIRECTORY.

    Example output:

    "intrinsic_parameters": {
        "fy": 940.2928257873841,
        "height_px": 480,
        "ppx": 320.6075282958033,
        "ppy": 239.14408757087756,
        "width_px": 640,
        "fx": 939.2693584627577
    },
    "distortion_parameters": {
        "rk2": 0.8002516496932317,
        "rk3": -5.408034254951954,
        "tp1": -0.000008996658362365533,
        "tp2": -0.002828504714921335,
        "rk1": 0.046535971648456166
    }
    
  5. Copy the output which contains the intrinsic_parameters and distortion_parameters into the JSON config on your machine’s CONFIGURE tab.

Config tab with configuration snippet highlighted

The following is a full example config:

{
  "components": [
    {
      "name": "color",
      "model": "webcam",
      "type": "camera",
      "namespace": "rdk",
      "attributes": {
        "intrinsic_parameters": {
          "fy": 940.2928257873841,
          "height_px": 480,
          "ppx": 320.6075282958033,
          "ppy": 239.14408757087756,
          "width_px": 640,
          "fx": 939.2693584627577
        },
        "distortion_parameters": {
          "rk2": 0.8002516496932317,
          "rk3": -5.408034254951954,
          "tp1": -0.000008996658362365533,
          "tp2": -0.002828504714921335,
          "rk1": 0.046535971648456166
        },
        "stream": "",
        "debug": false,
        "format": "",
        "video_path": "video0",
        "width_px": 0,
        "height_px": 0
      },
      "depends_on": []
    }
  ]
}

Next steps

For more configuration and usage info, see:

Have questions, or want to meet other people working on robots? Join our Community Discord.

If you notice any issues with the documentation, feel free to file an issue or edit this file.