当前位置: 首页 > 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 注…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...

【题解-洛谷】P10480 可达性统计

题目&#xff1a;P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图&#xff0c;分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M&#xff0c;接下来 M M M 行每行两个整数 x , y x,y x,y&#xff0c;表示从 …...