计算机视觉之相机模型

2023-05-16

目录

  • 一、相机模型
    • 1、相机与图像
    • 2、坐标系
    • 3、世界坐标系到摄像机坐标系
    • 4、摄像机坐标系到图像物理坐标系
    • 5、图像物理坐标系到图像像素坐标系
    • 6、摄像机坐标系到图像像素坐标系
    • 7、世界坐标系到图像像素坐标系
  • 二、 镜头畸变
    • 1、相机成像原理
    • 2、镜头畸变
      • 径向畸变:沿半径方向的畸变
      • 切向畸变:沿切线方向形成的畸变
    • 3、畸变矫正
  • 三、透视变换
    • 1、定义及算法流程
    • 2、示例代码

一、相机模型

1、相机与图像

  下图中如何从P到P’? 这是一个三维转二维的过程。
在这里插入图片描述

针孔相机模型存在四个坐标系:世界坐标系、摄像机坐标系、图像物理坐标系和图像像素坐
标系。
假设:
• 世界坐标系的坐标为Pw(Xw,Yw,Zw),
• 对应的摄像机坐标系坐标为Po(x,y,z),
• 对应的图像物理坐标系的坐标为P’(x’,y’),
• 对应的图像像素坐标系的坐标为p(u,v)

2、坐标系

世界坐标系:是客观三维世界的绝对坐标系,也称客观坐标系。就是物体在真实世界中的坐标。世界坐标系是随着物体的大小和位置变化的,单位是长度单位。

相机坐标系:以相机的光心为坐标系的原点,以平行于图像的x和y方向为x轴和y轴, z轴和光轴平行, x,y, z互相垂直,单位是长度单位。

图像物理坐标系:以主光轴和图像平面交点为坐标原点, x’和y’方向如图所示,单位是长度单位。

图像像素坐标系:以图像的顶点为坐标原点, u和v方向平行于x’和y’方向, 单位是以像素计。
在这里插入图片描述
相机成像:
在这里插入图片描述

3、世界坐标系到摄像机坐标系

这两个坐标系之间除了旋转矩阵R,还存在平移矩阵t。其关系可表示为:
在这里插入图片描述
R 、t 、0T都是矩阵
欧式变换:欧氏变换由两部分组成:旋转R 平移t
在这里插入图片描述
在这里插入图片描述
齐次坐标
  多次连续的旋转和平移的情况下。假设我们将向量a进行了两次欧氏变换,旋转和平移分别为R1, t1 和 R2, t2,分别得到:

b = R1*a + t1, c = R2*b + t2 ===>> c = R2*(R1*a + t1) + t2

这样下去公式会越来越长,我们可以用矩阵的形式进行表达:
在这里插入图片描述
在这里插入图片描述

4、摄像机坐标系到图像物理坐标系

在这里插入图片描述
在这里插入图片描述
相似三角形:
在这里插入图片描述
将Zc移到等式左边,并构建齐次坐标,然后将上述公式转为矩阵的形式:
在这里插入图片描述

5、图像物理坐标系到图像像素坐标系

在这里插入图片描述
在这里插入图片描述
dx和dy表示: x方向和y方向的一个像素分别占多少个(可能是小数) 长度单位。
齐次坐标下:
在这里插入图片描述

6、摄像机坐标系到图像像素坐标系

在这里插入图片描述

7、世界坐标系到图像像素坐标系

在这里插入图片描述
K表示相机的内参矩阵,设定好的;R、t表示相机的外参矩阵,随拍摄的图片而变化
在这里插入图片描述
  上述内容所讲的相机模型是指图像处理过程中计算需要用到的,而非真正的照相机在照相的过程,真正的照相机成像是光学原理进行成像的.

二、 镜头畸变

1、相机成像原理

在这里插入图片描述
在这里插入图片描述

2、镜头畸变

在这里插入图片描述
➢ 透镜由于制造精度以及组装工艺的偏差会引入畸变,导致原始图像的失真。
➢ 镜头的畸变分为径向畸变切向畸变两类。
在这里插入图片描述
r表示半径

径向畸变:沿半径方向的畸变

由透镜的形状引起的畸变称为径向畸变,透镜径向畸变后点位的偏移示意图如下所示
在这里插入图片描述
➢ 枕形畸变
➢ 桶形畸变
在这里插入图片描述

切向畸变:沿切线方向形成的畸变

  切向畸变是由于透镜本身与相机传感器平面(成像平面)或图像平面不平行而产生的。这种情况多是由于透镜被粘贴到镜头模组上的安装偏差导致,较少见,一般都是机器安装的,很少出问题。切向畸变示意图:
在这里插入图片描述

3、畸变矫正

• 径向畸变和切向畸变模型中一共有5个畸变参数,在Opencv中他们被排列成一个5*1的矩阵,依次包含k1、k2、 p1、 p2、 k3,经常被定义为Mat矩阵的形式,如Mat distCoeffs=Mat(1,5, CV_32FC1, Scalar::all(0));

• 这5个参数就是相机标定中需要确定的相机的5个畸变系数。

• 求得这5个参数后,就可以校正由于镜头畸变引起的图像的变形失真。这些参数在相机生产出来后就确定了,是可以得到的,在日常应用中一般都是已知的,相机标定中给定的。此外,也可通过矫正前的图像与矫正后的图像进行计算得到。
在这里插入图片描述
在这里插入图片描述
摄像中广角的原理类似将正常的图像变为畸变,使画面的内容变多。

三、透视变换

1、定义及算法流程

  透视变换是**将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。**我们常说的仿射变换是透视变换的一个特例。

  透视变换的目的就是把现实中为直线的物体,在图片上可能呈现为斜线,通过透视变换转换成直线的变换。

  仿射变换(Affine Transformation或 Affine Map),又称为仿射映射,是指在几何中,图像进行从一个向量空间进行一次线性变换和一次平移,变换为到另一个向量空间的过程。
在这里插入图片描述
  通用的变换公式为:这里的原始图片是带有畸变的,即x,y表示的图片
在这里插入图片描述
  下式中的X,Y是原始图片坐标(上式的x,y), 对应得到变换后的图片坐标(X’;Y’;Z’)其中Z’=1:
在这里插入图片描述
  一般地,我们令a33=1,展开上面公式,得到一个点的情况:
在这里插入图片描述
源点四个顶点坐标分别为A:(x0,y0),(x1,y1),(x2,y2),(x3,y3)
目标点四个顶点坐标分别为B: (X’0,Y’0),(X’1,Y’1),(X’2,Y’2),(X’3,Y’3)

将这八个点代入方程,并将其转换为矩阵相乘的格式:
在这里插入图片描述
上图中,点的坐标都是已知的,未知的只有warpMatrix中的元素的值,可通过解方程得到这些元素的值。

2、示例代码

根据上述算法过程实现代码:

import numpy as np
 
def WarpPerspectiveMatrix(src, dst):
    assert src.shape[0] == dst.shape[0] and src.shape[0] >= 4
    
    nums = src.shape[0]
    A = np.zeros((2*nums, 8)) # A*warpMatrix=B
    B = np.zeros((2*nums, 1))
    for i in range(0, nums):
        A_i = src[i,:]
        B_i = dst[i,:]
        A[2*i, :] = [A_i[0], A_i[1], 1, 0, 0, 0,
                       -A_i[0]*B_i[0], -A_i[1]*B_i[0]]
        B[2*i] = B_i[0]
        
        A[2*i+1, :] = [0, 0, 0, A_i[0], A_i[1], 1,
                       -A_i[0]*B_i[1], -A_i[1]*B_i[1]]
        B[2*i+1] = B_i[1]
 
    A = np.mat(A)
    #用A.I求出A的逆矩阵,然后与B相乘,求出warpMatrix
    warpMatrix = A.I * B #求出a_11, a_12, a_13, a_21, a_22, a_23, a_31, a_32
    
    #之后为结果的后处理
    warpMatrix = np.array(warpMatrix).T[0]
    warpMatrix = np.insert(warpMatrix, warpMatrix.shape[0], values=1.0, axis=0) #插入a_33 = 1
    warpMatrix = warpMatrix.reshape((3, 3))
    return warpMatrix
 
if __name__ == '__main__':
    print('warpMatrix')
    src = [[10.0, 457.0], [395.0, 291.0], [624.0, 291.0], [1000.0, 457.0]]
    src = np.array(src)
    
    dst = [[46.0, 920.0], [46.0, 100.0], [600.0, 100.0], [600.0, 920.0]]
    dst = np.array(dst)
    
    warpMatrix = WarpPerspectiveMatrix(src, dst)
    print(warpMatrix)

调用opencv库实现:

import cv2
import numpy as np

img = cv2.imread('photo1.jpg')

result3 = img.copy()

'''
注意这里src和dst的输入并不是图像,而是图像对应的顶点坐标。
'''
src = np.float32([[207, 151], [517, 285], [17, 601], [343, 731]])
dst = np.float32([[0, 0], [337, 0], [0, 488], [337, 488]])
print(img.shape)
# 生成透视变换矩阵;进行透视变换
m = cv2.getPerspectiveTransform(src, dst)
print("warpMatrix:")
print(m)
result = cv2.warpPerspective(result3, m, (337, 488))
cv2.imshow("src", img)
cv2.imshow("result", result)
cv2.waitKey(0)

注:本文章参考了百度百科、他人技术博客、八斗学院课件资料、计算机视觉书籍等综合整理而来,如有侵权,联系删除!水平有限,欢迎各位指导交流!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机视觉之相机模型 的相关文章

随机推荐

  • ros-pocketsphinx语音识别(二)-创建语音库

    ros pocketsphinx语音识别 xff08 二 xff09 创建语音库 注释 xff1a 本文大部分引用博主slam02 的博客 xff0c 因便于管理设置为原创 xff0c 希望作者不要介意 基于pocketsphinx的ROS
  • 关于 USRP 如何将采样频率设置到硬件达到的最低采样频率以下的问题

    做什么通信不好非要做水声通信 你资料少就少吧还一堆问题 得 xff0c 说正事 xff1a 目录 1 发送端上采样 2 接收端降采样 最近在尝试将水声 OFDM 在 X310 中运行 xff0c 首先遇到的地一个问题就是 xff1a 虽然
  • roslaunch运行报错: ERROR: cannot launch node of type

    roslaunch运行报错 ERROR cannot launch node of type 从github下载的代码 xff0c 在允许launch文件时候报错 1 检查是否在工作空间catkin make编译 xff0c 以及编译是否可
  • Python报错File “「string」“, line 1, in 「module」 NameError: name ‘q‘ is not defined

    Python报错File line 1 in NameError name q is not defined 笔者运行环境 xff1a Python 2 7 17 print span class token punctuation spa
  • MATLAB的appdesigner背景图片设置

    MATLAB的appdesigner背景图片设置 工作环境 xff1a windows10 MATLAB2017a 转变MATLAB2019b 前面因为课程需要做了一个简单的MATLABapp xff0c 在进行app背景图片设置的时候 x
  • ros-话题节点消息控制rviz中机械臂Publish Joint_State with Python to RVIZ-ros回炉再强学习(6)

    ros 话题节点消息Publish Joint State with Python to RVIZ ros回炉再强学习 xff08 6 xff09 笔者工作环境 xff1a ubuntu16 04 ros kinect 代码下载地址 xff
  • opencv边缘检测运用sobel算子源代码方法

    opencv边缘检测运用sobel算子源代码方法 span class token function import span cv2 span class token function import span numpy as np spa
  • v-rep仿真之键盘控制机械臂末端移动

    v rep仿真之键盘控制机械臂末端移动 键盘控制机械臂末端移动原理为 xff0c 设置机械臂逆运动学target xff0c 机械臂末端跟随target运动 xff0c 然后通过改变target的值 xff0c 从而达到控制机械臂末端移动的
  • urx驱动ur3和onrobot rg2

    urx驱动ur3和onrobot rg2 注意 xff1a 非常重要的一点 xff0c urx是可以在Python2和Python3都支持的 xff0c 随着时间改变 xff0c 如果有的读者发现Python2中不能使用 xff0c 报错m
  • ros-melodic安装解决sudo rosdep init问题

    ros melodic安装解决sudo rosdep init问题 解决办法1 去网站查看raw githubusercontent com的真实IP span class token function sudo span span cla
  • 上电浪涌电流

    上电浪涌电流 电机启动或者停转都会形成浪涌电流 xff0c 例如启动的浪涌最大 xff0c 毕竟电机启动静态电阻非常小 xff0c 上电等同短路 xff0c 其电机为感性负载 xff0c 由较大的无功电流 xff0c 对电网造成波动非常大
  • 电机功率计算公式

    电机功率计算公式 电动机输入功率 单相电机为P 61 UI xff0c 三相电机P 61 UIcos0 8 输出功率 xff08 驱动功率 xff09 P 61 FV F为力 牛顿 V xff1a 速度 m S xff09 换算到电机则有
  • C++ 中 map 字典与 set 集合的使用

    在 C 43 43 中 xff0c map 是关联容器 的一种 xff0c 关联容器将值 与键 关联到一起 xff0c 并使用键来查找值 这与 python 中的字典 类型类似 xff0c 也是用来存储键 值对 xff08 key valu
  • win11 安装 WSL2 在非 C 盘及配置(图形界面+代理)

    WSL 安装及配置 直接安装 WSL2 在非 C 盘启用 WSL 功能前提条件设置默认安装 WSL2安装在非 C 盘 图形界面先决条件更新 WSL 以支持 GUI 配置 WSL2 使用 Windows 网络代理 直接安装 WSL2 在非 C
  • CVTE嵌入式实习生与秋招

    目录 前言一 实习笔试二 实习面试三 实习工作内容四 公司看法 前言 今年暑假去CVTE实习了一个多月最后经过转正答辩 xff0c 获得了offer xff0c 现就我的实习经历和对公司的一些认知分享一下 xff08 仅代表个人观点 xff
  • 视频编解码行业及发展方向简述

    目录 一 视频行业1 视频是一个方兴未艾的大产业2 视频行业潜在商机大 人才缺口大3 了解华为海思的HI3518E方案 二 海思方案项目用到的硬件平台介绍1 本专栏文章使用的开发板配置2 处理器为什么选HI3518E 三 本专栏文章规划和核
  • 全面认识海思SDK及嵌入式层开发(1)

    目录 一 全面认识和检测配套开发套装1 套装配件介绍2 检测开发板3 注意 二 视频设备开发的技术流1 视频从产生到被消费的整个流程2 视频行业的商业角度分段3 几个疑问点 一 全面认识和检测配套开发套装 购买方式 xff1a 淘宝搜索 g
  • 嵌入式linux开发环境搭建(VMware16.0.0+Ubuntu16.04.3_X64)

    目录 一 安装VMware1 VMware介绍2 安装VMware16 0 0 二 安装ubuntu16 04 3 LTS1 Ubuntu介绍2 下载安装包iso3 安装 四 新安装Ubuntu的基本设置1 开机和关机等2 虚拟机基本设置3
  • 全面认识海思SDK及嵌入式层开发(2)

    目录 一 HI3518E方案系统整体架构介绍1 硬件上2 软件上 二 海思SDK的整体介绍三 海思SDK包的学习和实验1 2篇相关文档2 SDK包复制到linux原生目录中并解压3 SDK包操作的脚本程序研究4 SDK中源码包部分的配置编译
  • 计算机视觉之相机模型

    目录 一 相机模型1 相机与图像2 坐标系3 世界坐标系到摄像机坐标系4 摄像机坐标系到图像物理坐标系5 图像物理坐标系到图像像素坐标系6 摄像机坐标系到图像像素坐标系7 世界坐标系到图像像素坐标系 二 镜头畸变1 相机成像原理2 镜头畸变