相机内参 opencv

视场角定相机内参

import numpy as np
import cv2
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3Ddef calculate_camera_intrinsics(image_width=640, image_height=480, fov=55, is_horizontal=True):"""计算相机内参矩阵参数:image_width: 图像宽度(像素)image_height: 图像高度(像素)fov: 视野角(度)is_horizontal: 是否为水平视野角返回:K: 相机内参矩阵focal_length: 焦距(像素)"""# 将FOV从度转换为弧度fov_rad = np.radians(fov)# 计算焦距if is_horizontal:focal_length = (image_width / 2) / np.tan(fov_rad / 2)else:focal_length = (image_height / 2) / np.tan(fov_rad / 2)# 主点(通常位于图像中心)cx = image_width / 2cy = image_height / 2# 构建相机内参矩阵K = np.array([[focal_length, 0, cx], [0, focal_length, cy], [0, 0, 1]], dtype=np.float32)return K, focal_lengthdef visualize_camera_model(K, image_size, title="相机模型可视化"):"""可视化相机模型和视野"""fig = plt.figure(figsize=(10, 8))ax = fig.add_subplot(111, projection='3d')# 相机位置camera_pos = np.array([0, 0, 0])# 图像平面尺寸width, height = image_size# 焦距fx = K[0, 0]fy = K[1, 1]cx = K[0, 2]cy = K[1, 2]# 假设图像平面在z=f处z = fx# 计算图像平面四个角点的3D坐标top_left = np.array([(0 - cx) * z / fx, (0 - cy) * z / fy, z])top_right = np.array([(width - cx) * z / fx, (0 - cy) * z / fy, z])bottom_left = np.array([(0 - cx) * z / fx, (height - cy) * z / fy, z])bottom_right = np.array([(width - cx) * z / fx, (height - cy) * z / fy, z])# 绘制相机位置ax.scatter(camera_pos[0], camera_pos[1], camera_pos[2], c='r', marker='o', s=100, label='相机位置')# 绘制从相机到图像平面四角的视线for corner in [top_left, top_right, bottom_left, bottom_right]:ax.plot([camera_pos[0], corner[0]], [camera_pos[1], corner[1]], [camera_pos[2], corner[2]], 'b-', alpha=0.5)# 绘制图像平面x = np.array([top_left[0], top_right[0], bottom_right[0], bottom_left[0], top_left[0]])y = np.array([top_left[1], top_right[1], bottom_right[1], bottom_left[1], top_left[1]])z = np.array([top_left[2], top_right[2], bottom_right[2], bottom_left[2], top_left[2]])ax.plot(x, y, z, 'g-', alpha=0.8)# 设置坐标轴范围max_range = max(width, height, fx) * 0.5ax.set_xlim([-max_range, max_range])ax.set_ylim([-max_range, max_range])ax.set_zlim([0, max_range * 2])# 设置坐标轴标签ax.set_xlabel('X轴')ax.set_ylabel('Y轴')ax.set_zlabel('Z轴')# 设置视角ax.view_init(elev=20, azim=30)# 添加标题和图例ax.set_title(title)ax.legend()plt.tight_layout()plt.show()def visualize_camera_model_opencv(K, image_size, title="相机模型可视化"):"""使用OpenCV可视化相机模型和视野"""# 创建空白图像width, height = image_sizecanvas = np.ones((height, width, 3), dtype=np.uint8) * 255# 焦距和主点fx = K[0, 0]fy = K[1, 1]cx = K[0, 2]cy = K[1, 2]# 相机位置(图像中心)camera_center = (int(cx), int(cy))# 计算视野边界点fov_scale = min(width, height) * 0.4  # 视野显示比例# 计算四个方向的视野边界点points = [(int(cx), int(cy - fov_scale)),  # 上(int(cx + fov_scale), int(cy)),  # 右(int(cx), int(cy + fov_scale)),  # 下(int(cx - fov_scale), int(cy)),  # 左]# 绘制视野范围(矩形)cv2.rectangle(canvas, (points[3][0], points[0][1]), (points[1][0], points[2][1]), (0, 255, 0), 2)# 绘制主点cv2.circle(canvas, camera_center, 5, (0, 0, 255), -1)cv2.putText(canvas, "主点", (camera_center[0] + 10, camera_center[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)# 绘制坐标轴axis_length = 100cv2.arrowedLine(canvas, camera_center, (camera_center[0] + axis_length, camera_center[1]), (255, 0, 0), 2)  # X轴(蓝色)cv2.arrowedLine(canvas, camera_center, (camera_center[0], camera_center[1] + axis_length), (0, 0, 255), 2)  # Y轴(红色)# 添加焦距信息cv2.putText(canvas, f"fx: {fx:.2f}", (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2)cv2.putText(canvas, f"fy: {fy:.2f}", (20, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2)# 添加标题cv2.putText(canvas, title, (20, height - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2)# 显示图像cv2.imshow(title, canvas)cv2.waitKey(0)cv2.destroyAllWindows()
def main():# 图像尺寸image_width = 640image_height = 480# FOV(度)fov = 55# 计算相机内参(假设为水平FOV)K, focal_length = calculate_camera_intrinsics(image_width=image_width, image_height=image_height, fov=fov, is_horizontal=True)# 打印结果print(f"图像尺寸: {image_width}x{image_height} 像素")print(f"视野角(FOV): {fov} 度")print(f"焦距: {focal_length:.2f} 像素")print("\n相机内参矩阵:")print(K)# 可视化相机模型visualize_camera_model(K, (image_width, image_height))# visualize_camera_model_opencv(K, (image_width, image_height), title="相机模型可视化")# 如果是垂直FOV,也可以计算K_vertical, _ = calculate_camera_intrinsics(image_width=image_width, image_height=image_height, fov=fov, is_horizontal=False)print("\n如果这是垂直FOV,相机内参矩阵为:")print(K_vertical)if __name__ == "__main__":main()

 

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

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

相关文章

MATLAB 各个工具箱 功能说明

​ 想必大家在安装MATLAB时,或多或少会疑惑应该安装哪些工具箱。笔者遇到了两种情况——只安装了MATLAB主程序,老师让用MATLAB的时候却发现没有安装对应安装包;第二次安装学聪明了,全选安装,嗯……占用了20多个G。 ​…

学习日记-day14-5.23

完成目标: 学习java下半段课程 知识点: 1.多态转型 知识点 核心内容 重点 多态转型 向上转型(父类引用指向子类对象) 与向下转型(强制类型转换)的机制与区别 向上转型自动完成,向下转型需…

【编程语言】【Java】一篇文章学习java,复习完善知识体系

第一章 Java基础 1.1 变量与数据类型 1.1.1 基本数据类型 1.1.1.1 整数类型(byte、short、int、long) 在 Java 中,整数类型用于表示没有小数部分的数字,不同的整数类型有不同的取值范围和占用的存储空间: byte&am…

汇量科技前端面试题及参考答案

数组去重的方法有哪些? 在 JavaScript 中,数组去重是一个常见的操作,有多种方法可以实现这一目标。每种方法都有其适用场景和性能特点,下面将详细介绍几种主要的去重方法。 使用 Set 数据结构 Set 是 ES6 引入的一种新数据结构&a…

Git实战演练,模拟日常使用,快速掌握命令

01 引言 上一期借助Idea,完成了Git仓库的建立、配置、代码提交等操作,初步入门了Git的使用。然而日常开发中经常面临各种各样的问题,入门级的命令远远不够使用。 这一期,我们将展开介绍Git的日常处理命令,解决日常问…

wordpress主题开发中常用的12个模板文件

在WordPress主题开发中,有多种常用的模板文件,它们负责控制网站不同部分的显示内容和布局,以下是一些常见的模板文件: 1.index.php 这是WordPress主题的核心模板文件。当没有其他更具体的模板文件匹配当前页面时,Wor…

数据库blog5_数据库软件架构介绍(以Mysql为例)

🌿软件的架构 🍂分类 软件架构总结为两种主要类型:一体式架构和分布式架构 ● 一体化架构 一体式架构是一种将所有功能集成到一个单一的、不可分割的应用程序中的架构模式。这种架构通常是一个大型的、复杂的单一应用程序,包含所…

离线服务器算法部署环境配置

本文将详细记录我如何为一台全新的离线服务器配置必要的运行环境,包括基础编译工具、NVIDIA显卡驱动以及NVIDIA-Docker,以便顺利部署深度学习算法。 前提条件: 目标离线服务器已安装操作系统(本文以Ubuntu 18.04为例&#xff09…

chromedp -—— 基于 go 的自动化操作浏览器库

chromedp chromedp 是一个用于 Chrome 浏览器的自动化测试工具,基于 Go 语言开发,专门用于控制和操作 Chrome 浏览器实例。 chromedp 安装 go get -u github.com/chromedp/chromedp基于chromedp 实现的的简易学习通刷课系统 目前实现的功能&#xff…

高级特性实战:死信队列、延迟队列与优先级队列(三)

四、优先级队列:优先处理重要任务 4.1 优先级队列概念解析 优先级队列(Priority Queue)是一种特殊的队列数据结构,它与普通队列的主要区别在于,普通队列遵循先进先出(FIFO)的原则,…

python打卡day34

GPU训练及类的call方法 知识点回归: CPU性能的查看:看架构代际、核心数、线程数GPU性能的查看:看显存、看级别、看架构代际GPU训练的方法:数据和模型移动到GPU device上类的call方法:为什么定义前向传播时可以直接写作…

Newtonsoft Json序列化数据不序列化默认数据

问题描述 数据在序列号为json时,一些默认值也序列化了,像旋转rot都是0、缩放scal都是1,这样的默认值完全可以去掉,减少和服务器通信数据量 核心代码 数据结构字段增加[DefaultValue(1.0)]属性,缩放的默认值为1 public class Vec3DataOne{[DefaultValue(1.0)] public flo…

可增添功能的鼠标右键优化工具

软件介绍 本文介绍一款能优化Windows电脑的软件,它可以让鼠标右键菜单添加多种功能。 软件基本信息 这款名为Easy Context Menu的鼠标右键菜单工具非常小巧,软件大小仅1.14MB,打开即可直接使用,无需进行安装。 添加功能列举 它…

Gemini 2.5 Pro 一次测试

您好,您遇到的重定向循环问题,即在 /user/messaging、/user/login?return_to/user/messaging 和 /user/login 之间反复跳转,通常是由于客户端的身份验证状态检查和页面重定向逻辑存在冲突或竞争条件。 在分析了您提供的代码(特别…

vue3前端后端地址可配置方案

在开发vue3项目过程中,需要切换不同的服务器部署,代码中配置的服务需要可灵活配置,不随着run npm build把网址打包到代码资源中,不然每次切换都需要重新run npm build。需要一个配置文件可以修改服务地址,而打包的代码…

大模型微调与高效训练

随着预训练大模型(如BERT、GPT、ViT、LLaMA、CLIP等)的崛起,人工智能进入了一个新的范式:预训练-微调(Pre-train, Fine-tune)。这些大模型在海量数据上学习到了通用的、强大的表示能力和世界知识。然而,要将这些通用模型应用于特定的下游任务或领域,通常还需要进行微调…

编程技能:字符串函数10,strchr

专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏,故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 (一)WIn32 专栏导航 上一篇:编程技能:字符串函数09,strncmp 回到目录…

动态规划-53.最大子数组和-力扣(LeetCode)

一、题目解析 在给定顺序的数组中找出一段具有最大和的连续子数组,且大小最小为1. 二、算法原理 1.状态表示 我们可以意一一枚举出所有的子数组,但我们想要的是最大子数组,所以f[i]表示:以i位置为结尾,所有子数组的最…

C++ queue对象创建、queue赋值操作、queue入队、出队、获得队首、获得队尾操作、queue大小操作、代码练习

对象创建&#xff0c;代码见下 #include<iostream> #include<queue>using namespace std;int main() {// 1 默认构造函数queue<int> q1;// 2 拷贝构造函数queue<int> q2(q1);return 0;} queue赋值操作&#xff0c;代码见下 #include<iostream>…

全链路解析:影刀RPA+Coze API自动化工作流实战指南

在数字化转型加速的今天&#xff0c;如何通过RPA与API的深度融合实现业务自动化提效&#xff0c;已成为企业降本增效的核心命题。本文以「影刀RPA」与「Coze API」的深度协作为例&#xff0c;系统性拆解从授权配置、数据交互到批量执行的完整技术链路&#xff0c;助你快速掌握跨…