958 lines
30 KiB
C#
958 lines
30 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Windows.Forms;
|
|
using Flir.Atlas.Image;
|
|
using Flir.Atlas.Live.Device;
|
|
using Flir.Atlas.Live.Discovery;
|
|
using Newtonsoft.Json;
|
|
using ThermoCamUtils;
|
|
|
|
namespace ThermalImageStreamerDemo
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
#region Private Fields
|
|
|
|
private const string FileFilter = "IR Image Files(*.jpg;*.img;*.seq;*.fcf)|*.jpg;*.img;*.seq;*.fcf|All files (*.*)|*.*";
|
|
|
|
private readonly Timer _timerRefreshUi = new Timer();
|
|
|
|
#if false
|
|
private Camera IRCam.ThermoCamera;
|
|
#endif
|
|
|
|
private RecorderForm _recorder;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Protected Fields
|
|
|
|
protected const string colorPath = "images\\Color";
|
|
|
|
protected const string confFileName = "ThermoConf.json";
|
|
|
|
protected const string currImgFile = "ThermalData.jpg";
|
|
|
|
protected const string thermPath = "images\\Therm";
|
|
|
|
/// <summary>
|
|
/// Ultimo range di temperature osservato
|
|
/// </summary>
|
|
protected Range<double> _lastTempRange = new Range<double>(-999, 5000);
|
|
|
|
protected int currPoint = -1;
|
|
|
|
/// <summary>
|
|
/// Contenitore oggetti Image x FlirCam
|
|
/// </summary>
|
|
protected ImageData ImgData = new ImageData();
|
|
|
|
#if false
|
|
protected double lastCalcTemp = 0;
|
|
|
|
protected Point ImgData.lastPoint = new Point();
|
|
|
|
protected double lastReadTemp = 0;
|
|
#endif
|
|
|
|
protected double msLastCam = 0;
|
|
|
|
protected double msLastCol = 0;
|
|
|
|
protected double msLastMsr = 0;
|
|
|
|
protected double msLastPts = 0;
|
|
|
|
protected double msLastTra = 0;
|
|
|
|
protected Point refTempPoint = new Point();
|
|
|
|
protected Stopwatch sw = new Stopwatch();
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Public Fields
|
|
|
|
// Config File Names
|
|
public static readonly string BASE_PATH = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
|
|
|
#endregion Public Fields
|
|
|
|
#region Public Constructors
|
|
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
_timerRefreshUi.Interval = 100;
|
|
_timerRefreshUi.Tick += _timerRefreshUi_Tick;
|
|
// cerco se ho un set di parametri già impostati...
|
|
tryReloadConf();
|
|
// calcolo i currConf.destPoints
|
|
updateDestPt();
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Private Properties
|
|
|
|
private bool IsDirty { get; set; }
|
|
|
|
private bool liveView
|
|
{
|
|
get
|
|
{
|
|
return checkLive.Checked;
|
|
}
|
|
set
|
|
{
|
|
checkLive.Checked = value;
|
|
}
|
|
}
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Protected Properties
|
|
|
|
protected string confPath
|
|
{
|
|
get
|
|
{
|
|
// se esiste il file... path assoluto
|
|
string answ = confFileName;
|
|
if (!Path.IsPathRooted(answ))
|
|
{
|
|
answ = BASE_PATH + "\\" + confFileName;
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
protected ThermoCamConf currConf
|
|
{
|
|
get
|
|
{
|
|
return ImgData.currConf;
|
|
}
|
|
set
|
|
{
|
|
ImgData.currConf = value;
|
|
}
|
|
}
|
|
|
|
protected int dimX
|
|
{
|
|
get
|
|
{
|
|
int answ = 100;
|
|
int.TryParse(txtAB.Text, out answ);
|
|
currConf.TargetSize.X = answ;
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
currConf.TargetSize.X = value;
|
|
txtAB.Text = $"{value}";
|
|
}
|
|
}
|
|
|
|
protected int dimY
|
|
{
|
|
get
|
|
{
|
|
int answ = 100;
|
|
int.TryParse(txtBC.Text, out answ);
|
|
currConf.TargetSize.Y = answ;
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
currConf.TargetSize.Y = value;
|
|
txtBC.Text = $"{value}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ultimo range di temperature osservato
|
|
/// </summary>
|
|
protected Range<double> lastTempRange
|
|
{
|
|
get
|
|
{
|
|
return _lastTempRange;
|
|
}
|
|
set
|
|
{
|
|
_lastTempRange = value;
|
|
lblMinTemp.Text = $"{value.Minimum:N2}";
|
|
lblMaxTemp.Text = $"{value.Maximum:N2}";
|
|
}
|
|
}
|
|
|
|
protected double maxScale
|
|
{
|
|
get
|
|
{
|
|
double answ = 1000;
|
|
double.TryParse(txtMaxScale.Text, out answ);
|
|
currConf.TargetRange.Max = answ;
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
currConf.TargetRange.Max = value;
|
|
txtMaxScale.Text = $"{value:N0}";
|
|
}
|
|
}
|
|
|
|
protected double minScale
|
|
{
|
|
get
|
|
{
|
|
double answ = 0;
|
|
double.TryParse(txtMinScale.Text, out answ);
|
|
currConf.TargetRange.Min = answ;
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
currConf.TargetRange.Min = value;
|
|
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 bool saveEnabled
|
|
{
|
|
get
|
|
{
|
|
return chkSaveAll.Checked;
|
|
}
|
|
set
|
|
{
|
|
chkSaveAll.Checked = value;
|
|
}
|
|
}
|
|
|
|
protected bool showOrigBig
|
|
{
|
|
get
|
|
{
|
|
return chkShowOrig.Checked;
|
|
}
|
|
set
|
|
{
|
|
chkShowOrig.Checked = value;
|
|
}
|
|
}
|
|
|
|
#endregion Protected Properties
|
|
|
|
#region Private Methods
|
|
|
|
private void _recorder_SelectedFileMouseDoubleClick(object sender, SelectedFileEventArgs e)
|
|
{
|
|
var playback = new PlaybackForm(e.FilePath);
|
|
playback.Show();
|
|
}
|
|
|
|
private void _timerRefreshUi_Tick(object sender, EventArgs e)
|
|
{
|
|
// se è in live view --> continuo
|
|
if (liveView)
|
|
{
|
|
takePicture(saveEnabled);
|
|
processImage();
|
|
refreshDisplay();
|
|
}
|
|
// avanzo prog bar
|
|
progBar.Increment(3);
|
|
if (progBar.Value >= progBar.Maximum)
|
|
{
|
|
progBar.Value = 0;
|
|
}
|
|
}
|
|
|
|
private void btnLoad_Click(object sender, EventArgs e)
|
|
{
|
|
string dirPath = $"{BASE_PATH}\\{thermPath}";
|
|
string filePath = $"{dirPath}\\{currImgFile}";
|
|
if (File.Exists(filePath))
|
|
{
|
|
try
|
|
{
|
|
ImgData.Thermal = new ThermalImageFile(filePath);
|
|
ImgData.Thermal.TemperatureUnit = TemperatureUnit.Celsius;
|
|
ImgData.Thermal.Scale.IsAutoAdjustEnabled = true;
|
|
// carico DIRETTAMENTE da file...
|
|
ImgData.Origin = (Bitmap)Image.FromFile(filePath);
|
|
ImgData.Decorated = (Bitmap)Image.FromFile(filePath);
|
|
|
|
// aggiorno visualizzazione
|
|
processImage();
|
|
refreshDisplay();
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
|
|
private void btnReset_Click(object sender, EventArgs e)
|
|
{
|
|
pointSetup = true;
|
|
currConf.origPoints = new SetPoints();
|
|
}
|
|
|
|
private void btnSave_Click(object sender, EventArgs e)
|
|
{
|
|
takePicture(true);
|
|
processImage();
|
|
refreshDisplay();
|
|
}
|
|
|
|
private void Camera_ConnectionStatusChanged(object sender, Flir.Atlas.Live.ConnectionStatusChangedEventArgs e)
|
|
{
|
|
BeginInvoke((Action)(() => toolStripConnectionStatus.Text = e.Status.ToString()));
|
|
BeginInvoke((Action)(() => cameraToolStripMenuItem.Enabled = e.Status == ConnectionStatus.Connected));
|
|
// se si disconnette --> NUOVA richiesta connessione alla CHILD...
|
|
|
|
// TODO FARE!!!
|
|
}
|
|
|
|
private void checkLive_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
// non serve fare nulla
|
|
}
|
|
|
|
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;
|
|
}
|
|
if (!readTemp)
|
|
{
|
|
lblReadTemp.Text = "? °C";
|
|
lblTempRGB.Text = "? °C";
|
|
}
|
|
}
|
|
|
|
private void ConnectCamera(CameraDeviceInfo cameraDeviceInfo)
|
|
{
|
|
DisposeCamera();
|
|
switch (cameraDeviceInfo.SelectedStreamingFormat)
|
|
{
|
|
case ImageFormat.FlirFileFormat:
|
|
IRCam.ThermoCamera = new ThermalCamera();
|
|
break;
|
|
|
|
case ImageFormat.Argb:
|
|
IRCam.ThermoCamera = new VideoOverlayCamera();
|
|
break;
|
|
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
IRCam.ThermoCamera.ConnectionStatusChanged += Camera_ConnectionStatusChanged;
|
|
IRCam.ThermoCamera.GetImage().Changed += Image_Changed;
|
|
IRCam.ThermoCamera.Connect(cameraDeviceInfo);
|
|
if (IRCam.ThermoCamera.Recorder == null && _recorder != null)
|
|
{
|
|
_recorder.Dispose();
|
|
_recorder = null;
|
|
}
|
|
if (_recorder != null)
|
|
{
|
|
if (!_recorder.IsDisposed)
|
|
_recorder.Initialize(IRCam.ThermoCamera);
|
|
}
|
|
recorderToolStripMenuItem.Enabled = IRCam.ThermoCamera.Recorder != null;
|
|
_timerRefreshUi.Start();
|
|
}
|
|
|
|
private void DisconnectCamera()
|
|
{
|
|
if (IRCam.ThermoCamera == null) return;
|
|
|
|
IRCam.ThermoCamera.Disconnect();
|
|
}
|
|
|
|
private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
DisconnectCamera();
|
|
}
|
|
|
|
private void discoveryToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var discoveryDlg = new DiscoveryForm();
|
|
if (discoveryDlg.ShowDialog() == DialogResult.OK)
|
|
{
|
|
ConnectCamera(discoveryDlg.SelectedCameraDevice);
|
|
// salvo nome camera in conf attuale!
|
|
currConf.CameraName = discoveryDlg.SelectedCameraDevice.Name;
|
|
saveConf();
|
|
}
|
|
}
|
|
|
|
private void displayImages()
|
|
{
|
|
if (ImgData.Thermal != null)
|
|
{
|
|
lblImgA.Text = showOrigBig ? "ORIGINAL image" : "FINAL image";
|
|
lblImgB.Text = showOrigBig ? "FINAL image" : "ORIGINAL image";
|
|
|
|
pBoxA.Image = showOrigBig ? ImgData.ColorTransf : ImgData.Decorated;
|
|
pBoxB.Image = showOrigBig ? ImgData.Decorated : ImgData.ColorTransf;
|
|
pBoxC.Image = ImgData.GrayTransf;
|
|
}
|
|
}
|
|
|
|
private void DisposeCamera()
|
|
{
|
|
_timerRefreshUi.Stop();
|
|
if (IRCam.ThermoCamera == null) return;
|
|
if (_recorder != null)
|
|
{
|
|
_recorder.UnInitialize();
|
|
_recorder.Dispose();
|
|
}
|
|
IRCam.ThermoCamera.ConnectionStatusChanged -= Camera_ConnectionStatusChanged;
|
|
IRCam.ThermoCamera.GetImage().Changed -= Image_Changed;
|
|
IRCam.ThermoCamera.Dispose();
|
|
}
|
|
|
|
private void drawCrossAtPoints()
|
|
{
|
|
if (ImgData.Thermal != null)
|
|
{
|
|
sw.Restart();
|
|
// se ho dei punti x trasformazione --> disegno
|
|
if (currConf.origPoints.curr > 0)
|
|
{
|
|
foreach (var item in currConf.origPoints.Coords)
|
|
{
|
|
drawPoint(Color.Green, item);
|
|
}
|
|
}
|
|
// se ho punto acquisizione temp --> disegno!
|
|
if (refTempPoint != null)
|
|
{
|
|
drawPoint(Color.Blue, refTempPoint);
|
|
}
|
|
sw.Stop();
|
|
msLastPts = sw.ElapsedMilliseconds;
|
|
}
|
|
}
|
|
|
|
private void drawPoint(Color currColor, Point currPoint)
|
|
{
|
|
// disegno!
|
|
using (Graphics gr = Graphics.FromImage(ImgData.Decorated))
|
|
{
|
|
gr.SmoothingMode = SmoothingMode.AntiAlias;
|
|
|
|
Point[] crsPoints = new Point[4];
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
crsPoints[i] = currPoint;
|
|
}
|
|
crsPoints[0].X = crsPoints[0].X - 4;
|
|
crsPoints[1].X = crsPoints[1].X + 4;
|
|
crsPoints[2].Y = crsPoints[2].Y - 4;
|
|
crsPoints[3].Y = crsPoints[3].Y + 4;
|
|
|
|
using (Pen thick_pen = new Pen(currColor, 1))
|
|
{
|
|
gr.DrawLine(thick_pen, crsPoints[0], crsPoints[1]);
|
|
gr.DrawLine(thick_pen, crsPoints[2], crsPoints[3]);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if false
|
|
private void getTemperatures()
|
|
{
|
|
if (ImgData.Thermal != null)
|
|
{
|
|
lastReadTemp = 0;
|
|
if (readTemp)
|
|
{
|
|
// recupero temp da FLIR
|
|
lastReadTemp = ImgData.Thermal.GetValueAt(ImgData.lastPoint).Value;
|
|
|
|
// calcolo temp da RGB considerato limiti minMAX...
|
|
//int rgbVal = ImgData.lastImageOrig.Image.GetPixel(ImgData.lastPoint.X, ImgData.lastPoint.Y).R;
|
|
int rgbVal = getRSmooth(ImgData.lastPoint);
|
|
lastCalcTemp = lastTempRange.Minimum + ((lastTempRange.Maximum - lastTempRange.Minimum) * rgbVal / 255);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
private void Image_Changed(object sender, Flir.Atlas.Image.ImageChangedEventArgs e)
|
|
{
|
|
IsDirty = true;
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (_recorder != null && _recorder.IsDisposed == false)
|
|
{
|
|
_recorder.Dispose();
|
|
}
|
|
|
|
DisposeCamera();
|
|
}
|
|
|
|
private void MainForm_Load(object sender, EventArgs e)
|
|
{
|
|
}
|
|
|
|
private void MainForm_Shown(object sender, EventArgs e)
|
|
{
|
|
// avvio l'autoconnessione
|
|
if (!string.IsNullOrEmpty(currConf.CameraName))
|
|
{
|
|
discoveryCamera();
|
|
}
|
|
}
|
|
|
|
private void openToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
using (var dialog = new OpenFileDialog())
|
|
{
|
|
dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) + @"\FLIR";
|
|
dialog.Filter = FileFilter;
|
|
if (dialog.ShowDialog() != DialogResult.OK) return;
|
|
var playback = new PlaybackForm(dialog.FileName);
|
|
playback.Show();
|
|
}
|
|
}
|
|
|
|
private void pictureBox1_Click(object sender, EventArgs e)
|
|
{
|
|
// calcolo la ratio img originale --> pictureBox
|
|
double ratio = 1;
|
|
try
|
|
{
|
|
if (ImgData.Origin != null && ImgData.Origin.Width > 0)
|
|
{
|
|
ratio = (double)pBoxA.Width / ImgData.Origin.Width;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
// trasformo punto in equivalente originale
|
|
var mea = (MouseEventArgs)e;
|
|
ImgData.lastPoint = new Point() { X = (int)(mea.X / ratio), Y = (int)(mea.Y / ratio) };
|
|
lblPoint.Text = $"({mea.X},{mea.Y}) --> ({ImgData.lastPoint.X},{ImgData.lastPoint.Y})";
|
|
if (pointSetup)
|
|
{
|
|
// max 4 punti... se sono già FULL --> imposto singolo valore nuovo
|
|
if (currConf.origPoints.curr >= 4)
|
|
{
|
|
if (currPoint >= 0)
|
|
{
|
|
currConf.origPoints.Coords[currPoint] = ImgData.lastPoint;
|
|
}
|
|
else
|
|
{
|
|
currConf.origPoints = new SetPoints();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// salvo coordinate in base al num corrente...
|
|
try
|
|
{
|
|
currConf.origPoints.Coords.Add(ImgData.lastPoint);
|
|
currConf.origPoints.curr++;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
// salvo conf
|
|
saveConf();
|
|
|
|
// aggiorno visualizzazione
|
|
processImage();
|
|
refreshDisplay();
|
|
}
|
|
else if (readTemp)
|
|
{
|
|
refTempPoint = ImgData.lastPoint;
|
|
// aggiorno visualizzazione
|
|
processImage();
|
|
refreshDisplay();
|
|
}
|
|
}
|
|
|
|
private void processImage()
|
|
{
|
|
// disegno immagine
|
|
ImgData.getTemperatures(readTemp);
|
|
ImgData.calculateTarget(chkParallel.Checked, chkRevProc.Checked);
|
|
}
|
|
|
|
private void recorderToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_recorder == null || _recorder.IsDisposed)
|
|
{
|
|
_recorder = new RecorderForm();
|
|
_recorder.Initialize(IRCam.ThermoCamera);
|
|
_recorder.SelectedFileMouseDoubleClick += _recorder_SelectedFileMouseDoubleClick;
|
|
}
|
|
_recorder.Show();
|
|
_recorder.Focus();
|
|
}
|
|
|
|
private void refreshDisplay()
|
|
{
|
|
drawCrossAtPoints();
|
|
displayImages();
|
|
updateDisplay();
|
|
updateTempDisplay();
|
|
updateStatDisplay();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva su file il file di conf corrente
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool saveConf()
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
string rawData = JsonConvert.SerializeObject(currConf, Formatting.Indented);
|
|
File.WriteAllText(confPath, rawData);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
private void saveImgFile()
|
|
{
|
|
try
|
|
{
|
|
// fix percorsi
|
|
string dirPath = $"{BASE_PATH}\\{thermPath}";
|
|
string filePath = $"{dirPath}\\{currImgFile}";
|
|
if (!Directory.Exists(dirPath))
|
|
{
|
|
Directory.CreateDirectory(dirPath);
|
|
}
|
|
// salvo!
|
|
ImgData.Thermal.Scale.IsAutoAdjustEnabled = true;
|
|
ImgData.Thermal.SaveSnapshot(filePath);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupera immagine effettuando eventuale salvataggio
|
|
/// </summary>
|
|
/// <param name="doSave"></param>
|
|
private void takePicture(bool doSave)
|
|
{
|
|
sw.Restart();
|
|
if (!IsDirty) return;
|
|
IsDirty = false;
|
|
if (IRCam.ThermoCamera == null) return;
|
|
|
|
IRCam.ThermoCamera.GetImage().EnterLock();
|
|
try
|
|
{
|
|
// non funziona
|
|
#if false
|
|
// se richiesto imposto temperature min/max...
|
|
if (!chkAutoTemp.Checked)
|
|
{
|
|
Range<double> limits = new Range<double>(273.1 + minTemp, 273.1 + maxTemp);
|
|
IRCam.ThermoCamera.RemoteControl.CameraSettings.SetScaleLimits(limits);
|
|
}
|
|
#endif
|
|
ImgData.Thermal = (ThermalImage)IRCam.ThermoCamera.GetImage();
|
|
ImgData.Thermal.TemperatureUnit = TemperatureUnit.Celsius;
|
|
ImgData.Thermal.Scale.IsAutoAdjustEnabled = true;
|
|
// salvo img locale
|
|
ImgData.Origin = ImgData.Thermal.Image;
|
|
ImgData.Decorated = ImgData.Thermal.Image;
|
|
if (doSave)
|
|
{
|
|
saveImgFile();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Trace.TraceError(exception.Message);
|
|
}
|
|
finally
|
|
{
|
|
IRCam.ThermoCamera.GetImage().ExitLock();
|
|
}
|
|
|
|
sw.Stop();
|
|
msLastCam = sw.ElapsedMilliseconds;
|
|
|
|
#if false
|
|
ThermalImage myImg = (ThermalImage)_stream.GetImage();
|
|
myImg.TemperatureUnit = TemperatureUnit.Celsius;
|
|
string currPath = $"{labelOutputPath.Text}\\{DateTime.Now:yyyyMMyy_HHmmss}.jpg";
|
|
myImg.SaveSnapshot(currPath);
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica se il punto era in edit, altrimenti segnala e lo attiva... restituendo colore x il controllo
|
|
/// </summary>
|
|
/// <param name="selPoint"></param>
|
|
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 tryReloadConf()
|
|
{
|
|
if (File.Exists(confPath))
|
|
{
|
|
// se non è vuoto....
|
|
string rawData = File.ReadAllText(confPath);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
currConf = JsonConvert.DeserializeObject<ThermoCamConf>(rawData);
|
|
}
|
|
catch (Exception exc)
|
|
{ }
|
|
}
|
|
}
|
|
}
|
|
|
|
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 updateDestPt()
|
|
{
|
|
currConf.destPoints.Coords = new List<Point>();
|
|
// ciclo i punti A-B-C-D...
|
|
currConf.destPoints.Coords.Add(new Point() { X = 0, Y = 0 });
|
|
currConf.destPoints.Coords.Add(new Point() { X = dimX, Y = 0 });
|
|
currConf.destPoints.Coords.Add(new Point() { X = dimX, Y = dimY });
|
|
currConf.destPoints.Coords.Add(new Point() { X = 0, Y = dimY });
|
|
// salvo conf
|
|
saveConf();
|
|
}
|
|
|
|
private void updateDisplay()
|
|
{
|
|
lblOrigA.Text = "A";
|
|
lblOrigB.Text = "B";
|
|
lblOrigC.Text = "C";
|
|
lblOrigD.Text = "D";
|
|
// popolo
|
|
if (currConf.origPoints.Coords.Count > 0)
|
|
{
|
|
lblOrigA.Text = $"A: ({currConf.origPoints.Coords[0].X},{currConf.origPoints.Coords[0].Y})";
|
|
}
|
|
if (currConf.origPoints.Coords.Count > 1)
|
|
{
|
|
lblOrigB.Text = $"B: ({currConf.origPoints.Coords[1].X},{currConf.origPoints.Coords[1].Y})";
|
|
}
|
|
if (currConf.origPoints.Coords.Count > 2)
|
|
{
|
|
lblOrigC.Text = $"C: ({currConf.origPoints.Coords[2].X},{currConf.origPoints.Coords[2].Y})";
|
|
}
|
|
if (currConf.origPoints.Coords.Count > 3)
|
|
{
|
|
lblOrigD.Text = $"D: ({currConf.origPoints.Coords[3].X},{currConf.origPoints.Coords[3].Y})";
|
|
ImgData.calculateTarget(chkParallel.Checked, chkRevProc.Checked);
|
|
}
|
|
}
|
|
|
|
private void updateStatDisplay()
|
|
{
|
|
lblStats.Text = $"Camera: {msLastCam}ms | Persp {msLastTra}ms | Color {msLastCol}ms | Points {msLastPts}ms | Measures {msLastMsr}ms";
|
|
}
|
|
|
|
private void updateTempDisplay()
|
|
{
|
|
if (ImgData.Thermal != null)
|
|
{
|
|
if (readTemp)
|
|
{
|
|
// mostro temp da FLIR
|
|
lblReadTemp.Text = $"{ImgData.lastReadTemp:N2} °C";
|
|
|
|
//calcolo da immagine B/N
|
|
lblTempRGB.Text = $"{ImgData.lastCalcTemp:N2} °C";
|
|
// cambio colore se > 1 grado...
|
|
double delta = Math.Abs(ImgData.lastReadTemp - ImgData.lastCalcTemp);
|
|
if (delta < 1)
|
|
{
|
|
lblTempRGB.ForeColor = Color.Black;
|
|
}
|
|
else if (delta < 2)
|
|
{
|
|
lblTempRGB.ForeColor = Color.Blue;
|
|
}
|
|
else if (delta < 3)
|
|
{
|
|
lblTempRGB.ForeColor = Color.Orange;
|
|
}
|
|
else
|
|
{
|
|
lblTempRGB.ForeColor = Color.Red;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
|
|
#if false
|
|
/// <summary>
|
|
/// Calcola valore R ponderato dato un punto + intorno
|
|
/// </summary>
|
|
/// <param name="reqPoint"></param>
|
|
/// <returns></returns>
|
|
protected int getRSmooth(Point reqPoint)
|
|
{
|
|
int answ = 0;
|
|
if (ImgData.Origin != null)
|
|
{
|
|
// solo se il punto è entro limiti immagine --> 1 pixel entro bordo
|
|
if (reqPoint.X > 0 && reqPoint.X < ImgData.Origin.Width)
|
|
{
|
|
if (reqPoint.Y > 0 && reqPoint.Y < ImgData.Origin.Height)
|
|
{
|
|
int rgbValMain = ImgData.Origin.GetPixel(ImgData.lastPoint.X, ImgData.lastPoint.Y).R;
|
|
|
|
int rgbValN = ImgData.Origin.GetPixel(ImgData.lastPoint.X, ImgData.lastPoint.Y - 1).R;
|
|
int rgbValNO = ImgData.Origin.GetPixel(ImgData.lastPoint.X - 1, ImgData.lastPoint.Y - 1).R;
|
|
int rgbValO = ImgData.Origin.GetPixel(ImgData.lastPoint.X - 1, ImgData.lastPoint.Y).R;
|
|
int rgbValSO = ImgData.Origin.GetPixel(ImgData.lastPoint.X - 1, ImgData.lastPoint.Y + 1).R;
|
|
int rgbValS = ImgData.Origin.GetPixel(ImgData.lastPoint.X, ImgData.lastPoint.Y + 1).R;
|
|
int rgbValSE = ImgData.Origin.GetPixel(ImgData.lastPoint.X + 1, ImgData.lastPoint.Y + 1).R;
|
|
int rgbValE = ImgData.Origin.GetPixel(ImgData.lastPoint.X + 1, ImgData.lastPoint.Y).R;
|
|
int rgbValNE = ImgData.Origin.GetPixel(ImgData.lastPoint.X + 1, ImgData.lastPoint.Y - 1).R;
|
|
// calcolo valore ponderato
|
|
answ = (int)Math.Round((double)(1 * rgbValMain + 1 * (rgbValN + rgbValO + rgbValS + rgbValE) + rgbValNO + rgbValSO + rgbValSE + rgbValNE) / 10, 0);
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
#endif
|
|
|
|
#region Public Methods
|
|
|
|
public void discoveryCamera()
|
|
{
|
|
var discoveryDialog = new DiscoveryForm();
|
|
discoveryDialog.CameraName = currConf.CameraName;
|
|
if (!string.IsNullOrEmpty(currConf.CameraName))
|
|
{
|
|
//discoveryDialog.WindowState = FormWindowState.Minimized;
|
|
if (discoveryDialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
ConnectCamera(discoveryDialog.SelectedCameraDevice);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
} |