光平面标定代码

        本篇文章主要给出光平面标定代码,鉴于自身水平所限,如有错误,欢迎批评指正。(欢迎进Q群交流:874653199)

        数据分为棋盘格数据和激光条数据,激光条数据为在第22个位姿至第26个位姿下打在棋盘格标定板上采集的图像。

clc;
clear;%% 相机标定
image_filename='.\Calibration';%图像路径physicalLength=10;%物理长度image_format='jpeg';%图像格式namelist = dir([image_filename '\*.' image_format]);num = length(namelist);for i = 1:numfilename=namelist(i).name;filename_new=[image_filename '\'  filename];imageFileNames{i}=filename_new;
end[imagePoints, boardSize, imagesUsed] = detectCheckerboardPoints(imageFileNames);
imageFileNames = imageFileNames(imagesUsed);originalImage = imread(imageFileNames{1});
[mrows, ncols, ~] = size(originalImage);squareSize = physicalLength;  % in units of 'millimeters'
worldPoints = generateCheckerboardPoints(boardSize, squareSize);[cameraParams, imagesUsed, estimationErrors] = estimateCameraParameters(imagePoints, worldPoints, ...'EstimateSkew', false, 'EstimateTangentialDistortion', true, ...'NumRadialDistortionCoefficients', 2, 'WorldUnits', 'millimeters', ...'InitialIntrinsicMatrix', [], 'InitialRadialDistortion', [], ...'ImageSize', [mrows, ncols]);% h1=figure; showReprojectionErrors(cameraParams);
% h2=figure; showExtrinsics(cameraParams, 'CameraCentric');
% displayErrors(estimationErrors, cameraParams);
% undistortedImage = undistortImage(originalImage, cameraParams);IntrinsicMatrix=cameraParams.IntrinsicMatrix;
IntrinsicMatrix=IntrinsicMatrix';RadialDistortion=cameraParams.RadialDistortion;TangentialDistortion=cameraParams.TangentialDistortion;MeanReprojectionError =cameraParams.MeanReprojectionError;%% 光平面标定
boardSize=boardSize-1;path_laser='.\Laser';[a, b, c, d] = calibrateLightPlane(cameraParams, 22:26, path_laser,[8,12],0.3, 1);%% 写入标定结果
tempFile=[image_filename '\标定结果.txt'];
fid=fopen(tempFile,'w');fprintf(fid,'相机内参:\n');
for m=1:3
for n=1:3fprintf(fid,'%.6f     ',IntrinsicMatrix(m,n)); 
endfprintf(fid,'\n'); 
endfprintf(fid,'畸变系数 k1,k2,p1,p2:\n');
fprintf(fid,'%.6f \n',RadialDistortion(1,1)); 
fprintf(fid,'%.6f \n',RadialDistortion(1,2)); 
fprintf(fid,'%.6f \n',TangentialDistortion(1,1)); 
fprintf(fid,'%.6f \n',TangentialDistortion(1,2)); fprintf(fid,'反投影误差:\n');
fprintf(fid,'%.6f \n',MeanReprojectionError(1,1)); fprintf(fid,'光平面系数:\n');
fprintf(fid,'%.6f \n',a); 
fprintf(fid,'%.6f \n',b); 
fprintf(fid,'%.6f \n',c); 
fprintf(fid,'%.6f \n',d); fclose(fid);%% 光平面标定
function [a, b, c, d] = calibrateLightPlane(cameraParams, laserImagesIndex, laserImagesPath,boardSize, thresh, plotFlag)intriMatrix = cameraParams.IntrinsicMatrix';
radialDistortion = cameraParams.RadialDistortion;
tangentialDistortion=cameraParams.TangentialDistortion;
M1 = [intriMatrix(1,:), 0; intriMatrix(2,:), 0; intriMatrix(3,:), 0];allLaserPoint = [];
len = length(laserImagesIndex);
for i = 1 : lenindex = laserImagesIndex(i);R = cameraParams.RotationMatrices(:, :, index)';T = cameraParams.TranslationVectors(index, :)';   M2 = [R, T; 0, 0, 0, 1];M = M1 * M2;M = [M(:, 1:2), M(:, 4)];frame = imread([laserImagesPath, '\', num2str(index), '_laser.jpeg']);if(numel(size(frame))>2)frame = rgb2gray(frame);endpoints = cameraParams.ReprojectedPoints(:, :, index);col = [points(1,1), points(boardSize(1), 1), points(boardSize(1) * boardSize(2), 1), points(boardSize(1) * (boardSize(2) - 1)+1, 1)];row = [points(1,2), points(boardSize(1), 2), points(boardSize(1) * boardSize(2), 2), points(boardSize(1) * (boardSize(2) - 1)+1, 2)];BW = roipoly(frame, col, row);frame = uint8(BW) .* frame;laserPixel = getLaserCenter(frame, thresh, 50,  plotFlag);laserPixel=undistortCoor(intriMatrix,radialDistortion,tangentialDistortion,laserPixel);laserpixel = [laserPixel(:, 1)'; laserPixel(:, 2)'; ones(1, length(laserPixel(:, 1)))];laser_wcs =  pinv(M)*laserpixel;laser_wcs(1, :) = laser_wcs(1, :) ./laser_wcs(3,:);laser_wcs(2, :) = laser_wcs(2, :) ./laser_wcs(3,:);laser_wcs = [laser_wcs(1, :)', laser_wcs(2, :)', zeros(length(laserpixel(1, :)), 1), ones(length(laserpixel(1, :)), 1)];laser_ccs = (M2 * laser_wcs')';allLaserPoint = [allLaserPoint; laser_ccs];
endplaneData = allLaserPoint(:, 1:3);
xyz0=mean(planeData, 1);
centeredPlane=bsxfun(@minus, planeData, xyz0);
[U, S, V]=svd(centeredPlane);a=V(1,3);
b=V(2,3);
c=V(3,3);
d=-dot([a b c], xyz0);fprintf(' 光平面方程为: %f * X + %f * Y +  %f * Z +  %f = 0 \n', a, b, c, d);% 绘制拟合结果
if plotFlag ~= 0figure;rangeX = max(allLaserPoint(:, 1)) - min(allLaserPoint(:, 1));rangeY = max(allLaserPoint(:, 2)) - min(allLaserPoint(:, 2));y_buff = linspace(min(allLaserPoint(:, 2)) -  min(rangeX, rangeY), ...max(allLaserPoint(:, 2)) +  min(rangeX, rangeY), 100);x_buff = linspace(min(allLaserPoint(:, 1)) -  min(rangeX, rangeY), ...max(allLaserPoint(:, 1)) +  min(rangeX, rangeY), 100);[X_buff,Y_buff] = meshgrid(x_buff, y_buff);Z_buff = -d/c -a/c*X_buff -b/c *Y_buff;  % 依旧是平面方程mesh(X_buff,Y_buff,Z_buff);xlabel('X'); ylabel('Y'); zlabel('Z');title('激光平面');hold on;plot3(allLaserPoint(:, 1), allLaserPoint(:, 2), allLaserPoint(:, 3), 'rx'); clear x_buff y_buff X_buff Y_buff Z_buff
endendfunction pixels = getLaserCenter(frame_grey, thresh, grey_thresh,plotFlag)
if nargin < 4plotFlag = 0; 
endif max(frame_grey) < grey_threshpixels = [];return;
end[row, col] = size(frame_grey);% steger算法求中心
pixels= steger(frame_grey, thresh);if plotFlag ~= 0figure;imshow(frame_grey);hold onplot(pixels(:, 1),pixels(:, 2),'r.')hold off
endend%% steger光条中心提取
function pixel=steger(srcImage,thresh)if(length(size(srcImage))>2)srcImage=rgb2gray(srcImage);  
endsigma=3;
% thresh= 0.1;%graythresh(srcImage);%otsu  srcImage=double(srcImage);[m,n]=size(srcImage);ky=[-1,1];
kx=[-1;1];
kyy=[1,-2,1];
kxx=[1;-2;1];
kxy=[1,-1;-1,1];gausFilter = fspecial('gaussian',9,sigma);   %高斯滤波
dstImage=imfilter(srcImage,gausFilter,'replicate');  dx=imfilter(dstImage,kx);
dy=imfilter(dstImage,ky);
dxx=imfilter(dstImage,kxx);
dyy=imfilter(dstImage,kyy);
dxy=imfilter(dstImage,kxy);hessian=zeros(2,2);
points=zeros(m*n,2);for i=1:mfor j=1:nif(srcImage(i,j)/255>thresh)hessian(1,1)=dxx(i,j);hessian(1,2)=dxy(i,j);hessian(2,1)=dxy(i,j);hessian(2,2)=dyy(i,j);[eigenvectors,eigenvalues]=eig(hessian);if(abs(eigenvalues(1,1))>= abs(eigenvalues(2,2)))nx=eigenvectors(1,1);ny=eigenvectors(2,1);fmax_dist=eigenvalues(1,1);elsenx=eigenvectors(1,2);ny=eigenvectors(2,2);fmax_dist=eigenvalues(2,2);endt=-(nx*dx(i,j)+ny*dy(i,j))/(nx*nx*dxx(i,j)+2 * nx*ny*dxy(i,j)+ny*ny*dyy(i,j));if(abs(t*nx) <= 0.5 && abs(t*ny) <= 0.5)points((i-1)*m+j,:)=[ j+t*ny,i+t*nx];endendend
endindex = find(points(:,1)==0);
points(index,:) = [];
index = find(points(:,2)==0);
points(index,:) = [];pixel=points;figure(1);
imshow(uint8(srcImage));
hold on
plot(points(:,1),points(:,2),'r.','MarkerSize',1)
hold offend%% 光条中心坐标迭代去畸变
function undistortPoints=undistortCoor(intrinsic,distortCoff1,distortCoff2,points)
fx=intrinsic(1,1);
fy=intrinsic(2,2);
cx=intrinsic(1,3);
cy=intrinsic(2,3);
k1=distortCoff1(1);
k2=distortCoff1(2);
p1=distortCoff2(1);
p2=distortCoff2(2);
k3=0;n=size(points,1);
undistortPoints=zeros(n,2);for i=1:npx=(points(i,1)-cx)/fx;py=(points(i,2)-cy)/fy;px0=px;py0=py;for k=1:6pxfang = px*px;pyfang = py*py;prfang = pxfang + pyfang; pdoublexy = 2*px*py;dk = 1 + (k3*prfang^2+k2*prfang+k1)*prfang;%径向畸变校正模型dpx= p1*(pdoublexy + p2*(prfang+2*pxfang));dpy=p1*((prfang+2*pyfang) + p1*pdoublexy);%cm,cn为进行畸变校正后的在相机像平面上的坐标px=(px0-dpx)/dk;py=(py0-dpy)/dk; endx = fx*px + cx ;  y = fy*py + cy ; undistortPoints(i,:)=[x,y]; 
endend

原始数据:

标定结果:

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

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

相关文章

初识Linux之指令(二)

一&#xff1a;head指令 head 与 tail 就像它的名字一样的浅显易懂&#xff0c;它是用来显示开头或结尾某个数量的文字区块&#xff0c;head 用来显示档案的 开头至标准输出中&#xff0c;而 tail 想当然尔就是看档案的结尾。 语法&#xff1a;head 【参数】 【文件】 功能&…

開發 meshtastic 聊天機器人(2)

利用 Web 串接主機附近周邊藍芽(含 meshtastic client) pip install bleak (這個比較簡單) ----另外一個為 pybluez2 (pybluez) 2.程式 import streamlit as st import asyncio from bleak import BleakScannerasync def fetch_data():devices await BleakScanner.discover(…

京存非编存储走进中央民族大学

中央民族大学是一所具有鲜明民族特色的综合性全国重点大学&#xff0c;是国家民委、教育部、北京市共建高校。学校前身为1941年成立的延安民族学院。新中国成立后&#xff0c;经中央政府批准&#xff0c;1951年在北京成立中央民族学院&#xff0c;1993年11月更名为中央民族大学…

【量化交易】聚宽安装

安装JQData 更换源&#xff1a; 如果使用的是pip默认的PyPI源&#xff0c;可以尝试更换为一个更快的国内镜像源。例如阿里云、豆瓣等提供的PyPI镜像。 更改方法可以通过设置环境变量或者在pip命令中直接指定&#xff1a; PS C:\Users\bilirjs\Documents> pip config set …

No.13 笔记 | 网络安全防护指南:从法律法规到技术防御

一、法律法规 《中华人民共和国网络安全法》要点 遵守法律&#xff1a;所有个人和组织在使用网络时&#xff0c;必须遵守宪法和法律&#xff0c;不得利用网络从事危害国家安全等活动。 个人信息保护&#xff1a;禁止非法获取、出售或提供个人信息。若违反但未构成犯罪&#x…

Karmada核心概念

以下内容为翻译&#xff0c;原文地址 Karmada 是什么&#xff1f; | karmada 一、Karmada核心概念 一&#xff09;什么是Karmada 1、Karmada&#xff1a;开放&#xff0c;多云&#xff0c;多集群Kubernetes业务流程 Karmada (Kubernetes Armada)是一个Kubernetes管理系统&…

【NTN 卫星通信】卫星通信的专利

1 概述 好久没有看书了&#xff0c;最近买了本讲低轨卫星专利的书&#xff0c;也可以说是一个分析报告。推荐给喜欢的朋友。 2 书籍截图 图1 封面 图2 波音低轨卫星专利演进 图3 低轨卫星关键技术专利发展阶段 图4 第一页 3 参考文献 产业专利分析报告–低轨卫星通信技术

apisix云原生网关

定义 企业级网关通过域名、路由将请求分发到对应的应用上&#xff0c;通常承载数千个服务的流量&#xff0c;对稳定性有较高要求。 CNCF全景图 选型 Kubernetes抽象出两个核心概念&#xff1a;Service&#xff0c;为多个Pod提供统一的访问入口&#xff1b;Ingress&#xff…

【火山引擎】调用火山大模型的方法 | SDK安装 | 配置 | 客户端初始化 | 设置

豆包 (Doubao) 是字节跳动研发的大规模预训练语言模型。 目录 1 安装 2 配置访问凭证 3 客户端初始化 4 设置地域和访问域名 5 设置超时/重试次数 1 安装 通过pip安装PYTHON SDK。 pip install volcengine-python-sdk[ark] 2 配置访问凭证 获取 API Key 访问凭证具体步…

docker容器运行一段时间提示Failed to initialize NVML: Unknown Error

情况描述 服务器使用docker启动容器。启动以后一切正常也能跑程序。但是&#xff0c;在运行一段时间&#xff08;2天左右不等&#xff09;&#xff0c;会发现gpu掉了。输入nvidia-smi提示 Failed to initialize NVML: Unknown Error 主要发生条件是&#xff0c;docker启动的…

Oracle-19g数据库的安装

简介 Oracle是一家全球领先的数据库和云解决方案提供商。他们提供了一套完整的技术和产品&#xff0c;包括数据库管理系统、企业级应用程序、人工智能和机器学习工具等。Oracle的数据库管理系统是业界最受欢迎和广泛使用的数据库之一&#xff0c;它可以管理和存储大量结构化和…

Canmv k230 C++案例1——image classify学习笔记 初版

00 简介 用C编写代码的比mircopython要慢很多&#xff0c;需要编译开发环境&#xff0c;同时使用C更接近底层&#xff0c;效率利用率应该也是更高的&#xff0c;就是需要学习更多的内容&#xff0c;因为从零开始因此比较比较耗时。 注&#xff1a;以下为个人角度的理解&#x…

科技云报到:云服务的中场战事,从AI应用开始

科技云报到原创。 从去年的大模型之战&#xff0c;到今年的AI应用之争&#xff0c;云服务正在迈入全新的发展阶段。AI这个杠杆将各家厂商的竞争策略更向前推进了一步。 “云AI”能够孵化出多少可能&#xff1f;在业界眼中&#xff0c;“云AI”则意味着新的悬念&#xff1a;云计…

探索极简计算的新边界:从Uxn虚拟机看未来编程生态

越来越多的开发者追求复杂度和功能性的极致,然而,有一个小众的编程社区选择了截然不同的道路——极简主义。Uxn虚拟机便是这一思潮的代表之一。它通过简洁的指令集和有限的硬件资源模拟,试图打造一种可以在多种设备上运行的便携性编程环境。 与主流的重型操作系统和复杂…

wireshark抓包

网络抓包工具Wireshark下载安装&使用详细教程-CSDN博客 下载地址&#xff1a;Wireshark Downloadhttps://www.wireshark.org/download.html modbus tcp 关于wireshark无法分析出modbusTCP报文的事情_wireshark 协议一列怎么没有modbus tcp-CSDN博客 使用Wireshark过滤…

【动手学深度学习】6.2 图像卷积(个人向笔记)

1. 互相关运算 严格来说&#xff0c;卷积层是一个错误的叫法&#xff0c;因为它本质上是互相关运算而不是卷积运算。我们暂时忽略通道看看二维图像数据和隐藏表示。那么输出大小可以表示为 我们自己实现一个二维互相关运算 2. 卷积层 卷积层中有两个参数&#xff1a;卷积核权…

鸿蒙OS投票机制

(基于openharmony5.0) 投票机制 param get | grep ohos.boot.time 图 投票机制参数图 只有当所有的投票完成&#xff0c;开机动画才会退出&#xff0c;整理需要投票的系统应用&#xff08;三方应用不参与投票&#xff09;如下图所示&#xff1a; 以进程foundation为例&…

快速理解http的get和post

在网络通信中&#xff0c;HTTP 协议扮演着非常重要的角色&#xff0c;而不同的 HTTP 方法决定了客户端与服务器之间的交互方式。 这里讲一下最常用的两种方法——GET 和 POST。 一、GET 方法 GET 方法用于从服务器获取资源。 这就像去图书馆借书——你向图书馆请求一本特定的…

光路科技TSN交换机和电力专用交换机即将亮相第31届中国国际电力设备及技术展览会

在全球能源领域正经历深刻转型之际&#xff0c;可再生能源技术的飞跃进步正为电力行业的未来开辟新径。太阳能、风能等绿色能源&#xff0c;凭借其无可比拟的优势&#xff0c;正稳步取代化石燃料&#xff0c;成为电力行业的主流趋势。多国政府积极响应&#xff0c;出台多项政策…

Vue3获取ref元素的几种方式

静态绑定 获取单个 dom 元素 v-for 中使用 需要注意的是&#xff0c;访问的时候&#xff0c;要确保 ref 引用值已经成功绑定上元素&#xff0c;我们可以使用以下几种方式确保获取