手机单目相机内参标定

news2024/11/14 17:16:59

使用软件:

参考我之前的文章:
软件地址:https://github.com/DavidGillsjo/VideoIMUCapture-Android/releases

棋盘标定板下载

链接: https://pan.baidu.com/s/1wiPJsEf87Vc0D7KwJnt3GA?pwd=1234 
提取码: 1234 

过程

1.使用下载的软件录制一段视频,使用详见我的另一个文章
https://blog.csdn.net/qin_liang/article/details/127612977

录制的时候,可以使用电脑来显示这个棋盘格,只要根据视频上格子的大小修改标定代码中相应位置就行。录制时围绕棋盘格旋转拍摄就行。

2.录制后的视频使用ffmpeg转化为图片集,参考代码:
自己设定

import os
scene='calib'
ff_cmd = 'ffmpeg -i ./data/'+scene+'/'+scene+'.mp4 -qscale:v 1 -qmin 1 -vf fps=2 ./data/'+scene+'/input/%04d.jpg'
os.system(ff_cmd)

3.将图片转化为需要的形式,比如我这里手机采用横屏录制,那么我需要额外处理一下图片集,参考代码:

import os
from PIL import Image


def flip_images_in_folder(src_folder, dst_folder):
    # 创建目标文件夹,如果它不存在
    os.makedirs(dst_folder, exist_ok=True)

    # 遍历源文件夹中的所有文件
    for filename in os.listdir(src_folder):
        # 检查文件是否是图片(这里仅检查扩展名,可能需要根据实际情况调整)
        if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
            # 完整路径
            src_path = os.path.join(src_folder, filename)
            dst_path = os.path.join(dst_folder, filename)

            # 打开图片
            with Image.open(src_path) as img:
                # 转置图片(横竖翻转)
                img = img.transpose(Image.TRANSPOSE)
                flipped_img = img.transpose(Image.FLIP_TOP_BOTTOM)


                # 保存转置后的图片
                flipped_img.save(dst_path)

                print(f"Flipped image saved to {dst_path}")

            # 使用示例


# 指定源文件夹和目标文件夹
source_folder = 'D:\Data\PythonProject\gaussian-splatting\data\calib\input'  # 源文件夹路径
destination_folder = 'D:\Data\PythonProject\gaussian-splatting\data\calib\input_ok'  # 目标文件夹路径

# 调用函数翻转图片
flip_images_in_folder(source_folder, destination_folder)

得到的横向的图片集:
在这里插入图片描述

4.处理后的图片集就可以直接使用如下的代码进行标定,注意根据自己的情况修改格子size:

标定效果:
在这里插入图片描述

标定代码:

import numpy as np
import cv2
import os
from PIL import Image

# 遍历照片
def read_images_from_folder(folder_path):
    images = []
    for filename in os.listdir(folder_path):
        if filename.endswith(".jpg") or filename.endswith(".png"):
            image_path = os.path.join(folder_path, filename)
            try:
                image = Image.open(image_path)
                images.append(image_path)
            except IOError:
                print("Cannot open image: ", filename)
    return images

# 标定板格点数量和大小
pattern_size = (8, 6)  # 内部角点数量
square_size = 20  # 棋盘格方块大小(毫米)

# 存储棋盘格角点的3D坐标
obj_points = []
# 存储棋盘格对应的图像点坐标
img_points = []

# 准备棋盘格的3D坐标
objp = np.zeros((pattern_size[0] * pattern_size[1], 3), dtype=np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2) * square_size

# 指定文件夹路径
folder_path = "D:\Data\PythonProject\gaussian-splatting\data\calib\input_ok"
# 调用函数读取图片
images = read_images_from_folder(folder_path)

# 遍历所有标定图像
for image_path in images:
    # 读取图像并将其转换为灰度图
    image = cv2.imread(image_path)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 查找棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)

    # 如果找到棋盘格角点则存储对应的3D和2D坐标
    if ret:
        obj_points.append(objp)
        img_points.append(corners)

        # 在图像上绘制棋盘格角点
        cv2.drawChessboardCorners(image, pattern_size, corners, ret)
        cv2.imshow('Chessboard Corners', image)
        cv2.waitKey(500)

# 进行相机内参标定
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None)

# 打印相机内参和畸变系数
print("Camera Matrix:\n", camera_matrix)
print("\nDistortion Coefficients:\n", dist_coeffs)
np.savetxt('camera_matrix.txt', camera_matrix)
np.savetxt('dist_coeffs.txt', dist_coeffs)



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

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

相关文章

重学Java 18.学生管理系统项目

臣无祖母,无以至今日,祖母无臣,无以终余年 母孙二人,更相为命,是以区区不能废远 —— 陈情表.李密 —— 24.2.20 一、编写JavaBean public class Student {//学号private int id;//姓名private String name;//年龄pr…

MySQL死锁产生的原因和解决方法

一.什么是死锁 要想知道MYSQL死锁产生的原因,就要知道什么是死锁?在了解什么是死锁之前,先来看一个概念:线程安全问题 1.线程安全问题 1.1什么是线程安全问题 线程安全问题,指的是在多线程环境当中,线程并发访问某个资源,从而导致的原子性&a…

module ‘json‘ has no attribute ‘dumps‘

如果在使用Python的json模块时遇到AttributeError: module json has no attribute dumps错误,通常是因为在Python环境中json模块不支持dumps方法。这种情况可能是因为Python的json模块被重命名或修改过导致的。 解决方法可以尝试以下几种: 1.检查Pytho…

围剿尚未终止 库迪深陷瑞幸9.9阳谋

文|智能相对论 作者|霖霖 总能被“累了困了”的打工人优先pick的咖啡,刚复工就顺利站上话题C位。 #瑞幸9.9元一杯活动缩水#的话题才爬上新浪微博热搜,“库迪咖啡河北分公司运营总监带头坑害河北联营商”的实名举报帖就出现在了小红书,一时…

复旦大学MBA聚劲联合会:洞见智慧,拓宽思维格局及国际化视野

12月2日,“焕拥时代 俱创未来”聚劲联合会俱创会年度盛典暨俱乐部募新仪式圆满收官。16家复旦MBA俱乐部、200余名同学、校友、各界同仁齐聚复旦管院,一起在精彩纷呈的圆桌论坛里激荡思想,在活力四射的俱乐部风采展示中凝聚力量。      以…

第四十二回 假李逵翦径劫单身 黑旋风沂岭杀四虎-python读写csv和json数据

李逵答应了宋江三件事:不可吃酒,独自前行,不带板斧。李逵痛快答应了,挎一口腰刀,提着朴刀,带了一锭大银子,三五个小银子就下山去了。 宋江放心不下,于是请同乡朱贵也回家一趟&#…

Mybatis总结--传参

MyBatis 传递参数:从 java 代码中把参数传递到 mapper.xml 文件 六、一个简单参数: Dao 接口中方法的参数只有一个简单类型( java 基本类型和 String ), 占位符 #{ 任意字符 } ,和方法的参数名无关…

浅谈SpringMVC

什么是MVC模式 MVC:MVC是一种设计模式 MVC的原理图: 分析: 1:M-Model 模型(完成业务逻辑:有javaBean构成,servicedaoentity) 2:V-View 视图(做界面的展示…

MySQL sql注意点

本文列取了常用但是容易遗漏的一些知识点。另外关键词一般大写,为了便于阅读所以很多小写。也为了给自己查缺补漏。 distinct(去重) 也许你经常对单个字段去重,并且知道不建议用distinct,而是group by,因为…

Cesium 展示——加载 tileset.json 格式的模型数据

文章目录 需求分析需求 已给 tileset.json 文件,现需加载该模型文件, 该模型特点:模型上的各模块均可以进行点击设置,且相机视角拉近后可以看到内部隐藏的物件模块 分析 tileset.json :模型数据【模型加载】方法export function init3dTileLayer (option) {var tilesetMo…

让AI玩一千万次贪吃蛇

如果让人工智能来玩贪吃蛇游戏,会发生什么? 图源:DALLE 目录 贪吃蛇实现 游戏规则 游戏实现 Q学习算法实现 Q学习简介 Q表和Q值 Q学习更新规则 Q学习在贪吃蛇游戏中的应用 整体项目完整代码 运行过程截图 代码分析 环境设置 …

SORA技术报告

文档链接:https://openai.com/research/video-generation-models-as-world-simulators 文章目录 Video generation models as world simulatorsTurning visual data into patchesVideo compression networkSpacetime latent patchesScaling transformers for video …

Linux使用C语言获取进程信息

Linux使用C语言获取进程信息 Author: OnceDay Date: 2024年2月22日 漫漫长路,才刚刚开始… 全系列文章可查看专栏: Linux实践记录_Once_day的博客-CSDN博客 参考文档: Linux proc目录详解_/proc/mounts-CSDN博客Linux下/proc目录介绍 - 知乎 (zhihu.com)Linux内…

该如何选择适合的服务器

服务器,简单来说,就是一个专门用来为其他计算机提供服务的计算机。 我们熟悉的网站、应用和各种在线服务,绝大多数都运行在一台或多台服务器中,所以说服务器是整个网络世界的基石。 服务器一般具有高速的CPU运算、高数据吞吐、可扩…

CrossOver虚拟机软件2024有哪些功能?最新版本支持哪些游戏?

CrossOver由codewaver公司开发的类虚拟机软件,目的是使linux和Mac OS X操作系统和window系统兼容。CrossOver不像Parallels或VMware的模拟器,而是实实在在Mac OS X系统上运行的一个软件。CrossOvers能够直接在Mac上运行Windows软件与游戏,而不…

算法练习-组合【回溯算法】(思路+流程图+代码)

难度参考 难度:困难 分类:回溯算法 难度与分类由我所参与的培训课程提供,但需 要注意的是,难度与分类仅供参考。且所在课程未提供测试平台,故实现代码主要为自行测试的那种,以下内容均为个人笔记&#xff0…

Code-Audit(代码审计)习题记录6-7

介绍: 自己懒得搭建靶场了,靶场地址是 GitHub - CHYbeta/Code-Audit-Challenges: Code-Audit-Challenges为了方便在公网练习,可以随地访问,本文所有的题目均来源于网站HSCSEC-Code Audit 6、习题6 题目内容如下: 源代…

Python+Flask低代码数据融合引擎工具

我用了2年多时间开发了一个低代码数据融合引擎工具 1.整体界面 2.主要功能 1)通过excel文件生成mysql数据表结构及数据保存 说明:功能细节包括(excel文件上传,文件内容预览,建表导入数据),难点在于对excel数据类型判断,并与mysql数据类型对应 2)建立数据表结构并批量导入数据 …

python程序设计基础:字符串与正则表达式

第四章:字符串与正则表达式 4.1字符串 最早的字符串编码是美国标准信息交换码ASCII,仅对10个数字、26个大写英文字母、26个小写英文字母及一些其他符号进行了编码。ASCII码采用1个字节来对字符进行编码,最多只能表示256个符号。 随着信息技…

Ubuntu20.04开启/禁用ipv6

文章目录 Ubuntu20.04开启/禁用ipv61.ipv62. 开启ipv6step1. 编辑sysctl.confstep2. 编辑网络接口配置文件 3. 禁用ipv6(sysctl)4. 禁用ipv6(grub)附:总结linux网络配置 Ubuntu20.04开启/禁用ipv6 1.ipv6 IP 是互联网…