程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python computer vision camera calibration

編輯:Python

List of articles

  • python Computer vision - Camera calibration
    • One 、 Principle analysis
    • Two 、 Algorithm flow
    • 3、 ... and 、 Code
    • Four . result

python Computer vision - Camera calibration

One 、 Principle analysis

What is camera calibration ?
With the vigorous development of science and technology and economy , Robot work 、 Auto navigation and other technologies have been widely used , To a great extent, it has promoted the development of social productive forces . Whether it is active optical vision sensing or passive optical vision sensing , To infer the three-dimensional information of object space from the image , Or vice versa , Deduce two-dimensional image coordinates from three-dimensional spatial information , The spatial position and orientation of the camera in the reference coordinate system must be determined , And the geometric and optical parameters of the camera itself. Camera calibration technology is needed to solve this problem

The function of camera calibration is to eliminate the image distortion caused by the camera , Thus, the image is corrected , It provides the possibility for processing and calculating accurate values .
thus , Camera calibration has become a prerequisite for the accuracy of the system .

From the real three-dimensional world coordinates , You can get two-dimensional camera coordinates ,
But we start with two-dimensional camera coordinates , Can we accurately calculate the coordinates of the real three-dimensional world ? This is the meaning of camera calibration .

What is the principle of camera calibration ?
Camera calibration refers to establishing the relationship between camera image pixel position and scene point position , According to the camera imaging model , The correspondence between the coordinates of feature points in the image and the world coordinates , Solve the parameters of the camera model . The model parameters to be calibrated include internal parameters and external parameters .
The imaging principle of pinhole camera is to convert the real three-dimensional world coordinates to two-dimensional camera coordinates by projection , The model diagram is shown in the figure below :

As we can see from the picture , A point on a straight line in world coordinates shows only one point on the camera , Great changes have taken place , At the same time, it also loses and a lot of important information , This is exactly what we 3D The reconstruction 、 Key points and difficulties in the field of target detection and recognition . In the actual , The lens is not ideal for perspective imaging , With varying degrees of distortion . Theoretically, lens distortion includes radial distortion and tangential distortion , Tangential distortion has little effect , Usually only radial distortion is considered .

Radial distortion :
Radial distortion is mainly caused by the radial curvature of the lens ( The light is more curved away from the center of the lens than near the center ). Cause the real imaging point to deviate inward or outward from the ideal imaging point . The distorted image point is offset radially outward relative to the ideal image point , Far from the center , It's called occipital distortion ; The radial abnormal point is close to the center along the radial direction relative to the ideal point , Called barrel distortion .

Two 、 Algorithm flow

  1. Print a checkerboard diagram and paste it on a plane
  2. Take several template images from different angles
  3. Detect the feature points in the image
  4. The plane projection matrix in each image is calculated from the detected feature points H
  5. Determine the parameters of the camera

3、 ... and 、 Code

# -*- codeing =utf-8 -*-
import cv2
import numpy as np
import glob
# Find the corner of the chessboard 
# threshold 
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# Checkerboard template specification 
w = 11 # Number of inner corners , The inner corner is the point connected with other grids 
h = 8
# Checkerboard grid points in the world coordinate system , for example (0,0,0), (1,0,0), (2,0,0) ....,(8,5,0), Get rid of Z coordinate , Write it down as a two-dimensional matrix 
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
# Save the world coordinate and image coordinate pair of checkerboard corner points 
objpoints = [] # Three dimensional points in the world coordinate system 
imgpoints = [] # Two dimensional points in the image plane 
images = glob.glob('./ima/*.jpg') # Image used for calibration 
for fname in images:
img = cv2.imread(fname)
img = cv2.resize(img, (700, 375), interpolation=cv2.INTER_AREA)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the corner of the chessboard 
# Chessboard image (8 Bit grayscale or color image ) Chessboard size Where to store the corners 
ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
# If you find enough right , Store it 
if ret == True:
# Accurate corner detection 
# The input image Initial coordinates of corner points The search window is 2*winsize+1 dead zone Find the iterative termination condition of the corner 
cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
objpoints.append(objp)
imgpoints.append(corners)
# Show corners on image 
cv2.drawChessboardCorners(img, (w,h), corners, ret)
cv2.imshow('findCorners',img)
cv2.waitKey(1000)
cv2.destroyAllWindows()
# calibration 、 To distort 
# Input : Position in the world coordinate system Pixel coordinates The pixel size of the image 3*3 matrix , Camera intrinsic parameter matrix Distortion matrix 
# Output : Calibration results The internal parameter matrix of the camera Distortion coefficient Rotation matrix Translation vector 
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
# mtx: Internal parameter matrix 
# dist: Distortion coefficient 
# rvecs: Rotating vector ( External parameters )
# tvecs : Translation vector ( External parameters )
print (("ret:"),ret)
print (("mtx:\n"),mtx) # Internal parameter matrix 
print (("dist:\n"),dist) # Distortion coefficient distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
print (("rvecs:\n"),rvecs) # Rotating vector # External parameters 
print (("tvecs:\n"),tvecs) # Translation vector # External parameters 
# To distort 
img2 = cv2.imread('./ima/2.jpg')
h,w = img2.shape[:2]
# We've got intrinsic distortion coefficient of the camera , Before de distorting the image ,
# We can also use cv.getOptimalNewCameraMatrix() Optimize internal parameters and distortion coefficient ,
# By setting the free scale factor alpha. When alpha Set to 0 When ,
# It will return a clipped internal parameter and distortion coefficient that will remove the unwanted pixels after de distortion ;
# When alpha Set to 1 When , An inner parameter and distortion coefficient containing additional black pixels will be returned , And return a ROI Used to cut it out 
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) # Free scale parameter 
dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
# According to the front ROI Region crop picture 
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('./ima/calibresult.jpg',dst)
# Back projection error 
# Through the back projection error , We can evaluate the results . The closer the 0, It shows that the more ideal the result is .
# Through the internal parameter matrix calculated before 、 Distortion coefficient 、 Rotation matrix and translation vector , Use cv2.projectPoints() Calculate the projection from 3D points to 2D images ,
# Then calculate the error between the point obtained by back projection and the point detected on the image , Finally, calculate an average error for all calibrated images , This value is the back projection error .
total_error = 0
for i in range(len(objpoints)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
total_error += error
print (("total error: "), total_error/len(objpoints))

Four . result

Input picture sample :

Output :

Output parameters :

ret: 3.2089084482428625
mtx:
[[298.22403646 0. 349.40224378]
[ 0. 249.9301803 308.87597705]
[ 0. 0. 1. ]]
dist:
[[-0.01542965 -0.05742923 0.04474822 0.0136368 0.01877975]]
rvecs:
[array([[-0.30947814],
[ 0.33401078],
[ 2.41641327]]), array([[-0.11406369],
[-0.03094208],
[ 1.12212397]]), array([[-0.09734436],
[-0.01784972],
[ 1.48696195]]), array([[-0.2939506 ],
[ 0.50513446],
[ 3.02645373]]), array([[0.09769781],
[0.37093298],
[3.07432249]]), array([[-0.14125134],
[-0.40375224],
[-1.67651102]]), array([[-0.15323876],
[-0.37674176],
[-1.65194111]]), array([[-0.065466 ],
[-0.36197005],
[-1.95960452]]), array([[ 0.13847532],
[-0.1150688 ],
[-2.01085342]]), array([[-0.17608388],
[-0.32411952],
[-1.32817709]]), array([[-0.20703879],
[ 0.00763589],
[ 0.28986026]])]
tvecs:
[array([[ 8.9229434 ],
[-8.32737698],
[16.89551684]]), array([[ 0.87209331],
[-15.33212787],
[ 13.59312779]]), array([[ 3.59921773],
[-14.90849088],
[ 13.571556 ]]), array([[ 4.8131481 ],
[-2.24922584],
[14.75699795]]), array([[ 3.22211236],
[-1.80439912],
[13.44002642]]), array([[-2.34496458],
[-2.33449517],
[12.09128798]]), array([[-2.22919308],
[-2.35073525],
[12.0281442 ]]), array([[-2.13702847],
[-2.76957196],
[12.54089188]]), array([[-1.05509505],
[-5.39874714],
[12.34265496]]), array([[-1.72209533],
[-2.87686218],
[13.2875987 ]]), array([[ -4.15293414],
[-12.73524946],
[ 14.8851007 ]])]
total error: 0.3381936202146006

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved