从开源项目聊鱼眼相机的“360全景拼接”

news2024/11/20 21:36:47

目录

概述

从360全景的背景讲起

跨过参数标定聊透视变化

拼接图片后处理

参考文献


概述

        写这篇文章的原因完全源于开源项目(GitHub参阅参考文献1)。该项目涵盖了环视系统的较为全貌的制作过程,包含完整的标定、投影、拼接和实时运行流程。该篇文章主要是梳理全景拼接技术中的一些实现细节,并在些地方记录了自己的思考。鉴于该开源项目,后续将计划:(1)基于自动驾驶车辆环视相机标定参数(内外参), 完成360全景拼接demo;(2)这篇文章要跳过的参数标定环节,后面要单独拿出篇幅详析。

从360全景的背景讲起

        百度百科:“360度全景倒车影像,是一套通过车载显示屏幕观看汽车四周360度全景融合,超宽视角,无缝拼接的适时图像信息(鸟瞰图像),了解车辆周边视线盲区,帮助汽车驾驶员更为直观、更为安全地停泊车辆的泊车辅助系统,又叫全景泊车影像系统或全景停车影像系统(有别于市面上把汽车四周画面在显示屏幕上进行分割显示的“全景”系统)。”

源自网络,如侵联删

        说的通俗些,360全景影像给人视觉上呈现的就是鸟瞰图,即从天空望车顶或者地面的俯视图,但俯视效果的实现是通过多个视角的照片拼接而成的。如下图所示,我们观察自己的车就能发现在车的前后左右四个方向上都有一个鱼眼相机,一般左右方向的鱼眼相机因为视野的问题布置在后视镜下方的比较多。

源自网络,如侵联删

        把四个鱼眼相机通过一定的方法拼接到一张图上,再把车辆照片贴到图片中央,就能近似形成完成的全景图像。下图所示的就是开源项目中所使用的的四路鱼眼相机的前、后、左、右方向的照片。

跨过参数标定聊透视变化

        写这篇文章的重点是要梳理如何从鱼眼图片透视变换为全景图片,相机的内外参标定跳过。要完成从单目鱼眼图到鸟瞰图的变化,最重要的一步骤就是完成如下从左图到右图的投影变换,也叫做透视变换。

        从左侧到右侧的变化是通过如下表达式实现的。我这里插一句,有同学将透视矩阵叫做外参,我认为这种说法是牵强的。为了说明这个问题,我们就先在世界坐标系下讨论,其他坐标系一样的道理。

源自网络,如侵联删
  1. 请参上式,基于将像素坐标反投回世界坐标系,需要内外参。所以即便透视后就是世界坐标,透视矩阵能只叫外参吗?
  2. 其次透视转换后得到的坐标定义为世界坐标是否合适?因为每个视角的透视变换是分离的,并不在同一坐标下。
  3. 还有像素坐标到世界坐标得到的是归一化平面下的世界坐标,非严格意义的世界坐标,那透视转换后得到的坐标定义为世界坐标是否准确?

        以上三个问题抛砖引玉,愿与大家探讨。我也计划分别针对“相机内参”和“实车全景拼接”再写两篇文章专门从数据上来验证这个事情。

引用自: Perspective Transformation | TheAILearner
引用自: Perspective Transformation | TheAILearner

        上面的公式解释了透视变换矩阵及其元素物理意义,感兴趣可直接到原文地址拜读。下面对于透视变换的图例描述的也挺形象的

引用自: Perspective Transformation | TheAILearner

        作者针对四路鱼眼图都进行了同样的透视变换。但在实施投影之前还有个重要的工作,就是图像去畸变,并在去畸变的过程中做一些视野范围的校正。

源自网络,如侵联删

        关于CV库去畸变方法中的矫正矩阵:参考上式,如果你推导过内参矩阵对应元素位置数值的话,应该很清楚在对应非零元素位置乘系数的作用就是:完成像素坐标在各轴线的放缩及平移。而在图像大小已定义的情况下,这个变化的作用无异于“裁剪”的效果。这样一来,就完成了去畸变的工作。

def update_undistort_maps(self):
    new_matrix = self.camera_matrix.copy()
    # 校正内参
    new_matrix[0, 0] *= self.scale_xy[0]
    new_matrix[1, 1] *= self.scale_xy[1]
    new_matrix[0, 2] += self.shift_xy[0]
    new_matrix[1, 2] += self.shift_xy[1]
    width, height = self.resolution

    self.undistort_maps = cv2.fisheye.initUndistortRectifyMap(
        self.camera_matrix,
        self.dist_coeffs,
        np.eye(3),
        new_matrix,
        (width, height),
        cv2.CV_16SC2
    )
    return self

def undistort(self, image):
    print("undistort_maps: ", self.undistort_maps)
    result = cv2.remap(image, *self.undistort_maps, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
    return result

        进一步的我们开始处理透视变换:透视变换需要提供输入图片及其变换矩阵。变换矩阵的变换可参考源码,基本的道理就是假设真实世界中的标定布的尺寸缩放出几个点的对应坐标数值,将其作为dst、原鱼眼图片对应位置的坐标作为src,通过getPerspectiveTransform方法获取,此处不赘述,后续会写相关文章。 

def project(self, image):
    result = cv2.warpPerspective(image, self.project_matrix, self.project_shape)
    return result

        下一步要将各个视角的透视图拼起来:这里需要梳理清楚的主要是各个图的相对位置和方向的关系。由于各个视角的透视变换图都是单独处理的,相当于是摄像头的朝向,所以对于后方摄像头需要做中心变换贴在鸟瞰图的上方,左侧摄像头视图需要左旋放在左侧,右侧如法。

def flip(self, image):
    if self.camera_name == "front":
        return image.copy()
    elif self.camera_name == "back":
        return image.copy()[::-1, ::-1, :]
    elif self.camera_name == "left":
        return cv2.transpose(image)[::-1]
    else:
        return np.flip(cv2.transpose(image), 1)

拼接图片后处理

        最后阶段的鸟瞰图的拼接与平滑,不作为文章的重点赘述,但主要涉及到了几种策略:

birdview = BirdView()
Gmat, Mmat = birdview.get_weights_and_masks(projected)
birdview.update_frames(projected)
birdview.make_luminance_balance().stitch_all_parts()
birdview.make_white_balance()
birdview.copy_car_image()
  • 重叠区域中的像素值的加权平均处理
  • 为拼接图像的亮度一致性调整各区域的亮度
  • 通过色彩平衡改善摄像头不同通道的强度不同的问题

参考文献

[1]  https://github.com/neozhaoliang/surround-view-system-introduction

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1195616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入探析隔离CAN收发器NSI1050-DDBR各项参数

NSI1050-DDBR是一个隔离的CAN收发器,可以完全与ISO11898-2标准兼容。 NSI1050-DDBR集成了两个通道的数字隔离器和一个高电平可靠性CAN收发器。 数字隔离器是基于Novosense电容隔离技术的氧化硅隔离。 高度集成的解决方案可以帮助简化系统设计并提高可靠性。 NSI1050…

【postgresql】CentOS7 安装pgAdmin 4

CentOS7 安装PostgreSQL Web管理工具pgAdmin 4。 pgAdmin 是世界上最先进的开源数据库 PostgreSQL 最受欢迎且功能丰富的开源管理和开发平台。 下载地址: pgadmin-4 download pgAdmin 4分为桌面版和服务器版。 我们这里部署服务器版本。 安装RPM包。 安装源 s…

使用IDEA工具处理git合并后的冲突的细节

使用 IDEA 处理合并(merge) 使用IDEA处理git合并如果遇到冲突,对冲突文件的不冲突部分需要处理吗?会自动将双方不冲突的部分合并吗? 比如如下,使用 IDEA 合并 branch1 到 branch2 分支,出现了冲突,如下图…

Linux学习第二枪(yum,vim,g++/gcc,makefile的使用)

前言:在我的上一篇Linux博客我已经讲了基础指令和权限,现在我们来学习如何在Linux上运行和执行代码 一,yum yum是Linux中的软件包管理器,软件包是有人一些人写好的代码和程序作出软件包放到服务器上,我们使用yum就能…

DCMM咨询评估官方解答及各地补贴政策!

1、DCMM是什么? DCMM是国家标准GB/T 36073-2018《数据管理能力成熟度评估模型》(Data management Capability Maturity Model)的简称,是我国数据管理领域首个正式发布的国家标准,旨在帮助企业利用先进的数据管理理念和…

响应式青少年成长训练营培训网站模板源码

模板信息: 模板编号:28503 模板编码:UTF8 模板颜色:黑白 模板分类:学校、教育、培训、科研 适合行业:培训机构类企业 模板介绍: 本模板自带eyoucms内核,无需再下载eyou系统&#x…

pyOCD

pyOCD 目录结构

Proteus仿真--基于数码管设计的可调式电子钟

本文主要介绍基于51单片机的数码管设计的可调式电子钟实验(完整仿真源文件及代码见文末链接) 仿真图如下 其中数码管主要显示电子钟时间信息,按键用于调节时间 仿真运行视频 Proteus仿真--数码管设计的可调式电子钟(仿真文件程…

C 语言 switch 语句

C 语言 switch 语句 在本教程中,您将通过一个示例学习在C语言编程中创建switch语句。 switch语句使我们可以执行许多代替方案中的一个代码块。 虽然您可以使用if…else…if阶梯执行相同的操作。但是,switch语句的语法更容易读写。 switch … case的语…

下载思科模拟器Cisco packet Tracer7.0

一、下载地址 主要去思科官网下载,但是最新版本没有汉化。 官网地址:https://www.cisco.com/ 百度网盘链接:https://pan.baidu.com/s/1VPTDN7BRgXIWt7m1E_8FMQ?pwd1111 提取码:1111 下载时把它放到U盘里,如图。 解压…

关于安卓刷机,小米手机,各种安卓手机,理念+实践,如:小米8

关于安卓刷机: 比刚买的时候 更加流畅,调节性能 狂暴模式,且无任何冗余软件和垃圾。 作为普通人,就是刷自己想要的系统,比如开发版。打开Root权限,第三方Rec TWRP,面具Magisk,LSPo…

超全总结!探索性数据分析 (EDA)方法汇总!

探索性数据分析(EDA)是一种系统地分析、可视化和总结数据集的过程,以获取洞察并更好地理解数据中潜在的模式和趋势。 EDA是任何数据分析项目中的重要步骤,因为它有助于识别数据中的潜在问题和偏见。EDA有助于为建模和进一步分析奠…

极智芯 | 存算一体 弯道超车的希望

欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文分享一下 存算一体 弯道超车的希望。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:…

win11下安装odoo17(conda python11)

win11下安装odoo17 odoo17发行了,据说,UI做了很大改进,今天有空,体验一下 打开官方仓库: https://github.com/odoo/odoo 默认的版本已经变成17了 打开odoo/odoo/init.py,发现对python版本的要求也提高了…

揭秘南卡开放式耳机创新黑科技,核心技术剑指用户痛点

随着科技的进步和人们娱乐方式的升级,大家对听音工具的选择,从传统的耳机到蓝牙耳机再到AirPods这样的真无线耳机,而今年,也有一种全新的耳机爆发式涌入人们之中,那就是开放式耳机。 开放式耳机的出现,满足…

Vuex:模块化Module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 这句话的意思是,如果把所有的状态都放在/src/store/index.js中,当项目变得越来越大的时候,Vue…

小白版SpringMVC执行流程

目录 从MVC聊起 认识核心组件 SpringMVC执行流程 从MVC聊起 相信大家在刚接触到springMVC的时候,上手时接触的第一个理论应该就是mvc的含义,我们先简单的回顾一下,什么是MVC。 MVC的全名是Model View Controller,是一种使用“…

快块手多功能全自动引流软件-引流工具-引流脚本-自动引流技术功能介绍

脚本功能: 功能1_养号功能 功能2_评论区关注 功能3_评论区私信 功能4_评论区用户作品评论 功能5_评论区点赞 功能6_粉丝回关 功能7_自己粉丝私信 功能8_已关私信 功能9_好友私信 功能10_关键词搜索关注 功能11_关键词搜索私信 功能12_搜索ID关注 功能13_搜索ID私信…

Windows7+vs2005源码安装subversion

Windows源码安装subversion 一、运行环境 windows7 32位系统 VS2005完整安装 二、源码编译环境配置 1、python环境安装 python-2.4.msi2、perl环境安装 ActivePerl-5.8.8.822-MSWin32-x86-280952.msi3、openssl编译 C:>cd openssl-0.9.7f C:>perl Configure VC-W…

element ui中Select 选择器,自定义显示内容

正常情况下,下拉框选项展示内容,就是选择后展示的label内容 如图所示: 但是要想自定义选项内容,但是展示内容不是选项label的内容,可以在el-option标签内增加div进行自定义选项label展示,但选择后结果展示…