docker_ROS的usb_cam使用与标定
目录
准备
准备标定板
新建容器
新建usb_cam话题的ROS功能包
编写代码
编译
运行功能包
标定
安装camera_calibration标定功能包
启动发布usb_cam话题的功能包
启动camera_calibration标定功能包
准备
usb相机
标定板
一个带有ROS的docker镜像。
准备标定板
图片链接:
棋盘格图片
打印粘贴。或者可以使用手机平板等屏幕展示这张棋盘照片,测量棋盘小格尺寸,并保证标定过程中,图片不被缩放。
新建容器
使用--privileged参数建立镜像。基础的代码:
sudo docker run -it --privileged --name=lab1 your_image_name /bin/bash
修改 your_image_name为你的docker镜像名。--privileged参数使容器与宿主机共用device设备,有相同的/dev文件。但是,在进入容器之前,先连接相机,再进入容器,防止进入容器后刷新不出相机。
docker run的其他参数根据需要自行设置。
连接相机
进入容器
新建usb_cam话题的ROS功能包
新建ROS功能包,用来发布usb_cam的话题。
编写代码
使用C++语言编写,示例如下,
新建功能包,而后写入核心代码:
img_publisher.cpp文件
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui.hpp>
#include <opencv2/calib3d.hpp>
#include <cv_bridge/cv_bridge.h>
#include <iostream>int main(int argc, char** argv) {ros::init(argc, argv, "img_publisher");ros::NodeHandle nh;image_transport::ImageTransport it(nh);image_transport::Publisher pub = it.advertise("camera/image", 1);cv::VideoCapture cap;cv::Mat frame;int deviceID = 0;if (argc > 1)deviceID = argv[1][0] - '0';int apiID = cv::CAP_ANY;cap.open(deviceID + apiID);if (!cap.isOpened()) {std::cerr << "ERROR! Unable to open camera" << std::endl;return -1;}ros::Rate loop_rate(30);while (nh.ok()) {cap.read(frame);if (!frame.empty()) {sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();pub.publish(msg);}ros::spinOnce();loop_rate.sleep();}return 0;
}
CMakeLists.txt文件
cmake_minimum_required(VERSION 3.0.2)
project(usb_cam)## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTScv_bridgeimage_transportroscppsensor_msgsstd_msgs
)
find_package(OpenCV REQUIRED)
message(${OpenCV_VERSION})###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES usb_cam
# CATKIN_DEPENDS cv_bridge image_transport roscpp sensor_msgs std_msgs
# DEPENDS system_lib
)###########
## Build ##
############# Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include${catkin_INCLUDE_DIRS}${OpenCV_INCLUDE_DIRS}
)add_executable(img_publisher src/img_publisher.cpp)
add_executable(img_viewer src/img_viewer.cpp)target_link_libraries(img_publisher ${catkin_LIBRARIES} ${OpenCV_LIBS})
target_link_libraries(img_viewer ${catkin_LIBRARIES} ${OpenCV_LIBS})
编译
打开终端:
catkin_make
在~/.bashrc加入环境变量。
打开终端:
gedit ~/.bashrc
文末写入
source ~/catkin_ws/devel/setup.bash
保存文件,关闭。
运行功能包
打开终端:
rosrun usb_cam img_publisher
会发布一个话题
查看话题
rostopic list
正常接入相机,功能包才正常运行,此时会出现包括/camera/image话题等一系列话题。
标定
安装camera_calibration标定功能包
查看ROS的功能包:
rospack list
查看是否有“camera_calibration”功能包,没有则需要安装:
rosdep install camera_calibration
启动发布usb_cam话题的功能包
打开终端:
rosrun usb_cam img_publisher
查看话题
rostopic list
正常接入相机,功能包才正常运行,此时会出现包括/camera/image话题等一系列话题。
启动camera_calibration标定功能包
打开终端:
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.20 image:=/camera/image
其中, --size 8x6是棋盘交点的数量,9*7的格子就会有8*6个交点
--square 0.20是一个小棋盘格大小,单位:米。
image:=/camera/image,image:=相机话题名。
正常启动后,弹出标定窗口,间断地调整相机位置,直到右侧"calibrate"按钮亮起,
Moving the Checkerboard
In order to get a good calibration you will need to move the checkerboard around in the camera frame such that:
checkerboard on the camera's left, right, top and bottom of field of view
X bar - left/right in field of view
Y bar - top/bottom in field of view
Size bar - toward/away and tilt from the camera
checkerboard filling the whole field of view
checkerboard tilted to the left, right, top and bottom (Skew)At each step, hold the checkerboard still until the image is highlighted in the calibration window.
移动棋盘
为了获得良好的校准,您需要在相机框架中移动棋盘,以便:
相机视野左、右、上、下的棋盘
X条-视野中的左/右
Y条-视野中的顶部/底部
尺寸条-朝向/远离相机并倾斜
棋盘填充整个视野
向左、右、上、下倾斜的棋盘(倾斜)
在每一步中,保持棋盘静止,直到图像在校准窗口中高亮显示。
点击,开始计算。计算结束后"save"按钮亮起,结果点"save"按钮保存
If you are satisfied with the calibration, click COMMIT to send the calibration parameters to the camera for permanent storage. The GUI exits and you should see "writing calibration data to ..." in the console.
如果您对校准感到满意,请单击COMMIT将校准参数发送到相机以进行永久存储。GUI退出,您应该在控制台中看到“正在将校准数据写入…”。
参考
标定过程及参数:
相机内参标定究竟标了什么?相机内参外参保姆级教程 - 知乎
camera_calibration标定功能包介绍:
camera_calibration/Tutorials/MonocularCalibration - ROS Wiki
相关文章:
docker_ROS的usb_cam使用与标定
目录 准备 准备标定板 新建容器 新建usb_cam话题的ROS功能包 编写代码 编译 运行功能包 标定 安装camera_calibration标定功能包 启动发布usb_cam话题的功能包 启动camera_calibration标定功能包 准备 usb相机 标定板 一个带有ROS的docker镜像。 准备标定板 图…...

记一次RabbitMQ服务器异常断电之后,服务重启异常的处理过程
转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 问题描述: 机房突然停电,rabbitmq的主机异常断电,集群服务全部需要重启。但是在执行service…...

rime中州韵小狼毫 help lua Translator 帮助消息翻译器
lua 是 Rime中州韵/小狼毫输入法强大的武器,掌握如何在Rime中州韵/小狼毫中使用lua,你将体验到什么叫 随心所欲。 先看效果 在 rime中州韵 输入效果一览 中的 👇 help效果 一节中, 我们看到了在Rime中州韵/小狼毫输入法中输入 h…...

C++完成使用map Update数据 二进制数据
1、在LXMysql.h和LXMysql.cpp分别定义和编写关于pin语句的代码 //获取更新数据的sql语句 where语句中用户要包含where 更新std::string GetUpdatesql(XDATA kv, std::string table, std::string where); std::string LXMysql::GetUpdatesql(XDATA kv, std::string table, std…...

ARCGIS PRO SDK 访问Geometry对象
一、Geometry常用对象 二、主要类 1、ReadOnlyPartCollection:Polyline 和 Polygon 使用的 ReadOnlySegmentCollection 部件的只读集合,属性成员: 名字描述Count获取 ICollection 中包含的元素数。TIEM获取位于指定索引处的元素。Spatial…...

数据结构之各大排序(C语言版)
我们这里话不多说,排序重要性大家都很清楚,所以我们直接开始。 我们就按照这张图来一一实现吧! 一.直接插入排序与希尔排序. 这个是我之前写过的内容了,大家可以通过链接去看看详细内容。 算法之插入排序及希尔排序(…...
c++ 中多线程的使用
如果你的其他逻辑必须在线程 t1 和 t2 之后执行,但你又希望这些线程能够同时运行,你可以在主线程中使用 std::thread::detach 将线程分离,让它们在后台运行。这样,主线程不会等待这些线程的完成,而可以继续执行其他逻辑…...

理解二叉树的遍历(算法村第七关白银挑战)
二叉树的前序遍历 144. 二叉树的前序遍历 - 力扣(LeetCode) 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。 示例 1: 输入:root [1,null,2,3] 输出:[1,2,3]解 LeetCode以及面试中提供的方法可能…...

所有单片机使用的汇编语言是统一的吗?
所有单片机使用的汇编语言是统一的吗? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!&…...

C ++类
定义一个Person类,私有成员int age,string &name,定义一个Stu类,包含私有成员double *score,写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数,完成对Person的运算符重载(算术运算符、条件运算…...

STM32疑难杂症
1.keil的奇怪问题 创建的数组分配内存到0x10000000地址的时候,数据总是莫名其妙的出现问题,取消勾选就正常了 stm32f407内部有一个CCM内存,这部分内存只能由内核控制,任何外设都不能够进行访问。这样问题就来了,如果使…...
GIT使用简介
Git 是一种版本控制系统,常用于团队协作开发和管理代码。下面是 Git 的基本使用方式: 安装 Git:首先,在你的计算机上安装 Git。你可以从 Git 官方网站(https://git-scm.com/)下载适合你操作系统的版本&…...
easycode 插件配置文件
easycode是一个idea生成文件的插件,以下是我的一个项目中配置信息,需要的可以拿走,保存成json文件导入即可 {"author" : "XXX","version" : "1.2.8","userSecure" : "","…...

elasticsearch系列四:集群常规运维
概述 在使用es中如果遇到了集群不可写入或者部分索引状态unassigned,明明写入了很多数据但是查不到等等系列问题该怎么办呢?咱们今天一起看下常用运维命令。 案例 起初我们es性能还跟得上,随着业务发展壮大,发现查询性能越来越不…...
6.6 会话与输入事件(三)
三,Pointer会话 3.1 Pointer会话及其属性 指针输入会话使用SCREEN_EVENT_POINTER类型创建,通常用于控制光标的形状和位置。 指针会话的SCREEN_PROPERTY_MODE属性未使用。但是,可以使用下面的会话属性配置指针会话: SCREEN_PROPERTY_ACCELERATION表示一组六个整数,表示x…...

【自动化测试总结】优点、场景、流程、项目人员构成
一、自动化测试的概念 以程序测试程序,以代码代替思维,以脚本的运行代替手工测试,可以大大提高工作测试的效率。 二、自动化测试的优点 1.回归测试更为方便,可靠。自动化测试最主要的任务和特点,特别是在程序修改比较…...

杨中科 ASP.NETCore Rest
什么是Rest RPC 1、Web API两种风格: 面向过程(RPC) 、面向REST (REST) 2、RPC:“控制器/操作方法“的形式把服务器端的代码当成方法去调用。把HTTP当成传输数据的通道,不关心HTTP谓词。通过QueryString请求报文体给服务器传递数据。状态码。比如/Persons/GetAll…...

RTU数据采集终端
在现代工业控制系统中,数据采集是一个至关重要的步骤。RTU(远程终端单元)作为一种常用的数据采集终端设备,不仅可以实现数据的采集和传输,还可以实现现场设备的远程监控和控制。 一、RTU数据采集终端的工作原理 RTU数据采集终端是一种将现场…...
双指针--- 数组元素的目标和
目录 数组元素的目标和思路:暴力做法思路:双指针做法: 代码: 原题链接 数组元素的目标和 给定两个升序排序的有序数组 A 和 B ,以及一个目标值 x 。 数组下标从 0 开始。 请你求出满足 A[i]B[j]x 的数对 (i,j) 。 数据保证有唯…...

你的网站或许不需要前端构建(二)
前一阵,有朋友问我,能否在不进行前端编译构建的情况下,用现代语法开发网站界面。 于是,就有了这篇文章中提到的方案。 写在前面 这篇文章,依旧不想讨论构建或不构建,哪一种方案对开发更友好,…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...
拟合问题处理
在机器学习中,核心任务通常围绕模型训练和性能提升展开,但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正: 一、机器学习的核心任务框架 机…...