资源下载地址:https://download.csdn.net/download/sheziqiong/85836848
资源下载地址:https://download.csdn.net/download/sheziqiong/85836848

相机标定正畸并生成鸟瞰图

实验目的和要求

参考 Learning OpenCV 示例 18-1,利用棋盘格图像进行相机定标,将参数写入 XML 文件保存。棋盘格图像见群文件 LearningOpenCV/LearningOpenCV_Code/LearningOpenCV_Code/calibration

参考示例 19-1,根据求得的内参实现鸟瞰图(俯视)转换,测试图片见群文件 Learning OpenCV/LearningOpenCV_Code/LearningOpenCV_Code/birdseye

实验内容和原理

相机参数标定

参考 OpenCV 官方给出的文档(),可以看到它给出的理论知识。对于畸变,OpenCV 考虑了径向和切向因素。径向畸变的存在表现为“桶”或“鱼眼”效应,对于径向畸变使用以下公式正畸:

由于成像透镜与成像平面不会完全平行,所以会产生切向畸变。可通过以下公式表示:

因此,我们有五个失真参数,在 OpenCV 中表示为一行五列矩阵:

摄像机矩阵中包括了光学中心坐标

和焦距

,可以用它来将世界坐标转换为像素坐标:

坐标是以齐次的方式写的,其中 Z=z=1。

鸟瞰视角

本次实验中要求的鸟瞰视角是利用标定时得到的棋盘格坐标与理想中棋盘格应有的坐标一一对应来完成视角转换得到的。

利用得到的图像中的棋盘格的四个角的坐标和理想中的(0, 0), (0, 8), (5, 0), (5, 8),可以得到一个映射矩阵,再利用这个矩阵处理照片,即可得到照片中每个像素点映射到以棋盘格为标准坐标系的空间中对应的位置。

实验步骤与分析

读入图片并标注棋盘格。

利用了 glob 来读入当前路径下的图片,使用 cv2 自带的函数进行棋盘格的识别(6*9 个内部角点)。(因此在 esc 时不会直接退出而会继续处理下一张图像)

由于一张图用来求相机参数就基本够了,所以没有对所有照片求参再合并。

img = cv2.imread(fname)img = cv2.resize(img, (0, 0), fx = 0.5, fy = 0.5)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)cv2.imshow('img', img)cv2.waitKey(1)plt.subplot(2,2,1), plt.title('original image')plt.imshow(img)print('Done\n')# Find the chess board cornersprint('\nFinding Chessboard...')print('-----------------------------------------')ret, corners = cv2.findChessboardCorners(gray, (9,6),None)# If found, add object points, image points (after refining them)if ret == True:objpoints.append(objp)corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)imgpoints.append(corners2)img_ = img.copy()
# Draw and display the corners
# Use img_ here instead of img is for the later use of undistorted imageimg_ = cv2.drawChessboardCorners(img_, (9,6), corners2,ret)cv2.imshow('img',img)cv2.waitKey(1)

正畸

利用 cv2 给出的 calibrateCamera 函数,可以获得相机的参数矩阵和图像畸变的具体参数

# Using the cv2.calibrateCamera function, it can generate the needed matrices for the camera pose and how the image is distorted
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)

将参数保存至 matrices.xml 中及 coefs.npz 中(后者方便 python 程序直接使用)

# serialize the matrices
np.savez('coefs.npz', mtx=mtx, dist=dist, rvecs=rvecs, tvecs=tvecs)
cv_file = cv2.FileStorage("./save/matrices.xml", cv2.FILE_STORAGE_WRITE)cv_file.write("mtx", mtx)cv_file.write("dist", dist)cv_file.write("rvecs", rvecs[0])cv_file.write("tvecs", tvecs[0])cv_file.release()

找到 x 和 y 方向上像素点的畸变函数,再将像素点映射到校正后的位置上

# undistort
h,  w = img.shape[:2]
# generate the new matrix of camera pose after undistortion
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
# here we can get how the pixels are mapped to the new image
mapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)

得到剪切后的图像

x,y,w,h = roicropped = dst[y:y+h, x:x+w]

生成鸟瞰图

使用校正后的图像来重新标定棋盘格的位置,获取鸟瞰图的视角变换矩阵。

# use the undistorted image as the source, find the corners for generate the birdview image
img = dst
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, (9,6),None)
print('ret = ', ret)
if ret == True:objpoints.append(objp)corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)imgpoints.append(corners2)img_ = img.copy()# Draw and display the cornersimg_ = cv2.circle(img_, (corners[0][0][0], corners[0][0][1]), 63, (0, 0, 255), 5)img_ = cv2.circle(img_, (corners[8][0][0], corners[8][0][1]), 63, (0, 255, 0), 5)img_ = cv2.circle(img_, (corners[45][0][0], corners[45][0][1]), 63, (255, 255, 0), 5)img_ = cv2.circle(img_, (corners[53][0][0], corners[53][0][1]), 63, (255, 0, 255), 5)img_ = cv2.drawChessboardCorners(img_, (9,6), corners2,ret)cv2.imshow('img',img_)cv2.waitKey(1)corners = np.squeeze(corners)

进行 50x 的缩放,防止生成的图像太小。

Scale = 50
objpts = np.float32([[0, 0], [8, 0], [0, 5], [8, 5]])
objpts = objpts * Scale
print(objpts)
imgpts = np.float32([corners[0],corners[8],corners[45],corners[53]])
print(imgpts)cv2.destroyAllWindows()# find how it transformed
H = cv2.getPerspectiveTransform(imgpts, objpts)

显示鸟瞰图,并进行键盘动作的处理。

print("\nPress 'd' for lower birdseye view, and 'u' for higher (it adjusts the apparent 'Z' height), Esc to exit")Z = H[2, 2]
while True:H[2, 2] = ZPerspective_img = cv2.warpPerspective(img, H, (img.shape[1], img.shape[0]))cv2.imshow("Birdseye View", Perspective_img)KEY = cv2.waitKey() & 0xFFif KEY == ord('u'):Z += 0.05if KEY == ord('d'):Z -= 0.05if KEY == 27:cv2.destroyAllWindows()exit()

实验结果

自己拍摄的照片

由于给出的图畸变不是很明显,直接使用了自己拍摄的照片来测试正畸效果。

正畸

标定棋盘格:

校正后的图像:

输出了整个过程中的图像:

输出的 XML 文件:

<?xml version="1.0"?><rows>3</rows><cols>3</cols><dt>d</dt><data> 1.9185538075266456e+03 0. 6.6351052686831258e+02 0. 1.9239847846858713e+03 5.2501768650563508e+02 0. 0. 1.</data></mtx><rows>1</rows><cols>5</cols><dt>d</dt><data> -6.5131737583550275e-01 1.2672234354930185e+00 -7.6049220720545881e-03 -1.1437164634492115e-02 -5.9703308825363361e+00</data></dist><rows>3</rows><cols>1</cols><dt>d</dt><data> 3.2420766902989018e-01 -6.4589768076974197e-01 1.1011907909749442e-01</data></rvecs><rows>3</rows><cols>1</cols><dt>d</dt><data> -2.6876180482710543e+00 -1.2541719558169395e+00 1.5495572059324372e+01</data></tvecs></opencv_storage>

鸟瞰视角

很明显,将棋盘格映射到了左上角,并且可以通过 d 和 u 来控制视角升高与降低

其中上一张图是使用了 crop 前的图像,在上升下降时会产生较严重的畸变。

(顺便利用以前写的小工具生成了相机视角的 ply 文件):

  • 课程给出的测试图片(由于效果非常好所以不做 undistort 直接运行)
  • 由于电脑内存较小,所以稍微改了一下对老师给出的图像进行处理的程序。希望验收的时候使用我自己拍的图(效果更好 QAQ)


资源下载地址:https://download.csdn.net/download/sheziqiong/85836848
资源下载地址:https://download.csdn.net/download/sheziqiong/85836848

基于Python实现相机标定正畸并生成鸟瞰图相关推荐

  1. 基于python的相机标定(采用圆形标定板图片)

    基于python的相机标定(采用圆形标定板图片) 系列文章目录 与黑白棋盘格差别主要在于寻找角点的函数,只需将第一章内第二段代码 ret, corners1 = cv.findChessboardCo ...

  2. 【ZED】从零开始使用ZED相机(五):Opencv+Python实现相机标定(双目)

    引言 同样Opencv+Python实现双目相机的标定,单目标定详见[ZED]从零开始使用ZED相机(五):Opencv+Python实现相机标定(单目) 1 cv2.stereoCalibrate ...

  3. python appium自动化测试框架unittest_Appium基于Python unittest自动化测试 自动化测试框架 -- PO并生成html测试报告...

    基于python单元测试框架unittest完成appium自动化测试,生成基于html可视化测试报告 代码示例: #利用unittest并生成测试报告 class Appium_test(unitt ...

  4. 随机数写excel java代码_基于python实现在excel中读取与生成随机数写入excel中

    搜索热词 具体要求是:在一份已知的excel表格中读取学生的学号与姓名,再将这些数据放到新的excel表中的第一列与第二列,最后再生成随机数作为学生的考试成绩. 首先要用到的数据库有:xlwt,xlr ...

  5. python+OpenCV 相机标定

    相机标定 目录 原理 相机标定结果 流程简介 实验过程 总结 代码及调试问题 相机标定在机器人视觉和畸变校正上都是很关键的一部分,接下来用张正友相机标定法标定我的手机(Vivo xpaly5A)后置摄 ...

  6. OpenCV/Python:相机标定

    这也不是相机标定,只是了解相机标定之前的基础部分 import numpy as np import cv2 import glob'''在这里,我的棋盘格是8*8的,所以角点个数为7*7,当然棋盘格 ...

  7. 基于OpenCV进行相机标定

    相机已经存在了很长一段时间. 随着二十世纪末廉价针孔相机的推出,相机已经在日常生活中普及.虽然价格便宜,但是成像存在严重的畸变.不过,这些畸变是固定的形式,基于标定和重映技术可以纠正畸变.此外,基于标 ...

  8. 基于Python进行相机校准

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 相机校准的目的是找到相机的内在和外在参数. 总览 为了校准相机,我 ...

  9. python opencv 相机标定_使用OpenCV校准鱼眼镜头的方法

    01.简介 当我们使用的鱼眼镜头视角大于160°时,OpenCV中用于校准镜头"经典"方法的效果可能就不是和理想了.即使我们仔细遵循OpenCV文档中的步骤,也可能会得到下面这个奇 ...

最新文章

  1. 重温设计模式(三)——职责链模式(chain of responsibility)
  2. 【Flashback】Flashback Database闪回数据库功能实践
  3. 如何将word中的对象怎么显示到工具栏_MathType怎么添加到Word快速访问栏?
  4. asp 使用TreeView控件
  5. (王道408考研操作系统)第五章输入/输出(I/O)管理-第一节7:缓冲区管理
  6. 开关造成的毛刺_干冰清洗机模具清洗机干冰去毛刺机注意事项
  7. 俯瞰大雾弥漫下的鄱阳湖二桥
  8. 根据osdid 查询磁盘是ssd盘还是sas盘
  9. 访问javaweb服务器sessionid存放问题
  10. Python3实现顺序查找、冒泡排序、选择排序
  11. 案例:多任务udp聊天器
  12. 蓝桥基础练习 杨辉三角形 JAVA
  13. 软件项目管理第五章笔记---项目成本管理
  14. TFN系列超声波探伤仪为什么在众多品牌竞争中脱颖而出
  15. 手机扫描二维码登录原理
  16. const T vs. T const by Dan Saks
  17. java电子签名_java实现pdf文件电子签名
  18. 2017,我对自己狠一点,也要对自己好一点
  19. 弃用server酱 自建个人消息推送
  20. 打包失败,Gradle构建失败问题良心解决,看完这个一定让你轻松

热门文章

  1. Oracle常用语句大全
  2. zip解压缩,亲测有效!!!
  3. echarts 地图(区域渐变等)、地图和散点图结合、点击省份进入省份地图(双击切换回来)
  4. HTML头部结构详解
  5. 1-IMU参数解析以及选择
  6. 2019牛客网暑期多校赛第七场C题Governing sand --思维+前缀和
  7. 五轴数控木工雕刻机的优势及配置
  8. 双路cpu比单路强多少_双路cpu比单路强多少
  9. CNN终于杀回来了!京东AI开源最强ResNet变体CoTNet:即插即用的视觉识别模块
  10. eNSP VLAN基础(二)VLAN内部隔离