422 lines
12 KiB
C#
422 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using Flir.Atlas.Image;
|
|
using Flir.Atlas.Live.Device;
|
|
using Flir.Atlas.Live.Discovery;
|
|
using ThermoCamUtils;
|
|
|
|
namespace ThermalImageStreamerDemo
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
/// <summary>
|
|
/// Ultima immagine recuperata
|
|
/// </summary>
|
|
protected ThermalImage lastImage { get; set; }
|
|
private bool liveView
|
|
{
|
|
get
|
|
{
|
|
return checkLive.Checked;
|
|
}
|
|
set
|
|
{
|
|
checkLive.Checked = value;
|
|
}
|
|
}
|
|
|
|
protected bool pointSetup
|
|
{
|
|
get
|
|
{
|
|
return chkPointSetup.Checked;
|
|
}
|
|
set
|
|
{
|
|
chkPointSetup.Checked = value;
|
|
}
|
|
}
|
|
|
|
protected bool readTemp
|
|
{
|
|
get
|
|
{
|
|
return chkReadTemp.Checked;
|
|
}
|
|
set
|
|
{
|
|
chkReadTemp.Checked = value;
|
|
}
|
|
}
|
|
|
|
|
|
protected SetPoints origPoints = new SetPoints();
|
|
protected SetPoints destPoints = new SetPoints();
|
|
|
|
private Camera _camera;
|
|
readonly Timer _timerRefreshUi = new Timer();
|
|
|
|
protected Point lastPoint = new Point();
|
|
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
_timerRefreshUi.Interval = 100;
|
|
_timerRefreshUi.Tick += _timerRefreshUi_Tick;
|
|
// calcolo i destPoints
|
|
updateDestPt();
|
|
}
|
|
|
|
void _timerRefreshUi_Tick(object sender, EventArgs e)
|
|
{
|
|
// se è in live view --> continuo
|
|
if (liveView)
|
|
{
|
|
takePicture();
|
|
calculateTarget();
|
|
updateTempDisplay();
|
|
}
|
|
}
|
|
|
|
private void takePicture()
|
|
{
|
|
if (!IsDirty) return;
|
|
IsDirty = false;
|
|
if (_camera == null) return;
|
|
|
|
_camera.GetImage().EnterLock();
|
|
try
|
|
{
|
|
lastImage = (ThermalImage)_camera.GetImage();
|
|
pBoxOrig.Image = lastImage.Image;
|
|
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Trace.TraceError(exception.Message);
|
|
}
|
|
finally
|
|
{
|
|
_camera.GetImage().ExitLock();
|
|
}
|
|
|
|
#if false
|
|
ThermalImage myImg = (ThermalImage)_stream.GetImage();
|
|
myImg.TemperatureUnit = TemperatureUnit.Celsius;
|
|
string currPath = $"{labelOutputPath.Text}\\{DateTime.Now:yyyyMMyy_HHmmss}.jpg";
|
|
myImg.SaveSnapshot(currPath);
|
|
#endif
|
|
}
|
|
|
|
private void discoveryToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
var discoveryDlg = new DiscoveryForm();
|
|
if (discoveryDlg.ShowDialog() == DialogResult.OK)
|
|
{
|
|
ConnectCamera(discoveryDlg.SelectedCameraDevice);
|
|
}
|
|
}
|
|
|
|
private void ConnectCamera(CameraDeviceInfo cameraDeviceInfo)
|
|
{
|
|
DisposeCamera();
|
|
switch (cameraDeviceInfo.SelectedStreamingFormat)
|
|
{
|
|
case ImageFormat.FlirFileFormat:
|
|
_camera = new ThermalCamera();
|
|
break;
|
|
case ImageFormat.Argb:
|
|
_camera = new VideoOverlayCamera();
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
_camera.ConnectionStatusChanged += _camera_ConnectionStatusChanged;
|
|
_camera.GetImage().Changed += Image_Changed;
|
|
_camera.Connect(cameraDeviceInfo);
|
|
if (_camera.Recorder == null && _recorder != null)
|
|
{
|
|
_recorder.Dispose();
|
|
_recorder = null;
|
|
}
|
|
if (_recorder != null)
|
|
{
|
|
if (!_recorder.IsDisposed)
|
|
_recorder.Initialize(_camera);
|
|
}
|
|
recorderToolStripMenuItem.Enabled = _camera.Recorder != null;
|
|
_timerRefreshUi.Start();
|
|
}
|
|
|
|
private void DisposeCamera()
|
|
{
|
|
_timerRefreshUi.Stop();
|
|
if (_camera == null) return;
|
|
if (_recorder != null)
|
|
{
|
|
_recorder.UnInitialize();
|
|
_recorder.Dispose();
|
|
}
|
|
_camera.ConnectionStatusChanged -= _camera_ConnectionStatusChanged;
|
|
_camera.GetImage().Changed -= Image_Changed;
|
|
_camera.Dispose();
|
|
}
|
|
|
|
private bool IsDirty { get; set; }
|
|
void Image_Changed(object sender, Flir.Atlas.Image.ImageChangedEventArgs e)
|
|
{
|
|
IsDirty = true;
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
private void DisconnectCamera()
|
|
{
|
|
if (_camera == null) return;
|
|
|
|
_camera.Disconnect();
|
|
}
|
|
|
|
private void MainForm_Load(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
DisconnectCamera();
|
|
}
|
|
|
|
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
if (_recorder != null && _recorder.IsDisposed == false)
|
|
{
|
|
_recorder.Dispose();
|
|
}
|
|
|
|
DisposeCamera();
|
|
}
|
|
|
|
private RecorderForm _recorder;
|
|
private void recorderToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (_recorder == null || _recorder.IsDisposed)
|
|
{
|
|
_recorder = new RecorderForm();
|
|
_recorder.Initialize(_camera);
|
|
_recorder.SelectedFileMouseDoubleClick += _recorder_SelectedFileMouseDoubleClick;
|
|
}
|
|
_recorder.Show();
|
|
_recorder.Focus();
|
|
}
|
|
|
|
void _recorder_SelectedFileMouseDoubleClick(object sender, SelectedFileEventArgs e)
|
|
{
|
|
var playback = new PlaybackForm(e.FilePath);
|
|
playback.Show();
|
|
}
|
|
|
|
private const string FileFilter = "IR Image Files(*.jpg;*.img;*.seq;*.fcf)|*.jpg;*.img;*.seq;*.fcf|All files (*.*)|*.*";
|
|
|
|
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 btnAcquire_Click(object sender, EventArgs e)
|
|
{
|
|
takePicture();
|
|
}
|
|
|
|
private void checkLive_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
// non serve fare nulla
|
|
}
|
|
|
|
private void btnSetup_Click(object sender, EventArgs e)
|
|
{
|
|
pointSetup = true;
|
|
origPoints = new SetPoints();
|
|
}
|
|
|
|
private void pictureBox1_Click(object sender, EventArgs e)
|
|
{
|
|
// calcolo la ratio img originale --> pictureBox
|
|
double ratio = 1;
|
|
try
|
|
{
|
|
if (lastImage != null && lastImage.Width > 0)
|
|
{
|
|
ratio = (double)pBoxOrig.Width / lastImage.Width;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
// trasformo punto in equivalente originale
|
|
var mea = (MouseEventArgs)e;
|
|
lastPoint = new Point() { X = (int)(mea.X / ratio), Y = (int)(mea.Y / ratio) };
|
|
lblPoint.Text = $"({mea.X},{mea.Y}) --> ({lastPoint.X},{lastPoint.Y})";
|
|
if (pointSetup)
|
|
{
|
|
// max 4 punti... sae sono oltre --> resetto
|
|
if (origPoints.curr >= 4)
|
|
{
|
|
origPoints = new SetPoints();
|
|
}
|
|
// salvo coordinate in base al num corrente...
|
|
try
|
|
{
|
|
origPoints.Coords.Add(lastPoint);
|
|
origPoints.curr++;
|
|
}
|
|
catch
|
|
{ }
|
|
updateDisplay();
|
|
}
|
|
else if (readTemp)
|
|
{
|
|
updateTempDisplay();
|
|
}
|
|
}
|
|
|
|
private void updateTempDisplay()
|
|
{
|
|
if (lastImage != null)
|
|
{
|
|
double pointTemperature = 0;
|
|
if (readTemp)
|
|
{
|
|
pointTemperature = lastImage.GetValueAt(lastPoint).Value;
|
|
lblReadTemp.Text = $"{pointTemperature:N2} °C";
|
|
}
|
|
else
|
|
{
|
|
lblReadTemp.Text = "? °C";
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateDisplay()
|
|
{
|
|
lblOrigA.Text = "A";
|
|
lblOrigB.Text = "B";
|
|
lblOrigC.Text = "C";
|
|
lblOrigD.Text = "D";
|
|
// popolo
|
|
if (origPoints.Coords.Count > 0)
|
|
{
|
|
lblOrigA.Text = $"A: ({origPoints.Coords[0].X},{origPoints.Coords[0].Y})";
|
|
}
|
|
if (origPoints.Coords.Count > 1)
|
|
{
|
|
lblOrigB.Text = $"B: ({origPoints.Coords[1].X},{origPoints.Coords[1].Y})";
|
|
}
|
|
if (origPoints.Coords.Count > 2)
|
|
{
|
|
lblOrigC.Text = $"C: ({origPoints.Coords[2].X},{origPoints.Coords[2].Y})";
|
|
}
|
|
if (origPoints.Coords.Count > 3)
|
|
{
|
|
lblOrigD.Text = $"D: ({origPoints.Coords[3].X},{origPoints.Coords[3].Y})";
|
|
calculateTarget();
|
|
}
|
|
|
|
}
|
|
|
|
protected int dimX
|
|
{
|
|
get
|
|
{
|
|
int answ = 100;
|
|
int.TryParse(txtAB.Text, out answ);
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
txtAB.Text = $"{value}";
|
|
}
|
|
}
|
|
protected int dimY
|
|
{
|
|
get
|
|
{
|
|
int answ = 100;
|
|
int.TryParse(txtBC.Text, out answ);
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
txtBC.Text = $"{value}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua calcolo e display immagine target
|
|
/// </summary>
|
|
private void calculateTarget()
|
|
{
|
|
try
|
|
{
|
|
var pTransf = new PerspectiveTransform(origPoints.Coords, destPoints.Coords);
|
|
var transfImg = pTransf.convertImage((Bitmap)pBoxOrig.Image, dimX, dimY);
|
|
pBoxTraBn.Image = transfImg;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
|
|
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()
|
|
{
|
|
destPoints.Coords = new List<Point>();
|
|
// ciclo i punti A-B-C-D...
|
|
destPoints.Coords.Add(new Point() { X = 0, Y = 0 });
|
|
destPoints.Coords.Add(new Point() { X = dimX, Y = 0 });
|
|
destPoints.Coords.Add(new Point() { X = dimX, Y = dimY });
|
|
destPoints.Coords.Add(new Point() { X = 0, Y = dimY });
|
|
}
|
|
|
|
private void chkReadTemp_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
// deselezione setup punti
|
|
chkPointSetup.Checked = false;
|
|
}
|
|
|
|
private void chkPointSetup_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
// deselezione Get Temp
|
|
chkReadTemp.Checked = false;
|
|
}
|
|
|
|
}
|
|
}
|