不同相机之间图片像素对应关系求解(单应性矩阵求解)

2023-05-16

一、场景

        相机1和相机2相对位置不变,相机拍摄图片有重叠,求他们交叠部分的一一对应关系。数学语言描述为已知相机1图片中P点像素(u1, v1),相机1中P点在相机2图片中像素值为(u2, v2),它们存在某种变换,求变换矩阵。

        因为涉及的场景比较简单,目前没有涉及深度,同时采集的目标近似平面,所以可以简化场景,采用单应性矩阵求解。所以上述所涉及的变换矩阵假设为单应性矩阵H(3*3矩阵),它们满足如下关系。

         这样的话,简单很多(如果场景复杂,涉及了深度或者采集对象不是平面,可以使用本质矩阵/基础矩阵的方法获取这个变换矩阵),只需借助标准标定板计算得到H。

二、单应性矩阵

        定义:用 [理想成像] 的相机从不同位置拍摄 [同一平面物体] 的图像之间存在单应性,可以用 [透视变换] 表示 。有以下公式:

         接下来就是求解H矩阵,上述公式展开如下:

         由平面坐标与齐次坐标对应关系,上式可以表示为:

         进一步,

        写成AX=0形式,如下。这种形式求解方式很多,前面的博客也有所涉及。不过需要特别指出的是,虽然H矩阵有9个未知数,但是只有8个自由度(平面关系),其中h33=1。所以求解方程只需要4个不共线点即可求解。

 

三、实际效果

3.1 全部代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cv2
import numpy as np


def OnMouseAction(event, x, y, flags, param):
    """
    鼠标的回调函数,处理鼠标事件
    :param event:
    :param x:
    :param y:
    :param flags:
    :param param:
    :return:
    """
    if event == cv2.EVENT_LBUTTONDOWN:
        global gimg_x, gimg_y, gis_ok
        gimg_x = x
        gimg_y = y
        gis_ok = True
    elif event == cv2.EVENT_RBUTTONDOWN:
        print("右键点击")
    elif flags == cv2.EVENT_FLAG_LBUTTON:
        print("左鍵拖曳")
    elif event == cv2.EVENT_MBUTTONDOWN:
        print("中键点击")


def verification(img1, img2, H):
    def nothing(x):
        pass

    cv2.namedWindow('image1')
    cv2.setMouseCallback('image1', OnMouseAction)
    # create trackbars for color change
    cv2.createTrackbar('thr', 'image1', 121, 255, nothing)
    cv2.createTrackbar('Shading', 'image1', 255, 255, nothing)
    count = 0
    while True:
        cv2.imshow("image1", img1)
        cv2.imshow("image2", img2)

        k = cv2.waitKey(1) & 0xFF
        # 通过关闭窗口的右上角关闭
        if cv2.getWindowProperty('image1', cv2.WND_PROP_AUTOSIZE) < 1:
            break
        # 通过按键盘的ESC退出
        if k == 27:
            break
        global gimg_x, gimg_y, gis_ok
        if gis_ok:
            count += 1
            cv2.circle(img1, (gimg_x, gimg_y), 3, (0, 0, 255), -1)
            cv2.putText(img1, str(count), (gimg_x, gimg_y), 2, 1, (0, 0, 255))
            gis_ok = False

            (x, y, z) = np.matmul(H, np.array([gimg_x, gimg_y, 1]).T)

            cv2.circle(img2, (int(x / z), int(y / z)), 2, (0, 0, 255), -1)
            cv2.putText(img2, str(count), (int(x / z), int(y / z)), 2, 1, (0, 0, 255))


def getHomography(img1, img2):
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

    ret, corners1_1 = cv2.findChessboardCorners(gray1, (gcols, grows), None)
    if not ret:
        return ret, None
    # sub-pixel corner detection
    corners1_2 = cv2.cornerSubPix(gray1, corners1_1, (11, 11), (-1, -1), criteria)

    ret, corners2_1 = cv2.findChessboardCorners(gray2, (gcols, grows), None)
    if not ret:
        return ret, None
    # sub-pixel corner detection
    corners2_2 = cv2.cornerSubPix(gray2, corners2_1, (11, 11), (-1, -1), criteria)

    H, mask = cv2.findHomography(corners1_2, corners2_2, cv2.RANSAC)

    return True, H


gimg1Root = "./image_homography/1080p_1.png"
gimg2Root = "./image_homography/1080p_2.png"
gimg3Root = "./image_homography/720p_3.png"
(grows, gcols) = (8, 11)
def main():
    img1 = cv2.imread(gimg1Root)
    img2 = cv2.imread(gimg3Root)
    is_ok, H = getHomography(img1, img2)
    print(H)

    verification(img1, img2, H)


global gimg_x, gimg_y, gis_ok
gimg_x = 0
gimg_y = 0
gis_ok = False
if __name__ == "__main__":
    main()

3.2 实际效果

 

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

不同相机之间图片像素对应关系求解(单应性矩阵求解) 的相关文章

  • Windows10下安装point-cloud-annotation-tool点云标注工具——吐血之路总结

    零 为了标注点云数据 xff0c 经过多方查找免费开源的标注软件 xff0c 根据使用要求和方便程度最终选择了这款可以在Windows下编译安装的point cloud annotation tool xff0c 基于QT和vtk和PCL进
  • ROS 中CompressedImage消息的发布与订阅

    背景 xff1a 某些情况下需要录图像数据的包 xff0c 非常占空间和带宽 xff0c 尤其对于一些工业相机图像一张好几兆 xff0c 每秒30帧的话一份钟好几个G xff0c 这时候可以选择的订阅压缩图像 xff0c 下面直接来个dem
  • 【C#】简单的串口发送

    一 核心代码 xff1a SerialPort serialPort span class token operator 61 span span class token keyword new span span class token
  • 原生OKHttp以及OKHttpUtil的使用

    Android系统提供了两种HTTP通信类 xff0c HttpURLConnection和HttpClient 尽管Google在大部分安卓版本中推荐使用HttpURLConnection xff0c 但是这个类相比HttpClient实
  • c++编译器配置错误问题clang: error: linker command failed with exit code 1 (use -v to see invocation)

    背景 xff1a ubuntu18 04系统 之前装其他程序的时候安装了一些软件 xff0c 不知道什么时候g 43 43 编译器从 usr bin c 43 43 组里面给删掉了 xff0c 默认的编译器成了clang 43 43 xff
  • apollo7.0------浅谈激光雷达运动补偿(二)--计算解析

    背景介绍 运动补偿相关介绍参考第一篇博客 xff1a apollo7 0 浅谈激光雷达运动补偿 龙性的腾飞的博客 CSDN博客 lidar运动补偿 本篇博客主要解释一下上篇博客中运动补偿的计算部分 xff0c 简单来说就是一个利用四元数球面
  • Matlab激光雷达相机联合标定经验分享

    一 背景介绍 联合标定是做多传感器融合的基础工作 xff0c 也是一个没有最好只有更好的研究方向 xff0c 相关论文也是层出不穷 xff0c 网上也有许多开源的工作 xff0c 包括Autoware的工具箱我也试过 xff0c 感觉标定效
  • 如何更改Ubuntu系统的输出为HDMI(耳机,扬声器)?

    由于需要用HDMI外接音频设备 xff0c 故想要改变电脑输出 xff0c 本人用的为Ubuntu14 04 开始在网上搜寻怎么更改 xff0c 查到需在声音设置里面更改音频输出为HDMI xff0c 可当我打开声音设置 xff0c 嗯 x
  • PPT中插入图片背景透明化小技巧

    新版的编辑器真不适应 xff0c 费劲 xff01 xff01 xff01 最近两天做开题答辩ppt xff0c 发现了ppt中处理图片背景的一个小技巧 xff0c 在此分享给大家 PPT一般会带有背景图片 xff0c 那种带浅色调logo
  • ROS发布Float32MultiArray消息C++/Python

    在ros下发布一个字符串消息或整数消息 xff0c 网上例程不少 xff0c ROSwiki上也有教程 xff0c 有时就需要一次发送不止一个数据 xff0c 这时候就得用到数组了 xff0c C 43 43 的也好找 xff0c 不过py
  • c++中string、char *、char[]相互转换

    一 string转char 主要有三种方法可以将str转换为char 类型 xff0c 分别是 xff1a data c str copy 其中 xff0c copy 可能会报安全性错误 xff0c 自行解决即可 3 1 data 方法 s
  • char数组与char指针

    转载来源 xff1a https www cnblogs com nzbbody p 3553222 html https blog csdn net jack 20 article details 78913202 一 0 的添加 存在的
  • linux下tcpdump的使用

    简介 用简单的话来定义tcpdump xff0c 就是 xff1a dump the traffic on a network xff0c 根据使用者的定义对网络上的数据包进行截获的包分析工具 tcpdump可以将网络中传送的数据包的 头
  • khadas vim3安装ros1

    khadas vim3 按照网上的方法可以正常安装ros2 xff0c 但是按照ros1则可能会有一些奇奇怪怪的问题导致按照失败 xff0c 不过在一位群友的帮助下 xff0c 找到了解决的方法 khadas vim3 将源换为下面 xff
  • 【Android】CMake添加多个c文件

    1 准备工作 先下相关的插件 xff0c 进入setting xff0c 勾选这LLDB NDK CMake三个 xff0c 点击OK后即可下载 2 Native C 43 43 工程 简单总结一下CMake使用的操作步骤 1 新建Nati
  • 什么是字节序(端序、低端字节序、高端字节序、网络字节序)

    前言 一个内容为12 xff08 字符串 xff09 的文本文件 xff0c 它的第一个字节是什么 xff08 小端序 xff09 xff1f 如果你的回答是0x32 xff0c 那你真的应该好好理解下字节序了 如下图所示 xff0c 我这
  • APM中电机输出分析

    一 APM类分析 老规矩 xff0c 先上类图 xff08 1 xff09 如图 xff08 1 xff09 所示 xff0c AP Motors是大部分电机类的父类 xff0c 是AC AttitudeControl姿态控制类的保护型成员
  • 解决安装ROS时出现的sudo rosdep init错误问题

    解决安装ROS时出现的sudo rosdep init错误问题 目前安装ROS时输入sudo rosdep init的命令时 xff0c 可能会出现以下的错误 xff1a ERROR cannot download default sour
  • JS实现HTTP请求头-Basic Authorization

    HTTP协议中的 Authorization 请求消息头含有服务器用于验证用户代理身份的凭证 xff0c 通常会在服务器返回401 Unauthorized 状态码以及WWW Authenticate 消息头之后在后续请求中发送此消息头 A
  • C语言Post和Get方法 ,拿过去直接用

    C语言post 和get 方法的实现 我自己实现的post 和get 请求方法 xff0c 可以直接使用在单片机上 xff0c 比如ESP32 上 xff0c OPl1000 上面 xff0c 下面直接上代码 span class toke

随机推荐

  • QT中图表类QChart系列之(1)-基本用法,画折线图、各个类之间的关系

    参考 xff1a https www cnblogs com yunhaisoft p 5180127 html 首先要注意3点 xff1a xff08 1 xff09 在 pro文件中添加 xff1a QT 43 61 charts xf
  • STM32使用FIFO实现USART串口发送中断

    fifo就不要造轮子了 xff0c 用现成的就行了 linux内核中有目前人类写出的基于c语言的最强FIFO xff0c 请自行搜索学习 巧夺天工的kfifo xff0c kfifo精妙无比 xff0c 实在是高 xff0c 其中用到的环回
  • c++的json读取操作

    使用的开源库是nlohmann json 后续操作也都是基于该开源库操作 本地json文件如下 xff1a 34 model config 34 34 model type 34 34 paddlex 34 34 model cfg fil
  • 三维重建了解

    一 三维重建方法 1 1 传统方法 RGBD D来源结构光或者TOF xff1a 缺点 xff0c 重建范围受限 xff0c 一般不能重建大模型 xff1b 比如 xff0c kinectFusion xff0c DynamicFusion
  • docker容器常用命令

    一 常用命令 显示本地镜像 xff1a docker images 显示已经启动的容器 xff1a docker ps a 从docker hub拉取镜像 reed98 airsim v0是镜像名 xff1a docker pull ree
  • ARM学习随笔(12)定时器查询方式和中断方式

    定时器详细讲解 百度文库 点击打开链接 xff08 一 xff09 查询方式和中断方式的区别在于 xff1a 查询方式不断查询标志位然后进行处理 xff0c 而中断要编写中断服务子程序来处理中断事件 xff08 二 xff09 内部中断是指
  • vgg16网络裁剪并加载模型参数

    主要是测试下模型裁剪后转onnx的问题 删除vgg16网络全连接层 xff0c 加载预训练模型并重新保存模型参数 xff0c 将该参数用于转onnx模型格式 usr bin env python coding utf 8 64 Time 2
  • pth转onnx的三种情况

    usr bin env python coding utf 8 64 Time 2022 8 3 16 19 64 Author weiz 64 ProjectName cbir 64 File pth2onnx py 64 Descrip
  • 以vgg为backbone的简易图像检索系统

    图像检索 xff08 Content based Image Retrieval xff0c 简称CBIR xff09 即以图搜图 xff0c 基于图片语义信息 xff0c 诸如颜色 纹理 布局 CNN based高层语义等特征检索技术 该
  • img2pose: Face Alignment and Detection via 6DoF, Face Pose Estimation代码理解

    import argparse import os import sys import time import numpy as np from PIL import Image ImageOps from torchvision impo
  • 解决普通用户使用sudo找不到命令

    sudo bazel build c opt define MEDIAPIPE DISABLE GPU 61 1 mediapipe examples desktop face mesh face mesh cpu 出现 xff1a sud
  • sfm算法之三角化(三角测量)

    sfm算法流程一般是特征点提取 特征点匹配 计算本质矩阵 基础矩阵 xff0c 最后三角化 但是利用机械臂去观察周围 xff0c 前后帧姿态变化参数是具有的 xff0c 所以不需要通过基础矩阵获取 即利用机械臂的信息直接进行深度估计 已知
  • bazel构建项目案例(第三方库,编译成库,运行案例)

    使用bazel构建项目 xff0c 包含如何引入外部库 xff08 项目中引入了opencv和编译的tensorflow lite库 xff09 xff0c 如何编译成动态库和静态库 xff0c 以及如何调用编译好的库 项目根目录的所有文件
  • 各种小功能集二

    各种小功能集一 十一 C C 43 43 路径解析 头文件 std string UtilsGetPath const char pszFilename std string UtilsGetDirname const char pszFi
  • windows10配置paddleOCR的CPU版本总结

    paddleOCR的CPU版本依赖的库还是比较少的 如下 1 opencv库 本人配置的版本是opencv4 5 0 2 paddle inference 推理库 该库解压后有version txt文件 xff0c 版本信息如下 xff1a
  • 传统图像技术的边缘提取

    usr bin env python coding utf 8 import cv2 import os import numpy as np def laplacian img ksize 61 3 laplacian 61 cv2 La
  • TCP-UDP网络编程调试助手下载

    下载地址 xff1a 可能需要谷歌 xff1a 软件干净 xff0c 挺好用的 xff0c 如果有更好的 xff0c 欢迎留言 xff01 https www waveshare com wiki File TCP UDP Debug 7z
  • Data Matrix码的使用

    一 引言 Data Matrix原名Data code xff0c 由美国国际资料公司 International Data Matrix 简称ID Matrix 于1989年发明 Data Matrix又可分为ECC000 140与ECC
  • 小样本学习(Few-Shot Learning)训练参数意义

    一 常规参数 1 1 epoch 是指所有的训练数据都要跑一遍 假设有6400个样本 xff0c 在训练过程中 xff0c 这6400个样本都跑完了才算一个epoch 一般实验需要训练很多个epoch xff0c 直到LOSS稳定后才停止
  • 不同相机之间图片像素对应关系求解(单应性矩阵求解)

    一 场景 相机1和相机2相对位置不变 xff0c 相机拍摄图片有重叠 xff0c 求他们交叠部分的一一对应关系 数学语言描述为已知相机1图片中P点像素 u1 v1 xff0c 相机1中P点在相机2图片中像素值为 u2 v2 xff0c 它们