光流Zoom In and Out开发记录

2023-05-16

简介

    2018年7月,合作伙伴提出了一个想法——使用光流算法估计相机前后移动。经典的光流算法(Lukas-Kanade算法)适用于相机左右和上下移动,但是在相机前后移动时,虽然各个像素都有移动,但是移动速度是矢量,综合起来,整个相机的移动却接近0。这个是经典的LK光流算法的问题,其根源是速度位矢量,而相机前后移动就像是图片的放大(Zoom in)和缩小(Zoom out),使所有像素的移动速度矢量呈放射状均匀分布在相机视野中。

    我想到了一个可能的解决方法——改变坐标系,使像素在新坐标系下的移动速度朝向一致,而极坐标系就是适合使用的一种。因此,本文集中考虑极坐标系下的LK光流算法应用,专门用来计算相机的Zoom in and out情况。

光流算法

    光流算法是用来检测相机移动的,与SLAM的3D空间定位不同,光流算法是在2D平面下定位。其理论是相机发生平移时,画面会发生移动,并且是整体移动。

极坐标变换

1 介绍

    针对Zoom in and out问题下的光流算法,首先要做的是极坐标变换。具体而言,照片的像素坐标是使用直角坐标系表示的,但在Zoom in and out问题下,向光流算法输入的像素需要在极坐标系下,而不能是直角坐标系。

2 编程

    极坐标系的变换原理很简单,而相对麻烦的是编程。由于我们的应用背景是单片机,其对编程语言的要求是C语言,因此在开发最开始的阶段,我虽然是在Mac OS X上使用g++编译器,语言也仍然使用C/C++,但避免使用类、Vector等C++的功能。

问题1 - 像素保存

    这样,最先遇到的问题就是以什么形式保存照片,无论是直角坐标系下的,还是极坐标系下的。这里我选择使用数组,而且是一维数组,这是最简单的形式,因而通用型和稳定性最强。同时,由于我在2017年学习矩阵运算时,也遇到了单片机下的矩阵构建和保存问题,当时使用的就是这套思路,具备开发经验,问题不大。

    照片是二维的,而且在极坐标系下也是这样,使用一维数组表示二维的像素的思路是以照片每行的像素数量为进制,例如一个像素位于极坐标系下(2,8)处(像素编号从0开始),且每一行有10个像素,那么这个像素在一维数组中的位置是(8*10+2)。通用的表示方法是像素坐标(i,j),每一行的像素数量为binx,则其在一维数组中的位置是(j*binx+i)。

问题2 - 区间划分

    极坐标系包含两个分量——角度(theta)和半径(r)。一张极坐标系下的照片,实际上就是一张二维直方图(2D Hisgram),这个直方图的X轴是角度,Y轴是半径;而直方图的Z轴是计数,在这里表示像素的灰度值。实际上,Z轴也可以表示RGB值等等,具体使用哪个需要参考实际使用背景,而这里选择使用灰度值,是因为光流算法以灰度值为输入。

    直方图的特点是每条轴上都被均匀划分为若干区间,区间的数量称为”bin”,区间的最小值称为”min”,区间的最大值称为”max”。在这里,X轴代表的角度范围是[-180, 180](degree),其中最小值和最大值都是可以达到的,这里就出现了编程时会出现的一个Bug——在180度或者-180度时,像素坐标会超过直方图X轴上限。

    解决方法是增加区间数量并且扩大X轴的最小和最大值,目标是使180度被分配到最后一个区间(或者是-180被分配到第一个区间),在这里区间数使用40,区间范围使用了(-200, 200),那么180度就被分配到了X轴的38号区间,实际是第39个区间(因为区间编号是从0开始的)。

问题3 - 区间确定

    极坐标系下,像素的坐标,也就是角度和半径分别通过atan2()和sqrt()计算得到,但是这两个数并不是二维直方图的X轴和Y轴的区间编号。

    区间编号仍然需要通过计算得到,理论上的计算方法是(theta-min_theta)/binSize_theta。其中,theta是当前处理的像素的角度;min_theta是二维直方图上X轴(默认X轴用来表示角度)的最小值;binSize_theta是X轴上一个区间的宽度,计算方法是(max_theta-min_theta)/bin_theta。

    实际上,由于数组的编号是整数,数组的编号输入强制为int类型,因此,所计算出的区间编号需要转换为整数。这里就涉及到小数位的取舍问题,在当前的工作中,我统一使用“进一法”,即只要小数位不为零,整数位就加一,对应到函数是ceil()。

问题4 - 照片中心点确定

    在相机的Zoom in and out情况中,所有像素都是相对照片中心进行移动的,也就是所有像素的移动速度都是朝向(Zoom in)或者背向(Zoom out)照片中心的。因此,在进行极坐标系变换的时候,所有像素的角度(theta)和半径(r)都需要相对于照片中心进行计算。

    在编程实现上,所有像素都是离散的,根据每行像素的数量和每列像素的数量,也就是照片的分辨率,照片的中心可能出现在一个像素的边角上,也可能出现在像素的中心。这与行列上的像素数量的奇偶有关——以行为例,像素数量为奇数时,中心出现在像素中心;数量为偶数时,中心出现在像素的角上。

    由于最终需要得到像素在极坐标系的直方图下对应的区间编号(整数),方便起见,这里将照片的中心点强行归结到像素的角上。具体操作是通过照片的行、列像素数量计算各自的中点,再使用“进一法”(ceil())得到整数值。

问题5 - 极坐标系下像素互相远离

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

光流Zoom In and Out开发记录 的相关文章

  • 闭包详解(Python为例)

    不能简单讲 xff0c 这就要看一些底层的东西 堆栈结构等等 xff0c 估计还和编译原理有关 xff0c 我觉得重点在于延迟绑定怎么知道绑定的外层函数的局部变量 python的闭包是延迟绑定 什么是闭包 出现函数嵌套 即外层函数嵌套内层函
  • c++中函数只声明,不定义(不调用该函数)可以通过编译并运行

    c 43 43 中函数只声明 xff0c 不定义 xff0c 代码中也没有该函数的调用 xff0c 可以编译并运行 xff08 vs2015 xff09 Author gtkiller Date 2018 03 19 include lt
  • RMI的基础原理

    背景 上世纪90年代 焦点转移到跨平台通信 一台计算机可以通过某种类型网络在另一台计算机上发起一个动作 CORBA DCOM Java RMI 技术等等 xff0c 到现在的grpc等 Hello span class token keyw
  • 一次因修改Python编码规范而引起的“血案“

    简单来说就是因为如下代码 导致了ZipOutputPath的一个函数异常 导致zip包不能正确下载 有如下报错 UnboundLocalError local variable 39 val 39 referenced before ass
  • Python之禅(The Zen of Python)源码分析

    简介 非常高兴大家能够订阅这个专栏 在这里我将会给大家分享一些Python相关源码的剖析 在接下来的这段日子里 我会一同带各位pythonista探索Python的奥秘 该从什么开始 思来想去 我觉得作为一个Python初学者还是Pytho
  • Linux常用命令速查表

    目录即文件 dev null 等价于只写文件 所有写入它的内容都会永远丢失 而尝试从它那儿读取内容则什么也读不到 禁止标准输出 cat filename gt dev null 文件内容丢失 xff0c 而不会输出到标准输出 禁止标准错误
  • git常用命令速查表

    这是一些比较常用的命令 大家可以复制后用typora做成pdf格式 xff0c 方便快速查询 后续不定期更新 官方文档 官方文档 https git scm com docs 本地文档 file D cmder vendor git for
  • python开发中的常用命令

    这是一些比较常用的命令 大家可以复制后用typora做成pdf格式 xff0c 方便快速查询 后续不定期更新 pip升级 pip package installer for python use pip to install package
  • Python手写一个Base64编解码工具

    这里我们只实现标准的base64 补充位用 61 填充 编码 下面是base64字符的对照表 因为base64编码是将6bit表示成8bit 所以在原来的基础上会增长1 3 另外2 6 61 64 xff0c 这也是为什么这个表会有64个索
  • Python彩蛋源码分析(二)

    简介 非常高兴大家能够订阅这个专栏 在这里我将会给大家分享一些Python相关源码的剖析 在接下来的这段日子里 我会一同带各位pythonista探索Python的奥秘 hello world hello world hello pytho
  • Python源码剖析专栏总览

    简介 非常高兴大家能够订阅这个专栏 在这里我将会给大家分享一些Python相关源码的剖析 在接下来的这段日子里 我会一同带各位pythonista探索Python的奥秘 将会分析一些源码的构思设计以及这些工具的使用方法 彩蛋篇 Easter
  • maven笔记小抄

    settings xml settings xml位置 标签指定本地下载的依赖在本地的保存位置 user home m2 repository表示C Users username m2 settings xml idea中File Sett
  • linux 下 tcpdump 详解 后篇(自己实现抓包过滤)

    一 概述 在了解了tcpdump的原理后 xff0c 你有没有想过自己去实现抓包过滤 xff1f 可能你脑子里有个大概的思路 xff0c 但是知道了理论知识 xff0c 其实并不能代表你完全的理解 只要运用后 xff0c 你才知道哪些点需要
  • Python字节码分析(一)

    简介 非常高兴大家能够订阅这个专栏 在这里我将会给大家分享一些Python相关源码的剖析 在接下来的这段日子里 我会一同带各位pythonista探索Python的奥秘 Pyc文件 简介 当在文件被当成模块导入时才会生成pyc文件 pyc文
  • Python基本类型(一)

    简介 非常高兴大家能够订阅这个专栏 在这里我将会给大家分享一些Python相关源码的剖析 在接下来的这段日子里 我会一同带各位pythonista探索Python的奥秘 basic data types in python Python中的
  • xmlrpc源码解读(一)

    简介 非常高兴大家能够订阅这个专栏 在这里我将会给大家分享一些Python相关源码的剖析 在接下来的这段日子里 我会一同带各位pythonista探索Python的奥秘 将会分析一些源码的构思设计以及这些工具的使用方法 一个简单的RPC实例
  • Python代码整洁之道勘误

    简介 本博文是对 lt Python代码整洁之道 gt 一书的一些错误进行矫正 这本书英文名字是 lt Clean Python Elegant Coding int Python gt 这本书的作者是Sunil Kapil 这本书错误非常
  • 自己动手写strcat函数

    char catstr char a char b char x 61 a while a 61 39 0 39 a 43 43 while b 61 39 0 39 a 61 b a 43 43 b 43 43 a 61 39 0 39
  • 为什么C++开发不需要安装STL库

    如果交叉编译工具链的路径已经添加到path变量中的话 xff0c 可以直接使用 v即可查看 xff0c 比如我的是arm linux gnueabihf g 43 43 那么直接arm linux gnueabihf g 43 43 v或者
  • 为什么要内存对齐

    为什么要内存对齐 xff1f 很多CPU是从对齐的地址开始加载数据 xff0c 外部总线从内存一次获取的数据往往不是1比特 xff0c 而是4比特或8比特或更多 xff0c 与数据总线带宽有关 比如有一个int数据类型 xff0c 其分配的

随机推荐

  • marlin2.0.x 固件相关配置文档说明

    主要目的 了解对应参数的作用 xff0c 以优化3D打印机的打印效果 具体分析 配置文件有两个 Configuration h 包含硬件核心 语言和控制器的设置 xff0c 以及最常见的功能和组件的设置 xff0c 主要配置的地方 Conf
  • c++容器--vector deque list set map stack queue特性及其选取准则

    1 vector xff08 连续的空间存储 可以使用 操作符 xff09 快速的访问随机的元素 xff0c 快速的在末尾插入元素 xff0c 但是在序列中间岁间的插入 xff0c 删除元素要慢 xff0c 而且如果一开始分配的空间不够的话
  • 网络、串口之应用层通讯协议编订

    一种二进制通信协议 消息长度 BYTES 结构描述Header4SyncBytes格式 xff1a 0x09 0x6f 0x01 0x01 xff0c 表示不同设备之间的交互Header4FullMessageLength数据总长度 xff
  • STM32基于串口接收缓存非空中断(RXNE)和空闲中断的串口转发功能

    STM32基于串口接收缓存非空中断 xff08 RXNE xff09 和空闲中断的串口转发功能 0 实验背景 本实验的目的是实现串口的双向转发 xff0c 即向串口1写入数据后 xff0c 串口2及时输出串口1收到的数据 xff1b 向串口
  • Ubuntu16.04 中 搭建Janus Server

    Ubuntu16 04 局域网中搭建Janus Server janus简介 Janus是WebRTC 服务器端的开源项目 xff0c 官方对其定义是一个WebRTC服务器端 xff0c 支持的功能比较丰富 xff0c 通过core模块来支
  • 堆栈溢出一般是由什么原因导致

    背景 全局变量存放在静态存储区 位置是固定的 局部变量在栈空间 栈地址是不固定的 栈 xff1a 就是那些由编译器在需要的时候分配 xff0c 在不需要的时候自动清楚的变量的存储区 里面的变量通常是局部变量 函数参数等 堆 xff1a 就是
  • 简单明了的蓝牙服务及UUID介绍

    什么是蓝牙 蓝牙 xff0c 是一种支持设备短距离通信 xff08 一般10m内 xff09 的无线电技术 xff0c 能在包括移动电话 PDA 无线耳机 笔记本电脑 相关外设等众多设备之间进行无线信息交换 利用 蓝牙 技术 xff0c 能
  • 深入详细理解矩阵 (矩阵的加减乘、转置、共轭、共轭转置)

    简介 矩阵 英文名Matrix 在数学名词中 xff0c 矩阵用来表示统计数据等方面的各种有关联的数据 这个定义很好地解释了Matrix代码制造世界的数学逻辑基础 矩阵是数学中最重要的基本概念之一 xff0c 是代数学的一个主要研究对象 x
  • 无线模块的参数介绍和选型要点

    01 通信频点 通信频点 xff1a 无线模块在工作的时候向外辐射出去的电波频率 xff1b 无线串口模块常用的频点大致可以分为170MHz 230MHz 315MHz 433MHz 490MHz 780MHz 868MHz 915MHz
  • 使用freertos如何确定分配堆栈空间大小

    前言 运行freertos系统的大部分都是资源有限的MCU xff0c 所以对于ram我们都要考虑尽量的节省 xff0c 避免资源浪费 xff0c 从而也可以针对项目选择性价比更好的mcu 关系分析 首先要配置freertos的堆 heap
  • windows从零搭建googletest之c++测试工程

    简介 googletest xff08 也称gtest xff09 是由Google测试技术团队开发的测试框架 为c c 43 43 代码提供了一套优秀的单元测试解决方案 本文介绍使用googletest在windows下从零搭建自己的单元
  • c++ 常用转换vector<uint8_t> 转string

    std span class token double colon punctuation span vector span class token operator lt span span class token keyword uin
  • c语言解析协议常用套路

    简介 协议定义username len value while 读取 2个switch case解析 读取value 代码示例 span class token keyword struct span span class token cl
  • c++模板 --- 模板的嵌套

    简介 明白类型是什么即可 xff0c 可以适当运用using语法起别名 简化代码 一 函数模板嵌套 span class token keyword template span span class token operator lt sp
  • DWA算法详解

    首先在V m V d的范围内采样速度 xff1a allowable v 61 generateWindow robotV robotModel
  • C++OpenCV实现YOLO算法对目标进行检测实战

    基本概念 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 加载darknet框架的YoloV4模型做目标检测 OpenCV DNN模块支持常见深度学习框架如TensorFlowCaffe Darknet等 对
  • 使用GooSeeker软件进行爬虫

    一 使用GooSeeker软件进行爬虫 xff0c 它是进行读取大量数据的 xff0c 都出来的数据是xml格式的 xff0c 可以通过office excel将xml格式转化成表格形式 1 爬虫取数据 xff1a 1 xff09 先要在网
  • 51单片机--堆栈

    堆栈的作用是用在调用子程序或中断程序时保护现场 xff0c 因为51单片机的寄存器是十分有限的 xff0c 而相对来说普通数据存储器更充足 xff0c 通过入栈将寄存器中的内容临时保存到堆栈中 xff08 普通数据存储器 xff09 xff
  • Git-命令行-使用 Tag 标记你的代码

    前言 正文开始之前 xff0c 我想我们需要弄明白几个问题 xff1a tag 是什么 xff1f 使用tag 的好处 xff1f tag 和 branch 的区别以及使用场景 xff1f tag 是什么 xff1f tag 翻译过来是标签
  • 光流Zoom In and Out开发记录

    简介 2018年7月 xff0c 合作伙伴提出了一个想法 使用光流算法估计相机前后移动 经典的光流算法 xff08 Lukas Kanade算法 xff09 适用于相机左右和上下移动 xff0c 但是在相机前后移动时 xff0c 虽然各个像