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

WPF实现相机标定

WPF实现相机标定

一 标定参数类

/// <summary>/// 标定参数类/// </summary>publicclassCalibrationModel{[Category("创建标定描述文件参数"),Description("圆点行数")]publicint行数{get;set;}=7;[Category("创建标定描述文件参数"),Description("圆点行数")]publicint列数{get;set;}=7;[Category("创建标定描述文件参数"),Description("两个圆之间的距离, 单位米")]publicdouble圆间距{get;set;}=0.007;[Category("创建标定描述文件参数"),Description("比例值: Mark直径比上Mark中心距离")]publicdouble比例{get;set;}=0.5;[Category("创建标定描述文件参数"),Description("用于标定的描述文件")]publicstring描述文件{get;set;}=@".//标定文件//caltab.descr";[Category("创建标定描述文件参数"),Description("制作标定板的PS文件")]publicstringPS文件{get;set;}=@".//标定文件//caltab.ps";[Category("创建标定对象参数"),Description("厚度")]publicint厚度{get;set;}=1;[Category("创建标定对象参数"),Description("相机类型")]publicstring相机类型{get;set;}="面扫描(除法)";[Category("创建标定对象参数"),Description("单个相机像元的宽")]publicdouble像元宽{get;set;}=8.3;[Category("创建标定对象参数"),Description("单个相机像元的高")]publicdouble像元高{get;set;}=8.3;[Category("创建标定对象参数"),Description("图像宽")]publicdouble图像宽{get;set;}=1120;[Category("创建标定对象参数"),Description("图像高")]publicdouble图像高{get;set;}=1120;[Category("创建标定对象参数"),Description("镜头的焦距")]publicdouble焦距{get;set;}=8;[Category("标定结果"),Description("标定效果,越接近0越越好")]publicdouble平均误差{get;set;}=999.9;}

二 保存参数文件

/// <summary>/// 保存参数文件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidmaterialButton43_Click(objectsender,EventArgse){CalibrationModelcalibrationModel=propertyGrid_Cali.SelectedObjectasCalibrationModel;XmlSerializerHelper.WriteXML(calibrationModel,@".//标定文件//CalibrationModel.xnml",typeof(CalibrationModel));}

三 读取参数

if(File.Exists(@".//标定文件//CalibrationModel.xnml")){propertyGrid_Cali.SelectedObject=XmlSerializerHelper.ReadXML(@".//标定文件//CalibrationModel.xnml",typeof(CalibrationModel));}else{propertyGrid_Cali.SelectedObject=newCalibrationModel();}

四 创建标定板描述文件

/// <summary>/// 创建标定板描述文件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidmaterialButton49_Click(objectsender,EventArgse){CalibrationModelcalibrationModel=propertyGrid_Cali.SelectedObjectasCalibrationModel;// 创建保存文件夹if(!Directory.Exists(Path.GetDirectoryName(calibrationModel.描述文件))){Directory.CreateDirectory(Path.GetDirectoryName(calibrationModel.描述文件));}HOperatorSet.GenCaltab(calibrationModel.行数,calibrationModel.列数,calibrationModel.圆间距,calibrationModel.比例,calibrationModel.描述文件,calibrationModel.PS文件);MessageBox.Show("创建标定描述文件成功");}

五 创建标定对象

/// <summary>/// 创建标定文件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidmaterialButton48_Click(objectsender,EventArgse){// 1.创建标定对象HOperatorSet.CreateCalibData("calibration_object",1,1,outhv_CalibDataID);// 2 确定描述文件CalibrationModelcalibrationModel=propertyGrid_Cali.SelectedObjectasCalibrationModel;HOperatorSet.SetCalibDataCalibObject(hv_CalibDataID,0,calibrationModel.描述文件);// 3.确定相机参数// 获取标定数据varFocus=calibrationModel.焦距*0.001;varKappa=0;varSx=calibrationModel.像元宽*1e-06;varSy=calibrationModel.像元高*1e-06;varImageWidth=calibrationModel.图像宽;varImageHeight=calibrationModel.图像高;varCx=ImageWidth*0.5;// 图像中心点varCy=ImageHeight*0.5;// 图像中心点HTupleCameraParam=newHTuple();CameraParam.TupleConcat("area_scan_division",Focus,Kappa,Sx,Sy,Cx,Cy,ImageWidth,ImageHeight);HOperatorSet.SetCalibDataCamParam(hv_CalibDataID,0,newHTuple(),CameraParam);MessageBox.Show("创建标定对象成功");}

六 加载标定图像

/// <summary>/// 加载标定图像/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidmaterialButton47_Click(objectsender,EventArgse){OpenFileDialogofd=newOpenFileDialog();ofd.Multiselect=true;if(ofd.ShowDialog()==DialogResult.OK){string[]filepaths=ofd.FileNames;for(inti=0;i<filepaths.Length;i++){HOperatorSet.ReadImage(outHObjectho_Image,filepaths[i]);hWindow_Final_Cali.HobjectToHimage(ho_Image);// 查找当前图像中与标定板匹配到的标定板的轮廓及原点中心HOperatorSet.FindCalibObject(ho_Image,hv_CalibDataID,0,0,i,newHTuple(),newHTuple());// 获取对应轮廓及每个标定板上原点的中心HOperatorSet.GetCalibDataObservContours(outHObjectho_Contours,hv_CalibDataID,"caltab",0,0,i);HOperatorSet.GetCalibDataObservPoints(hv_CalibDataID,0,0,i,outHTuplehv_Row,outHTuplehv_Column,outHTuplehv_Index,outHTuplehv_Pose);HOperatorSet.GenCrossContourXld(outHObjectho_Cross,hv_Row,hv_Column,10,0.785398);hWindow_Final_Cali.DispObj(ho_Contours,"blue");hWindow_Final_Cali.DispObj(ho_Cross,"red");}}}

七 标定,生成畸变矫正文件

/// <summary>/// 标定/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidmaterialButton41_Click(objectsender,EventArgse){// 标定HOperatorSet.CalibrateCameras(hv_CalibDataID,outHTuplehv_Error);// 更新UI显示误差CalibrationModelcalibrationModel=propertyGrid_Cali.SelectedObjectasCalibrationModel;calibrationModel.平均误差=hv_Error.D;propertyGrid_Cali.SelectedObject=calibrationModel;// 获取相机内参HOperatorSet.GetCalibData(hv_CalibDataID,"camera",0,"params",outHTuplehv_CameraParameters);// 生成畸变矫正参数HOperatorSet.ChangeRadialDistortionCamPar("adaptive",hv_CameraParameters,0,outHTuplehv_CamParamChange);//生成畸变矫正MapHOperatorSet.GenRadialDistortionMap(outHObjectho_Map,hv_CameraParameters,hv_CamParamChange,"bilinear");// 保存畸变矫正文件HOperatorSet.WriteImage(ho_Map,"tiff",0,@"./Map");//** 8.获取相机外参HOperatorSet.GetCalibData(hv_CalibDataID,"calib_obj_pose",(newHTuple(0)).TupleConcat(0),"pose",outHTuplehv_Object_Pose_1);HOperatorSet.SetOriginPose(hv_Object_Pose_1,0,0,0.002,outHTuplehv_PoseCalibParams);//** 9.保存相机参数HOperatorSet.WriteTuple(hv_CameraParameters,"CameraParameters.tup");HOperatorSet.WriteTuple(hv_PoseCalibParams,"CameraPose.tup");}

八 查看畸变矫正效果

/// <summary>/// 查看畸变矫正效果/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidmaterialButton42_Click(objectsender,EventArgse){// 读取畸变矫正文件HOperatorSet.ReadImage(outHObjectMap,@"./标定文件/Map");OpenFileDialogopenFileDialog=newOpenFileDialog();if(openFileDialog.ShowDialog()==DialogResult.OK){stringfilePath=openFileDialog.FileName;HOperatorSet.ReadImage(outHObjectImage,filePath);HOperatorSet.MapImage(Image,Map,outHObjectimageMapped);hWindow_Final_Cali.HobjectToHimage(imageMapped);}}
http://www.jsqmd.com/news/425194/

相关文章:

  • 告别传统风控!AI应用架构师详解:金融AI风险预警的4大技术颠覆与架构转型
  • Java基于springboot+vue的智慧医疗采购系统
  • 题解:uoj1015 【ULR #3】我的 XOR 卷积人生
  • Java基于springboot+vue的智慧农场系统
  • nodejs+php+vueJAVA的邮件过滤系统设计与实现
  • 保姆级教程:Python+ComfyUI 本地 AI 绘图全流程
  • 【建筑能耗模拟软件EnergyPlus第二期】天气站点数据
  • Java基于springboot+vue的景区服务平台
  • Java基于springboot+vue的易物小店交换系统
  • nodejs+php+vueO2O小程序生鲜食品商城订购系统
  • nodejs+php+vueOA公文发文管理系统
  • Java基于springboot+vue的旧时光咖啡厅管理系统
  • uni-app x Android 平台 UTS 踩坑全记录:类型、存储、网络、渲染避坑指南
  • Java基于springboot+vue的智慧旅游系统
  • nodejs+php+vue 家庭理财系统 个人理财收支系统 微信小程序
  • nodejs+php+vueHadoop技术下的校园二手交易系统的设计与实现
  • 《人月神话》阅读笔记三
  • 《人月神话》阅读笔记二
  • 华为OD机考双机位C卷 - 商品推荐多属性排序 (Java Python JS GO C++ C)
  • 为什么你的提示工程大数据处理框架不稳定?架构师带你排查根因
  • 华为OD机考双机位C卷 - 卡牌游戏 (Java Python JS GO C++ C)
  • 《人月神话》阅读笔记一
  • 层序地层学练习报告
  • [20260228]如何实现字符串拆分输出数字序列.txt
  • 云原生环境下的大数据集成:挑战与解决方案
  • 基础PWM经三电平逆变器控制1.6MW异步电机仿真:从原理到实现
  • 库周报|IPO辅导1起、融资4起;2家上市公司营收合计超25亿元;2034年3D打印市场将达7500亿元
  • 派息率174%的现金奶牛!联发股份全年分红2.1亿,资产负债率仅28%显财务韧性
  • 【stm32简单外设篇】- 继电器模块
  • PyTorch神经网络组件之Softmax