using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommonMethods;
using ToolBase;
using ViewROI;
using HalconDotNet;
using System.Data;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using Logger;
using static DataStruct.DataStructClass;
namespace EyeHandCalibTool
{
[Serializable]
public class EyeHandCalib : IToolBase
{
///
/// 仿射变换矩阵
///
public HTuple homMat2D = new HTuple();
///
/// 标定类型 四点标定|九点标定
///
public CalibType calibType = CalibType.Four_Point;
///
/// 标定表源数据
///
public DataTable CalibSourceDataTable { get; set; } = null;
///
/// 输入点信息
///
public Point inputPoint = new Point();
///
/// 输出点信息
///
public Point outputPoint = new Point();
///
/// 矩阵名称
///
public string homMat2DName { get; set; } = Guid.NewGuid().ToString();
///
/// X平移
///
private HTuple _translateX = 0;
internal HTuple TranslateX
{
get
{
_translateX = Math.Round((double)_translateX, 2);
return _translateX;
}
set
{
value = Math.Round((double)value, 2);
_translateX = value;
}
}
///
/// Y平移
///
private HTuple _translateY = 0;
internal HTuple TranslateY
{
get
{
_translateY = Math.Round((double)_translateY, 2);
return _translateY;
}
set
{
value = Math.Round((double)value, 2);
_translateY = value;
}
}
///
/// X缩放
///
private HTuple _scanX = 1;
internal HTuple ScanX
{
get
{
_scanX = Math.Round((double)_scanX, 2);
return _scanX;
}
set
{
value = Math.Round((double)value, 2);
_scanX = value;
}
}
///
/// Y缩放
///
private HTuple _scanY = 1;
internal HTuple ScanY
{
get
{
_scanY = Math.Round((double)_scanY, 2);
return _scanY;
}
set
{
value = Math.Round((double)value, 2);
_scanY = value;
}
}
///
/// 角度旋转
///
private HTuple _rotation = 0;
internal HTuple Rotation
{
get
{
_rotation = Math.Round((double)_rotation, 2);
return _rotation;
}
set
{
value = Math.Round((double)value, 2);
_rotation = value;
}
}
///
/// 轴斜切
///
private HTuple _theta = 0;
internal HTuple Theta
{
get
{
_theta = Math.Round((double)_theta, 2);
return _theta;
}
set
{
value = Math.Round((double)value, 2);
_theta = value;
}
}
public override void DispImage()
{
// throw new NotImplementedException();
}
public override void DispMainWindow(HWindowTool_Smart window)
{
// throw new NotImplementedException();
}
public override void Run(SoftwareRunState softwareRunState)
{
try
{
// 若首次加载且本地存在矩阵,优先读取本地
if (File.Exists(homMat2DName) && homMat2D.Length == 0)
{
HOperatorSet.ReadTuple(homMat2DName, out homMat2D);
}
// 再次判断
if (homMat2D.Length == 0)
{
runMessage = $"{FormEyeHandCalib.Instance.myToolInfo.FormToolName}未生成仿射矩阵工具,需要先标定标准!";
toolRunStatu = ToolRunStatu.Tool_Run_Error;
FormEyeHandCalib.Instance.SetToolStatus(runMessage, toolRunStatu);
}
else
{
HTuple tupOutX, tupOutY;
HOperatorSet.AffineTransPoint2d(homMat2D, inputPoint.Row, inputPoint.Col, out tupOutX, out tupOutY);
outputPoint.Row = tupOutX;
outputPoint.Col = tupOutY;
runMessage = $"{FormEyeHandCalib.Instance.myToolInfo.FormToolName}运行成功";
toolRunStatu = ToolRunStatu.Succeed;
FormEyeHandCalib.Instance.SetToolStatus(runMessage, toolRunStatu);
}
}
catch (Exception ex)
{
runMessage = $"{FormEyeHandCalib.Instance.myToolInfo.FormToolName}运行出现异常";
toolRunStatu = ToolRunStatu.Tool_Run_Error;
}
}
///
/// 初始化标定数据源
///
public void InitDataTable()
{
CalibSourceDataTable = new DataTable();
//初始化DataTable,并将datatable绑定到DataGridView的数据源
DataColumn c1 = new DataColumn("像素X", typeof(double));
DataColumn c2 = new DataColumn("像素Y", typeof(double));
DataColumn c3 = new DataColumn("机械X", typeof(double));
DataColumn c4 = new DataColumn("机械Y", typeof(double));
CalibSourceDataTable.Columns.Add(c1);
CalibSourceDataTable.Columns.Add(c2);
CalibSourceDataTable.Columns.Add(c3);
CalibSourceDataTable.Columns.Add(c4);
CalibSourceDataTable.Rows.Clear();
for (int i = 0; i < (int)calibType; i++)
{
DataRow dr = CalibSourceDataTable.NewRow();
dr[0] = 0;
dr[1] = 50;
dr[2] = 0;
dr[3] = 50;
CalibSourceDataTable.Rows.Add(dr);
}
}
///
/// 导入标定数据
///
public void ReadCalibData()
{
OpenFileDialog digOpenFile = new OpenFileDialog();
digOpenFile.FileName = string.Empty;
digOpenFile.Title = "请选择表格文件";
digOpenFile.Filter = "CSV文件(*.csv)|*.csv";
if (digOpenFile.ShowDialog() == DialogResult.OK)
{
string[] lines = File.ReadAllLines(digOpenFile.FileName, Encoding.Default);
for (int i = 0; i < lines.Length; i++)
{
string[] data = Regex.Split(lines[i], ",");
for (int j = 0; j < data.Length; j++)
{
CalibSourceDataTable.Rows[i][j] = data[j];
if (j == 3) //只导入前四列
break;
}
if (i == (int)calibType) //若标定类型为四点标定,则导入前四行,若为九点标定,则导入前九行
break;
}
}
}
///
/// 导出标定数据
///
public void ExportCalibData()
{
try
{
SaveFileDialog dig_saveImage = new SaveFileDialog();
dig_saveImage.FileName = "CalibData " + DateTime.Now.ToString("yyyy_MM_dd");
dig_saveImage.Title = "请选择导出路径";
dig_saveImage.Filter = "CSV文件(*.csv)|*.csv";
if (dig_saveImage.ShowDialog() == DialogResult.OK)
{
File.Create(dig_saveImage.FileName).Close();
string data = string.Empty;
for (int i = 0; i pixelRowList = new List();
List pixelColList = new List();
List MechanicalXList = new List();
List MechanicalYList = new List();
try
{
for (int i = 0; i < CalibSourceDataTable.Rows.Count; i++)
{
pixelRowList.Add(Convert.ToDouble(CalibSourceDataTable.Rows[i][0]));
pixelColList.Add(Convert.ToDouble(CalibSourceDataTable.Rows[i][1]));
MechanicalXList.Add(Convert.ToDouble(CalibSourceDataTable.Rows[i][2]));
MechanicalYList.Add(Convert.ToDouble(CalibSourceDataTable.Rows[i][3]));
}
}
catch(Exception ex)
{
LoggerClass.WriteLog("标定失败,标定数据异常(错误代码:12901)", ex);
return false;
}
try
{
HTuple pixelRow = new HTuple(pixelRowList.ToArray());
HTuple pixelCol = new HTuple(pixelColList.ToArray());
HTuple mechanicalX = new HTuple(MechanicalXList.ToArray());
HTuple mechanicalY = new HTuple(MechanicalYList.ToArray());
HOperatorSet.VectorToHomMat2d(pixelRow, pixelCol, mechanicalX, mechanicalY, out homMat2D);
}
catch(HalconException ex)
{
LoggerClass.WriteLog("标定失败,标定数据异常,无法确定仿射变换关系(错误代码:12902)", ex);
return false;
}
HOperatorSet.HomMat2dToAffinePar(homMat2D, out _scanX, out _scanY, out _rotation, out _theta, out _translateX, out _translateY);
return true;
}
catch (Exception ex)
{
LoggerClass.WriteLog("手动标定出现异常", ex);
return false;
}
}
}
///
/// 标定类型 四点|九点
///
[Serializable]
public enum CalibType
{
Four_Point = 4,
Nine_Point = 9,
}
}