当前位置:网站首页>Camera calibration with OpenCV
Camera calibration with OpenCV
2022-06-27 18:49:00 【51CTO】
List of articles
- What is camera calibration , Why is it important ?
- Why use a chessboard ?
- Use OpenCV Perform camera calibration
- Print chessboard
- Measure the length of the square
- Take pictures of the chessboard from different distances and directions
- Find the corner
- Write a for camera calibration Python Code
- Output
What is camera calibration , Why is it important ?
The job of the camera is to convert the light that shines on its image sensor into an image . An image consists of picture elements called pixels .
In a perfect world , These pixels ( That is, what the camera sees ) It looks exactly like what you see in the real world . However , No camera is perfect . They all contain physical defects , In some cases, it will cause serious distortion .
for example , See the following extreme example of image distortion .

This is the same image after calibrating the camera and correcting the distortion .

Do you see that this can cause problems …… Especially in the precision critical robot technology ?
Imagine , You have a mechanical arm working in the warehouse . Its job is to pick up items from the conveyor belt and put them into the dustbin .
To help the robot determine the exact location of the object , There is a camera at the top . To obtain accurate conversion between camera pixel coordinates and real-world coordinates , You need to calibrate the camera to eliminate any distortion .
The two most important forms of distortion are radial distortion and tangential distortion .
Radial distortion occurs when the line appears to be bent . The following is an example of a radial distortion called barrel distortion . Notice that the bulge in the image makes the line ( In the real world ) It looks bent .

When the camera lens is not completely parallel to the camera sensor , Tangential distortion will occur . Tangential distortion makes the real world look stretched or tilted . It can also make objects look closer than in real life .
In order to accurately represent the real world on the camera , We have to calibrate the camera . We want to know , When we see an object of a certain size in the real world , This size is converted to a known size in the camera pixel coordinates .
for example , By calibrating the camera , We can make the manipulator have better “ Hands and eyes ” The coordinated ability . You can also let autonomous vehicle know pedestrians 、 The position of dogs and other objects relative to cars .
Calibrating the camera is done using a known real-world mode ( For example, chessboard ) To estimate the external parameters of camera lens and image ( Rotation and translation vectors ) And internal parameters ( For example, focal length 、 Optical center, etc ) Process sensors , To reduce distortion errors caused by camera defects .
These parameters include :
- The focal length
- Images ( Namely optics ) center ( Usually not entirely in ( Width /2, Height /2) It's about )
- Scaling factor for pixels along rows and columns
- skewness factor
- Lens distortion
Why use a chessboard ?

Checkerboard calibration is a standard technique , Used to perform camera calibration and estimate the values of unknown parameters I mentioned in the previous section .
OpenCV There is a checkerboard calibration Library , It tries to put the real world on the chessboard 3D Points map to 2D Camera coordinates . This information is then used to correct the distortion .
Please note that , You can use any object ( book 、 laptop 、 Automobile, etc ), But the chessboard has unique characteristics , It is very suitable for correcting camera distortion :
- It's flat , So you don't have to deal with z Axis (z=0), Just deal with x and y Axis . All the points on the chessboard are on the same plane .
- There are clear corners and points , It's easy to put 3D Points in the real world coordinate system are mapped to the camera 2D A point in a pixel coordinate system .
- Points and angles appear on a straight line .
Use OpenCV Perform camera calibration
Print chessboard
The first step is to take a chessboard and print it on a regular A4 Size paper . You can learn from OpenCV Download this... From the documentation pdf Official chessboard , Then print it out .
Measure the length of the square
Measure the side length of one of the squares . As far as I'm concerned , I measured 2.3 centimeter (0.023 rice ).
Take pictures of the chessboard from different distances and directions
We need to shoot at least from different distances and directions 10 A picture of a chessboard . I will shoot 19 A picture , So that my algorithm will have a large number of input images for performing camera calibration .
Tape the chessboard onto a flat solid object .
Taking pictures , Then move them to a directory on your computer .
Here are some examples of photos I took :

Find the corner
use Python Write the following code . You can copy and paste this code into your favorite IDE in . Select a checkerboard image as the test case . I named the file draw_corners.py. This code will draw a corner on the input chessboard image , Then save the drawing to an image file .
import
cv2
# Import the OpenCV library to enable computer vision
import
numpy
as
np
# Import the NumPy scientific computing library
# Author: Addison Sears-Collins
# https://automaticaddison.com
# Description: Detect corners on a chessboard
filename
=
'chessboard_input1.jpg'
# Chessboard dimensions
number_of_squares_X
=
10
# Number of chessboard squares along the x-axis
number_of_squares_Y
=
7
# Number of chessboard squares along the y-axis
nX
=
number_of_squares_X
-
1
# Number of interior corners along x-axis
nY
=
number_of_squares_Y
-
1
# Number of interior corners along y-axis
def
main():
# Load an image
image
=
cv2.
imread(
filename)
# Convert the image to grayscale
gray
=
cv2.
cvtColor(
image,
cv2.
COLOR_BGR2GRAY)
# Find the corners on the chessboard
success,
corners
=
cv2.
findChessboardCorners(
gray, (
nY,
nX),
None)
# If the corners are found by the algorithm, draw them
if
success
==
True:
# Draw the corners
cv2.
drawChessboardCorners(
image, (
nY,
nX),
corners,
success)
# Create the output file name by removing the '.jpg' part
size
=
len(
filename)
new_filename
=
filename[:
size
-
4]
new_filename
=
new_filename
+
'_drawn_corners.jpg'
# Save the new image in the working directory
cv2.
imwrite(
new_filename,
image)
# Display the image
cv2.
imshow(
"Image",
image)
# Display the window until any key is pressed
cv2.
waitKey(
0)
# Close all windows
cv2.
destroyAllWindows()
main()
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.

Write a for camera calibration Python Code
Now we know how to recognize the corners on the chessboard , Let's write code to perform camera calibration .
This is the code. . I put the distorted image in my working directory named “ Distortion ” In the folder of . This folder is where the output is saved undistorted .
Don't be afraid of how long the code is . To make it easier for everyone to understand each line , I put a lot of notes here . Just copy and paste the code into your favorite text editor or IDE Then you can . I named the file camera_calibration.py.
# Author: Addison Sears-Collins
# https://automaticaddison.com
# Description: Perform camera calibration using a chessboard.
import
cv2
# Import the OpenCV library to enable computer vision
import
numpy
as
np
# Import the NumPy scientific computing library
import
glob
# Used to get retrieve files that have a specified pattern
# Path to the image that you want to undistort
distorted_img_filename
=
'distorted/chessboard_input12.jpg'
# Chessboard dimensions
number_of_squares_X
=
10
# Number of chessboard squares along the x-axis
number_of_squares_Y
=
7
# Number of chessboard squares along the y-axis
nX
=
number_of_squares_X
-
1
# Number of interior corners along x-axis
nY
=
number_of_squares_Y
-
1
# Number of interior corners along y-axis
# Store vectors of 3D points for all chessboard images (world coordinate frame)
object_points
= []
# Store vectors of 2D points for all chessboard images (camera coordinate frame)
image_points
= []
# Set termination criteria. We stop either when an accuracy is reached or when
# we have finished a certain number of iterations.
criteria
= (
cv2.
TERM_CRITERIA_EPS
+
cv2.
TERM_CRITERIA_MAX_ITER,
30,
0.001)
# Define real world coordinates for points in the 3D coordinate frame
# Object points are (0,0,0), (1,0,0), (2,0,0) ...., (5,8,0)
object_points_3D
=
np.
zeros((
nX
*
nY,
3),
np.
float32)
# These are the x and y coordinates
object_points_3D[:,:
2]
=
np.
mgrid[
0:
nY,
0:
nX].
T.
reshape(
-
1,
2)
def
main():
# Get the file path for images in the current directory
images
=
glob.
glob(
'*.jpg')
# Go through each chessboard image, one by one
for
image_file
in
images:
# Load the image
image
=
cv2.
imread(
image_file)
# Convert the image to grayscale
gray
=
cv2.
cvtColor(
image,
cv2.
COLOR_BGR2GRAY)
# Find the corners on the chessboard
success,
corners
=
cv2.
findChessboardCorners(
gray, (
nY,
nX),
None)
# If the corners are found by the algorithm, draw them
if
success
==
True:
# Append object points
object_points.
append(
object_points_3D)
# Find more exact corner pixels
corners_2
=
cv2.
cornerSubPix(
gray,
corners, (
11,
11), (
-
1,
-
1),
criteria)
# Append image points
image_points.
append(
corners)
# Draw the corners
cv2.
drawChessboardCorners(
image, (
nY,
nX),
corners_2,
success)
# Display the image. Used for testing.
#cv2.imshow("Image", image)
# Display the window for a short period. Used for testing.
#cv2.waitKey(200)
# Now take a distorted image and undistort it
distorted_image
=
cv2.
imread(
distorted_img_filename)
# Perform camera calibration to return the camera matrix, distortion coefficients, rotation and translation vectors etc
ret,
mtx,
dist,
rvecs,
tvecs
=
cv2.
calibrateCamera(
object_points,
image_points,
gray.
shape[::
-
1],
None,
None)
# Get the dimensions of the image
height,
width
=
distorted_image.
shape[:
2]
# Refine camera matrix
# Returns optimal camera matrix and a rectangular region of interest
optimal_camera_matrix,
roi
=
cv2.
getOptimalNewCameraMatrix(
mtx,
dist,
(
width,
height),
1,
(
width,
height))
# Undistort the image
undistorted_image
=
cv2.
undistort(
distorted_image,
mtx,
dist,
None,
optimal_camera_matrix)
# Crop the image. Uncomment these two lines to remove black lines
# on the edge of the undistorted image.
#x, y, w, h = roi
#undistorted_image = undistorted_image[y:y+h, x:x+w]
# Display key parameter outputs of the camera calibration process
print(
"Optimal Camera matrix:")
print(
optimal_camera_matrix)
print(
"\n Distortion coefficient:")
print(
dist)
print(
"\n Rotation Vectors:")
print(
rvecs)
print(
"\n Translation Vectors:")
print(
tvecs)
# Create the output file name by removing the '.jpg' part
size
=
len(
distorted_img_filename)
new_filename
=
distorted_img_filename[:
size
-
4]
new_filename
=
new_filename
+
'_undistorted.jpg'
# Save the undistorted image
cv2.
imwrite(
new_filename,
undistorted_image)
# Close all windows
cv2.
destroyAllWindows()
main()
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
Output
This is the original distorted image .

This is an undistorted image , The output . Please note that , The distorted image has the same size as the undistorted image . Both images are 600 x 450 Pixels .

The correction is very subtle , So it may be difficult to see ( My camera must be very good !). As you see below gif As seen in , When I flip back and forth between two images , The effect will be more obvious .

边栏推荐
- MFS distributed file system
- JS event binding and common events
- Using WebDAV instead of 445 port file share
- Summary of domestic database certification test guide (updated on June 16, 2022)
- MongoDB和MySQL的区别
- MySQL中的行转列和列转行
- Lvgl8.x migrating to stm32f4
- Rxjs mergeMap 的使用场合
- 银河麒麟V10系统激活
- After the number length of Oracle exceeds 19, the entity uses long mapping. Why does this cause problems?
猜你喜欢

如何使用物联网低代码平台进行画面管理?

Open source summer 2022 | opengauss project selected and announced

JS event binding and common events

云原生数据库:数据库的风口,你也可以起飞
![[Tang Laoshi] C -- encapsulation: member method](/img/47/9a4ffd787624f6208b6aee66c38b48.jpg)
[Tang Laoshi] C -- encapsulation: member method

国内首家!EMQ加入亚马逊云科技“初创加速-全球合作伙伴网络计划”
![Contest3182 - the 39th individual training match for 2021 freshmen_ C: [string] ISBN number](/img/98/11ca12889a1b653ce8158920bf5136.jpg)
Contest3182 - the 39th individual training match for 2021 freshmen_ C: [string] ISBN number

产学合作协同育人,麒麟软件携手南开大学合力完成《软件测试与维护》实践课程

广汽三菱全新欧蓝德首次国内亮相于年内上市 产品力全面焕新

Teach you to use elastic search: run the first hello world search command
随机推荐
[Tang Laoshi] C -- encapsulation: member method
China's Industrial Software Market Research Report is released, and SCADA and MES of force control enrich the ecology of domestic industrial software
手把手教你在Windows 10安装Oracle 19c(详细图文附踩坑指南)
Bit.Store:熊市漫漫,稳定Staking产品或成主旋律
Simple anti shake for wechat applet
Openssf security plan: SBOM will drive software supply chain security
Two methods of MySQL database login and logout
Offline disk group
(POJ - 1847) tram (shortest circuit)
Vscode suggests that you enable gopls. What exactly is it?
(5) SPI application design and simulation verification 1 - logic sorting
Contest3182 - the 39th individual training match for 2021 freshmen_ E: ringring
建立自己的网站(10)
[UVM foundation] build of UVM_ Phase execution sequence
2022年信创行业空间测算
How to create a login interface
技术分享 | kubernetes pod 简介
D use in
DOM object in JS
How to turn off the server terminal name of vscode