相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像。
相机标定的输入:标定图像上所有内角点的图像坐标,标定板图像上所有内角点的空间三维坐标(一般情况下假定图像位于Z=0平面上)。
相机标定的输出:摄像机的内参、外参系数。
这三个基础的问题就决定了使用Opencv实现张正友法标定相机的标定流程、标定结果评价以及使用标定结果矫正原始图像的完整流程:
-
准备标定图片
-
对每一张标定图片,提取角点信息
-
对每一张标定图片,进一步提取亚像素角点信息
-
在棋盘标定图上绘制找到的内角点(非必须,仅为了显示)
-
相机标定
-
对标定结果进行评价
-
查看标定效果——利用标定结果对棋盘图进行矫正
我准备的是下图这种格子数为7×5,内角点为6×4的棋盘格图片,手机型号为荣耀PLAY。
将它放在一个平面上从不同角度拍摄10张照片作为实验素材。
代码如下:
import cv2
import numpy as np
import glob
# 设置寻找亚像素角点的参数,采用的停止准则是最大循环次数30和最大误差容限0.001
criteria = (cv2.TERM_CRITERIA_MAX_ITER | cv2.TERM_CRITERIA_EPS, 30, 0.001)
# 获取标定板角点的位置
objp = np.zeros((4 * 6, 3), np.float32)
objp[:, :2] = np.mgrid[0:6, 0:4].T.reshape(-1, 2) # 将世界坐标系建在标定板上,所有点的Z坐标全部为0,所以只需要赋值x和y
obj_points = [] # 存储3D点
img_points = [] # 存储2D点
images = glob.glob("image4/*.jpg")
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
size = gray.shape[::-1]
ret, corners = cv2.findChessboardCorners(gray, (6, 4), 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, (6, 4), corners, ret) # 记住,OpenCV的绘制函数一般无返回值
i+=1;
cv2.imwrite('conimg'+str(i)+'.jpg', img)
cv2.waitKey(1500)
print(len(img_points))
cv2.destroyAllWindows()
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, size, None, None)
print("ret:", ret)
print("mtx:\n", mtx) # 内参数矩阵
print("dist:\n", dist) # 畸变系数 distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
print("rvecs:\n", rvecs) # 旋转向量 # 外参数
print("tvecs:\n", tvecs ) # 平移向量 # 外参数
print("-----------------------------------------------------")
img = cv2.imread(images[2])
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))#显示更大范围的图片(正常重映射之后会删掉一部分图像)
print (newcameramtx)
print("------------------使用undistort函数-------------------")
dst = cv2.undistort(img,mtx,dist,None,newcameramtx)
x,y,w,h = roi
dst1 = dst[y:y+h,x:x+w]
cv2.imwrite('calibresult3.jpg', dst1)
print ("方法一:dst的大小为:", dst1.shape)
代码中的9、10、21、35行中的角点数根据自己的棋盘格大小进行更改。
实验分为两步,第一步主要是对每张图片进行角点的提取,结果如下:
第二步就是实现相机的标定,运行结果如下:
mtx为内参数矩阵,dist为畸变系数:
rvecs为旋转向量:
tvecs为平移向量:
畸变矫正:
矫正前后的图片
通过标定得到荣耀PLAY的后置摄像头的内置参数矩阵为:
矫正后的图和原图通过对比发现差距并不大,只是在宽度上有一点拉伸(肉眼能看出的差距只有图片右上角的白字因为图片的拉伸而消失了),原因应该是原图基本上没有出现明显的畸变。(应该是现在的手机相机比较厉害吧…)
得到物体从三维世界映射到相机成像平面的变换矩阵,这一过程最关键的部分就是要得到相机的内参和外参。
校正透镜畸变
由于透镜的制造工艺(球面透镜),会使成像产生多种形式的畸变,通过标定计算畸变系数来校正各种像差
2 相机标定原理
上面提到,相机标定的目的之一是为了建立物体从三维世界到成像平面上各坐标点的对应关系,所以首先我们需要定义这样几个坐...
什么是相机标定?
在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,必须建立相机成像的几何模型,这些几何模型参数就是相机参数。在大多数条件下这些参数必须通过实验与计算才能得到,这个求解参数的过程就称之为相机标定
如何标定?
在视觉测量中,首先是要定义四个坐标系,即 摄像机坐标系 、 图像物理坐标系 、 像素坐标系 和 世界坐标系(参考坐标...
#相机标定原理
参考博客:https://blog.csdn.net/honyniu/article/details/51004397
摄像机标定(Camera calibration)简单来说是从世界坐标系换到图像坐标系的过程,也就是求最终的投影矩阵 PP 的过程
基本的坐标系:
世界坐标系(world coordinate system);
相机坐标系(camera coordinate sy...
1.1 简介
相机标定的目的和意义在于我们所处的世界是三维的,而照片是二维的,这样我们可以把相机认为是一个函数,输入量是一个场景,输出量是一幅灰度图。这个从三维到二维的过程的函数是不可逆的。而相机标定的目标是我们找一个合适的数学模型,求出这个模型的参数,这样我们能够近似这个三维到二维的过程,使这个三维到二维的过程的函数找到反函数。
“张正友标定”是指张正友教授1998...
(u,v)为成像面坐标系中的二维点;
A为相机的内参数矩阵:(cx,cy)为主光轴点,一般为图像的中心;fx和fy为焦距;
[R|t]为相机的外参数矩阵:R为旋转矩阵,t为位移矩阵;
上述公式的简单推理过程如下
考虑到镜头畸变
其中,k1,k...
### 回答1:
在 Linux 中卸载通过 make install 安装到系统文件夹中的程序,可以使用 make uninstall 命令。需要注意的是,这需要在安装时使用相同的配置选项才能正常工作。如果不能使用 make uninstall,可以手动删除程序安装的文件。
### 回答2:
在Linux系统中,如果你使用了`make install`命令将程序安装到系统文件夹中,你可以通过以下步骤卸载这些程序:
1. 打开终端。
2. 使用`cd`命令切换到你安装程序的目录。该目录通常是你运行`make install`命令时所指定的目录,默认情况下是`/usr/local`。
3. 运行`make uninstall`命令。如果该命令可用,它将卸载程序并删除相关文件。但并非所有程序都提供这个卸载选项,所以你可能需要继续执行下面的步骤。
4. 如果没有`make uninstall`命令,可以通过查看`Makefile`文件来确定程序的安装位置和文件列表。使用文本编辑器打开`Makefile`文件。
5. 在`Makefile`文件中,查找并记录下安装的文件列表。这些文件通常包括二进制文件、库文件、配置文件以及其他相关文件。
6. 运行`rm`命令删除这些文件。例如,如果安装的二进制文件位于`/usr/local/bin`目录下,你可以运行`sudo rm /usr/local/bin/程序名称`删除它。
7. 继续删除其他安装的文件,确保不遗漏。
8. 如果你之前使用了`make install`的`--prefix`选项指定了其他目录,也要在该目录下重复上述步骤,删除对应的文件。
9. 删除可能存在的相关配置文件。这些配置文件通常位于`/etc`目录下。你可以使用`sudo rm /etc/程序名称`命令来删除它们。
10. 最后,在终端中运行`sudo updatedb`命令以更新系统文件搜索索引。
通过以上步骤,你可以将通过`make install`安装到系统文件夹中的程序完全卸载。请注意,操作系统本身的文件不可删除,只能删除自行安装的程序文件。
### 回答3:
在Linux中,卸载已经通过"make install"命令安装到系统文件夹中的程序可以按照以下步骤进行:
1. 打开终端或命令行界面。
2. 使用"cd"命令进入已安装程序所在的目录。通常情况下,"make install"会将程序安装到默认目录,即/usr/local目录下。所以可以使用如下命令进入该目录:
`cd /usr/local`
3. 查找已安装的程序。如果安装程序的时候没有指定安装目录,则可能需要通过"find"命令来查找具体的安装路径。例如,查找名称为"program"的程序可以使用如下命令:
`find . -name program`
4. 找到要卸载的程序后,使用"rm"命令将其从系统中删除。例如,要删除名为"program"的程序可以使用如下命令:
`rm -rf ./program`
这里的"-rf"选项用于递归删除程序及其子目录和文件,并且不再显示提示框。
5. 在完成上述步骤后,已经成功卸载了通过"make install"安装到系统文件夹中的程序。
请注意,在卸载程序时需小心操作,确保卸载的是正确的程序,并且备份重要的数据以防止误删除。