基于python opencv实现广角相机标定和图像畸变矫正

42 篇文章 5 订阅
20 篇文章 1 订阅

目的:

  1. 实现相机标定,得到相机的内参以及畸变旋转参数等
  2. 尝试矫正由相机产生的图像畸变

代码:

import cv2 as cv
import numpy as np
import glob
import os

#循环中断
criteria=(cv.TERM_CRITERIA_EPS+cv.TERM_CRITERIA_MAX_ITER,30,0.001)

#标定板交叉点的个数
row=6
column=4
objp=np.zeros((row*column,3),np.float32)
objp[:,:2]=np.mgrid[0:row,0:column].T.reshape(-1,2)

objpoints=[]   #实际空间3D点
imgpoints=[]   #图像中2D点

#批量读取图片
images=glob.glob('D:\\python\\photos\\chess\\*.jpg') 

for fname in images:
    img=cv.imread(fname)
    gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    
    #找标定板角点
    ret,corners=cv.findChessboardCorners(gray,(row,column),None)
    
    if ret==True:
        objpoints.append(objp)
        
        corners2=cv.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
        imgpoints.append(corners2)
        
#标定相机
ret,Matrix,dist,rvecs,tvecs=cv.calibrateCamera(objpoints,imgpoints,gray.shape[::-1],None,None)

datadir="D:\\python\\photos\\chess\\"

path=os.path.join(datadir)
img_list=os.listdir(path)

for i in img_list:
    img=cv.imread(os.path.join(path,i))
    h,w=img.shape[:2]                                    
    newMatrix, roi = cv.getOptimalNewCameraMatrix(Matrix, dist, (w,h), 1, (w,h)) #矫正图像

    dst = cv.undistort(img, Matrix, dist, None, newMatrix)
    cv.imwrite('D:\\python\\practice\\photos\\calibrated\\'+i,dst)

#计算重投影误差
tot_error = 0
for i in range(len(objpoints)):
    imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], Matrix, dist)
    error = cv.norm(imgpoints[i],imgpoints2, cv.NORM_L2)/len(imgpoints2)
    tot_error += error

#输出参数
print('ret:\n',ret)
print('mtx:\n',Matrix)
print('dist:\n',dist)
print('rvecs:\n',rvecs)
print('tvecs:\n',tvecs)
print ("total error: ", tot_error/len(objpoints))

欢迎关注公众号:算法工程师的学习日志

好的,下面我给您讲解一下: 1. 相机标定:通过拍摄不同姿态的标定板,使用OpenCV中的calibrateCamera函数来计算相机的内参矩阵和畸变参数,从而实现相机标定。 2. 畸变矫正:通过相机标定得到的内参矩阵和畸变参数,使用OpenCV中的undistort函数来对图像进行畸变矫正,从而得到更加准确的图像。 3. 霍夫圆检测:使用OpenCV中的HoughCircles函数进行霍夫圆检测,该函数会返回检测到的圆形的圆心坐标和半径。 具体实现过程可以参考以下代码: ```python import cv2 import numpy as np # 相机标定 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) objp = np.zeros((6*7, 3), np.float32) objp[:, :2] = np.mgrid[0:7, 0:6].T.reshape(-1, 2) objpoints = [] imgpoints = [] images = glob.glob('calib/*.png') for fname in images: img = cv2.imread(fname) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, corners = cv2.findChessboardCorners(gray, (7, 6), None) if ret == True: objpoints.append(objp) corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) imgpoints.append(corners2) img = cv2.drawChessboardCorners(img, (7, 6), corners2, ret) cv2.imshow('img', img) cv2.waitKey(500) cv2.destroyAllWindows() ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) # 畸变矫正 img = cv2.imread('test.png') h, w = img.shape[:2] newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h)) dst = cv2.undistort(img, mtx, dist, None, newcameramtx) # 霍夫圆检测 gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY) circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1, minDist=100, param1=50, param2=30, minRadius=0, maxRadius=0) circles = np.uint16(np.around(circles)) for i in circles[0, :]: cv2.circle(dst, (i[0], i[1]), i[2], (0, 255, 0), 2) cv2.circle(dst, (i[0], i[1]), 2, (0, 0, 255), 3) cv2.imshow('result', dst) cv2.waitKey(0) cv2.destroyAllWindows() ``` 以上代码中,calib文件夹中存放的是标定板的图片,test.png是待检测的圆形图片。运行代码后,会弹出标定板图片,需要手动选择标定板的角点,然后程序会自动计算相机内参矩阵和畸变参数。接着会输出畸变矫正后的图片,并在图片中检测圆形并标记出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值