Bazinga_521 2020-08-18 15:28 采纳率: 16.7%
浏览 320

图片畸变矫正过程中的参数调节

最近在学习相机标定和图片的畸变矫正,看了张氏标定法和关于畸变矫正的博客和代码。
自己根据opencv官方文档的介绍,仿写了标定和矫正代码,但是效果一直不满意,或者说效果达不到预期,特来求助各位大佬。
因为标定过程中用的棋盘格是用手机拍摄的,为了控制变量因素,待矫正的图片也选择用手机拍摄的,图片如下_
****

这是用手机拍摄的图片

这是矫正后的图片

第一张是畸变图片,第二张是矫正后的图片
从矫正后的图片可以看出,效果好像只是在原畸变图片的基础上进行了裁剪,并没有达到矫正的作用。

于是,又选择了一张网图进行测试。效果如下:
原图
矫正后
从第二张矫正后的图片可以看出,左上角畸变反而更严重了
经过一番尝试之后,还是不懂代码里边的参数怎么调节,请大神看了之后,给点拨迷津。
附上标定用的棋盘格:
标定用
这种棋盘格,用手机拍的,共使用了18张,不同角度的图片。

**下边,附上源代码:
**

import numpy as np
import cv2 as cv
import glob
import matplotlib.pyplot as plt

#终止条件
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER,30,0.001)
#准备对象点
objp = np.zeros((9*6,3),np.float32)
objp[:,:2] = np.mgrid[0:6,0:9].T.reshape(-1,2)
#用于存储所有图像的对象点和图像点的数组、
objpoints = []
imgpoints = []
images = glob.glob('C:\\Users\\16238\\Desktop\\board\\*.jpg')
for fname in images:
    img = cv.imread(fname)
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    #找到棋盘格角点
    ret,corners = cv.findChessboardCorners(gray,(6,9),None)
    #如果找到,添加对象点,图像点(细化)
    if ret == True:
        objpoints.append(objp)
        corners2 = cv.cornerSubPix(gray,corners,(15,15),(-1,-1),criteria)
        imgpoints.append(corners)
        #绘制并显示角点
        cv.drawChessboardCorners(img,(6,9),corners2,ret)
        #cv.imshow('img',img)
        cv.waitKey(0)
cv.destroyAllWindows()

import pickle

ret,mtx,dist,rvecs,tvecs = cv.calibrateCamera(objpoints,imgpoints,gray.shape[::-1],None,None)

print("ret:",ret)
print("mtx:\n",mtx)#内参矩阵
print("dist:\n",dist)#畸变系数
print("rvecs:\n",rvecs)#旋转向量
print("tvecs:\n",tvecs)#平移向量

img = cv.imread('1.jpg')
h,w = img.shape[:2]
newcameramtx,roi = cv.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h))

dst = cv.undistort(img,mtx,dist,None,newcameramtx)
#对给定的目标和图像点进行摄像机标定


dst = cv.undistort(img,mtx,dist,None,newcameramtx)

#使用remapping
mapx,mapy = cv.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv.remap(img,mapx,mapy,cv.INTER_LINEAR)
#裁剪图像
#x,y,w,h = roi
#dst = dst[y:y+w,x:x+h]
cv.imwrite('undistort.jpg',dst)


mean_error = 0
for i in range(len(objpoints)):
    imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2)/len(imgpoints2)
    mean_error += error
print("total error: ", mean_error/len(objpoints))

  • 写回答

1条回答 默认 最新

  • zqbnqsdsmd 2020-08-20 09:31
    关注
    评论

报告相同问题?

悬赏问题

  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码