可用的双目标定代码(先单目标定再双目标定)

2023-05-16

最近做双目项目需要进行标定,网上查看一些资料。目前所用是先进行单目标定,然后在进行双目标定。代码如下,配以后使用

//biaoding.cpp
#include<opencv2/calib3d/calib3d.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>
#include <opencv2/calib3d/calib3d_c.h>
#include<iostream>
#include <dirent.h>

using namespace std;
using namespace cv;

int n = 1;
int m = 1;

int i = 1;
int j = 1;
//需要按实际情况修改=======
const int boardwidth = 8;  //棋盘格内角个数
const int boardhight = 6; //棋盘格内角个数
const int squaresize = 27.5; //棋盘格变长,mm
cv::Size imagesize ;
const cv::Size boardsize = cv::Size(boardwidth,boardhight);
//======================
vector<cv::Point3f> objectpoint;
vector<vector<cv::Point3f>> objpoint;

vector<cv::Point2f> cornerL;
vector<cv::Point2f> cornerR;

vector<vector<cv::Point2f>> imagepointL;
vector<vector<cv::Point2f>> imagepointR;


Mat cameraMatrixL = Mat(3, 3, CV_32FC1, Scalar::all(0)); 
Mat cameraMatrixR = Mat(3, 3, CV_32FC1, Scalar::all(0)); 
vector<Mat> rvecsMat_left;                                          // 存放所有图像的旋转向量,每一副图像的旋转向量为一个mat
vector<Mat> tvecsMat_left;                                          // 存放所有图像的平移向量,每一副图像的平移向量为一个mat
Mat distcoeffL = Mat(1, 5, CV_32FC1, Scalar::all(0)); 
Mat distcoeffR = Mat(1, 5, CV_32FC1, Scalar::all(0)); 
vector<Mat> rvecsMat_right;                                          // 存放所有图像的旋转向量,每一副图像的旋转向量为一个mat
	vector<Mat> tvecsMat_right;                                          // 存放所有图像的平移向量,每一副图像的平移向量为一个mat
cv::Mat R,T,E,F;
cv::Mat R1, R2, P1, P2 , Q;

cv::Mat maplx, maply, maprx, mapry;

cv::Mat imageL, grayimageL;
cv::Mat imageR, grayimageR;

cv::Rect validROIL, validROIR;

//单目标定
void m_calibration(vector<vector<Point2f>>& image_points_seq, Size board_size, Size square_size, Mat& cameraMatrix, Mat& distCoeffs, vector<Mat>& rvecsMat, vector<Mat>& tvecsMat,int image_count)
{
	/*棋盘三维信息*/
	vector<vector<Point3f>> object_points_seq;                     // 保存标定板上角点的三维坐标

	for (int t = 0; t < image_count; t++)
	{
		vector<Point3f> object_points;
		for (int i = 0; i < board_size.height; i++)
		{
			for (int j = 0; j < board_size.width; j++)
			{
				Point3f realPoint;
				/* 假设标定板放在世界坐标系中z=0的平面上 */
				realPoint.x = i * square_size.width;
				realPoint.y = j * square_size.height;
				realPoint.z = 0;
				object_points.push_back(realPoint);
			}
		}
		object_points_seq.push_back(object_points);
	}

	/* 运行标定函数 */
	double err_first = calibrateCamera(object_points_seq, image_points_seq, imagesize, cameraMatrix, distCoeffs, rvecsMat, tvecsMat, CV_CALIB_FIX_K3);
	cout << "重投影误差1:" << err_first << "像素" << endl << endl;
	cout << "标定完成!!!" << endl;


	cout << "开始评价标定结果………………";
	double total_err = 0.0;            // 所有图像的平均误差的总和 
	double err = 0.0;                  // 每幅图像的平均误差
	double totalErr = 0.0;
	double totalPoints = 0.0;
	vector<Point2f> image_points_pro;     // 保存重新计算得到的投影点

	for (int i = 0; i < image_count; i++)
	{

		projectPoints(object_points_seq[i], rvecsMat[i], tvecsMat[i], cameraMatrix, distCoeffs, image_points_pro);   //通过得到的摄像机内外参数,对角点的空间三维坐标进行重新投影计算

		err = norm(Mat(image_points_seq[i]), Mat(image_points_pro), NORM_L2);

		totalErr += err * err;
		totalPoints += object_points_seq[i].size();

		err /= object_points_seq[i].size();
		//fout << "第" << i + 1 << "幅图像的平均误差:" << err << "像素" << endl;
		total_err += err;
	}
	cout << "重投影误差2:" << sqrt(totalErr / totalPoints) << "像素" << endl << endl;
	cout << "重投影误差3:" << total_err / image_count << "像素" << endl << endl;


	//保存定标结果  	
	cout << "开始保存定标结果………………" << endl;
	Mat rotation_matrix = Mat(3, 3, CV_32FC1, Scalar::all(0)); /* 保存每幅图像的旋转矩阵 */
	cout << "相机内参数矩阵:" << endl;
	cout << cameraMatrix << endl << endl;
	cout << "畸变系数:\n";
	cout << distCoeffs << endl << endl << endl;
	for (int i = 0; i < image_count; i++)
	{
		Rodrigues(rvecsMat[i], rotation_matrix);
	}
	cout << "定标结果完成保存!!!" << endl;
}
void worldpoint(int framenumber)
{
	
	for (int i = 0; i < boardhight; i++)
	{
		for (int j = 0; j < boardwidth; j++)
		{
			objectpoint.push_back(cv::Point3f(i*squaresize,j*squaresize,0.0f));
		}
	}
	for (int w = 1; w <= framenumber;w++)
	{
		objpoint.push_back(objectpoint);
	}
}

void outputparam()
{
	cv::FileStorage fs("intrinsics.yml", cv::FileStorage::WRITE);
	fs << "cameraMatrixL" << cameraMatrixL << "cameraDistcoeffL" << distcoeffL << "cameraMatrixR" << cameraMatrixR << "cameraDistcoeffR" << distcoeffR;
	fs.release();
	std::cout << "cameraMatrixL=:" << cameraMatrixL << endl << "cameraDistcoeffL=:" << distcoeffL << endl << "cameraMatrixR=:" << cameraMatrixR << endl << "cameraDistcoeffR=:" << distcoeffR << endl;

	fs.open("extrinsics.yml", cv::FileStorage::WRITE);
	fs << "R" << R << "T" << T << "Rl" << R1 << "Rr" << R2 << "Pl" << P1 << "Pr" << P2 << "Q" << Q;
	std::cout << "R=" << R << endl << "T=" << T << endl << "Rl=" << R1 << endl << "Rr=" << R2 << endl << "Pl=" << P1 << endl << "Pr=" << P2 << endl << "Q=" << Q << endl;
	fs.release();

}

int getFilesName(string path)
{
    DIR *pDir;
	std::vector<std::string> filenames;
    struct dirent* ptr;
    if(!(pDir = opendir(path.c_str())))
        return -1;
    while((ptr = readdir(pDir))!=0) {
        if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0)
            filenames.push_back(path + "/" + ptr->d_name);
    }
    closedir(pDir);
	return filenames.size();
}
int main()
{
	//读取图片
	char* leftStr="/home/×××/×××/biaoding/left/";
	char* rightStr="/home/×××/×××/biaoding/right/";

	int framenumberleft = getFilesName(leftStr);
	int framenumberright = getFilesName(leftStr);
	assert(framenumberleft==framenumberright);
	int framenumber = framenumberleft;
	int current = 1;
	std::cout<<framenumber<<endl;
	while (current <= framenumber)
	{
		char frameL[50];
		
		snprintf(frameL, sizeof(frameL),"%s%d.jpg", leftStr,n++);
		imageL = cv::imread(frameL);
			
		cv::cvtColor(imageL,grayimageL,cv::ColorConversionCodes::COLOR_BGR2GRAY);

		char frameR[50];
		
		snprintf(frameR, sizeof(frameR), "%s%d.jpg",rightStr, m++);
		imageR = cv::imread(frameR);
		if (current == 1)  //读入第一张图片时获取图像宽高信息
		{
			imagesize = cv::Size(imageL.cols,imageL.rows);
			cout << "image_size.width = " << imagesize<< endl;
		}

		cv::cvtColor(imageR, grayimageR, cv::ColorConversionCodes::COLOR_BGR2GRAY);

		bool foundL, foundR;


		foundL = cv::findChessboardCorners(imageL,boardsize,cornerL);
		foundR = cv::findChessboardCorners(imageR, boardsize, cornerR);

		if (foundL == true && foundR == true)
		{
		cv::cornerSubPix(grayimageL,cornerL,cv::Size(11,11),cv::Size(-1,-1),cv::TermCriteria(cv::TermCriteria::MAX_ITER|cv::TermCriteria::EPS, 30, 1e-6));
		cv::cornerSubPix(grayimageR, cornerR, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 30, 1e-6));

		cv::drawChessboardCorners(imageL,boardsize,cornerL,foundL);
		cv::imshow("L", imageL);
		cv::waitKey(10);
		cv::drawChessboardCorners(imageR, boardsize, cornerR, foundR);
		cv::imshow("R", imageR);
		cv::waitKey(10);

		imagepointL.push_back(cornerL);
		imagepointR.push_back(cornerR);

		cout << "The image  " << current << "  is good" << endl;
		}
		else
		{
			std::cout << "The image is bad please try again" << endl;
		}
		current++;
	}
	cout << "左右单目开始标定" << endl;
	//进行left标定
	std::cout<<"current:"<<current<<endl;
	//左图
	std::cout<<"============================ left start==========================="<<std::endl;
	m_calibration(imagepointL, boardsize, Size(squaresize,squaresize), cameraMatrixL, distcoeffL, rvecsMat_left, tvecsMat_left,current-1);
	//右图
	std::cout<<"============================ right start==========================="<<std::endl;
	m_calibration(imagepointR, boardsize, Size(squaresize,squaresize), cameraMatrixR, distcoeffR, rvecsMat_right, tvecsMat_right,current-1);

	std::cout<<"============================ left re==========================="<<std::endl;
	cout << "相机内参数矩阵:" << endl;
	cout << cameraMatrixL << endl << endl;
	cout << "畸变系数:\n";
	cout << distcoeffL << endl << endl << endl;

	std::cout<<"============================ right re==========================="<<std::endl;
	cout << "相机内参数矩阵:" << endl;
	cout << cameraMatrixR << endl << endl;
	cout << "畸变系数:\n";
	cout << distcoeffR << endl << endl << endl;

	worldpoint(framenumber);

	cout << "双目开始标定" << endl;

	double err = cv::stereoCalibrate(objpoint, imagepointL, imagepointR, cameraMatrixL, distcoeffL, cameraMatrixR, distcoeffR, imagesize, R, T, E, F, 	
		CALIB_USE_INTRINSIC_GUESS,
 cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 30, 1e-6));

	
	cout << "The err = " << err << endl;

	cv::stereoRectify(cameraMatrixL,distcoeffL, cameraMatrixR,distcoeffR,imagesize,R,T,R1,R2,P1,P2,Q, cv::CALIB_ZERO_DISPARITY, -1, imagesize, &validROIL, &validROIR);

	cv::initUndistortRectifyMap(cameraMatrixL,distcoeffL,R1,P1,imagesize, CV_32FC1,maplx,maply);
	cv::initUndistortRectifyMap(cameraMatrixR,distcoeffR,R2,P2,imagesize,CV_32FC1,maprx,mapry);

	outputparam();

	cv::Mat canvas;
	double sf;
	int w, h;
	sf = 600. / MAX(imagesize.width, imagesize.height);
	w = cvRound(imagesize.width * sf);
	h = cvRound(imagesize.height * sf);
	canvas.create(h, w * 2, CV_8UC3);


	int currents = 1;
	while (currents <= framenumber)
	{

		char frameL[50];

		snprintf(frameL, sizeof(frameL), "%s%d.jpg",leftStr, i++);
		imageL = cv::imread(frameL);
		

		char frameR[50];

		snprintf(frameR, sizeof(frameR), "%s%d.jpg",rightStr, j++);
		imageR = cv::imread(frameR);
		
		cv::Mat rectifyImageL2, rectifyImageR2;
		cv::remap(imageL, rectifyImageL2, maplx, maply, cv::InterpolationFlags::INTER_LINEAR);
		cv::remap(imageR, rectifyImageR2, maprx, mapry, cv::InterpolationFlags::INTER_LINEAR);

		cv::Mat canvasPart = canvas(cv::Rect(w * 0, 0, w, h));
		resize(rectifyImageL2, canvasPart, canvasPart.size(), 0, 0, cv::INTER_AREA);
		cv::Rect vroiL(cvRound(validROIL.x*sf), cvRound(validROIL.y*sf),
			cvRound(validROIL.width*sf), cvRound(validROIL.height*sf));
		cv::rectangle(canvasPart, vroiL, cv::Scalar(0, 0, 255), 3, 8);

		canvasPart = canvas(cv::Rect(w, 0, w, h));
		resize(rectifyImageR2, canvasPart, canvasPart.size(), 0, 0, cv::INTER_LINEAR);
		cv::Rect vroiR(cvRound(validROIR.x * sf), cvRound(validROIR.y*sf),
			cvRound(validROIR.width * sf), cvRound(validROIR.height * sf));
		cv::rectangle(canvasPart, vroiR, cv::Scalar(0, 255, 0), 3, 8);

		for (int i = 0; i < canvas.rows; i += 16)
			line(canvas, cv::Point(0, i), cv::Point(canvas.cols, i), cv::Scalar(0, 255, 0), 1, 8);

		cv::imshow("rectified", canvas);

		if (cv::waitKey() > 0)
		{
			currents++;
		}

	}
	return 0;
}

//编译
g++ biaoding.cpp -o biao  `pkg-config opencv4 --cflags --libs`

参考

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可用的双目标定代码(先单目标定再双目标定) 的相关文章

  • C++变量前面加下划线的含义

    C 43 43 变量前面加下划线和不加下划线都不会影响对变量的定义 xff0c 只是风格问题 xff0c 更喜欢将成员变量或者私有成员变量的前面加上下划线 以表示该变量是某个类的属性 比如 xff1a int size int getsiz
  • tensorflow中GPU相关设置解决显存不足

    1 显存不足时报错如下 xff1a E tensorflow stream executor cuda cuda dnn cc 359 could not create cudnn handle CUDNN STATUS INTERNAL
  • freertos 学习笔记——第一章、裸机进阶RTOS

    第一章 前言 1 1裸机的软件写法 1 xff0c 轮询系统 void main sys init while 1 task 1 task 2 任务处理在循环中依次执行 2 xff0c 前后台系统 中断被成为前台 xff0c 无限循环被成为
  • freertos学习笔记——第三章、任务控制——3.1 全局变量造成的困扰

    裸机中经常使用全局变量 xff0c 但在RTOS中大量使用全局变量会造成很多问题 在RTOS中也可以使用全局变量但使用时一定要注意有哪些任务会写这个变量 xff0c 哪些任务会读这个变量 尤其切记在使用这个变量的过程中变量的数值发生改变 x
  • MTK项目总结

    一 sensor路径 vendor mediateck propri sensor校准 xff1a 加速度校准 adb shell 34 echo 1 gt sys bus platform drivers gsensor test cal
  • JAVA简述和JDK环境搭建

    一 Java 语言背景介绍 1 什么是 Java 语言 xff1f Java 语言是美国 Sun 公司 xff08 Stanford University Network xff09 在 1995 年推出的计算机语言 2009年 xff0c
  • Java变量、标识符以及类型转换详解

    本篇文章为本人学习笔记 xff0c 如有错误 xff0c 希望指正 一 进制 进制详细概念以及转换 xff1a https blog csdn net diyu122222 article details 80692904 这篇写的很好 x
  • Java运算符的使用和规则

    本篇文章为本人学习笔记 xff0c 如有错误 xff0c 希望指正 Java中运算符大致分为以下几类 xff1a 算数运算符赋值运算符自增自减运算符关系运算符逻辑运算符三元运算符 1 算数运算符 算数运算符包括 xff1a 作用 43 加法
  • Java的内存分配理解

    本篇文章为本人学习笔记 xff0c 如有错误 xff0c 希望指正 Java 程序在运行时 xff0c 需要在内存中分配空间 为了提高运算效率 xff0c 就对空间进行了不同区域的划分每一片区域都有特定的处理数据方式和内存管理方式 区域名称
  • IntelliJ IDEA的Debug教程

    1 什么是Debug模式 它是供程序员使用的程序调试工具 xff0c 它可以用于查看程序的执行流程 xff0c 也可以用于追踪程序执行过程来调试程序 2 Debug模式操作流程 如何加断点 选择要设置断点的代码行 xff0c 在行号的区域后
  • opencv获取相机图像并发布为ROS节点

    仅记录工程中的使用 完整代码请查看 xff1a https github com chx725 cv and ros ROS是最普遍使用的机器人系统之一 xff0c 提供了各种功能包 xff0c 仿真环境 xff0c 模型 xff0c 可视
  • Java中两种方法实现栈和队列(面试)

    学到LinkedList xff0c 上课时老师提了一下代码实现栈和队列 xff0c 面试可能会用上 xff0c 就码了栈和队列两种实现方案 如有问题 xff0c 希望指出 一 栈 1 数组实现栈 span class token comm
  • docker容器迁移教程

    前言 被领导要求部署一个和测试环境一样的演示环境 xff0c 并且数据库也要同步过去 xff0c 服务器上的各种服务都是docker部署的 xff0c 由于之前docker玩的比较少 xff0c 所以还是踩了不少坑的 xff0c 在此记录一
  • Java多sheet模板导出表格

    前言 需求是这样的 xff0c 需要在页面导出列表表格时同时导出每项的详情数据 xff0c 而且详情表格并不是一个常规的二维表格 xff0c 就像图中这样的效果 xff0c 所以要解决的最主要两个问题就是 xff1a 多sheet实现 异形
  • docker容器时间不同步导致在java应用中获取的时间不正确问题

    一 前言 在把Java应用部署到docker容器时 xff0c 发现应用获取到的时间和现实时间相差了8个小时 xff0c 会导致一系列不必要的麻烦 二 解决方案 1 首选需要确保宿主机的时区和时间的准确 现在宿主机上用 date R 看一下
  • Caffeine一级缓存介绍和应用

    Caffeine介绍 redis和caffeine的区别 相同点就不用说 xff0c 广义上都是缓存的方式 咱们就说说不同 redis是将数据存储到内存里 xff1b caffeine是将数据存储在本地应用里caffeine和redis相比
  • Java中使用es条件构造器BoolQueryBuilder

    前言 由于es在java中查询没法像mybatis那样方便 xff0c 而且es的构造器使用也比较繁琐 xff0c 理解不是很方便 xff0c 所以写一篇文章来记录es构造器BoolQueryBuilder查询时各种条件的构造的正确姿势 教
  • 群晖docker容器内mysql部署和远程连接

    群晖docker容器内mysql部署和远程连接 1 docker内Mysql部署2 Mysql远程访问配置 1 docker内Mysql部署 首先在群晖docker内安装ubuntu镜像 xff0c 启用镜像时注意对容器和宿主机的端口映射进
  • eclipse的安装及配置PyDev插件(win10)

    原博文 xff1a Windows下安装Eclipse 43 python2 7 43 Pydev 一 安装eclipse 学习Java第一步就是装eclipse 我每学习一门语言都会先死在安装程序上 这个也一样 一 去eclipse官网下
  • 小微企业技术人员面试流程及常见问题整理分析

    技术人员面试流程 在同一个小的企业做久了 xff0c 当有人员离职后 xff0c 招聘中的面试的工作就落在了资历老一点的员工上 虽然不是专业的HR xff0c 但还是在此记录一下一些人员面试的基本流程步骤及主要内容 一 面试流程 1 接待应

随机推荐

  • Ubuntu 解决触摸板不识别问题

    Ubuntu 解决触摸板不识别问题 span class hljs built in sudo span vi etc default grub span class hljs comment 把GRUB CMDLINE LINUX 61
  • 图像的灰度化、二值化

    目录 1 图像像素点 2 灰度化 3 二值化 4 使用open cv库进行图片的灰度化 二值化 4 1 将图片转换为灰度图 4 2 将灰度图转换为二值化图图片 1 图像像素点 在图像处理中 xff0c 用RGB三个分量 xff08 R xf
  • 【嵌入式】stm32程序跳转实验

    嵌入式 stm32程序跳转实验 菜老越 于 2019 04 23 17 54 56 发布 2888 收藏 22 分类专栏 xff1a 嵌入式 文章标签 xff1a keil stm32 程序跳转 IAP BootLoader 版权 嵌入式
  • C++/C语言实现HTTP的GET和POST请求

    阅读目录 HTTP请求和IP TCP 实现GET请求 实现POST请求 xff1a 参考 xff1a 回到顶部 HTTP请求和IP TCP 所谓的HTTP协议是基于IP TCP协议的 xff0c 所以要获取远端的html数据只要创建sock
  • C++ 简单实现HTTP GET/POST 请求

    HTTP 超文本传输协议 是一种客户端与服务端的传输协议 xff0c 最早用于浏览器和服务器之间的通信 xff0c 后来因为其使用灵活 方便等特点 xff0c 广泛用于客户端与服务端的通信 文章将简单介绍HTTP协议 xff0c 同时以C
  • 分布式系统架构简单介绍

    目录 xff1a 一 什么是分布式系统 xff1f 二 为什么要走分布式系统架构 xff1f 三 系统如何进行拆分 xff1f 四 分布式之后带来的技术挑战 xff1f 一 什么是分布式系统 xff1f 在谈分布式系统架构前 xff0c 我
  • 使用javascript实现对于chineseocr的API调用

    ChineseOCR在线API 网页地址 界面 提供多种接口调用方式 xff0c 比如在线调用 Javascript api调用 curl api调用和python api调用四种方式 xff0c 本次使用javascript api调用的
  • Qt-QMessageBox用法详解

    QMessageBox 是 Qt 框架中常用的一个类 xff0c 可以生成各式各样 各种用途的消息对话框 xff0c 如图 1 所示 图 1 QMessageBox消息对话框 很多 GUI 程序都会用到消息对话框 xff0c 且很多场景中使
  • C++中UDP通讯详解

    C 43 43 Socket编程及TCP UDP通信代码实现 一 简介 Socket编程的目的是使网络的进程进行通信 xff0c 基于TCP IP协议簇 xff0c 通过三元组 xff08 ip地址 协议 端口 xff09 标志进程 xff
  • sphinx写文档的简单尝试--index.rst的内容分析

    先说简单的结论 xff0c rst上手难度远高于markdown 功能扩展完爆markdown 在安装sphinx后 xff0c 开始编写shpinx的第一步 xff0c 就是使用sphinx quickstart来生成配置文件 我的目录结
  • 读书笔记:嵌入式常用算法_note_1

    目录 折线插值 抛物线插值 折线插值 include lt stdio h gt define N 10 折线由10段线段组成 即有11个插值节点 float w 61 10 0 插值节点间隔为10 0 即 w 61 y1 y0 61 10
  • Linux下免费git工具集合

    该博文来自于ieayoio的博客 xff1a http www ieayoio com win和mac下的git图形工具都有挺多的 xff0c 然而对于因git而生的Linux xff0c git的图形工具普遍被认为相当落后 xff0c 然
  • [rospack] Error: package ‘.....‘ not found

    在ros编程中如果报出 rospack Error package 39 39 not found 某个包没有找到 xff0c 则有一下几方面的原因 1 包名写错了2 工作空间真的没有这个包存在3 包所在的ros工作空间没有在ros环境中
  • Pytorch中TypeError: 'DataLoader' object is not subscriptable错误

    今天学习pytorch遇到以下问题 TypeError 39 DataLoader 39 object is not subscriptable 一开始设置的参数如下 cifar train 61 DataLoader cifar trai
  • undefined reference to `vtable for fmt::v7::format_error‘

    在使用eigen3和sophus 库时 xff0c 如遇到以下错误 undefined reference to 96 vtable for fmt v7 format error 39 undefined reference to 96
  • 什么是嵌入式软件工程师?需具备哪些能力?

    计算机嵌入式逐渐被大家认可 xff0c 然而嵌入式软件工程师到底是什么 做一个好的嵌入式软件工程师又需要具备哪些能力呢 今天尚观教育小编跟大家聊一聊 1 嵌入式软件工程师是什么 嵌入式系统一般由嵌入式微处理器 外围硬件设备 嵌入式操作系统以
  • STM32串口中断接收到的16进制数据如何判断

    最近用到了一款WIFI摄像头 xff0c 这款摄像头可以通过手机app控制 xff0c 从而使串口发送指定的数据 xff0c 这样会以来就可以通过这款摄像头在手机app上控制小车的前后左右 xff0c 还可以实现无线图传的功能 这款摄像头通
  • ROS Robotics By Example No transform from [left_wheel] to [base_link]

    1 问题描述 在第二章中搭建双轮机器人 lt xml version 61 34 1 0 34 gt lt robot name 61 34 dd robot 34 gt lt base link gt lt link name 61 34
  • ROS中的坐标转换1

    1 坐标转换 坐标转换是指坐标系之间的平移以及旋转关系 xff0c 如坐标系A B C A xff0c B之间存在一个转换关系 T B A T B A T B A B与
  • 可用的双目标定代码(先单目标定再双目标定)

    最近做双目项目需要进行标定 xff0c 网上查看一些资料 目前所用是先进行单目标定 xff0c 然后在进行双目标定 代码如下 xff0c 配以后使用 span class token comment biaoding cpp span sp