using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Model;
using Bro.Common.UI;
using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Bro.Common.Calibration
{
public partial class CalibrationStatic9PointFrm : Form
{
///
/// 标定点位信息
///
public List CPoints
{
get
{
return canvas1.Elements.Where(p => p.IsEnabled && (p is CrossHair)).Select(p => ((CrossHair)p).CenterPoint).ToList();
}
}
///
/// 运动点位信息
///
public CustomizedPoint MovingPosition { get; set; } = new CustomizedPoint();
Canvas canvas1 = new Canvas();
PLCBase PLC = null;
CameraBase Camera = null;
Bitmap Image = null;
CalibrationStatic9PointConfig Config = null;
HDevEngineTool tool = null;
public CalibrationStatic9PointFrm()
{
InitializeComponent();
canvas1 = new Canvas();
canvas1.Dock = DockStyle.Fill;
plCanvas.Controls.Add(canvas1);
}
public CalibrationStatic9PointFrm(string display, CameraBase camera, PLCBase plc, Bitmap image, CalibrationStatic9PointConfig config)
{
InitializeComponent();
if (!string.IsNullOrWhiteSpace(display))
{
this.Text = display;
}
Camera = camera;
PLC = plc;
Image = image;
propCalibrationConfig.SelectedObject = Config = config;
Camera.OnImageUpdated -= Camera_UpdateShowImage;
Camera.OnImageUpdated += Camera_UpdateShowImage;
canvas1.LoadImage(Image);
LoadHalconTool();
}
AutoResetEvent _imgShowedHandle = new AutoResetEvent(true);
private void Camera_UpdateShowImage(CameraBase camera, Bitmap image)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => LoadImage(image)));
}
else
{
LoadImage(image);
}
}
private void LoadImage(Bitmap image)
{
canvas1.LoadImage(image);
_imgShowedHandle.Set();
}
private void PointTest()
{
canvas1.Elements.Clear();
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
PointF p = new PointF();
p.X = 300 + i * 100;
p.Y = 500 + j * 150;
CrossHair ch = new CrossHair(new CalibrationPoint(p));
ch.Index = i * 3 + j + 1;
ch.Name = p.X.ToString() + "--" + p.Y.ToString();
canvas1.Elements.Add(ch);
}
}
}
private void LoadHalconTool()
{
if (string.IsNullOrWhiteSpace(Config.CameraOpConfig.AlgorithemPath))
{
return;
}
txtAlgorithemPath.Text = Config.CameraOpConfig.AlgorithemPath;
string directoryPath = Path.GetDirectoryName(Config.CameraOpConfig.AlgorithemPath);
string fileName = Path.GetFileNameWithoutExtension(Config.CameraOpConfig.AlgorithemPath);
tool = new HDevEngineTool(directoryPath);
tool.LoadProcedure(fileName);
Thread.Sleep(1000);
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
private void btnDone_Click(object sender, EventArgs e)
{
if (CPoints.Count < 9)
{
if (MessageBox.Show("一般需设置至少9个标定点的信息,是否确认完成", "完成确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
return;
}
if (CPoints.Count(p => p.X == 0 && p.Y == 0) > 1)
{
if (MessageBox.Show("标定点的XY信息未设置完成,是否确认完成", "完成确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
return;
}
GetCurrentPosition();
if (Config.IsEnableROIFilter)
{
Config.ROIList.Clear();
CPoints.ForEach(u =>
{
ROI_Circle circle = new ROI_Circle();
if (u.IsBasePoint)
{
circle.ROI_Index = "1";
}
circle.Center = new CustomizedPoint(u.U, u.V);
circle.Radius = Config.ROI_Radius;
Config.ROIList.Add(circle);
});
}
this.DialogResult = DialogResult.OK;
}
public virtual void GetCurrentPosition()
{
//if (Config.PLCSetting.IsRealTimeDataFromPLC)
//{
// int x = PLC.Read(Config.PLCSetting.XAddress, 2).ParseUnsignShortListToInt()[0];
// int y = PLC.Read(Config.PLCSetting.YAddress, 2).ParseUnsignShortListToInt()[0];
// MovingPosition = new CustomizedPoint(x, y);
// Config.PLCSetting.LocationX = x;
// Config.PLCSetting.LocationY = y;
//}
//else
//{
// MovingPosition = new CustomizedPoint(Config.PLCSetting.LocationX, Config.PLCSetting.LocationY);
//}
}
private void btnCalibrate_Click(object sender, EventArgs e)
{
DoCalibration();
}
private void DoCalibration()
{
canvas1.Elements.Clear();
if (Config.IsEnableROIFilter)
{
Config.ROIList.ForEach(r =>
{
canvas1.Elements.Add(r);
});
}
try
{
HTuple outputX = new HTuple();
HTuple outputY = new HTuple();
using (HObject hImage = canvas1.MAP.ConvertBitmapToHObject())
{
tool.InputImageDic.Clear();
tool.InputImageDic["INPUT_Image"] = hImage;
tool.RunProcedure();
if (!tool.IsSuccessful)
throw new ProcessException($"{Config.CameraOpConfig.AlgorithemPath}算法运行失败");
outputX = tool.GetResultTuple("OUTPUT_X");
outputY = tool.GetResultTuple("OUTPUT_Y");
}
List chList = new List();
for (int i = 0; i < outputX.DArr.Length; i++)
{
CalibrationPoint point = new CalibrationPoint(new PointF((float)outputX.DArr[i], (float)outputY.DArr[i]));
if (Config.IsEnableROIFilter && Config.ROIList.Count > 0)
{
var roi = Config.ROIList.FirstOrDefault(r => r.IsMouseInSide(new Point((int)point.U, (int)point.V)));
if (roi != null)
{
CrossHair ch = new CrossHair(point);
ch.IsShowRemark = Config.IsShowRemark;
ch.Index = i + 1;
ch.Name = point.U.ToString("f3") + "--" + point.V.ToString("f3");
if (roi.ROI_Index == "1")
{
ch.CenterPoint.IsBasePoint = true;
}
chList.Add(ch);
}
}
else
{
CrossHair ch = new CrossHair(point);
ch.IsShowRemark = Config.IsShowRemark;
ch.Index = i + 1;
ch.Name = point.U.ToString("f3") + "--" + point.V.ToString("f3");
chList.Add(ch);
}
}
Config.ROIList.ForEach(r =>
{
canvas1.Elements.Add(r);
});
}
catch (Exception ex)
{
MessageBox.Show(ex.GetExceptionMessage());
}
}
private void btnQuickSetXY_Click(object sender, EventArgs e)
{
if (MessageBox.Show("快捷设置XY坐标仅适用于标定坐标系和相机坐标系基本平行情况下", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) != DialogResult.OK)
{
return;
}
if (CPoints.Count(p => p.IsBasePoint) > 1)
{
MessageBox.Show("基准点只能选择一个");
return;
}
var basePoint = CPoints.FirstOrDefault(p => p.IsBasePoint);
if (basePoint == null)
{
MessageBox.Show("请选择一个基准点");
return;
}
List uList = CPoints.Select(p => Math.Abs(p.U - basePoint.U)).OrderBy(u => u).ToList();
List vList = CPoints.Select(p => Math.Abs(p.V - basePoint.V)).OrderBy(u => u).ToList();
float intervalU = uList.FirstOrDefault(u => u > Config.IgnorePixel);
float intervalV = vList.FirstOrDefault(u => u > Config.IgnorePixel);
CPoints.ForEach(p =>
{
if (!p.IsBasePoint)
{
if (Config.IsInvert)
{
p.X = (int)(Math.Round((p.V - basePoint.V) / intervalV)) * Config.IntervalX + basePoint.X;
p.Y = (int)(Math.Round((p.U - basePoint.U) / intervalU)) * Config.IntervalY + basePoint.Y;
}
else
{
p.X = (int)(Math.Round((p.U - basePoint.U) / intervalU)) * Config.IntervalX + basePoint.X;
p.Y = (int)(Math.Round((p.V - basePoint.V) / intervalV)) * Config.IntervalY + basePoint.Y;
}
}
else
{
if (Config.IsEnableROIFilter)
{
var roi1st = Config.ROIList.FirstOrDefault(u => u.IsMouseInSide(new Point((int)p.U, (int)p.V)));
if (roi1st != null)
{
roi1st.ROI_Index = "1";
}
}
}
});
MessageBox.Show("快捷配置完成!");
}
private void btnReSnap_Click(object sender, EventArgs e)
{
Camera.Snapshot(Config.CameraOpConfig, out HObject hImage);
hImage.Dispose();
}
private void chkContinueMode_CheckedChanged(object sender, EventArgs e)
{
if (chkContinueMode.Checked)
{
Task.Run(() =>
{
while (chkContinueMode.Checked)
{
Camera.Snapshot(Config.CameraOpConfig, out HObject hImage);
hImage.Dispose();
_imgShowedHandle.WaitOne(3000);
}
});
}
}
private void btnTest_Click(object sender, EventArgs e)
{
PointTest();
}
private void btnReadLocation_Click(object sender, EventArgs e)
{
//int x = PLC.Read(Config.PLCSetting.XAddress, 2).ParseUnsignShortListToInt()[0];
//int y = PLC.Read(Config.PLCSetting.YAddress, 2).ParseUnsignShortListToInt()[0];
//string msg = string.Format("X:{0};Y:{1}", x, y);
//if (MessageBox.Show(msg + "\r\n是否保存到配置?", "坐标获取", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
//{
// Config.PLCSetting.LocationX = x;
// Config.PLCSetting.LocationY = y;
//}
GetCurrentPosition();
}
private void btnReloadAlgorithem_Click(object sender, EventArgs e)
{
LoadHalconTool();
MessageBox.Show("算法重新载入完成");
}
private void btnClearROI_Click(object sender, EventArgs e)
{
Config.ROIList.Clear();
DoCalibration();
}
private void CalibrationProcessFrm_FormClosing(object sender, FormClosingEventArgs e)
{
chkContinueMode.Checked = false;
}
}
}