基于OpenCV的摄像机标定
opencv calibratecameracharuco工作原理

opencv calibratecameracharuco工作原理OpenCV是一个开源计算机视觉库,其中的calibrateCameraCharuco函数用于相机标定。
此函数的工作原理如下:相机标定是计算机视觉中的重要任务之一,它用于估计相机的内参矩阵和畸变参数。
内参矩阵包含了相机的焦距、光心等信息,而畸变参数用于补偿镜头失真引起的图像畸变。
Charuco是Chessboard和ArUco Marker的结合体。
Charuco棋盘是一种具有一些特殊标记的人工印刷棋盘,它可以提供更高的位姿精度和更好的平面几何稳定性。
ArUco Marker是一种能够被计算机自动识别的二维码。
calibrateCameraCharuco函数的工作原理如下:1. 准备相机和Charuco棋盘:使用相机拍摄一系列具有不同位姿的Charuco棋盘图像。
这些图像应涵盖场景中所有感兴趣的视角和深度范围。
2. 检测Charuco角点:使用OpenCV的detectMarkers函数检测Charuco棋盘图像上的角点。
3. 检测角点中的虚拟像素:使用interpolateCornersCharuco函数提取Charuco棋盘上的虚拟像素坐标。
4. 收集标定数据:将实际世界中的Charuco角点坐标和对应的虚拟像素坐标传递给calibrateCameraCharuco函数。
5. 进行相机标定:calibrateCameraCharuco函数通过最小化重投影误差来估计相机的内参矩阵和畸变参数。
重投影误差是指从图像上检测到的角点重新投影到实际世界角点的误差。
6. 输出结果:calibrateCameraCharuco函数将相机的内参矩阵和畸变参数作为输出,并可以将这些参数应用于后续的相机校正和图像处理任务中。
总结而言,calibrateCameraCharuco函数通过使用Charuco棋盘和ArUco Marker 来提供高精度的相机标定。
鱼眼相机外参标定函数 opencv

鱼眼相机外参标定函数 opencv鱼眼相机外参标定函数 OpenCV鱼眼相机是一种广角摄像头,由于其光学结构的特殊性,导致重要的成像参数与其他相机不同。
因此,鱼眼相机的标定与校正是摄影学和计算机视觉领域的一个重要研究领域。
本文介绍了OpenCV中鱼眼相机外参标定函数的使用和操作方法。
鱼眼相机的成像原理是一种广角投影模型,与标准透视投影模型不同,鱼眼相机的成像有很大的失真,导致了相机成像参数的独特性。
鱼眼相机的标定包括内参标定与外参标定。
内参标定是通过拍摄多个不同的图案来确定焦距、光斑偏移、球形变形等参数。
而外参标定则是使用鱼眼相机拍摄标准平面或球面上的图案,并通过拟合重建图案来确定相机的姿态和位置。
OpenCV提供了一系列鱼眼相机标定函数,这些函数主要包括fisheye::calibrate和fisheye::stereoCalibrate等。
这些函数的使用与普通相机的标定类似,但是需要指定鱼眼相机的投影模型类型和特定的参数。
在调用这些函数之前,需要准备好标定所需的图像和相应的图案,并通过手动或自动的方式确定一些参数,例如相机和标志的大小、布局和位置。
在进行鱼眼相机外参标定时,需要首先调用cv::calibrateCamera函数对相机内参进行标定,得到相机的投影矩阵和畸变系数。
接着,我们需要准备一组标定图案,并使用鱼眼相机拍摄标定图案获得图像与3D世界坐标之间的关系。
OpenCV中提供的fisheye::findChessboardCorners 函数可以自动从鱼眼相机图像中检测棋盘格标定图案的角点。
之后,我们需要使用cv::solvePnP进行姿态估计,将像素坐标系映射为相机坐标系。
最后,通过fisheye::calibrate函数拟合反投影误差,得到相机的外参,包括旋转矩阵和平移矩阵。
值得一提的是,鱼眼相机的标定和校对是一个非常耗时的过程,需要耐心细致的操作。
同时,鱼眼相机的投影模型与其他相机不同,因此需要特殊的算法和处理方式。
学习笔记:使用opencv做双目测距(相机标定+立体匹配+测距).

学习笔记:使⽤opencv做双⽬测距(相机标定+⽴体匹配+测距).最近在做双⽬测距,觉得有必要记录点东西,所以我的第⼀篇博客就这么诞⽣啦~双⽬测距属于⽴体视觉这⼀块,我觉得应该有很多⼈踩过这个坑了,但⽹上的资料依旧是云⾥雾⾥的,要么是理论讲⼀⼤堆,最后发现还不知道怎么做,要么就是直接代码⼀贴,让你懵逼。
所以今天我想做的,是尽量给⼤家⼀个明确的阐述,并且能够上⼿做出来。
⼀、标定⾸先我们要对摄像头做标定,具体的公式推导在learning opencv中有详细的解释,这⾥顺带提⼀句,这本书虽然确实⽼,但有些理论、算法类的东西⾥⾯还是讲的很不错的,必要的时候可以去看看。
Q1:为什么要做摄像头标定?A: 标定的⽬的是为了消除畸变以及得到内外参数矩阵,内参数矩阵可以理解为焦距相关,它是⼀个从平⾯到像素的转换,焦距不变它就不变,所以确定以后就可以重复使⽤,⽽外参数矩阵反映的是摄像机坐标系与世界坐标系的转换,⾄于畸变参数,⼀般也包含在内参数矩阵中。
从作⽤上来看,内参数矩阵是为了得到镜头的信息,并消除畸变,使得到的图像更为准确,外参数矩阵是为了得到相机相对于世界坐标的联系,是为了最终的测距。
ps1:关于畸变,⼤家可以看到⾃⼰摄像头的拍摄的画⾯,在看矩形物体的时候,边⾓处会有明显的畸变现象,⽽矫正的⽬的就是修复这个。
ps2:我们知道双⽬测距的时候两个相机需要平⾏放置,但事实上这个是很难做到的,所以就需要⽴体校正得到两个相机之间的旋转平移矩阵,也就是外参数矩阵。
Q2:如何做摄像头的标定?A:这⾥可以直接⽤opencv⾥⾯的sample,在opencv/sources/sample/cpp⾥⾯,有个calibration.cpp的⽂件,这是单⽬的标定,是可以直接编译使⽤的,这⾥要注意⼏点:1.棋盘棋盘也就是标定板是要预先打印好的,你打印的棋盘的样式决定了后⾯参数的填写,具体要求也不是很严谨,清晰能⽤就⾏。
之所⽤棋盘是因为他检测⾓点很⽅便,and..你没得选。
pythonopencv设置摄像头分辨率以及各个参数的方法

pythonopencv设置摄像头分辨率以及各个参数的⽅法1,为了获取视频,你应该创建⼀个 VideoCapture 对象。
他的参数可以是设备的索引号,或者是⼀个视频⽂件。
设备索引号就是在指定要使⽤的摄像头。
⼀般的笔记本电脑都有内置摄像头。
所以参数就是 0。
你可以通过设置成 1 或者其他的来选择别的摄像头。
之后,你就可以⼀帧⼀帧的捕获视频了。
但是最后,别忘了停⽌捕获视频。
使⽤ ls /dev/video*命令可以查看摄像头设备2,cap.read() 返回⼀个布尔值(True/False)。
如果帧读取的是正确的,就是 True。
所以最后你可以通过检查他的返回值来查看视频⽂件是否已经到了结尾。
有时 cap 可能不能成功的初始化摄像头设备。
这种情况下上⾯的代码会报错。
你可以使⽤cap.isOpened(),来检查是否成功初始化了。
如果返回值是True,那就没有问题。
否则就要使⽤函数 cap.open()。
你可以使⽤函数 cap.get(propId) 来获得视频的⼀些参数信息。
这⾥propId 可以是 0 到 18 之间的任何整数。
每⼀个数代表视频的⼀个属性,见表其中的⼀些值可以使⽤cap.set(propId,value) 来修改,value 就是你想要设置成的新值。
例如,我可以使⽤ cap.get(3) 和 cap.get(4) 来查看每⼀帧的宽和⾼。
默认情况下得到的值是 640X480。
但是我可以使⽤ ret=cap.set(3,320)和 ret=cap.set(4,240) 来把宽和⾼改成 320X240。
CV_CAP_PROP_POS_MSEC Current position of the video file in milliseconds.• CV_CAP_PROP_POS_FRAMES 0-based index of the frame to be decoded/captured next.• CV_CAP_PROP_POS_AVI_RATIO Relative position of the video file: 0 - start of the film, 1 - end of the film.• CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream.• CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream.• CV_CAP_PROP_FPS Frame rate.• CV_CAP_PROP_FOURCC 4-character code of codec.• CV_CAP_PROP_FRAME_COUNT Number of frames in the video file.• CV_CAP_PROP_FORMAT Format of the Mat objects returned by retrieve() .• CV_CAP_PROP_MODE Backend-specific value indicating the current capture mode.• CV_CAP_PROP_BRIGHTNESS Brightness of the image (only for cameras).• CV_CAP_PROP_CONTRAST Contrast of the image (only for cameras).• CV_CAP_PROP_SATURATION Saturation of the image (only for cameras).• CV_CAP_PROP_HUE Hue of the image (only for cameras).• CV_CAP_PROP_GAIN Gain of the image (only for cameras).• CV_CAP_PROP_EXPOSURE Exposure (only for cameras).• CV_CAP_PROP_CONVERT_RGB Boolean flags whether images should be converted to RGB. indicating• CV_CAP_PROP_WHITE_BALANCE Currently unsupported• CV_CAP_PROP_RECTIFICATION Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend cur-rently)#!/usr/bin/env python# -*- coding: utf-8 -*-import cv2import numpyfrom hlf_module import hlf_definefrom std_msgs.msg import Stringimport matplotlib.pyplot as plotimport xml.dom.minidomimport pylabimport rospyimport timecap = cv2.VideoCapture(0)cap.set(3,640) #设置分辨率cap.set(4,480)fps =cap.get(cv2.CAP_PROP_FPS) #获取视频帧数face_casade = cv2.CascadeClassifier('/opt/ros/kinetic/share/OpenCV-3.2.0-dev/haarcascades/haarcascade_frontalface_default.xml')Node_name='neck'#print cap.isOpened()class Detect_face():def __init__(self):'''定义节点Node_name(全局变量,⽽⾮具体名称)'''self.err_pub=hlf_define.err_publisher()#错误消息发布者rospy.init_node(Node_name,anonymous=True)self.neck_puber=rospy.Publisher(hlf_define.TOPIC_ACTION_NECK,String,queue_size=10)time.sleep(0.5)def head_motor_value(self):#解析xml⽂件获取舵机的范围值dom = xml.dom.minidom.parse('/home/sb/catkin_ws/src/hlf_robot/scripts/hlf_action/head_value.xml')#得到⽂档元素对象root = dom.documentElementitemlist = root.getElementsByTagName('login')item = itemlist[0]max_value=item.getAttribute("max")min_value=item.getAttribute("min")return max_value,min_valuedef detect_face(self):# get a frame#frame=cv2.imread('/home/sb/桌⾯/timg.jpeg')ret, frame = cap.read()gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)#转成灰度图#frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)# show a framecv2.imshow("capture", gray)faces = face_casade.detectMultiScale(gray,1.2,5) #检测⼈脸#print len(faces)if len(faces)>0:#判断是否检测到⼈脸result = ()max_face = 0value_x=0for (x,y,w,h) in faces:if (w*h > max_face): #检测最⼤⼈脸max_face = w*hresult = (x,y,w,h)# max_face.append(width*height)x=result[0]w=result[2]z=value_x=value_x+x+w/2return zelse:return 1if __name__=='__main__':face=Detect_face()motor_max,motor_min= face.head_motor_value()x=[]i=1while True:try:z=face.detect_face()if z != 1:x.append(z)if len(x)>(fps-1):true_x = int(sum(x)/30)if(true_x>319):motor_value=int(1500+(int(motor_max)-1500)*(true_x-319)/320)#转换成舵机值头部向左转face.neck_puber.publish('%s'%motor_value)elif (true_x<319):motor_value=int(1500-(1500-int(motor_min))*(319-true_x)/320)face.neck_puber.publish('%s'%motor_value)x=[]else:if i==fps:face.neck_puber.publish('1500')i=1else:i +=1print (U'未检测到⼈脸')if cv2.waitKey(1) & 0xFF == ord('q'):breakexcept Exception,e:print ecap.release()cv2.destroyAllWindows()以上这篇python opencv设置摄像头分辨率以及各个参数的⽅法就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
OpenCV机器人手眼标定(九点标定法)

OpenCV机器⼈⼿眼标定(九点标定法) 对于初学者⽽⾔,对相机的标定经常模糊不清。
不知道机器坐标与相机坐标如何转换,两个坐标系⼜是如何建⽴? 我们通常是利⽤张⽒标定法,针对于相机的畸变进⾏标定,利⽤校正得到的参数对图形进⾏处理后再呈现出来。
这个⽅法⽹上⽤的⼈很多,资料也较为全⾯。
这⾥就不做说明了。
本⽂主要是针对机械⼿的⼿眼标定,⼀般⽽⾔⽬前相机的畸变较⼩,精度也较为准确,使⽤该⽅法进⾏标定也能得到较好的效果。
⾸先,对于九点标定⽽⾔。
我们使⽤到的是OpenCv中的estimateRigidTransform 函数。
函数定义如下:Mat estimateRigidTransform(InputArraysrc,InputArraydst,boolfullAffine)前两个参数,可以是:src=srcImage (变换之前的图⽚Mat) dst=transImage(变换之后的图⽚Mat)也可以: src=array(变换之前的关键点Array) dst=array(变换之后的关键点Array)第三个参数: 1(全仿射变换,包括:rotation, translation, scaling,shearing,reflection)其主要原理为:如果我们有⼀个点变换之前是[x,y,1],变换后是[x’,y’,1] 则fullAffine表⽰如下:TX=Y展开后表⽰如果我们想求这【a-f】 6个变量需要有6个⽅程,也就是3组点。
但是⽐三个点多呢?⽐如:20个点。
那就是⽤最⼩⽅差。
标定步骤1、⾸先我们需要准备⼀块,标定板。
如果条件不⾜,可以使⽤⽩纸画上九个圆进⾏代替。
2、相机位置,机械⼿位置全部固定好,标定针固定在机械⼿上,固定好后不能够再移动。
标定针的位置⼀定要与夹⼿或吸盘之内的⼯具同⼀位置⾼度。
3、将标定板放到相机下⽅,位置区域要与机械⼿⼯作的区域⼀样,包括⾼度必须尽量⼀致,这是标定准确度的关键。
摄像机标定和图像径向畸变校正

摄像机标定和图像径向畸变校正声明:欢迎任何⼈和组织转载本blog中⽂章,但必须标记⽂章原始链接和作者信息。
开拓进取的⼩乌龟------->CSDNBlog这段时间断断续续在弄这个摄像头的标定和图像畸形矫正的问题,基本差不多了,乘休息时间,发点成果和⼤家分享吧!⼀、标定关于摄像头的标定,说实话⽹上的资料太多了,⽅法也很多的。
个⼈觉得想要研究这个的话,可以先了解基本原理,然后看opencv的例⼦calibration。
如果你还了解的更深⼊的话,建议下载⼀些论⽂看看。
在这⾥说明⼀点。
opencv的calibration是基于张正友标定法的,我们在标定的过程中要避免两次标定板的⾓度倾斜相差过⼩,这样会产⽣很⼤的误差(当然我们可以结合⼀些论⽂上的⽅法的来改进算法)。
⼆、畸形矫正其实在opencv的calibration这个例⼦中完成了畸形矫正。
但是我在我的⼯程中,由于⼀些条件的限制,在没有做矫正的情况下,2.8的镜头刚好照满整个触摸区域,但是经过矫正后,由于主要是径向畸变,可是opencv是校正前后图像⼀样⼤⼩的做法,必然导致有⼀部分校正后的图像被裁剪了。
没办法,我只好⾃⼰去按原理写最基本的校正算法了。
现在贴⼀些基本算法原理出来。
具体代码如下:(TMD,插代码的也被和谐了,么烂CSDN,准备转移blog了)//#pragma parallel omp forfor (int i = 0; i < realWidth; i ++){//#pragma parallel omp forfor (int j = 0; j < realHeight; j ++){// 图像物理坐标系中点在图像像素坐标系中的对应点u、vdouble u = i - 65;double v = j - 25;// 根据图像在图像物理和图像像素坐标系中点的关系来计算图像物理坐标系中的点//// u = x / dx + u0 fx = 1 / dx// v = y / dy + v0 fy = 1 / dydouble x = (u - u0) / fx;double y = (v - v0) / fy;double r2 = pow(x, 2) + pow(y, 2);double r4 = pow(r2, 2);double fr = 1 + k1 * r2 + k2 * r4 + k3 * r2 * r4;double ud = (u - u0) * fr + u0;double vd = (v - v0) * fr + v0;int u0 = int(ud);int v0 = int(vd);int u1 = int(1 + ud);int v1 = int(1 + vd);if (ud > 0 && ud < 640 && vd > 0 && vd < 480){fcImagePlus->image.pData[i + j * realWidth] = pixelInterpolation(tmpImage[0].image.pData,ud, vd, u0, v0, u1, v1);}}}结果贴图:。
C#EmguCV机械手相机9点坐标标定
C#EmguCV机械⼿相机9点坐标标定很多初学者,都对标定概念模糊不清,分不清坐标系之间的关系,搞不清相机标定和机械⼿相机标定有什么关系,想当初⾃⼰也是⼀个⼈摸索了很久,本⽂将尽量给⼤家解释。
我们通常所说的相机标定分为两种,⼀种是相机参数的标定,这⼀般⽤到张⽒标定法,标定的作⽤是校正相机⾃⾝的畸变,利⽤校正得到的参数对图形进⾏处理后再呈现出来。
关于这⽅⾯的资料,⽹上⼤把,我也不再此说明。
⼀般的机械⼿定位也不会进⾏这个标定,因为现在的相机畸变还是很⼩的,精度可以满⾜⼤多数要求。
本⽂要介绍的是第⼆种,相机和机械⼿之间的标定,作⽤:建⽴相机坐标系和机械⼿坐标系之间的关系,即给机械⼿装上眼睛,让它去哪就去哪。
常⽤的⽅法是9点标定,所⽤到函数是EstimateRigidTransform,⽹上关于 estimateRigidTransform 的详细说明很少,Emgucv的⼏乎没有。
当时找了N久,⼀度以为opencv没有坐标系转换的算法,差点就投奔halcon去了,不得不说,opencv在机器视觉⽅⾯的应⽤是完全不如halcon的。
EstimateRigidTransform有两个⽅法。
⽅法⼀:Mat EstimateRigidTransform(PointF[] sourcePoints, PointF[] destinationPoints, bool fullAffine);返回的是⼀个2*3的double的矩阵。
第⼀个参数sourcePoints:换之前图像上的点(相机坐标系下的点)第⼆个参数destinationPoints:换之后图像上的点(机械⼿坐标系下的点)第三个参数fullAffine: TRUE(全仿射变换,包括:rotation, translation, scaling,shearing,reflection)FALSE(带有约束的仿射变换)⽅法⼆:Mat EstimateRigidTransform(IInputArray src, IInputArray dst, bool fullAffine); //返回的是图像第⼀个参数src:变换之前的图像第⼆个参数dst:变换之前的图像第三个参数fullAffine: TRUE(全仿射变换,包括:rotation, translation, scaling,shearing,reflection)FALSE(带有约束的仿射变换)因为我们需要的是坐标点,所以选⽤第⼀个函数。
相机模型与标定(十二)--opencv圆形标志点检测算法
相机模型与标定(⼗⼆)--opencv圆形标志点检测算法本来以为圆形检测⽐较简单,实际还是花费我近⼀上午时间,⽹上⼏乎没有相关资料(除了OpenCV官⽹)。
这⾥坐下简单介绍,分享给⼤家。
⾮对称圆形标定物检测:1.findCirclesGrid函数的使⽤,如下:case ASYMMETRIC_CIRCLES_GRID:boardSize.width = 4;boardSize.height = 11;found = findCirclesGrid(view, boardSize, pointbuf, CALIB_CB_ASYMMETRIC_GRID | CALIB_CB_CLUSTERING, blobDetector);标定图⽚:需要注意的是:1.boardSize 的宽度,需要设置为图⽚中固定个数的⽅向,如上图,⽔平⽅向,分别有5,6两种个数,垂直⽅向只有⼀种个数,因此,宽度设置为4,此后,以4为⼀⾏,则实际该图⽚在⽔平⽅向有11⾏,因此,⾼度设置为11.这⾥弄错,返回就是false了。
2.CALIB_CB_CLUSTERING 标志标识在检测到中⼼点后,会以层次Kmean⽅式聚类检测值,并计算检测点围成的凸包⾓点,并排序外部⾓点。
同时,会根据排序后的2D外部⾓点和理想估计点,计算单应性H,再计算出所有监测点的投影点,再根据Knn选取跟理想估计点近似最近点,作为实际输出的圆形中点。
3.不设置CALIB_CB_CLUSTERING标志时,则根据CirclesGridFinder 类(⼏何特征),检测相关圆形,并排序输出。
对称圆形标志检测,流程与上⾯⼀致,只是不⽤关注长宽设置问题。
实际上,主要思路在于利⽤简单斑点检测器,检测出圆形后,做后续的相关过滤,排序,确认等操作。
基于OpenCV的Matlab标定实现研究
C res 以用 于 检 测 标 定 板 图 像 的 角 点 以 及 角 度 , 值 通 过 最 小化 得 到 。通 过 设 为 O 可 以 on r 可 q , 建 立 系统 方程 如下 : 点数量。 函数 输 入 必须 是 8位 的灰 色 的灰 色 或 彩 色 图 像, 同时可 以根 据 函数 标 志位 n g 选 项 , 择 对 输 as 选 入 图像 的处 理 准则 。 处理 准则 有 : ) 用 自适 应 其 A使
O
0
1 ●●
, ●, ●j
+
] ● ●
_● !
一
— . ...... . .。. .....L .... . .
图 1标定系统的坐标系
巧
1t y ,:
Z
”
1图像 坐 标 系 : l所示 的 坐标 系 ( i Y 和 . 图 OX ) (0 v o u )均 为 图像 坐标 系 ,ou )为 图像像 素坐 标 (0 v 系 . OX ( i Y)为 图像 物 理 坐 标 系 或 图像 实 际 坐 标 系。
Y2 I Y3 1
L
考 虑到镜 头 的径 向崎变 和切 向崎 变 的公 式 变
形为:
—...。.....L . . . .... . . . . . . .
y Z
1● ●●● ●●, ●j
=
—.........L ... . R . . . .... . . .
: (+ k r ) 2 。 + ( 2 ’ 1 r + 2 + ’ , + x )
Y’ y (+k k r ) 2 2 ‘ + ( 2 ’ ' 1 f + 2 + p Y’ , + y )
r 。
“=
OpenCV相机标定findChessboardCorners()与cornerSubPi。。。
OpenCV相机标定findChessboardCorners()与cornerSubPi。
OpenCV 官⽅⽂档findChessboardCorners():Finds the positions of internal corners of the chessboard.bool cv::findChessboardCorners( InputArray image, Size patternSize, OutputArray corners, int flags = CALIB_CB_ADAPTIVE_THRESH+CALIB_CB_NORMALIZE_IMAGE )Python:retval, corners = cv.findChessboardCorners(image, patternSize[, corners[, flags]])Parametersimage Source chessboard view. It must be an 8-bit grayscale or color image.patternSizeNumber of inner corners per a chessboard row and column ( patternSize = cvSize(points_per_row,points_per_colum) = cvSize(columns,rows)). corners Output array of detected corners.flags Various operation flags that can be zero or a combination of the following values:CALIB_CB_ADAPTIVE_THRESH Use adaptive thresholding to convert the image to black and white, rather than a fixed threshold level (computed from the average image brightness CALIB_CB_NORMALIZE_IMAGE Normalize the image gamma with equalizeHist before applying fixed or adaptive thresholding.CALIB_CB_FILTER_QUADS Use additional criteria (like contour area, perimeter, square-like shape) to filter out false quads extracted at the contour retrieval stage.CALIB_CB_FAST_CHECK Run a fast check on the image that looks for chessboard corners, and shortcut the call if none is found. This can drastically speed up the call in the degene no chessboard is observed.The function attempts to determine whether the input image is a view of the chessboard pattern and locate the internal chessboard corners. The function returns a non-zero value if all of the corners are found and they are placed in a certain order (row by row, left to right in every row). Otherwise, if the function fails to find all the corners or reorder them, it returns 0. For example, a regular chessboard has 8 x 8 squares and 7 x 7 internal corners, that is, points where the black squares touch each other. The detected coordinates are approximate, and to determine their positions more accurately, the function calls cornerSubPix. You also may use the function cornerSubPix with different parameters if returned coordinates are not accurate enough.cornerSubPix():Refines the corner locations.Python: cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria)Parameter:image Input imagecornersInitial coordinates of the input corners and refined coordinates provided for outputwinSize Half of the side length of the search window. For example, if winSize=Size(5,5) , then a 5*2+1 x 5*2+1 = 11 x 11 search window is used.zeroZone Half of the size of the dead region in the middle of the search zone over which the summation in the formula below is not done. It is used sometimes to avoid possible singularities of the autocorrelation matrix. The value of (-1,-1) indicates that there is no such a size.criteria Criteria for termination of the iterative process of corner refinement. That is, the process of corner position refinement stops either after criteria.maxCount iterations or when the corner position moves by less than criteria.epsilon on some iteration.。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第28卷第1期计算机工程与设计2007年1月V01.28No.1ComputerEngineeringandDesignJan.2007
基于OpenCV的摄像机标定尹文生,罗瑜林,李世其(华中科技大学机械科学与工程学院,湖北武汉430074)摘要:以增强现实系统中摄像机标定技术为研究对象,分析了开放计算机视觉函数库OpenCV中的摄像机模型,特别充分考虑了透镜的径向畸变和切向畸变影响及求解方法,给出了基于OpenCV的摄像机标定算法。该算法充分发挥了OpenCV的函数库功能,提高了标定精度和计算效率,具有良好的跨平台移植性,可以满足增强现实和其它计算机视觉系统的需要。关键词:计算机视觉;增强现实;摄像机模型;透镜畸变;摄像机标定中图法分类号:TP391文献标识码:A文章编号:1000.7024(2007)01—0197.03
CameracalibrationbasedonOpenCV
YINWel"1。sheng,LUOYu.1in,LIShi—qi
(SchoolofMechanicalScienceandEngineering,HuazhongUniversityofScienceandTechnology,Wuhan430074,China)
Abstract:Fortheapplicationsoftechnologyofcameracalibrationtoaugustreality,thecameramodelinOpenCV(opensourcecomputer
visionlibrary)isdiscussed,especiallyontheinfluencesandsolvingmethodsoflensradialdistortionandtangentialdistortion,and
an
arithmeticofcameracalibrationbasedonOpenCVisgiven.Thisarithmeticmakesuseofthefunctionsofthelibraryeffectively,improves
precisionandefficiencyofcomputation,andhasagoodpropertyfortheapplicationtomulti-platform.It
can
meettheneedsofaugust
realityandothercomputervisionsystems.
Keywords:computervision;augustreality;cameramodel;lensdistortion;cameracalibration
0引言摄像机标定,是指建立摄像机成像几何模型,描述空间坐标系中物体点同它在图像平面上像点之间对应关系的过程。摄像机标定的目的就是确定几何模型参数即摄像机参数“1。摄像机标定是计算机视觉应用中的关键技术,在增强现实系统中也必须采用摄像机标定技术实现图像的注册眨”。摄像机标定技术在立体视觉研究中占有非常重要的地位。一个完整的立体视觉系统通常可分为图像获取、摄像机标定、特征提取、立体匹配、深度确定及内插等6大部分“1。精确标定摄像机内外参数不仅可以直接提高测量精度,而且可以为后继的立体图像匹配与三维重建奠定良好的基础。一】。目前通常采用的标定方法是基于“两步法圳””的传统摄像机标定方法,该方法比主动视觉摄像机标定方法和摄像机自标定方法标定精度高,而且标定过程简单,经过多年的研究已经发展得比较成熟,鲁棒性高。OpenCV(Intel。opensourcecomputervisionlibrary)是Intel。开放计算机视觉函数库,它由一系列C函数和少量C++类构成,实现了图像处理和计算机视觉方面的很多通用算法,具备强大的图像和矩阵运算能力。该函数库中实现的摄像机标定方法采用的是文献[11]中的两步标定方法,而且在2005年7月最新发布的beta5版本中,不只完全重写了摄像机标定函数,而且引入了文献[12】中的自动寻找角点的方法,进一步提高了标定的智能化程度,用户只需导入用于标定的图片,整个标定过程无需人工的介入。OpenCV中的摄像机标定模块为用户提供了良好的接口,同时支持MS.Windows、Linux平台,有效地提高了开发效率,并且执行速度快,具有良好的跨平台移植性,因此可以很好地应用于工程实际当中。
l标定原理1.1摄像机模型摄像机标定首先要选择合适的摄像机模型,确定内外部参数。OpenCV标定算法中的摄像机模型以针孔模型(pin—holemodel)为基础,引入透镜的径向畸变和切向畸变,该模型相比于只引入一阶径向畸变的Tasi模型和针孔模型更加真实地反映了透镜实际的畸变情况m1。在该模型中,将空间点P在世界坐标系中的坐标值呱,K,乙)变换为图像平面上像素坐标系中
坐标值(“,v)的过程可分解为下述的4步变换”1:
收稿日期:2005-12・06E-marl:wsyin@mail.hust.edu.cn基金项目:国家民用航天科研专项计划基金项目(科工技[2004]1530)。作者简介:尹文生(1963一),男,湖南常宁人,博士,副教授,研究方向为智能CAD、虚拟现实技术、机器人遥操作系统;罗瑜林(1981一),男,江西吉安人,硕士研究生,研究方向为机器人遥操作系统、机器视觉;李世其(1965一),男,江西吉安人,博士,教授,研究方向为CAD/CAE、虚拟现实技术、机器人遥操作系统。
一197— 万方数据K,乙)变换为摄像机坐标系中的坐标值只(疋,K,乙)如下㈧…=㈠M㈤
(2)将坐标值只(冠,K,zc)在针孔模型中进行规范化投影,得只=[妻甜引∽
(3)引入透镜的畸变,畸变后的规范化坐标值可以用雎如砌
阱Xdc,峨‰叫州黝;篙]㈤
将Pd(xa,ya)转换为图像上像素坐标系上的坐标值B(“,访f吲:时‰(4)
够可=f/.劬sx/咖(5)
像素之间的有效距离(mm/pixel);dpy为计算机图像在垂直方向
换)方法计算出摄像机的内部参数和外部参数的初值Ⅲ。该步虑透镜畸变的影响,得到的参数值并不准确。不过作为下一数据拟合目标函数““如式6所示。既要将图像上Ⅳ个角点的坐标值(U,K)(f=1,…朋拾取出来,还要利用上述畸变模型计算出这Ⅳ个标志点的坐标值(‰vJ)(f=1,…朋,然后利用式6进行数
转化为求解非线性最小二乘的问题,通过非线性优化算法“”多次迭代,最后得到使目标函数的值最小的参数值,降低了求解难度。迭代的初值由第①步的DLT方法算出,DLT方法不
2基于OpenCV的摄像机标定基于OpenCV的摄像机标定采用平面棋盘格标定模板,一198一为了提高角点提取的成功率,在标定方块的外围,还要求保留一个方块宽的白色空白区域,如图1所示。摄像机只需在不同的角度抓取几张平面标定模板的图片,就可以实现对摄像机的标定。显然,由于采用最小二乘法,抓得图越多,标定的结果就越精确。图1平面棋盘格标定模板虽然OpenCV中自动寻找角点函数提取角点的成功率很高,但是若碰到光线被遮挡等情况,使得标定模板上的标定块在图像上不清晰或提取的角点数目与设定的数目不相符的状况,就会导致角点提取失败,如图2所示:因此OpenCV并不保证能够提取所有图像上的角点。所以在设计标定算法时必须要考虑角点不能被提取的情况:一方面,如果角点提取成功的图过少,则标定出来的结果就不一定能满足精度的要求,需要重新采图;另一方面,由于摄像机外部参数的个数与标定图像的个数相关联,所以在最后计算标定结果时,应将提取角点失败的图像舍弃,再根据剩下图像的数目,动态地分配参数在内存中的储存空间,如果没有这么一个筛选的过程,盲目得在内存中分配参数的储存空间,则在提取角点失败的图像上,不能找到与角点在世界坐标系中的坐标值相对应的像素坐标系上的坐标值,在这种情况下强行计算的话,很容易出现程序报错,得不到标定结果的情况。因此,本文提出以下摄像机标定算法:(1)读取一组标定用图像数据;(2)用cvFindChessboardComers()筛选图像;将读入的一组图像数据分别代入cvFindChessboardComers0函数,如果返回值是1,则表示在该幅图像上提取的角点数目和设定的相同,提取角点成功;若为0,则表示角点提取失败,该幅图要抛弃;(3)如果可用的标定图的数目满足设定的最少标定用图的数目,继续步骤(4);否则,则应重新采图,返回步骤(1);(4)根据筛选剩下图像的数目用cvCreateMat0为摄像机的内外部参数、角点在世界坐标系的坐标值以及在图像坐标系中的坐标值分配内存存储空间;(5)将筛选剩下的图像代入cvFindChessboardComers0,得到角点在图像像素坐标系中坐标值;再将图像和得到的图像像素坐标系中坐标值代入FindComerSubPix()函数,进一步精(a)角点提取失败(b)角点提取成功图2角点提取图像
万方数据确得到角点亚像素级的坐标值;(6)将角点在世界坐标系的坐标值以及在图像坐标系中的坐标值代入cvCalibrateCamera20函数,最后得到摄像机的内外部参数值;(7)最后注意要用cvReleaseMat0函数释放cvCreateMat()函数分配的内存空间,防止内存泄露。
3实验结果根据上述标定原理和开发步骤,在Windows2000pro平台下利用VC++6.0开发了一个基于OpenCVbeta5版本的摄像机标定程序,程序界面如图3所示。程序经过严格测试,运行稳定,没有出现内存泄露的情况,寻找角点成功率高,标定一组9幅768x512像素的图像,用时O.3秒,可以达到实用的要求。图3标定程序界面为了验证该标定程序的标定结果,利用文献[12】中的图像数据进行标定,并将计算得到的结果与文献[12]中提供的基于相同原理的标定程序得到的标定值进行比较。比较结果如表1所示,其中计算值表示本文程序计算的值;给定值为文献[12】中程序的计算值。从表中可以看到,两者的值是非常接近的。4结束语利用OpenCV开发的摄像机标定程序具有标定结果精确、运算效率高、跨平台移植性好等特性,可以有效地应用于基于增强现实的机器人遥操作系统和其它计算机视觉系统应用中。参考文献:[1]邱茂林,马颂德,李毅.计算机视觉中摄像机定标综述[J].自动化学报,2000,26(1):43—55.[2】ChunyuGao,HongHua,AhujaN.Easycalibrationofahead-mountedprojectivedisplayforaugmentedrealitysystems[C].ProceedingsIEEEVirtualReality,2003.53—60.[3]GibsonS,CookJ,HowardT,eta1.Accuratecameracalibrationforoff-line,video—basedaugmentedreality[C].ProceedingsoftheIEEEandACMInternationalSymposiumonMixedandAugmentedReality,2002.37-46.【4】DavidAForsyth,JeanPonce.计算机视觉——一种现代方法[M].北京:电子工业出版社,2004.[5】RashmiSundareswara,SchraterPR.Bayesianmodelingofca—meracalibrationandreconstruction[C].ProceedingsFifthInter-nationalConferenceon3-DDigitalImagingandModeling,2005.394.401.[6]RodriguezT,SturmP,WilczkowiakM,eta1.VISIRE:Photorea—