In [1]:
#提取所有检测图片
import glob
images = glob.glob("E:\Test_imges/*.jpg")
In [1]:
#棋盘标定
# coding=utf-8
import cv2
import numpy as np

# 设置寻找亚像素角点的参数,采用的停止准则是最大循环次数30和最大误差容限0.001
criteria = (cv2.TERM_CRITERIA_MAX_ITER | cv2.TERM_CRITERIA_EPS, 30, 0.001)

#设定棋盘横纵参数
x,y=11,8

# 获取标定板角点的位置
objp = np.zeros((x * y, 3), np.float32)
objp[:, :2] = np.mgrid[0:x, 0:y].T.reshape(-1, 2)  # 将世界坐标系建在标定板上,所有点的Z坐标全部为0,所以只需要赋值x和y

obj_points = []  # 存储3D点
img_points = []  # 存储2D点

i=0
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    size = gray.shape[::-1]
    ret, corners = cv2.findChessboardCorners(gray, (x, y), None)
    #print(corners)

    if ret:

        obj_points.append(objp)
        #在原角点的基础上寻找亚像素角点
        corners2 = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), criteria) 
        #print(corners2)
        if [corners2]:
            img_points.append(corners2)
        else:
            img_points.append(corners)

        cv2.drawChessboardCorners(img, (x, y), corners, ret)  # OpenCV的绘制函数一般无返回值
        i+=1
        cv2.imwrite('chessboard'+str(i)+'.jpg', img)
        cv2.waitKey(1500)

print(len(img_points))
cv2.destroyAllWindows()
# 标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, (3000,4000), None, None)#size图片尺寸,未设置,tuple类型

print("ret:", ret)
print("mtx:", mtx) # 内参数矩阵
print("dist:", dist)  # 畸变系数   distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
print("rvecs:", rvecs)  # 旋转向量  # 外参数
print("tvecs:", tvecs ) # 平移向量  # 外参数
10
ret: 0.6034656484375196
mtx: [[3.46706020e+03 0.00000000e+00 1.53076867e+03]
 [0.00000000e+00 3.46612170e+03 2.01506578e+03]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]
dist: [[ 2.98747578e-01 -2.38376967e+00 -1.91990369e-04  7.75053363e-04
   5.24296009e+00]]
rvecs: [array([[-0.04814146],
       [-0.19805164],
       [-0.01611279]]), array([[-0.05857207],
       [ 0.25726468],
       [-0.03622482]]), array([[-0.26283773],
       [ 0.00406836],
       [-0.02836761]]), array([[ 0.11325151],
       [-0.29267606],
       [-0.24485429]]), array([[0.03654181],
       [0.36617318],
       [0.30823712]]), array([[-0.2279373 ],
       [ 0.24614305],
       [ 0.39151749]]), array([[-0.37970194],
       [-0.06548714],
       [-0.40256486]]), array([[-0.11043704],
       [ 0.41937632],
       [-0.06089215]]), array([[-0.1349403 ],
       [-0.48651913],
       [ 0.28989606]]), array([[-0.14343477],
       [ 0.25002587],
       [-0.06997245]])]
tvecs: [array([[-3.14943299],
       [-2.68881339],
       [28.24934916]]), array([[-7.64596377],
       [-3.59689334],
       [30.44712761]]), array([[ -5.69152288],
       [-10.3377668 ],
       [ 30.3679679 ]]), array([[-3.56758529],
       [-0.45837763],
       [29.09574447]]), array([[-7.85523525],
       [-4.06623205],
       [30.06502994]]), array([[ -7.78091572],
       [-11.30186817],
       [ 36.00030819]]), array([[-4.29531013],
       [-6.94139307],
       [34.55544274]]), array([[-9.86432222],
       [-2.13682508],
       [34.93451369]]), array([[-2.4666996 ],
       [-5.25780146],
       [28.46556912]]), array([[-8.83054719],
       [-5.21811431],
       [29.64621938]])]
In [3]:
#结果预存
import numpy as np
ret = 0.6034656484375196
mtx = np.array([[3.46706020e+03, 0.00000000e+00, 1.53076867e+03],
 [0.00000000e+00, 3.46612170e+03, 2.01506578e+03],
 [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
dist = np.array([[ 2.98747578e-01, -2.38376967e+00, -1.91990369e-04,  7.75053363e-04,
   5.24296009e+00]])
rvecs = [np.array([[-0.04814146],
       [-0.19805164],
       [-0.01611279]]), np.array([[-0.05857207],
       [ 0.25726468],
       [-0.03622482]]), np.array([[-0.26283773],
       [ 0.00406836],
       [-0.02836761]]), np.array([[ 0.11325151],
       [-0.29267606],
       [-0.24485429]]), np.array([[0.03654181],
       [0.36617318],
       [0.30823712]]), np.array([[-0.2279373 ],
       [ 0.24614305],
       [ 0.39151749]]), np.array([[-0.37970194],
       [-0.06548714],
       [-0.40256486]]), np.array([[-0.11043704],
       [ 0.41937632],
       [-0.06089215]]), np.array([[-0.1349403 ],
       [-0.48651913],
       [ 0.28989606]]), np.array([[-0.14343477],
       [ 0.25002587],
       [-0.06997245]])]
tvecs: [np.array([[-3.14943299],
       [-2.68881339],
       [28.24934916]]), np.array([[-7.64596377],
       [-3.59689334],
       [30.44712761]]), np.array([[ -5.69152288],
       [-10.3377668 ],
       [ 30.3679679 ]]), np.array([[-3.56758529],
       [-0.45837763],
       [29.09574447]]), np.array([[-7.85523525],
       [-4.06623205],
       [30.06502994]]), np.array([[ -7.78091572],
       [-11.30186817],
       [ 36.00030819]]), np.array([[-4.29531013],
       [-6.94139307],
       [34.55544274]]), np.array([[-9.86432222],
       [-2.13682508],
       [34.93451369]]), np.array([[-2.4666996 ],
       [-5.25780146],
       [28.46556912]]), np.array([[-8.83054719],
       [-5.21811431],
       [29.64621938]])]
In [16]:
#单一尝试
import numpy as np
import cv2
x,y = 11,8
def draw(img, corners, imgpts):
        corner = tuple(corners[0].ravel())
        img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5) 
        img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5) 
        img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5) 
        return img

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((x * y, 3), np.float32)
objp[:,:2] = np.mgrid[0:x,0:y].T.reshape(-1,2)
axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3)

img = cv2.imread(images[2])
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, (x, y),None)
if ret == True:
    corners2 = cv2.cornerSubPix(gray,corners,(5, 5),(-1,-1),criteria)
    # Find the rotation and translation vectors.
    ret, rvecs, tvecs, inliers = cv2.solvePnPRansac(objp, corners2, mtx, dist)
    # project 3D points to image plane
    imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
    img = draw(img,corners2,imgpts) 
    cv2.imwrite("review2"+ '.jpg', img)
    cv2.imshow('showme',img)
    cv2.waitKey(0)
cv2.destroyAllWindows()
<ipython-input-16-ae4098a9d9e4>:7: DeprecationWarning: an integer is required (got type numpy.float32).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
<ipython-input-16-ae4098a9d9e4>:8: DeprecationWarning: an integer is required (got type numpy.float32).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
<ipython-input-16-ae4098a9d9e4>:9: DeprecationWarning: an integer is required (got type numpy.float32).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
In [ ]:
#相机姿态重构 P2
#创建一个函数:draw, 它的参数有棋盘上的角点(使用cv2.findChessboardCorners() 得到)和要绘制的 3D 坐标轴上的点。
import cv2
import numpy as np

def draw(img, corners, imgpts):
        corner = tuple(corners[0].ravel())
        img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5) 
        img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5) 
        img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5) 
        return img

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
objp = np.zeros((x * y, 3), np.float32)
objp[:,:2] = np.mgrid[0:x,0:y].T.reshape(-1,2)
axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3)
j=0
for fname in images: 
        img = cv2.imread(fname)
        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        ret, corners = cv2.findChessboardCorners(gray, (x, y),None)
        if ret == True:
                corners2 = cv2.cornerSubPix(gray,corners,(5, 5),(-1,-1),criteria)
                # Find the rotation and translation vectors.
                ret, rvecs, tvecs, inliers = cv2.solvePnPRansac(objp, corners2, mtx, dist)
                # project 3D points to image plane
                imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
                img = draw(img,corners2,imgpts) 
                j+=1
                cv2.imwrite("review"+ str(j)+ '.jpg', img)
                cv2.imshow('showme',img)
                cv2.waitKey(1500)
cv2.destroyAllWindows()
In [7]:
#畸变矫正
import cv2
img = cv2.imread(images[1])#随便从有畸变的图片中挑一张进行矫正
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))#显示更大范围的图片(正常重映射之后会删掉一部分图像)
print (newcameramtx)
dst = cv2.undistort(img,mtx,dist,None,newcameramtx)
x,y,w,h = roi
dst1 = dst[y:y+h,x:x+w]
cv2.imwrite('calibresult.jpg', dst1)
print ("dst的大小为:", dst1.shape)
[[3.48711987e+03 0.00000000e+00 1.53191442e+03]
 [0.00000000e+00 3.54943628e+03 2.01423843e+03]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]
dst的大小为: (3461, 2570, 3)
In [3]:
#相机姿态重构 P1
def draw(img, corners, imgpts):
    corner = tuple(corners[0].ravel())     
    img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)     
    img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
    img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
    return img

# criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# objp = np.zeros((x * y,3), np.float32)
# objp[:,:2] = np.mgrid[0:x,0:y].T.reshape(-1,2)
axis = np.float32([[3,0,0], [0,3,0], [0,0,-3]]).reshape(-1,3)

for fname in images:
    img2 = cv2.imread(fname)
    gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
    ret, corners = cv2.findChessboardCorners(gray, (x, y),None)
    if ret == True:
        corners2 = cv2.cornerSubPix(gray,corners,(5, 5),(-1,-1),criteria)
        # 找到旋转和平移矢量。
        ret,rvecs, tvecs = cv2.solvePnP(objp, corners2, mtx, dist)
        # 将3D点投影到图像平面
        imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
        img2 = draw(img2,corners2,imgpts)
        cv2.imwrite(fname[:6]+'.png', img2)    
cv2.destroyAllWindows()
<ipython-input-3-5f61c7c85e06>:4: DeprecationWarning: an integer is required (got type numpy.float32).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  img = cv2.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
<ipython-input-3-5f61c7c85e06>:5: DeprecationWarning: an integer is required (got type numpy.float32).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  img = cv2.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
<ipython-input-3-5f61c7c85e06>:6: DeprecationWarning: an integer is required (got type numpy.float32).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  img = cv2.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)