当前位置: 首页 > news >正文

opencv-rust 系列2: camera_calibration

opencv-rust 系列2: camera_calibration

前言: 这里只是opencv-rust自带示例的中文注解. 略微增加了一些代码也是我在调试时用到的.

说明:

  1. camera_calibration.rs是opencv-rust自带的示例, 在examples目录中可以找到,我增加了一些中文注释如下.
  2. 如需运行可以在项目根目录执行命令: cargo run --example camera_calibration
  3. 在vscode软件内点击main函数上方绿色三角"Run"运行程序时, 当前位置是项目的根目录.
  4. 在命令行使用cargo run运行程序时, 当前位置是命令行所处目录.
  5. 为了保持统一,我使用项目根目录为当前目录设定, 所以运行本程序一定要在项目根目录.
  6. 使用highgui::imshow("Source", &img)?;显示窗口时不要使用中文!!! 建议 opencv 程序都不要使用中文.
  7. 文末贴两张图,你可以下载后以jpg后缀名保存到./examples/data目录,以供程序运行使用.
  8. 当然,Cargo.toml中需包含:
[dependencies]
opencv = "0.93.1"
  1. 源代码如下:
//! Port of code from the tutorial at: https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.htmluse std::error::Error;
use std::fs;
use opencv::core::{no_array, Point2f, Point3f, Size, TermCriteria, TermCriteria_EPS, TermCriteria_MAX_ITER, Vector};
use opencv::prelude::*;
use opencv::{calib3d, highgui, imgcodecs, imgproc};
use std::env;fn main() -> Result<(), Box<dyn Error>> {// 获取当前工作目录let current_dir = env::current_dir().expect("无法获取当前目录");// 打印当前工作目录的路径println!("当前路径: {}", current_dir.display());// 设置校准的终止条件,包括最大迭代次数和最小精度let criteria = TermCriteria {typ: TermCriteria_EPS + TermCriteria_MAX_ITER, 	// 终止条件类型max_count: 30,									// 最大迭代次数epsilon: 0.001,									// 精度阈值};// 准备三维世界中的物体点,例如棋盘格的角点, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)let objp_len = 6 * 7;	// 棋盘格的尺寸为6x7let objp = Vector::from_iter((0..objp_len).map(|i| Point3f::new((i % 7) as f32, 	// x坐标(i / 7) as f32, 	// y坐标0.)));				// z坐标,假设棋盘格位于z=0的平面上// 读取当前目录下所有.jpg文件let images = fs::read_dir("./examples/data")?.into_iter().flatten().filter(|entry| entry.path().extension().map_or(false, |ext| ext == "jpg"));//对每张图片进行校正for image in images {// 初始化用于存储所有图像的物体点和图像点的数组let mut objpoints = Vector::<Vector<Point3f>>::new(); // 三维世界中的点let mut imgpoints = Vector::<Vector<Point2f>>::new(); // 图像平面中的点// 读取原始图像并显示 println!("准备读取图片: {}", image.path().to_string_lossy());let mut img = imgcodecs::imread_def(image.path().to_string_lossy().as_ref())?; highgui::imshow("Origin", &img)?;highgui::wait_key(5000)?;let mut gray = Mat::default();// 将图像转换为灰度图imgproc::cvt_color_def(&img, &mut gray, imgproc::COLOR_BGR2GRAY)?;let mut corners = Vector::<Point2f>::default();// 在灰度图中查找棋盘格角点let ret = calib3d::find_chessboard_corners_def(&gray, Size::new(7, 6), &mut corners)?;if ret {println!("找到角点, 正在对该图校正");// 如果找到了角点,将其添加到物体点数组objpoints.push(objp.clone()); // 使用亚像素级精度细化角点位置imgproc::corner_sub_pix(&gray, &mut corners, Size::new(11, 11), Size::new(-1, -1), criteria)?;// 在图像上绘制角点并显示calib3d::draw_chessboard_corners(&mut img, Size::new(7, 6), &corners, ret)?;highgui::imshow("Source", &img)?;// 将角点添加到图像点数组imgpoints.push(corners);// 相机校准let mut mtx = Mat::default();			// 相机内参矩阵let mut dist = Mat::default();			// 畸变系数let mut rvecs = Vector::<Mat>::new();	// 旋转向量let mut tvecs = Vector::<Mat>::new();	// 平移向量calib3d::calibrate_camera_def(&objpoints,&imgpoints,gray.size()?,&mut mtx,&mut dist,&mut rvecs,&mut tvecs,)?;//下面使用两种方法去除图像的畸变:// 方法1,使用cv.undistort()去除图像畸变let mut dst_undistort = Mat::default();calib3d::undistort_def(&img, &mut dst_undistort, &mtx, &dist)?;highgui::imshow("Result using undistort", &dst_undistort)?;// 方法2,使用remapping方法去除图像畸变let mut mapx = Mat::default();let mut mapy = Mat::default();calib3d::init_undistort_rectify_map(&mtx,&dist,&no_array(),&no_array(),img.size()?,f32::opencv_type(),&mut mapx,&mut mapy,)?;let mut dst_remap = Mat::default();imgproc::remap_def(&img, &mut dst_remap, &mapx, &mapy, imgproc::INTER_LINEAR)?;// 显示使用remap方法去畸变后的结果highgui::imshow("Result using remap", &dst_undistort)?;// 等待按键,然后继续处理下一张图像highgui::wait_key_def()?;}else {println!("没有找到角点, 该图不能进行校正");}}// 销毁所有OpenCV创建的窗口highgui::destroy_all_windows()?;Ok(())
}

在这里插入图片描述
在这里插入图片描述

相关文章:

opencv-rust 系列2: camera_calibration

opencv-rust 系列2: camera_calibration 前言: 这里只是opencv-rust自带示例的中文注解. 略微增加了一些代码也是我在调试时用到的. 说明: camera_calibration.rs是opencv-rust自带的示例, 在examples目录中可以找到,我增加了一些中文注释如下.如需运行可以在项目根目录执行命…...

JVM和GC案例详解

接上文JVM环境配置说明&#xff1a;上文博客 一、JVM远程连接设置 1. JMX方式连接(这种方式没有GC监控)&#xff0c;设置如下 2. 连接成功后可以查看基础配置参数(和服务器配置一致) 2. jstatd方式连接(这种方式没有CPU监控) 添加jstatd方式连接 双击Tomcat&#xff0…...

postgreSql下载安装

一、下载 官网&#xff1a;PostgreSQL: The worlds most advanced open source database 二、安装 1.找到.exe文件&#xff0c;双击安装 2.跟着安装向导操作 三、启动...

GPT-SOVIT模型部署指南

一、模型介绍 强大的小样本语音转换和文本转语音 WebUI。 具有以下特征&#xff1a; 零样本 TTS&#xff1a; 输入 5 秒的声音样本并体验即时文本到语音的转换。少量样本 TTS&#xff1a; 仅使用 1 分钟的训练数据对模型进行微调&#xff0c;以提高语音相似度和真实感。跨语…...

怎么定时发朋友圈?

要实现微信朋友圈的定时发布&#xff0c;可以采用以下几种方法&#xff1a; 1、 绑定QQ号并使用QQ空间定时功能&#xff1a; 于微信和QQ的紧密联系&#xff0c;可以通过绑定QQ号&#xff0c;利用QQ空间的定时发布功能来间接实现微信朋友圈的定时发布。首先&#xff0c;在QQ空…...

如何利用phpstudy创建mysql数据库

phpStudy诞生于2007年&#xff0c;是一款老牌知名的PHP开发集成环境工具&#xff0c;产品历经多次迭代升级&#xff0c;目前有phpStudy经典版、phpStudy V8&#xff08;2019版&#xff09;等等&#xff0c;利用phpstudy可以快速搭建一个mysql环境&#xff0c;接下来我们就开始吧…...

五、Linux之Vi和Vim编辑器

基本介绍 Vi Linux 系统会内置 vi 文本编辑 Vim 具有程序编辑的能力&#xff0c;可以看做是 Vi 的增强版本&#xff0c;可以主动的以字体颜色辨别语法的正确性&#xff0c;方便程序设计。 代码补完、编译及错误跳转等方便编程的功能特别丰富 常用的三种模式 正常模式 以 vim …...

git删除错误的commit

文章目录 1、git删除错误的commit2、.gitignore配置文件不生效的问题 1、git删除错误的commit git的流程如图&#xff1a; 当某次失误造成commit的版本有问题&#xff0c;需要回退到正常的版本修改后重新add。 首先通过git log查看commit提交记录&#xff0c;可以看到HEAD-…...

代码随想录算法训练营Day08 | 344.反转字符串、541. 反转字符串II、卡码网:54.替换数字

文章目录 344.反转字符串思路与重点 541. 反转字符串II思路与重点 卡码网&#xff1a;54.替换数字思路与重点 344.反转字符串 题目链接&#xff1a;344. 反转字符串 - 力扣&#xff08;LeetCode&#xff09;讲解链接&#xff1a;代码随想录 (programmercarl.com)状态&#xff…...

mysql锁之乐观锁、悲观锁、表锁、行锁、共享锁、排他锁

mysql锁之乐观锁、悲观锁、表锁、行锁、共享锁、排他锁 MySQL锁概述 锁是计算机协调多个进程或线程并发访问某一个资源的机制&#xff0c;在数据库中&#xff0c;除传统的计算资源&#xff08;CPU、RAM、I/O&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资…...

【软件干货】Android应用进程如何保活?

​1.Android 应用进程保活方法介绍 在Android应用程序中&#xff0c;为了保证应用的正常运行和稳定性&#xff0c;有时需要对应用进程进行保活。以下是一些实现进程保活的方法&#xff1a; 1、使用前台服务(Foreground Service)&#xff1a;将服务调用startForeground()方法&…...

neo4j部署保姆级教程

由于公司是基于大数据架构的&#xff0c;让部署neo4j数据库&#xff0c;之前没有接触过&#xff0c;然后紧急学了一下&#xff0c;并且从网上找了一些教程&#xff0c;决定还是记录下来&#xff0c;后续有时间了会在出一篇使用教程 环境准备&#xff08;root用户&#xff09; …...

【STM32CubeMX开发】-2.2-TIM_输出一个PWM信号

目录 1 Tim定时器的时钟源 2 Tim定时器的配置 2.1 PWM配置 2.2 中断配置 3 生成代码 4 测试结果 结尾 1 Tim定时器的时钟源 TIM3的时钟来源自APB1 Timer clocks&#xff0c;时钟树上所有总线频率均设置为了STM32F0能达到的最高频率&#xff0c;此时APB1 Timer clocks …...

Ngx+Lua+Redis 快速存储POST数据

系统几万台设备有windows有安卓还有linux系统&#xff0c;每个设备三分钟就会向服务器post设备的硬件信息&#xff0c;数据格式json&#xff0c;后台管理界面只需要最新的数据&#xff0c;不需要历史数据&#xff0c;业务逻辑非常简单&#xff0c;PHP代码就几行&#xff0c;已经…...

go-delve的使用

go-delve的非交互使用方式&#xff1a; dlv要执行的命令文件&#xff1a;cmd.dlv goroutines exit 执行非交互命令&#xff1a; yes n | dlv --allow-non-terminal-interactivetrue attach $pid --init cmd.dlv --end--...

Python网络爬虫技术详解

Python网络爬虫技术详解 引言 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;又称网络蜘蛛&#xff08;Web Spider&#xff09;或网络机器人&#xff08;Web Robot&#xff09;&#xff0c;是一种按照一定规则自动抓取互联网信息的程序或脚本。它们通过遍历网页链…...

Golang | Leetcode Golang题解之第474题一和零

题目&#xff1a; 题解&#xff1a; func findMaxForm(strs []string, m, n int) int {dp : make([][]int, m1)for i : range dp {dp[i] make([]int, n1)}for _, s : range strs {zeros : strings.Count(s, "0")ones : len(s) - zerosfor j : m; j > zeros; j--…...

算法刷题技巧

算法题&#xff1a;https://leetcode.cn/studyplan/top-100-liked/ 哈希表 使用哈希表&#xff0c;增删改查的时间复杂度均为O(1)。何时使用哈希表&#xff1f; 在某个区域内查找一个已知元素&#xff0c;可以使用哈希表作为这个区域根据一个特征对元素进行分类&#xff0c;特征…...

BMS、EMS PCS 简介

1 储能系统的构成 完整的电化学储能系统主要由电池组、电池管理系统&#xff08;BMS&#xff09;、能量管理系统&#xff08;EMS&#xff09;、储能变流器&#xff08;PCS&#xff09;以及其他电气设备构成。 在储能系统中&#xff0c;电池组将状态信息反馈给电池管理系统BMS&…...

spug3发布项目

一、启动spug项目 1.spug代码仓库地址: spug: 开源运维平台&#xff1a;面向中小型企业设计的无 Agent的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件在线上传下载、应用发布、任务计划、配置中心、监控、报警等一系列功能。 - Gitee.com 注…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...