Python使用OpenCV进行标定

这篇文章主要介绍了关于python使用opencv进行标定,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

本文结合OpenCV官方样例,对官方样例中的代码进行修改,使其能够正常运行,并对自己采集的数据进行实验和讲解。

一、准备

OpenCV使用棋盘格板进行标定,如下图所示。为了标定相机,我们需要输入一系列三维点和它们对应的二维图像点。在黑白相间的棋盘格上,二维图像点很容易通过角点检测找到。而对于真实世界中的三维点呢?由于我们采集中,是将相机放在一个地方,而将棋盘格定标板进行移动变换不同的位置,然后对其进行拍摄。所以我们需要知道(X,Y,Z)的值。但是简单来说,我们定义棋盘格所在平面为XY平面,即Z=0。对于定标板来说,我们可以知道棋盘格的方块尺寸,例如30mm,这样我们就可以把棋盘格上的角点坐标定义为(0,0,0),(30,0,0),(60,0,0),···,这个结果的单位是mm。

3D点称为object points,2D图像点称为image points。

立即学习“Python免费学习笔记(深入)”;

Python使用OpenCV进行标定

二、检测棋盘格角点

为了找到棋盘格模板,我们使用openCV中的函数cv2.findChessboardCorners()。我们也需要告诉程序我们使用的模板是什么规格的,例如8*8的棋盘格或者5*5棋盘格等,建议使用x方向和y方向个数不相等的棋盘格模板。下面实验中,我们使用的是10*7的棋盘格,每个方格边长是20mm,即含有9*6的内部角点。这个函数如果检测到模板,会返回对应的角点,并返回true。当然不一定所有的图像都能找到需要的模板,所以我们可以使用多幅图像进行定标。除了使用棋盘格,我们还可以使用圆点阵,对应的函数为cv2.findCirclesGrid()。

找到角点后,我们可以使用cv2.cornerSubPix()可以得到更为准确的角点像素坐标。我们也可以使用cv2.drawChessboardCorners()将角点绘制到图像上显示。如下图所示:

Python使用OpenCV进行标定

三、标定

通过上面的步骤,我们得到了用于标定的三维点和与其对应的图像上的二维点对。我们使用cv2.calibrateCamera()进行标定,这个函数会返回标定结果、相机的内参数矩阵、畸变系数、旋转矩阵和平移向量。

四、去畸变

第三步我们已经得到了相机内参和畸变系数,在将图像去畸变之前,我们还可以使用cv.getOptimalNewCameraMatrix()优化内参数和畸变系数,通过设定自由自由比例因子alpha。当alpha设为0的时候,将会返回一个剪裁过的将去畸变后不想要的像素去掉的内参数和畸变系数;当alpha设为1的时候,将会返回一个包含额外黑色像素点的内参数和畸变系数,并返回一个ROI用于将其剪裁掉。

然后我们就可以使用新得到的内参数矩阵和畸变系数对图像进行去畸变了。有两种方法进行去畸变:

(1)使用cv2.undistort()

这是一个最直接的办法,只用直接调用函数就可以得到去畸变的图像,使用上面的ROI可以对其进行剪裁。代码如下:

# undistortdst = cv2.undistort(img, mtx, dist, None, newcameramtx)# crop the imagex,y,w,h = roidst = dst[y:y+h, x:x+w]cv2.imwrite('calibresult.png',dst)

登录后复制

下图显示将一张图片去畸变后,保留黑色像素的结果:

Python使用OpenCV进行标定

(2)使用remmaping

这是一个分两步的方法,首先计算一个从畸变图像到非畸变图像的映射,然后使用这个映射关系对图像进行去畸变。
代码如下:

# undistortmapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)# crop the imagex,y,w,h = roidst = dst[y:y+h, x:x+w]cv2.imwrite('calibresult.png',dst)

登录后复制

五、反投影误差

通过反投影误差,我们可以来评估结果的好坏。越接近0,说明结果越理想。通过之前计算的内参数矩阵、畸变系数、旋转矩阵和平移向量,使用cv2.projectPoints()计算三维点到二维图像的投影,然后计算反投影得到的点与图像上检测到的点的误差,最后计算一个对于所有标定图像的平均误差,这个值就是反投影误差。

代码

所有步骤的代码如下所示:

#coding:utf-8import cv2import numpy as npimport glob# 找棋盘格角点# 阈值criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)#棋盘格模板规格w = 9h = 6# 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为二维矩阵objp = np.zeros((w*h,3), np.float32)objp[:,:2] = np.mgrid[0:w,0:h].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, (w,h),None) # 如果找到足够点对,将其存储起来 if ret == True:  cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)  objpoints.append(objp)  imgpoints.append(corners)  # 将角点在图像上显示  cv2.drawChessboardCorners(img, (w,h), corners, ret)  cv2.imshow('findCorners',img)  cv2.waitKey(1)cv2.destroyAllWindows()# 标定ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)# 去畸变img2 = cv2.imread('calib/00169.png')h, w = img2.shape[:2]newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) # 自由比例参数dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)# 根据前面ROI区域裁剪图片#x,y,w,h = roi#dst = dst[y:y+h, x:x+w]cv2.imwrite('calibresult.png',dst)# 反投影误差total_error = 0for i in xrange(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 += errorprint "total error: ", total_error/len(objpoints)

登录后复制

相关推荐:

OpenCVcv::Mat中的数据写入txt文件中

OpenCV cv.Mat与.txt文件数据的读写操作

以上就是Python使用OpenCV进行标定的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2262408.html

(0)
上一篇 2025年2月27日 06:53:46
下一篇 2025年2月27日 06:54:00

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Python 统计字数的思路详解

    这篇文章主要介绍了python 统计字数的思路详解,文中还给大家提供了不借助第三方模块的解决方法,感兴趣的朋友一起看看吧  问题描述: 用 Python 实现函数 count_words(),该函数输入字符串 s 和数字 n,返回 s 中 …

    编程技术 2025年2月27日
    200
  • 编程中常用的语言有哪些种类

    编程语言种类包括:编译型语言:提高执行速度(例:C、Java)解释型语言:逐行执行,速度较慢(例:Python、JavaScript)面向对象语言:强调数据封装、继承(例:C++、Python)面向过程语言:强调程序流程(例:C、Fortr…

    2025年2月27日
    200
  • Python 使用PIL numpy 实现拼接图片

    这篇文章主要介绍了关于python 使用pil numpy 实现拼接图片,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 python纵向合并任意多个图片,files是要拼接的文件list # -*- coding:utf-8…

    编程技术 2025年2月27日
    200
  • 编程语言入门哪个比较实用

    最适用的入门编程语言:Python:简单好用,适用于数据科学、Web 开发和自动化。Java:稳定可靠,适用于企业软件和移动应用程序开发。C++:高性能、适用于操作系统和游戏开发。JavaScript:易于使用,适用于Web 应用程序和移动…

    2025年2月27日
    200
  • 对Python 网络设备巡检脚本的实例讲解

    这篇文章主要介绍了关于对python 网络设备巡检脚本的实例讲解,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 1、基本信息 我公司之前采用的是人工巡检,但奈何有大量网络设备,往往巡检需要花掉一上午(还是手速快的话),浪费时…

    2025年2月27日
    200
  • 计算机编程语言有几种

    截至 2023 年 3 月,已知存在超过 700 种编程语言。它们可根据特性和用途进行分类,如面向过程、面向对象和函数式语言等。目前最流行的语言包括 Python、C、Java、C++ 和 C# 等。选择编程语言取决于项目需求、开发人员技能…

    2025年2月27日
    200
  • Python基于win32ui模块创建弹出式菜单

    这篇文章主要介绍了python基于win32ui模块创建弹出式菜单,结合实例形式分析了python使用win32ui模块创建弹出式菜单的具体步骤与相关操作技巧,并附带说明了win32ui模块的安装命令,需要的朋友可以参考下 本文实例讲述了P…

    编程技术 2025年2月27日
    200
  • 编程的软件是用什么语言编写的

    编程语言是一种正式语言,用于程序员与计算机交互,描述计算机应执行的任务。常用的编程语言包括:C++、Java、Python、C# 和 JavaScript。每种语言都有其优点和缺点,选择取决于项目需求和目标平台。 编程软件的语言 编程软件本…

    2025年2月27日
    200
  • Python使用Windows API创建窗口示例

    这篇文章主要介绍了python使用windows api创建窗口操作,结合实例形式分析了python基于win32gui模块调用windows api创建窗口具体操作步骤与相关实现技巧,需要的朋友可以参考下 本文实例讲述了Python使用W…

    编程技术 2025年2月27日
    200
  • 电脑编程语言有几种语言啊

    计算机编程语言类型分为:面向过程语言、面向对象语言、函数式语言、声明性语言和脚本语言。选择一种语言取决于任务、程序员技能、社区支持和生态系统。 根据应用需求,不同编程语言可以组合使用。 计算机编程语言の種類 计算机编程语言是计算机与程序员之…

    2025年2月27日
    200

发表回复

登录后才能评论