鱼眼相机去畸变(图像拉直/展开/矫正)算法及实战总结

本文介绍两种方法

1、经纬度矫正法

2、棋盘格矫正法

一、经纬度矫正法

1、算法说明

经纬度矫正法, 可以把鱼眼图想象成半个地球, 然后将地球展开成地图,经纬度矫正法主要是利用几何原理, 对图像进行展开矫正。

        经过P点的入射光线没有透镜的话,本应交于相机成像平面的e点。然而,经过鱼眼相机的折射,光线会交于相机成像平面的d点,就产生了畸变,因此畸变图像整体上呈现出像素朝图像中心点聚集的态势。

        而去畸变,就是将折射到d点的点,重新映射回到e点,因此去畸变之后的图像与原始的鱼眼图像相比,仿佛是把向心聚集的像素又重新向四周铺展开来。

       详细的推导流程及公式见地址:AVM环视系统——鱼眼相机去畸变算法 - 知乎

2、 代码

import math
from PIL import Imageim = Image.open("/Users/Fisheye_photo-600x600.jpg")
im.show()width, high = im.size
sqrt_len = min(width, high)
im = im.transform((sqrt_len, sqrt_len),Image.EXTENT,((width-sqrt_len)/2, (high-sqrt_len)/2, sqrt_len+(width-sqrt_len)/2, sqrt_len+(high-sqrt_len)/2))
width = high = sqrt_lenidata = im.getdata()
odata = []alpha = math.pi/2out_high = round(high * math.tan(alpha/2))
out_width = round(width * math.tan(alpha/2))
out_radius = round(high * math.tan(alpha/2))
out_center_x = out_width / 2
out_center_y = out_high / 2out_bl_x = 0
out_br_x = out_width - 1
out_bt_y = 0
out_bb_y = out_high - 1out_bl_cx = out_bl_x - out_center_x
out_br_cx = out_br_x - out_center_x
out_bt_cy = out_bt_y - out_center_y
out_bb_cy = out_bb_y - out_center_ysrc_radius = round(high * math.sin(alpha/2))
src_center_x = width / 2
src_center_y = high / 2for i in range(0, high * width):ox = math.floor(i / out_width)oy = i % out_highcx = ox - out_center_x;cy = oy - out_center_y;out_distance = round(math.sqrt(pow(cx, 2) + pow(cy, 2)))theta = math.atan2(cy, cx)if (-math.pi/4 <= theta <= math.pi/4):bx = out_radius * math.cos(math.pi/4)by = bx * math.tan(theta)elif (math.pi/4 <= theta <= math.pi*3/4):by = out_radius * math.sin(math.pi/4)bx = by / math.tan(theta)elif (-math.pi*3/4 <= theta <= -math.pi/4):by = out_radius * math.sin(-math.pi/4)bx = by / math.tan(theta)else:bx = out_radius * math.cos(-math.pi*3/4)by = bx * math.tan(theta)bdy_distance = round(math.sqrt(pow(cx, 2) + pow(cy, 2)))src_distance = src_radius * bdy_distance / out_radiussrc_x = round(src_center_x + math.cos(theta) * src_distance)src_y = round(src_center_y + math.sin(theta) * src_distance)src_idx = src_x*width + src_y    if(0 < src_idx < high*width):odata.append(idata[src_idx])else:odata.append((0,0,0))om = Image.new("RGB", (high, width))
om.putdata(odata)
om.show()

3、代码及图片地址:GitHub - duducosmos/defisheye: Fast Corrects for fisheye distortion in an image.

二、棋盘格矫正方法

1、算法说明

利用棋盘格进行标定, 然后计算鱼眼镜头的畸变系数以及内参, opencv中自带有fisheye模块, 可以直接根据棋盘格标定结果,采用cv2.fisheye.calibrate计算畸变系数以及内参, 然后使用cv2.fisheye.initUndistortRectifyMap函数计算映射矩阵, 最后根据映射矩阵, 使用cv2.remap进行矫正。

2、代码

import cv2
import numpy as np
import math
import time# 鱼眼有效区域截取
def cut(img):img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)(_, thresh) = cv2.threshold(img_gray, 20, 255, cv2.THRESH_BINARY)contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cnts = sorted(contours, key=cv2.contourArea, reverse=True)[0]x,y,w,h = cv2.boundingRect(cnts)r = max(w/ 2, h/ 2)# 提取有效区域img_valid = img[y:y+h, x:x+w]return img_valid, int(r)# 鱼眼矫正
def undistort(src,r):# r: 半径, R: 直径R = 2*r# Pi: 圆周率Pi = np.pi# 存储映射结果dst = np.zeros((R, R, 3))src_h, src_w, _ = src.shape# 圆心x0, y0 = src_w//2, src_h//2for dst_y in range(0, R):theta =  Pi - (Pi/R)*dst_ytemp_theta = math.tan(theta)**2for dst_x in range(0, R):# 取坐标点 p[i][j]# 计算 sita 和 fiphi = Pi - (Pi/R)*dst_xtemp_phi = math.tan(phi)**2tempu = r/(temp_phi+ 1 + temp_phi/temp_theta)**0.5tempv = r/(temp_theta + 1 + temp_theta/temp_phi)**0.5if (phi < Pi/2):u = x0 + tempuelse:u = x0 - tempuif (theta < Pi/2):v = y0 + tempvelse:v = y0 - tempvif (u>=0 and v>=0 and u+0.5<src_w and v+0.5<src_h):dst[dst_y, dst_x, :] = src[int(v+0.5)][int(u+0.5)]# 计算在源图上四个近邻点的位置# src_x, src_y = u, v# src_x_0 = int(src_x)# src_y_0 = int(src_y)# src_x_1 = min(src_x_0 + 1, src_w - 1)# src_y_1 = min(src_y_0 + 1, src_h - 1)## value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, :] + (src_x - src_x_0) * src[src_y_0, src_x_1, :]# value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, :] + (src_x - src_x_0) * src[src_y_1, src_x_1, :]# dst[dst_y, dst_x, :] = ((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1 + 0.5).astype('uint8')return dstif __name__ == "__main__":t = time.perf_counter()frame = cv2.imread('../imgs/pig.jpg')cut_img,R = cut(frame)result_img = undistort(cut_img,R)cv2.imwrite('../imgs/pig_nearest.jpg',result_img)print(time.perf_counter()-t)

效果图

3、代码地址

https://github.com/HLearning/fisheye

三、总结:比对两个算法

本人用两个算法对一张图像进行拉直,发现经过经纬度矫正算法生成的图像原作者裁剪掉了边缘部分,见下图效果图,中间黑框内的图像是经过“经纬度矫正法”得到的效果图,外面的大图是用“棋盘格矫正法”得到的效果图

为了更直观,更改了图像的透明度,可以看出两个算法的效果还是多少有些差别的。

其实,两个算法的边缘部分都被严重拉伸,丢不丢掉看适用场景和个人需要吧。

四、知识拓展

立体标定

算法说明

坐标映射建立,各区域的角点都有一维世界坐标为0,对应图5中三幅子图像分别为Y=0,X=0,Z=0。根据棋盘方格边长以及与世界坐标原点间隔的方格数,可得到所有角点的世界坐标。从而建立起二维图像坐标与三维世界坐标的一一映射,用于模型参数的求解。

 

参考地址:采用立体标定板的鱼眼相机快速标定方法_真空技术_新闻动态_深圳市鼎达信装备有限公司

基于双经度模型的鱼眼图像畸变矫正方法

基于双经度模型的鱼眼图像畸变矫正方法 - 百度文库

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机上记录的备忘录内容怎么分享到电脑上查看?

手机已经成为了我们生活中不可或缺的一部分&#xff0c;我们用它来处理琐碎事务&#xff0c;记录生活点滴&#xff0c;手机备忘录就是我们常用的工具之一。但随着工作的需要&#xff0c;我们往往会遇到一个问题&#xff1a;手机上记录的备忘录内容&#xff0c;如何方便地分享到…

如何在Keil和IAR环境编译生成的bin文件添加CRC校验值

之前写过一篇文章介绍过 CRC 的原理和应用。在程序升级的情况下&#xff0c;我们可以在烧录下载的 bin 文件添加 CRC 校验值&#xff0c;以校验我们获取的bin文件是否正确。 下面我打算使用 APM32F407 的工程代码&#xff0c;介绍下如何在 Keil 环境和 IAR 环境对编译生成的 b…

leetCode 45.跳跃游戏 II 贪心算法

45. 跳跃游戏 II - 力扣&#xff08;LeetCode&#xff09; 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 &…

【算法——双指针】LeetCode 18 四数之和

题目描述&#xff1a; 解题思路&#xff1a;双指针 四数之和与前面三数之和思路一样&#xff0c;排序后&#xff0c;枚举 nums[a]作为第一个数&#xff0c;枚举 nums[b]作为第二个数&#xff0c;那么问题变成找到另外两个数&#xff0c;使得这四个数的和等于 target&#xff0c…

面试题:熟悉设计模式吗?谈谈简单工厂模式和策略模式的区别

刚刚接触设计模式的时候&#xff0c;我相信单例模式和工厂模式应该是用的最多的&#xff0c;毕竟很多的底层代码几乎都用了这些模式。自从接触了一次阿里的公众号发的一次文章关于 DDD的使用 以后&#xff0c;就逐渐接触了策略模式。现在在项目中运用最多的也是这几种设计模式了…

【数据结构初阶】六、线性表中的队列(C语言 -- 链式结构实现队列)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【数据结构初阶】五、线性表中的栈&#xff08;C语言 -- 顺序表实现栈&#xff09;_高高的胖子的博客-CSDN博客 1 . 队列&#xff08;Queue&#xff09; 队列的概念和结构&#xf…

【Linux】文件权限详解

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的…

国庆作业6

TCP服务器 #include "head.h" #define PORT 2580 //端口号 #define IP "192.168.31.219" //本机IP int main(int argc, const char *argv[]) {sqlite3* dbNULL;if(sqlite3_open("./my.db",&db)!SQLITE_OK){fprintf(stde…

Java 随机数的获得方法(5种)

1. Math.random() 静态方法 产生的随机数是 0 - 1 之间的一个 double&#xff0c;即 0 < random < 1 代码&#xff1a; 结果&#xff1a; 当调用 Math.random() 方法时&#xff0c;自动创建了一个伪随机数生成器&#xff0c;实际上用的是 new java.util.Random()。当接…

pwnable_hacknote

pwnable_hacknote Arch: i386-32-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x8047000)32位&#xff0c;没开PIE main部分就不贴了&#xff0c;直接贴主要的函数 unsigned int ADD() {int v0; // ebxint i; // [e…

【Kafka专题】Kafka快速实战以及基本原理详解

目录 前言课程内容一、Kafka介绍1.1 MQ的作用1.2 为什么用Kafka 二、Kafka快速上手2.1 实验环境2.2 单机服务体验2.3 认识Kafka模型架构2.4 Kafka集群2.5 理解服务端的Topic、Partion和Broker2.6 章节总结&#xff1a;Kafka集群的整体结构 三、Kraft集群&#xff08;拓展&#…

【计算机网络】高级IO之select

文章目录 1. 什么是IO&#xff1f;什么是高效 IO? 2. IO的五种模型五种IO模型的概念理解同步IO与异步IO整体理解 3. 阻塞IO4. 非阻塞IOsetnonblock函数为什么非阻塞IO会读取错误&#xff1f;对错误码的进一步判断检测数据没有就绪时&#xff0c;返回做一些其他事情完整代码myt…

Linux和本地Windows如何互传文件(sz和rz指令)

目录 关于 rzsz 注意事项 安装软件 rz的使用&#xff08;本地主机文件传到Windows中&#xff09; sz的使用(Linux中的文件传到本地Windows主机中) 关于 rzsz 这个工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件. 安装完毕之后可以通过直接拖拽的方式将文件…

【源码】hamcrest 源码阅读及空对象模式、模板方法模式的应用

文章目录 前言1. 类图概览2. 源码阅读2.1 抽象类 BaseMatcher2.1 接口 Description提炼模式&#xff1a;空对象模式 2. 接口 Description 与 SelfDescribing 配合使用提炼模式 模板方法 后记 前言 hamcrest &#xff0c;一个被多个测试框架依赖的包。听说 hamcrest 的源码质量…

Linux性能优化--性能工具:系统内存

3.0.概述 本章概述了系统级的Linux内存性能工具。本章将讨论这些工具可以测量的内存统计信息&#xff0c;以及如何使用各种工具收集这些统计结果。阅读本章后&#xff0c;你将能够&#xff1a; 理解系统级性能的基本指标&#xff0c;包括内存的使用情况。明白哪些工具可以检索…

解决u盘在我的电脑中重复显示两个

删除注册表&#xff1a; [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\DelegateFolders\{F5FB2C77-0E2F-4A16-A381-3E560C68BC83}]

910数据结构(2019年真题)

算法设计题 问题1 有一种排序算法叫做计数排序。这种排序算法对一个待排序的表&#xff08;采用顺序存储&#xff09;进行排序&#xff0c;并将排序结果存放到另一个新的表中。必须注意的是&#xff0c;表中所有待排序的关键字互不相同&#xff0c;计数排序算法针对表中的每个…

视频增强修复工具Topaz Video AI mac中文版安装教程

Topaz Video AI mac是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频&#xff0c;包括低分辨率视频、老旧影片、手机录制的视频等等。 使用Topaz Video AI非常简单&#xff…

5-1.(OOP)初步分析MCV架构模式

组成&#xff1a;模型&#xff08;model&#xff09;、视图&#xff08;view&#xff09;、控制器&#xff08;controller&#xff09; view&#xff1a;界面、显示数据 model&#xff1a;数据管理、负责在数据库中存取数据以及数据合法性验证 controller&#xff1a;负责转…

Python大数据之PySpark(四)SparkBaseCore

文章目录 SparkBase&Core环境搭建-Spark on YARN扩展阅读-Spark关键概念[了解]PySpark角色分析[了解]PySpark架构后记 SparkBase&Core 学习目标掌握SparkOnYarn搭建掌握RDD的基础创建及相关算子操作了解PySpark的架构及角色 环境搭建-Spark on YARN Yarn 资源调度框…