using AiControlRequest;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using PaintDotNet;
using PaintDotNet.Base.CommTool;
using PaintDotNet.DbOpreate.DbBll;
using PaintDotNet.DbOpreate.DbModel;
using PaintDotNet.ImageCollect;
using StageController;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using TUCamera;
using static AiControlRequest.AiControl;
namespace Metis.AutoAnalysis
{
internal partial class AutoAnalysisDialog : FloatingToolForm, IStageEvent
{
///
/// 样品台展示控件
///
SampleStageControl _samplesControl;
Dictionary _stageSettingList;
SampleStageModel _stageSettingNow;
string _stageSettingName;
///
/// 结果展示控件
///
ScanGridControl _scanGird;
AxisController m_stage;
private double m_PxLength;
Dictionary ResultList = new Dictionary();
protected int ConvertUMToPX(double length)
{
return (int)(length / m_PxLength);
}
protected double ConvertPXToUm(double length)
{
return length * m_PxLength;
}
public int VisionWidthPixel;
public int VisionHeightPixel;
public double VisionWidth;
public double VisionHeight;
public int NumRow;
public int NumCol;
private AppWorkspace _app;
public AutoAnalysisDialog(AppWorkspace app)
{
_app = app;
InitializeComponent();
Startup.instance.rules.TryGetValue(MeasurementUnit.Micron, out m_PxLength);
_scanGird = new ScanGridControl();
_scanGird.MouseDown += _scanGird_MouseDown;
pnlScanGrid.Controls.Add(_scanGird);
InitSmapleStageControl();
DirRoot = @"D:\AiTest";//Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
_camera = TUCameraManager.GetInstance().GetCurrentCamera();
var size = _camera.GetResolution();
VisionWidthPixel = size.Width == 0 ? 1000 : size.Width;
VisionHeightPixel = size.Height == 0 ? 1000 : size.Height;
VisionWidth = ConvertPXToUm(VisionWidthPixel);
VisionHeight = ConvertPXToUm(VisionHeightPixel);
lblImageSize.Text = string.Format("{0:f0}*{1:f0}", VisionWidthPixel, VisionHeightPixel);
SetAnalyzeModelFromXml("自动分析");
}
#region Load Close
private void AutoAnalysisDialog_Load(object sender, EventArgs e)
{
CameraConfigs.GetInstance().CameraParamInit();
_stageSettingList = SampleStageManager.GetAll();
foreach (var s in _stageSettingList.Keys) cmbSampleStageList.Items.Add(s);
if (cmbSampleStageList.Items.Count > 0)
cmbSampleStageList.SelectedIndex = 0;
cmbScanMode.SelectedIndex = 0;
cmbAutoFocusParm.SelectedIndex = 0;
tmrUpdateUI.Start();
tmrUpdateUI.Tick += TmrUpdateUI_Tick;
UpdateUserList();
StartCapture();
InitStage();
InitOfflineTest();
InitCheckConfig();
}
int[] _detectParams = new int[3];
private CheckConfigModel _checkconfig;
private void CheckItemChange(string str)
{
for (int i = 0; i < 3; i++)
_detectParams[i] = int.Parse(str.Split(',')[i]);
}
private void InitCheckConfig()
{
try
{
string CheckconfigPath = @"Automation\checkitem\checkconfig.xml";
_checkconfig = XmlSerializeHelper.Load(CheckconfigPath);
cmbProjuctSelect.DropDownStyle = ComboBoxStyle.DropDownList;
foreach (var item in _checkconfig.Items)
{
cmbProjuctSelect.Items.Add(item.Name);
cmbProjuctSelect.SelectedIndex = 0;
}
}
catch
{
MessageBox.Show("请检查\"\\Automation\\checkitem\\checkconfig.xml\"文件是否有错误。", "检测配置文件错误");
}
}
///
/// 更新控件状态
///
private void TmrUpdateUI_Tick(object sender, EventArgs e)
{
grpStage.Enabled = !_isWorking;
grpFocus.Enabled = !_isWorking;
grpStageInfo.Enabled = !_isWorking;
grpStageDisplay.Enabled = !_isWorking;
grpWorkOperate.Enabled = m_stage.IsOpen;
grpAiOperate.Enabled = !_isWorking || _pause;
grpRange.Enabled = !_isWorking;
btnLocate.Enabled = !_isWorking & m_stage.IsOpen;
btnLookBack.Enabled = _workDone || _pause;
btnAnalysis.Enabled = _workDone || _pause;
btnReport.Enabled = _workDone;
btnStart.Text = !_isWorking || _pause ? "开始" : "暂停";
btnStop.Enabled = _isWorking;
cmbProjuctSelect.Enabled = !_isWorking;
if (_isWorking)
{
_resultScanSelect = -1;
}
}
private void AutoAnalysisDialog_FormClosing(object sender, FormClosingEventArgs e)
{
StopCapture();
StopWork();
}
public void InitStage()
{
m_stage = AxisController.GetInstance();
pnlTest.Width = 0;
if (!m_stage.IsOpen)
{
// MessageBox.Show(PdnResources.GetString("Message.AxisController.NotConnected"));
//grpWorkOperate.Enabled = false;
return;
}
m_stage.SetWorkspeedXY();
var dialog = TransferProgressDialog.CreatDialog("平台复位", "复位中...", null, "Stop");
m_stage.ResetStage(
() =>
{
this.Invoke(new Action(dialog.Close));
});
dialog.ShowDialog();
}
#endregion
private void cmbSampleStageList_SelectedIndexChanged(object sender, EventArgs e)
{
_stageSettingNow = _stageSettingList[cmbSampleStageList.Text];
_stageSettingName = cmbSampleStageList.Text;
UpdateSmapleStageControl();
BuildTableList();
var hc = Math.Ceiling(_stageSettingNow.Width * 1000 / VisionWidth);
var vc = Math.Ceiling(_stageSettingNow.Height * 1000 / VisionHeight);
nupHorizon.Value = (decimal)hc;
nupVertical.Value = (decimal)vc;
ClearResult();
}
#region ScanGrid Display
private void nupHorizon_ValueChanged(object sender, EventArgs e)
{
var colN = (int)nupHorizon.Value;
var rowN = (int)nupVertical.Value;
if (colN != 0 && rowN != 0)
UpdateScanGrid(colN, rowN);
else { return; }
var width = ConvertUMToPX(_stageSettingNow.Width * 1000 / colN);
var height = ConvertUMToPX(_stageSettingNow.Height * 1000 / rowN);
lblStageSize.Text = string.Format("{0:f0}*{1:f0}", width, height);
}
private void UpdateScanGrid(int c, int r)
{
lblTotal.Text = (c * r).ToString();
NumCol = c;
NumRow = r;
_scanGird.NumCol = c;
_scanGird.NumRow = r;
_scanGird.VsnWitch = VisionWidth;
_scanGird.VsnHeight = VisionHeight;
_scanGird.InitGrid(_stageSettingNow);
}
private void _scanGird_MouseDown(object sender, MouseEventArgs e)
{
_resultLookId = _scanGird.GetHitId(e.X, e.Y);
_resultScanSelect = _scanGird.GetIndex(e.X, e.Y);
ShowResult();
}
#endregion
#region SampleStage
void InitSmapleStageControl()
{
_samplesControl = new SampleStageControl();
_samplesControl.OnSelectChanged += (value) =>
{
UpdateInfoTable(value);
// if (_workDone)
UpdateScanGridByResult(value);
};
pnlStageDisplay.Controls.Add(_samplesControl);
}
private void UpdateSmapleStageControl()
{
_samplesControl.Update(_stageSettingNow);
}
private void ResetSmapleState()
{
for (int i = 0; i < _tables.Length; i++)
{
var table = _tables[i];
if (table == null)
_samplesControl.SetState(i, 0);
else
_samplesControl.SetState(i, 1);
}
}
#endregion
#region User
List _userList;
private void UpdateUserList()
{
cmbUser.Items.Clear();
_userList = SampleStageManager.GetUsers();
foreach (var s in _userList) cmbUser.Items.Add(s);
if (cmbUser.Items.Count > 0)
cmbUser.SelectedIndex = 0;
}
private void btnAddUser_Click(object sender, EventArgs e)
{
var form = new AddUser() { CallOK = AddUser };
form.TopMost = true;
form.ShowDialog();
}
private void AddUser(string s)
{
if (_userList.Contains(s))
return;
_userList.Insert(0, s);
SampleStageManager.SaveUsers(_userList);
UpdateUserList();
}
private void DelUser(string s)
{
_userList.Remove(s);
SampleStageManager.SaveUsers(_userList);
UpdateUserList();
}
private void btnDelUser_Click(object sender, EventArgs e)
{
DelUser(cmbUser.Text);
}
#endregion
#region Information
string[] _infos;
DataTable[] _tables;
char _spliter = ';';
string GetUser()
{
return cmbUser.Text;
}
void BuildTableList()
{
dgvStageInfo.DataSource = null;
_tables = new DataTable[_stageSettingNow.WorkPoits.Count];
_infos = new string[_stageSettingNow.WorkPoits.Count];
}
private void txbInfo_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
btnAddInfo_Click(null, null);
}
}
private void btnAddInfo_Click(object sender, EventArgs e)
{
if (!_tables.Any((t) => t == null))
{
MessageBox.Show("所有工位已经添加完成");
return;
}
var user = GetUser();
if (string.IsNullOrEmpty(user))
{
MessageBox.Show("请先添加检测员。");
return;
}
var infostr = txbInfo.Text;
if (string.IsNullOrEmpty(infostr)) return;
txbInfo.Text = "";
var list = infostr.Split(_spliter);
var sampleEditSelect = _tables.ToList().FindIndex((t) => t == null);
_samplesControl.SelectIndex = sampleEditSelect;
var table = new DataTable();
table.Columns.Add("工位 ", typeof(string));
table.Columns.Add("样品信息 ", typeof(string));
table.Columns.Add("检测 ", typeof(bool));
table.Columns.Add("结果 ", typeof(string));
table.Columns.Add("检测员 ", typeof(string));
for (int i = 0; i < list.Length; i++)
{
var row = table.NewRow();
if (i == 0)
row[0] = "#" + (sampleEditSelect + 1);
int j = 1;
row[j++] = list[i];
row[j++] = true;
row[j++] = "";
row[j++] = user;
table.Rows.Add(row);
}
_tables[sampleEditSelect] = table;
_infos[sampleEditSelect] = infostr;
_samplesControl.SetState(sampleEditSelect, 1);
UpdateInfoTable(sampleEditSelect);
}
private void UpdateInfoTable(int i)
{
var table = _tables[i];
dgvStageInfo.DataSource = table;
}
private void btnDelInfo_Click(object sender, EventArgs e)
{
if (_samplesControl.SelectIndex < 0) return;
var i = _samplesControl.SelectIndex;
_tables[i] = null;
_infos[i] = null;
dgvStageInfo.DataSource = null;
_samplesControl.SetState(i, 0);
}
private bool IsCheck(int id)
{
return (bool)dgvStageInfo.Rows[id].Cells[2].Value;
}
#endregion
#region Work
int _workSampleIndex;
int _workScanIndex;
bool _isWorking;
bool _pause = false;
bool _workDone;
bool _isOnce = false;
bool _restart = false;
ResultModel _resultWorking;
///
/// 聚焦间隔
///
int _focusInterval = 1;
///
/// 蛇形扫描: 0:连续,1:间隔
///
int _mode = 0;
private void btnStart_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(_dirRoot))
{
MessageBox.Show("请选择");
return;
}
var str = cmbProjuctSelect.Text;
if (string.IsNullOrEmpty(str))
{
MessageBox.Show("检测项目不能为空");
return;
}
var item = _checkconfig.Items.First((i) => i.Name == str);
CheckItemChange(item.Value);
var table = _tables[0];
if (table == null)
{
MessageBox.Show("请添加样品信息。");
return;
}
var hasCheck = false;
for (int i = 0; i < table.Rows.Count; i++)
{
hasCheck |= (bool)table.Rows[i][2];
}
if (!hasCheck)
{
MessageBox.Show("请选择检测项。");
return;
}
if (!_isWorking)
{
StartWork();
}
else
{
if (_pause)
{
_restart = rdbReplayAll.Checked;
_isWorking = !_restart;
}
else
{
}
_pause = !_pause;
}
_isOnce = rdbOnlyCurrent.Checked;
}
private void btnStop_Click(object sender, EventArgs e)
{
StopWork();
}
private void StartWork()
{
_workSampleIndex = 0;
_workScanIndex = 0;
_resultCmpAll = new List();
_resultList = new List();
NewWorkDir();
InitAi(_dirCurrent);
Directory.Delete(_dirCurrent);
_isWorking = true;
ResetSmapleState();
new Thread(Runtime).Start();
}
private void PauseWork()
{
_pause = true;
}
private void StopWork()
{
AutoFocusWorkflow.Stop();
_pause = false;
_isWorking = false;
}
private void Runtime()
{
Console.WriteLine("In to work runtime");
while (_isWorking)
{
while (_pause)
{
Thread.Sleep(50);
if (!_isWorking) break;
}
ToWorkStartPoint(_workSampleIndex);
NewWorkDir();
aicontrol.GradePaht = _dirCurrent;
var rule = Startup.instance.ruleDB;
if (rule != null)
{
int mul = (int)rule.gain_multiple;
double umperpx = (double)(rule.physical_length / (decimal)rule.pixel_length);
// aicontrol.StartAndSetGradeParam(catagoryParam.Inclusion, itemParam.Inclusion, jsonParam.InclusionALL, mul, umperpx);
aicontrol.StartAndSetGradeParam((catagoryParam)_detectParams[0], (itemParam)_detectParams[1], (jsonParam)_detectParams[2], mul, umperpx);
}
else
{
aicontrol.StartAndSetGradeParam((catagoryParam)_detectParams[0], (itemParam)_detectParams[1], (jsonParam)_detectParams[2], 1, 1);
}
_samplesControl.SetState(_workSampleIndex, 2);
_scanGird.Reset();
//Scan
ScanSampleWorkflow();
if (!_isWorking) break;
_samplesControl.SetState(_workSampleIndex, 3);
_resultFlag = _workSampleIndex + 1;
EndGrade(_workSampleIndex);
if (_workSampleIndex < _stageSettingNow.WorkPoits.Count - 1)
ToWorkStartPoint(_workSampleIndex + 1);
WaitAiCompleteAll();
_workSampleIndex++;
if (_workSampleIndex >= _stageSettingNow.WorkPoits.Count) break;
}
Console.WriteLine("Out of work runtime.");
//当全部扫码完成退出循环,_isWorking依然为true,则认为完成
_workDone = _isWorking;
StopWork();
if (_restart)
{
_restart = false;
StartWork();
}
}
private void ScanSampleWorkflow()
{
for (; _workScanIndex < NumCol * NumRow && _isWorking; _workScanIndex += 1 + _mode)
{
while (_pause)
{
Thread.Sleep(50);
if (!_isWorking) return;
}
if (_isOnce) _pause = true;
//Console.Write("Before To Next:");
m_stage.WaitMoveDone();
ToNext(Offx, Offy, _workScanIndex);
_scanGird.SetDoning(_workScanIndex, _workScanIndex / (_mode + 1) + 1);
_resultWorking = new ResultModel() { SampleId = _workSampleIndex, ScanId = _workScanIndex, ResultId = _workScanIndex / (_mode + 1) + 1 };
_resultList.Add(_resultWorking);
if (rbtAutoFocus.Checked)
{
if ((_workScanIndex / (_mode + 1) + 1) % _focusInterval == 0)
AutoFocusWorkflow.AutoFocusFast(m_stage, () => _imgNow);
}
SetShoot();
}
_workScanIndex = 0;
}
bool _shootFlag = false;
private void SetShoot()
{
_shootFlag = true;
while (_isWorking && _shootFlag)
{ Thread.Sleep(10); }
}
private void CatchShoot(Bitmap img)
{
_shootFlag = false;
_resultWorking.File = Save(img);
var type = CheckPicBoundary(img);
if (type == 3 || (type == 2 && _checkconfig.Border == 1))
aicontrol.PostFileName(_resultWorking.FileName);
}
class ResultModel
{
public int SampleId;
public int ScanId = -1;
public bool Done;
//public string Result;
string _file;
public string File
{
get => _file;
set
{
_file = value;
var i = value.LastIndexOf('\\');
Dir = value.Substring(0, i + 1);
FileName = value.Substring(i + 1);
}
}
public string Dir;
public string FileName;
public int ResultId;
}
#endregion
#region Move To
float Offx => _stageSettingNow.Width * 1000 / NumCol;
float Offy => _stageSettingNow.Height * 1000 / NumRow;
///
/// 移动到开始位置
///
///
private void ToWorkStartPoint(int i)
{
var p = GetWorkStartPoint(i);
m_stage.To(p.X, p.Y);
}
private PointF GetWorkStartPoint(int i)
{
var x = (_stageSettingNow.WorkPoits[i].X - _stageSettingNow.Width / 2) * 1000;
var y = (_stageSettingNow.WorkPoits[i].Y - _stageSettingNow.Height / 2) * 1000;
return new PointF(x, y);
}
private void ToNext(double offx, double offy, int i)
{
double x = 0, y = 0;
int r = i / NumCol;
int c = i % NumCol;
if (_mode == 0)
{
if (i == 0) ;
else if (c == 0)
y = offy;
else if (r % 2 == 0)
x = offx;
else
x = -offx;
}
if (_mode == 1)
{
if (i == 0) ;
else if (r % 2 == 0)
{
if (c == 0)
{
x = -offx;
y = offy;
}
else if (c == 1)
{
x = offx;
y = offy;
}
else x = 2 * offx;
}
else
{
if (c == 0)
{
x = offx;
y = offy;
}
else if (c == 1)
{
x = -offx;
y = offy;
}
else x = -2 * offx;
}
}
m_stage.Move(x, y);
// Console.Write("To Next:");
m_stage.WaitMoveDone();
}
private void ToScanPoint(int sampleId, int scanId)
{
var p = GetWorkStartPoint(sampleId);
float offx = scanId / NumCol % 2 == 0 ? scanId % NumCol : NumCol - scanId % NumCol - 1;
float offy = (int)(scanId / NumCol);
offx *= Offx;
offy *= Offy;
m_stage.To(p.X + offx, p.Y + offy);
}
#endregion
#region Preview
private void btnPreview_Click(object sender, EventArgs e)
{
PreviewPure.StartPreiew(sender as Button);
}
private TUCamera.TUCamera _camera;
private Bitmap _imgNow;
protected void StartCapture()
{
if (_camera != null)
{
// 开启预览
_camera.m_bufHandler += CallbackDraw;
_camera.StartWaitForFrame();
}
}
public void StopCapture()
{
if (_camera != null)
{
// 开启预览
_camera.m_bufHandler -= CallbackDraw;
_camera.StopWaitForFrame();
}
}
private void CallbackDraw(Bitmap obj)
{
var bmp = (Bitmap)obj.Clone();
if (bmp.PixelFormat == PixelFormat.Format8bppIndexed)
{
ColorPalette palette = bmp.Palette;
for (int i = 0; i < 256; i++)
{
palette.Entries[i] = Color.FromArgb(i, i, i);
}
bmp.Palette = palette;
}
if (_shootFlag)
CatchShoot(bmp);
else
{
try
{
_imgNow = (Bitmap)bmp.Clone();
PreviewPure.ShowPrieview(bmp);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace, ex.Message);
}
}
}
#endregion
#region Save
string _dirRoot;
string DirRoot
{
get => _dirRoot;
set
{
_dirRoot = value;
lblDirectory.Text = value;
try
{
GetDriverInfo(value);
}
catch { }
}
}
string _dirCurrent;
private void btnChangDir_Click(object sender, EventArgs e)
{
if (_isWorking)
return;
var path = SelectFolder();
if (string.IsNullOrEmpty(path)) return;
DirRoot = path;
}
public string SelectFolder()
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
if (string.IsNullOrEmpty(dialog.SelectedPath))
{
// System.Windows.MessageBox.Show("文件夹路径不能为空", "提示");
return null;
}
else
return dialog.SelectedPath;
}
else return null;
}
///
/// 读取硬盘信息
///
/// 盘符
public void GetDriverInfo(string disk)
{
long lsum = 0, ldr = 0;
long gb = 1024 * 1024 * 1024;
DriveInfo drive = new DriveInfo(disk);
lsum = drive.TotalSize / gb;
ldr = drive.TotalFreeSpace / gb;
lblDisk.Width = (int)(lblDisk.Parent.Width - lblDisk.Parent.Width * ldr / lsum);
}
public string Save(Bitmap img)
{
var time = DateTime.Now.ToString("yyyyMMddHHmmss");//日期时间
var id = _workSampleIndex + 1;//工位号
var x = m_stage.X;//坐标x
var y = m_stage.Y;//坐标y
var i = _workScanIndex + 1;//图序号
var stage = _stageSettingName;//样品台名称
var fileName = _dirCurrent + "\\" + string.Format("{0}_{1}_{2}_{3}_{4:f2}_{5:f2}.jpg", time, i, stage, id, x, y);
img.Save(fileName, ImageFormat.Jpeg);
return fileName;
}
///
/// 创建工作目录
///
public void NewWorkDir()
{
this.Invoke(new Action(() =>
{
_dirCurrent = DirRoot + "\\" + DateTime.Now.ToString("yyyyMMddHHmmss");// + "_" + cmbSampleStageList.Text;
Directory.CreateDirectory(_dirCurrent);
}));
}
#endregion
#region Ai Api
AiControl aicontrol;
int _resultFlag = -1;
void InitAi(string dir)
{
aicontrol = new AiControl(dir);
aicontrol.CompleteBatchEvent += Aicontrol_CompleteBatchEvent;
aicontrol.CompleteAllEvent += Aicontrol_CompleteAllEvent;
}
void Aicontrol_CompleteAllEvent(string result)
{
//Console.WriteLine("CompleteAllEvent");
Console.WriteLine("全部完成,结果:" + result);
_resultCmpAll.Add(result);
this.Invoke(new Action(() =>
{
lblResult.Text = JsonHelper.ParseResultString(result);
}));
//ResultList.Add(_resultFlag, resultfilename);
_resultFlag = -1;
//生成报告
}
void Aicontrol_CompleteBatchEvent(List batchfilenames)
{
foreach (var file in batchfilenames)
{
try
{
var result = _resultList.First((r) => r.FileName == file);
_scanGird.SetDone(result.ScanId);
result.Done = true;
}
catch
{
Console.WriteLine("获取结果时发生错误");
}
}
Console.WriteLine("批次完成");
}
void EndGrade(int flag)
{
_resultFlag = flag;
aicontrol.EndGrade();
}
void WaitAiCompleteAll()
{
while (_resultFlag != -1)
{
if (!_isWorking && !_offlineWorking)
_resultFlag = -1;
Thread.Sleep(50);
}
}
#endregion
#region Ai Operate
List _resultList = new List();
int _resultLookId = -1;
int _resultSampleSelect = -1;
int _resultScanSelect = -1;
List _resultCmpAll = new List();
ResultModel ResultSelect => _resultList.FirstOrDefault((r) => r.ResultId == _resultLookId && r.SampleId == _resultSampleSelect);
private void ClearResult()
{
_resultList = new List();
_resultLookId = -1;
_resultSampleSelect = -1;
_resultScanSelect = -1;
_resultCmpAll = new List();
}
private void btnLookBack_Click(object sender, EventArgs e)
{
if (_resultLookId < 1)
return;
try
{
PreviewPure.ShowImage(ResultSelect.File, "查看原图");
}
catch { }
}
private void btnAnalysis_Click(object sender, EventArgs e)
{
if (_resultLookId < 1)
return;
var file = aicontrol.GetImageProcess(ResultSelect.File);
try
{
PreviewPure.ShowImage(file, "分析过程");
}
catch { }
}
private void ShowResult()
{
if (_resultLookId < 1)
{
Console.WriteLine("尚未分析");
return;
}
var result = ResultSelect;
if (result == null || string.IsNullOrEmpty(result.File)) return;
var str = aicontrol.GetImageTestResult(ResultSelect.File);
ConsoleResult(string.IsNullOrEmpty(str) ? "没有结果" : str);
}
private void ConsoleResult(string msg)
{
lblResult.Text = msg;
}
private void UpdateScanGridByResult(int sampleId)
{
try
{
var list = _resultList.Where((r) => r.SampleId == sampleId).ToList();
_resultSampleSelect = sampleId;
_scanGird.Reset();
foreach (var item in list)
{
if (_resultCmpAll[sampleId].Contains(item.FileName))
_scanGird.SetResult(item.ScanId, item.ResultId);
else if (item.Done)
{
_scanGird.SetDone(item.ScanId, item.ResultId);
}
else
{
_scanGird.SetDoning(item.ScanId, item.ResultId);
}
}
lblResult.Text = JsonHelper.ParseResultString(_resultCmpAll[sampleId]);
}
catch { }
}
private void btnLocate_Click(object sender, EventArgs e)
{
if (!_isWorking)
{
if (_resultSampleSelect > -1 && _resultScanSelect > -1)
ToScanPoint(_resultSampleSelect, _resultScanSelect);
}
}
private void btnReport_Click(object sender, EventArgs e)
{
var result = new List();
AutoAnalysisReportDialog reportDialog = new AutoAnalysisReportDialog(this, "自动分析", result);
if (reportDialog.hasModule)
{
reportDialog.StartPosition = FormStartPosition.CenterScreen;
reportDialog.ExportReport = ExportReport;
reportDialog.ShowDialog();
}
else
{
reportDialog = null;
}
}
void ExportReport()
{ //获取word书签与excel单元格的关系,以字典方式存储
List infos = mic_module_infos_BLL.FindAll().FindAll(a => a.analyze_classify == this.analyzeSettingModel.analyzeClassify);
Dictionary tagInfos = new Dictionary();
if (infos != null && infos.Count > 0)
{
foreach (mic_module_infos info in infos)
{
tagInfos.Add(info.tag_name, info.cell_position);
}
}
List> inclusionList = new List>();
List inclusionHead = new List();
List bitList = new List();
for (int i = 0; i < _resultCmpAll.Count; i++)
{
var item = _resultCmpAll[i];
var list = new List();
var rStr = JsonHelper.ParseResultString(item);
list.Add("样品" + (i + 1) + ", 测试结果:");
list.Add(rStr);
inclusionList.Add(list);
if (string.IsNullOrEmpty(rStr)) continue;
list = rStr.Split(';').ToList();
var dict = JsonHelper.ParseResultArray(item);
foreach (var head in list)
{
var list1 = dict[head];
foreach (var f in list1)
{
var list2 = new List();
list2.Add(head);
list2.Add(f);
inclusionList.Add(list2);
}
}
}
_app.CreateAnalysisReport(AnalyzeSettingModel, inclusionList, bitList, tagInfos);
}
#endregion
#region Offline work
bool _offlineWorking = false;
string _srcDir = "";
List _srcList = new List();
double _x;
double _y;
void InitOfflineTest()
{
}
private void btnOfflineTest_Click(object sender, EventArgs e)
{
if (_offlineWorking)
{
StopWorkOffline();
btnOfflineTest.Text = "脱机运行";
return;
}
_srcDir = SelectFolder();
if (string.IsNullOrEmpty(_srcDir))
return;
_srcList = Directory.GetFiles(_srcDir).ToList();
if (string.IsNullOrEmpty(_dirRoot))
{
MessageBox.Show("Please select a dir first.");
return;
}
StartWorkOffline(); btnOfflineTest.Text = "停止";
}
void StartWorkOffline()
{
_offlineWorking = true;
_workSampleIndex = 0;
_workScanIndex = 0;
NewWorkDir();
InitAi(_dirCurrent);
//_sampleStage.Reset();
new Thread(RunTimeOffline).Start();
}
void StopWorkOffline()
{
_offlineWorking = false;
}
private void RunTimeOffline()
{
while (_offlineWorking)
{
if (_srcList.Count < NumCol * NumRow * (_workSampleIndex + 1))
{
_offlineWorking = false;
return;
}
_x = _stageSettingNow.WorkPoits[_workSampleIndex].X * 1000;
_y = _stageSettingNow.WorkPoits[_workSampleIndex].Y * 1000;
//_scanGird.Reset();
//_sampleStage.SetState(_sampleIndex, 2);
Console.WriteLine("样品" + (_workSampleIndex + 1) + "开始");
// aicontrol.StartAndSetGradeParam(cat, item, json, 100, 0.2755);
OfflineWorkflow();
EndGrade(_workSampleIndex);
Console.WriteLine("扫描完成");
WaitAiCompleteAll();
//_sampleStage.SetState(_sampleIndex, 3);
_workSampleIndex++;
//_offlineWorking = false;
if (_workSampleIndex >= _stageSettingNow.WorkPoits.Count)
_offlineWorking = false;
}
}
private void OfflineWorkflow()
{
var offx = _stageSettingNow.Width * 1000 / NumCol;
var offy = _stageSettingNow.Height * 1000 / NumRow;
for (int i = _workScanIndex; i < NumCol * NumRow && _offlineWorking; i++)
{
_workScanIndex = i;
int r = i / NumCol;
int c = i % NumCol;
if (i == 0) ;
else if (c == 0)
_y += offy;
else if (r % 2 == 0)
_x += offx;
else
_x -= offx;
Thread.Sleep(300);
aicontrol.PostFileName(CopyFile());
//_scanGird.SetDone(r * NumCol + c);
}
_workScanIndex = 0;
}
private string CopyFile()
{
var file = _srcList[_workScanIndex + NumCol * NumRow * _workSampleIndex];
var disFile = CreateFileOffline();
File.Copy(file, _dirCurrent + "\\" + disFile);
return disFile;
}
private string CreateFileOffline()
{
var time = DateTime.Now.ToString("yyyyMMddHHmmss");//日期时间
var id = _workSampleIndex;//工位号
var i = _workScanIndex + 1;//图序号
var stage = _stageSettingName;//样品台名称
var fileName = string.Format("{0}_{1}_{2}_{3}_{4}_{5}.jpg", time, i, stage, id, _x, _y);
return fileName;
}
#endregion
#region Stage Event
public void OnUpdatePosition()
{
}
public void OnTimeoutConnect()
{
btnStart.Enabled = false;
StopWork();
}
public void OnErrorSend()
{
}
#endregion
private void cmbScanMode_SelectedIndexChanged(object sender, EventArgs e)
{
_mode = cmbScanMode.SelectedIndex;
}
private void cmbAutoFocusParm_SelectedIndexChanged(object sender, EventArgs e)
{
int.TryParse(cmbAutoFocusParm.Text, out _focusInterval);
}
///
/// 是否包含胶体
/// 1、全胶体
/// 2、部分胶体
/// 3、无胶体
///
/// 源图像
///
private unsafe int CheckPicBoundary(Bitmap source)
{
int type = 3;
Mat gray = null;
try
{
var mat = BitmapConverter.ToMat(source);
if (mat.Channels() == 3)
gray = mat.CvtColor(ColorConversionCodes.BGR2GRAY);
else gray = mat;
gray.ForEachAsByte(this.Gray_ForEachAsByte);
OpenCvSharp.Point leftTop = new OpenCvSharp.Point(0, 0);
OpenCvSharp.Point rightTop = new OpenCvSharp.Point(gray.Width - 1, 0);
OpenCvSharp.Point leftBottom = new OpenCvSharp.Point(0, gray.Height - 1);
OpenCvSharp.Point rightBottom = new OpenCvSharp.Point(gray.Width - 1, gray.Height - 1);
byte leftTopV = gray.At(0, 0);
byte rightTopV = gray.At(0, gray.Width - 1);
byte leftBottomV = gray.At(gray.Height - 1, 0);
byte rightBottomV = gray.At(gray.Height - 1, gray.Width - 1);
Rect rect;
int leftTopNum = 0, rightTopNum = 0, leftBottomNum = 0, rightBottomNum = 0;
if (leftTopV == 0) leftTopNum = Cv2.FloodFill(gray, leftTop, new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
if (rightTopV == 0) rightTopNum = Cv2.FloodFill(gray, rightTop, new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
if (leftBottomV == 0) leftBottomNum = Cv2.FloodFill(gray, leftBottom, new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
if (rightBottomV == 0) rightBottomNum = Cv2.FloodFill(gray, rightBottom, new Scalar(0), out rect, null, null, FloodFillFlags.Link8);
if (leftTopNum == 0 && rightTopNum == 0 && leftBottomNum == 0 && rightBottomNum == 0)
{
type = 3;
}
else if (leftTopNum > 0 && rightTopNum > 0 && leftBottomNum > 0 && rightBottomNum > 0)
{
type = 1;
}
else
{
if (leftTopNum > 10000 || rightTopNum > 10000 || leftBottomNum > 10000 || rightBottomNum > 10000)
{
type = 2;
}
}
}
catch (Exception)
{
}
finally
{
if (gray != null)
{
gray.Dispose();
GC.Collect();
}
}
return type;
}
private unsafe void Gray_ForEachAsByte(byte* value, int* position)
{
int y = position[0];
int x = position[1];
if (*value <= 90)
{
*value = 0;
}
else
{
*value = 255;
}
}
}
}