using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.IO; using System.Reflection; using System.Threading; using System.Windows.Forms; using Flir.Atlas.Image; using Flir.Atlas.Live.Device; using Flir.Atlas.Live.Discovery; using Newtonsoft.Json; using Thermo.Cam.Utils; namespace Thermo.Cam.Setup { public partial class MainForm : Form { #region Protected Fields protected int currPoint = -1; /// /// Classe gestione ThermoCam (oggetti Image, metodi processing...) x FlirCam /// protected TCContr TCamCtrl = new TCContr($"{BASE_PATH}\\images\\", BASE_PATH); #endregion Protected Fields #region Public Fields public static readonly string BASE_PATH = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); #endregion Public Fields #region Public Constructors public MainForm() { InitializeComponent(); // collego eventi ImgData TCamCtrl.eh_CameraConnected += ImgData_eh_CameraConnected; TCamCtrl.eh_CameraDisposed += ImgData_eh_CameraDisposed; TCamCtrl.eh_CameraConnStatusChanged += ImgData_eh_CameraConnStatusChanged; // cerco se ho un set di parametri già impostati... TCamCtrl.tryReloadConf(); // sistemo le conf temp setRangeTemp(); // calcolo i currConf.destPoints updateDestPt(); setTimerInterval(); timerUI.Start(); // cerco camera TCamCtrl.discoveryCamera(); // aspetto 500 msec... Thread.Sleep(500); } #endregion Public Constructors #region Private Properties private bool liveView { get { return chkLive.Checked; } set { chkLive.Checked = value; } } #endregion Private Properties #region Protected Properties protected int dimX { get { int answ = 100; int.TryParse(txtAB.Text, out answ); TCamCtrl.currConf.TargetSize.X = answ; return answ; } set { TCamCtrl.currConf.TargetSize.X = value; txtAB.Text = $"{value}"; } } protected int dimY { get { int answ = 100; int.TryParse(txtBC.Text, out answ); TCamCtrl.currConf.TargetSize.Y = answ; return answ; } set { TCamCtrl.currConf.TargetSize.Y = value; txtBC.Text = $"{value}"; } } protected double maxRangeTemp { get { double answ = 1000; double.TryParse(txtMaxScale.Text, out answ); return answ; } set { txtMaxScale.Text = $"{value:N0}"; } } protected double minRangeTemp { get { double answ = 0; double.TryParse(txtMinScale.Text, out answ); return answ; } set { txtMinScale.Text = $"{value:N0}"; } } protected bool pointSetup { get { return chkPointSetup.Checked; } set { chkPointSetup.Checked = value; } } protected bool readTemp { get { return chkReadTemp.Checked; } set { chkReadTemp.Checked = value; } } protected int SamplePeriod { get { int answ = 100; int.TryParse(txtSPeriod.Text, out answ); return answ; } set { txtSPeriod.Text = $"{value}"; } } protected bool saveEnabled { get { return chkSaveAll.Checked; } set { chkSaveAll.Checked = value; } } protected bool showTransfBig { get { return chkShowTransfBig.Checked; } set { chkShowTransfBig.Checked = value; } } #endregion Protected Properties #region Public Properties public object ConfigurationManager { get; private set; } #endregion Public Properties #region Private Methods private void btnDeleteOlder_Click(object sender, EventArgs e) { int maxHours = 90 * 24; int.TryParse(txtMaxHours.Text, out maxHours); TCamCtrl.cleanDataDir(maxHours); } private void btnExportConfig_Click(object sender, EventArgs e) { // effettua esportazione config in area ThermoActive string ThermoConfPath = System.Configuration.ConfigurationManager.AppSettings["ThermoConfPath"]; if (!Directory.Exists(ThermoConfPath)) { Directory.CreateDirectory(ThermoConfPath); } // salvo conf corrente TCamCtrl.saveConf(); // salvo in folder target TCamCtrl.saveConf(ThermoConfPath); // info export fatto lblExportInfo.Text = $"{DateTime.Now} Configuration exported!"; } private void btnLoad_Click(object sender, EventArgs e) { // "" --> carica ultima scattata (altrimenti nome) TCamCtrl.fileLoad(""); // aggiorno visualizzazione processImage(); refreshDisplay(); } private void btnReset_Click(object sender, EventArgs e) { pointSetup = true; TCamCtrl.currConf.OrigPoints = new SetPoints(); } private void btnResetPoint_Click(object sender, EventArgs e) { TCamCtrl.resetMeasurePoints(); } private void btnSave_Click(object sender, EventArgs e) { TCamCtrl.takePicture(); processImage(); refreshDisplay(); // salvo immagini TCamCtrl.fileSave(); } private void checkLive_CheckedChanged(object sender, EventArgs e) { setTimerInterval(); } private void chkPointSetup_CheckedChanged(object sender, EventArgs e) { // deselezione Get Temp if (readTemp) { readTemp = false; } } private void chkReadTemp_CheckedChanged(object sender, EventArgs e) { // deselezione setup punti if (pointSetup) { pointSetup = false; } } private void chkShowOrig_CheckedChanged(object sender, EventArgs e) { refreshDisplay(); } private void disconnectToolStripMenuItem_Click(object sender, EventArgs e) { TCamCtrl.DisconnectCamera(); } private void discoveryToolStripMenuItem_Click(object sender, EventArgs e) { var discoveryDlg = new DiscoveryForm(); if (discoveryDlg.ShowDialog() == DialogResult.OK) { TCamCtrl.ConnectCamera(discoveryDlg.SelectedCameraDevice); // salvo nome camera in conf attuale! TCamCtrl.currConf.CameraName = discoveryDlg.SelectedCameraDevice.Name; if (discoveryDlg.SelectedCameraDevice.IpSettings != null) { TCamCtrl.currConf.CameraAddress = discoveryDlg.SelectedCameraDevice.IpSettings.IpAddress; } TCamCtrl.saveConf(); } } private void displayImages() { if (TCamCtrl.Thermal != null) { try { lblImgA.Text = showTransfBig ? "FINAL image" : "ORIGINAL image"; lblImgB.Text = showTransfBig ? "ORIGINAL image" : "FINAL image"; pBoxA.Image = showTransfBig ? TCamCtrl.ColorTransf : TCamCtrl.Decorated; pBoxB.Image = showTransfBig ? TCamCtrl.Decorated : TCamCtrl.ColorTransf; } catch (Exception exc) { Console.WriteLine($"EXCEPTION displayImage: {Environment.NewLine}{exc}"); } } } private void ImgData_eh_CameraConnected(object sender, EventArgs e) { setTimerInterval(); } private void ImgData_eh_CameraConnStatusChanged(object sender, Flir.Atlas.Live.ConnectionStatusChangedEventArgs e) { try { BeginInvoke((Action)(() => toolStripConnectionStatus.Text = e.Status.ToString())); BeginInvoke((Action)(() => toolStripConnectionStatus.ForeColor = e.Status == ConnectionStatus.Connected ? Color.Green : Color.Gray)); BeginInvoke((Action)(() => cameraToolStripMenuItem.Enabled = e.Status == ConnectionStatus.Connected)); BeginInvoke((Action)(() => chkLive.Checked = e.Status == ConnectionStatus.Connected)); } catch { } } private void ImgData_eh_CameraDisposed(object sender, EventArgs e) { setTimerInterval(); } private void lblOrigA_Click(object sender, EventArgs e) { lblOrigA.ForeColor = toggleEditPoint(0); } private void lblOrigB_Click(object sender, EventArgs e) { lblOrigB.ForeColor = toggleEditPoint(1); } private void lblOrigC_Click(object sender, EventArgs e) { lblOrigC.ForeColor = toggleEditPoint(2); } private void lblOrigD_Click(object sender, EventArgs e) { lblOrigD.ForeColor = toggleEditPoint(3); } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { timerUI.Stop(); TCamCtrl.stopDiscovery(); TCamCtrl.DisconnectCamera(); TCamCtrl.DisposeCamera(); } private void MainForm_Load(object sender, EventArgs e) { } private void MainForm_Shown(object sender, EventArgs e) { } private void pictureBox1_Click(object sender, EventArgs e) { // calcolo la ratio img originale --> pictureBox double ratio = 1; try { if (TCamCtrl.Origin != null && TCamCtrl.ColorTransf.Width > 0 && TCamCtrl.Origin.Width > 0) { int denom = showTransfBig ? TCamCtrl.ColorTransf.Width : TCamCtrl.Origin.Width; ratio = (double)pBoxA.Width / denom; } } catch { } // trasformo punto in equivalente originale var mea = (MouseEventArgs)e; var clickPoint = new Point() { X = (int)(mea.X / ratio), Y = (int)(mea.Y / ratio) }; // se sono nell'immagine originale if (!showTransfBig) { TCamCtrl.lastPoint = clickPoint; } else { // altrimenti antitrasformata... List point2fix = new List(); point2fix.Add(clickPoint); var revPoint = TCamCtrl.reversePoint(point2fix); if (revPoint.Count > 0) { TCamCtrl.lastPoint = revPoint[0]; } } // indico punto rilevato e trasformato lblPoint.Text = $"({mea.X},{mea.Y}) --> ({TCamCtrl.lastPoint.X},{TCamCtrl.lastPoint.Y})"; if (pointSetup) { // max 4 punti... se sono già FULL --> imposto singolo valore nuovo if (TCamCtrl.currConf.OrigPoints.curr >= 4) { if (currPoint >= 0) { TCamCtrl.currConf.OrigPoints.Coords[currPoint] = TCamCtrl.lastPoint; } else { TCamCtrl.currConf.OrigPoints = new SetPoints(); } } else { // salvo coordinate in base al num corrente... try { TCamCtrl.currConf.OrigPoints.Coords.Add(TCamCtrl.lastPoint); TCamCtrl.currConf.OrigPoints.curr++; } catch { } } // salvo conf TCamCtrl.saveConf(); // aggiorno visualizzazione processImage(); refreshDisplay(); } else if (readTemp) { // accodo! TCamCtrl.addMeasurePoint(true); // aggiorno visualizzazione processImage(); refreshDisplay(); } } private void processImage() { // disegno immagine TCamCtrl.getTemperatures(readTemp); TCamCtrl.calculateTarget(); } private void refreshDisplay() { TCamCtrl.drawCrossAtPoints(); displayImages(); updateDisplay(); updateTempDisplay(); updateStatDisplay(); } /// /// Sistema le temp range min/Max /// private void setRangeTemp() { TCamCtrl.currConf.TargetRange.Min = minRangeTemp; TCamCtrl.currConf.TargetRange.Max = maxRangeTemp; } private void setTimerInterval() { // cambio periodo timer! timerUI.Interval = chkLive.Checked ? SamplePeriod : SamplePeriod * 4; } private void timerUI_Tick(object sender, EventArgs e) { updateForm(); } /// /// Verifica se il punto era in edit, altrimenti segnala e lo attiva... restituendo colore x il controllo /// /// private Color toggleEditPoint(int selPoint) { Color answ = Color.Black; lblOrigA.ForeColor = answ; lblOrigB.ForeColor = answ; lblOrigC.ForeColor = answ; lblOrigD.ForeColor = answ; readTemp = false; pointSetup = true; if (currPoint == selPoint) { // deseleziono currPoint = -1; } else { // indico selezionato currPoint = selPoint; answ = Color.Green; } return answ; } private void txtAB_TextChanged(object sender, EventArgs e) { // ricalcolo in proporzione altro valore... dimY = (int)((double)dimX * 256 / 320); // aggiorno punti dest updateDestPt(); } private void txtBC_TextChanged(object sender, EventArgs e) { // ricalcolo in proporzione altro valore... dimX = (int)((double)dimY * 320 / 256); // aggiorno punti dest updateDestPt(); } private void txtMaxScale_TextChanged(object sender, EventArgs e) { setRangeTemp(); } private void txtMinScale_TextChanged(object sender, EventArgs e) { setRangeTemp(); } private void updateDestPt() { TCamCtrl.currConf.DestPoints.Coords = new List(); // ciclo i punti A-B-C-D... TCamCtrl.currConf.DestPoints.Coords.Add(new Point() { X = 0, Y = 0 }); TCamCtrl.currConf.DestPoints.Coords.Add(new Point() { X = dimX, Y = 0 }); TCamCtrl.currConf.DestPoints.Coords.Add(new Point() { X = dimX, Y = dimY }); TCamCtrl.currConf.DestPoints.Coords.Add(new Point() { X = 0, Y = dimY }); // salvo conf TCamCtrl.saveConf(); } private void updateDisplay() { string textA = "A"; string textB = "B"; string textC = "C"; string textD = "D"; // popolo if (TCamCtrl.currConf.OrigPoints.Coords.Count > 0) { textA = $"A: ({TCamCtrl.currConf.OrigPoints.Coords[0].X},{TCamCtrl.currConf.OrigPoints.Coords[0].Y})"; } if (TCamCtrl.currConf.OrigPoints.Coords.Count > 1) { textB = $"B: ({TCamCtrl.currConf.OrigPoints.Coords[1].X},{TCamCtrl.currConf.OrigPoints.Coords[1].Y})"; } if (TCamCtrl.currConf.OrigPoints.Coords.Count > 2) { textC = $"C: ({TCamCtrl.currConf.OrigPoints.Coords[2].X},{TCamCtrl.currConf.OrigPoints.Coords[2].Y})"; } if (TCamCtrl.currConf.OrigPoints.Coords.Count > 3) { textD = $"D: ({TCamCtrl.currConf.OrigPoints.Coords[3].X},{TCamCtrl.currConf.OrigPoints.Coords[3].Y})"; TCamCtrl.calculateTarget(); } lblOrigA.Text = textA; lblOrigB.Text = textB; lblOrigC.Text = textC; lblOrigD.Text = textD; } private void updateForm() { // se è in live view --> continuo if (liveView) { TCamCtrl.takePicture(); processImage(); refreshDisplay(); // salvo immagini if (saveEnabled) { TCamCtrl.fileSave(); } } // avanzo prog bar progBar.Increment(5); if (progBar.Value >= progBar.Maximum) { progBar.Value = 0; } } private void updateStatDisplay() { if (TCamCtrl.ExTime.Stats.Count > 0) { try { lblStats.Text = $"Camera: {TCamCtrl.lastStatTime("ImageAcquisition")}ms | Color + Persp {TCamCtrl.lastStatTime("ImageColor")}ms | Points {TCamCtrl.lastStatTime("AddPoints")}ms | Measures {TCamCtrl.lastStatTime("GetAllTemperatures")}ms"; } catch (Exception exc) { Console.WriteLine($"EXCEPTION updateStatDisplay{Environment.NewLine}{exc}"); } } } private void updateTempDisplay() { if (TCamCtrl.Thermal != null) { if (readTemp) { try { // mostro TUTTE le misure... lstView.Items.Clear(); foreach (var item in TCamCtrl.currConf.MeasPoints) { var listViewItem = new ListViewItem(); listViewItem.Text = $"{item.Id}"; listViewItem.SubItems.Add($"{item.Coords.X},{item.Coords.Y}"); listViewItem.SubItems.Add($"{item.Temperature:N2}"); lstView.Items.Add(listViewItem); } // mostro minimo / massimo lblMinTemp.Text = $"{TCamCtrl.lastTempRange.Minimum:N2}"; lblMaxTemp.Text = $"{TCamCtrl.lastTempRange.Maximum:N2}"; } catch (Exception exc) { Console.WriteLine($"EXCEPTION updateTempDisplay{Environment.NewLine}{exc}"); } } } } #endregion Private Methods } }