OpenCV-Python相机标定:Camera Calibration

这篇具有很好参考价值的文章主要介绍了OpenCV-Python相机标定:Camera Calibration。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.概述:

在使用相机拍照片时,大多数人会考虑拍的好不好看,关注相机中物体坐标的并不多,但是对于地信学科来说,如果能从照片中获取物体的真实位置,对地理信息获取大有帮助,在这里面,十分关键的一步就是相机标定。

相机标定的基本原理也是相对简单的,看官网中的一个示意图,很容易发现,物点P(Xw,Yw,Zw),像点(u,v)和相机点三点在同一条线上(红线),如果知道多对物点和像点,画出他们的连线,找到的焦点就是相机的位置,同时还可以根据这些线的走向解算相机的旋转角,旋转角坐标偏移共同构成了相机的外参。(实际上,这里的像点并不是照片中物体的坐标,而是相机中感光片上的坐标,他们的转化需要一定的几何变化)

OpenCV-Python相机标定:Camera Calibration

2.基本假设

影响上面相机外参精度的变量有很多,例如镜头畸变,像主点跟感光片的相对位置等等,这些可以归纳为相机的内参

在此仅使用OpenCV-Python中的函数做一个小实验,拍摄工具是手机,所以也不方便找到这些参数,因此不考虑内参的影响,假设相机内参是完美的,即没有畸变和偏移。

所以它的内参矩阵可以假设为下面的样子,27是我手机拍照时显示的焦距,单位mm,8.17是用宽度的像素个数除以照片宽度得到的,也就是1mm有多少像素:

OpenCV-Python相机标定:Camera Calibration

 假设没有畸变,因此畸变参数全部设置为0

OpenCV-Python相机标定:Camera Calibration

参考了这个文章;

相机标定——相机的内参矩阵IntrinsicMatrix参数解释_人工智睿的博客-CSDN博客_相机内参矩阵

 3.坐标获取

基于上面的假设,问题就简单多了,需要的数据只有物点坐标像点坐标,在这里拍摄了一个照片,用来提供上面的数据,A4纸上画的是X轴和Y轴,电脑屏幕的棋盘作为Z轴刻度,电脑屏幕棋盘的第一条线距离桌面8.5cm。

OpenCV-Python相机标定:Camera Calibration

下面的代码可帮助获取屏幕坐标,在输入真实坐标后,保存这些坐标

import numpy as np
import cv2 as cv
import glob
#定义两个列表,realcoo存储真实坐标,imacoo存储相片坐标
imacoo=[]
realcoo=[]
#OpenCV点击相片的事件相应函数,左键双击提示输入三维坐标,右键双击保存输入的点为numpy的一种文件格式,便于后续使用
def GetCoordinate(event,x,y,flags,param):
    #event判断事件类型,右键双击保存为cooimfoText.npz文件
    if event == cv.EVENT_RBUTTONDBLCLK:
        np.savez('cooimfoText.npz', imacoo=imacoo, realcoo=realcoo)
    #如果是左键双击,就键入物体的真实坐标
    if event == cv.EVENT_LBUTTONDBLCLK:
        print(x,y)
        strcoo = input("请输入三维坐标,以逗号隔开")
        coo = strcoo.split(',')
        realcoo.append((float(coo[0]), float(coo[1]), float(coo[2])))
        imacoo.append((x,y))
#打开图像
img = cv.imread("IMG_20221028_151422.jpg")
width,height=img.shape[:2]
#由于手机分辨率太高了,电脑屏幕显示不下,所以缩放一下
imgresize = cv.resize(img,(int(0.2*height), int(0.2*width)), interpolation = cv.INTER_CUBIC)
#窗口命名
cv.namedWindow('room')
#事件绑定
cv.setMouseCallback('room',GetCoordinate)
#打开图像,开始采集点坐标
cv.imshow('room',imgresize)
key=cv.waitKey(0)

4. 外参解算

解算主要用到了OpenCV的这个函数solvePnP(),看下图它的参数,第一个就是上面的物点坐标,第二个是像点坐标,第三个是相机参数A(在上面已经做了假设),第四个是畸变参数(假设为[0,0,0,0,0]),它的返回值就是rvec:相机旋转参数,tvec相机平移参数

OpenCV-Python相机标定:Camera Calibration

使用下面的代码完成解算过程

import numpy as np
import cv2 as cv

#根据假设,定义的相机内部参数和畸变参数
M = np.asarray([[27 * 8.17, 0, 0], [0, 27 * 8.17, 0], [0, 0, 1]], dtype=float)
C = np.asarray([0, 0, 0, 0, 0], dtype=float)
#打开刚获取到的坐标文件
with np.load('cooimfoText.npz') as X:
    imacoo = X['imacoo']
    realcoo = X['realcoo']
    #屏幕坐标转迪卡尔坐标
    for i in range(0,len(imacoo)):
        imacoo[i][1]=793-imacoo[i][1]
    #转化为浮点型
    realcoo = realcoo.astype(np.float32)
    imacoo = imacoo.astype(np.float32)
    #解算相机外参
    retval, rvec, tvec = cv.solvePnP(realcoo, imacoo,M, C)
    #打印结果
    print("解算结果:",retval)
    print("旋转角度:",rvec)
    print("偏移距离:",tvec)

输出结果为:

OpenCV-Python相机标定:Camera Calibration

比对照片,可以大概判断结果结果基本符合实际情况,距离大致相同。

5.问题解决

问题1:solvePnP()与calibrateCamera()的异同?

calibrateCamera():从校准模式的多个视图中查找相机的内在和外在参数。

solvePnP():从 3D-2D 点对应中查找对象姿势,它需要的参数更简单,需要二维和三维对应的点,同时要输入相机的内参。

在最初的计算中,计划使用的是calibrateCamera()函数,它的介绍是从校准模式的多个视图中查找相机的内在和外在参数。在计算是,它频繁报错,后来查看官网的介绍,发现更适合使用solvePnP()计算本例。

OpenCV-Python相机标定:Camera Calibration

他们需要输入的类型都是浮点型的坐标,如果输入int会报错:objectPoints should contain vector of vectors of points of type Point3f in function

问题2:相机内参矩阵矩阵对结果影响有多大?

按照经验来看,手机相机畸变参数并不大,因此假设为0也对结果影响较小,但是焦距和像主点偏移就不一定了,在完成本例时,由于开始对概念不清晰,试了多次焦距参数,略微改变都会带来很大的结果差别,因此要注意这个参数尽量精细。

OpenCV-Python相机标定:Camera Calibration文章来源地址https://www.toymoban.com/news/detail-488890.html

到了这里,关于OpenCV-Python相机标定:Camera Calibration的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python opencv实现相机内参标定

    使用python opencv 标定相机内参。 (1)从网络上下载一张棋盘格图片,粘贴到word文档上,设定尺寸大小为合适值,作为标定板。 (2)在不同距离,不同角度下用手机相机拍摄棋盘图片。 (3)调用 opencv findChessboardCorners 和 cornerSubPix 函数提取棋盘的角点。 (4)调用 opencv cal

    2024年02月13日
    浏览(55)
  • 相机标定(Camera calibration)原理及步骤

     这已经是我第三次找资料看关于相机标定的原理和步骤,以及如何用几何模型,我想十分有必要留下这些资料备以后使用。这属于笔记总结。 1.为什么要相机标定?        在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点

    2024年02月09日
    浏览(41)
  • Python OpenCV 单目相机标定、坐标转换相关代码(包括鱼眼相机)

      本文不讲原理,只关注代码,有很多博客是讲原理的,但是代码最多到畸变矫正就结束了,实际上就是到 OpenCV 官方示例涉及的部分。   在官方示例中使用黑白棋盘格求解了相机的内外参和畸变系数,并对图像做了畸变矫正,但在实际使用时还缺少很多功能,以下是本

    2024年02月02日
    浏览(36)
  • 相机标定原理与实战【python-opencv】

    相机的功能就是将真实的三维世界拍摄形成二维的图片。所以可以将相机成像的过程看做一个函数,输入是一个三维的场景,输出是二维的图片。但是,当我们想将二维的图片反映射成三维场景时,很明显,我们无法仅通过一张二维图来得到真实的三维场景。也就是说,上述

    2024年02月09日
    浏览(64)
  • 【OpenCv】相机标定介绍及python/c++实现

    之前有一个项目需要公司标内参,之前对这方面没有接触过,网上找了很多资料,记录下相机标定的基础知识。文章是个人浅显理解。如有错误还请指正,非常感谢! 参考链接: 坐标系转换:相机参数标定(camera calibration)及标定结果如何使用_Aoulun的博客-CSDN博客 标定ope

    2024年02月15日
    浏览(41)
  • Matlab相机标定——使用Single Camera Calibrator App

     什么是相机标定?​​​​​​​         Single Camera Calibrator App支持棋盘格、圆圈格和自定义检测器图案。有关这些图案的细节和包含可打印图案的PDF文件,请参见校准图案。 分享一个可以生成各种标定板的网站:https://calib.io/pages/camera-calibration-pattern-generator (1)本文

    2024年02月04日
    浏览(53)
  • ROS功能包camera_calibration标定相机内参

    目录 1 安装 2启动相机程序 3启动功能包 4 采集图像进行标定 Ubuntu 20.04 + ROS Noetic 单目相机:basler Ubuntu20.04对应的ROS版本号为 noetic basler相机外部硬触发,转换图像格式并发送到ROS下的topic_basler软件手动硬触发信号 Ubuntu20.04 ROS读取basler相机图像步骤 根据自己标定板尺寸,输入

    2024年02月04日
    浏览(41)
  • MATLAB - 激光雷达 - 相机联合标定(Lidar-Camera Calibration)

          激光雷达 - 相机标定建立了三维激光雷达点和二维相机数据之间的对应关系,从而将激光雷达和相机输出融合在一起。 激光雷达传感器和相机被广泛用于自动驾驶、机器人和导航等应用中的三维场景重建。激光雷达传感器捕捉环境的三维结构信息,而相机则捕捉色彩、

    2024年02月20日
    浏览(52)
  • 使用ROS功能包camera_calibration进行单目相机和双目相机的内参和外参标定

    本文总结使用ROS标定单目和双目相机的过程,同时提供生成棋盘格文件的方法。 参考链接: [1]使用ros标定相机的内参和外参 [2]ROS下采用camera_calibration进行双目相机标定 棋盘格可以自己买一个,或者打印一个粘在板子上,棋盘格电子版生成可以参考博客《使用kalibr标定工具进

    2024年02月11日
    浏览(48)
  • python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)

    今天的低价单孔摄像机(照相机)会给图像带来很多畸变。畸变主要有两 种:径向畸变和切想畸变。如下图所示,用红色直线将棋盘的两个边标注出来, 但是你会发现棋盘的边界并不和红线重合。所有我们认为应该是直线的也都凸 出来了。 在 3D 相关应用中,必须要先校正这些畸变

    2024年02月06日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包