Files
cms_thermo_active/ThermoCamUtils/ImageData.cs
T
2021-02-13 11:59:02 +01:00

217 lines
7.6 KiB
C#

using Flir.Atlas.Image;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ThermoCamUtils
{
/// <summary>
/// Classe gestione aree di memoria immagini (thermo, trasformate, ...)
/// </summary>
public class ImageData
{
#region Protected Fields
/// <summary>
/// Ultimo range di temperature osservato
/// </summary>
protected Range<double> lastTempRange = new Range<double>(0, 5000);
/// <summary>
/// Stopwatch x benchmarking
/// </summary>
protected Stopwatch sw = new Stopwatch();
#endregion Protected Fields
#region Public Fields
/// <summary>
/// Statistiche esecuzione task
/// </summary>
public ExecTime ExTime = new ExecTime();
/// <summary>
/// Ultima temp calcolata da immagine B/N
/// </summary>
public double lastCalcTemp = 0;
/// <summary>
/// Ultimo punto acquisito
/// </summary>
public Point lastPoint = new Point();
/// <summary>
/// Ultima temp letta da FLIR
/// </summary>
public double lastReadTemp = 0;
#endregion Public Fields
#region Public Properties
/// <summary>
/// Ultima immagine ricolorata e trasformata (perspective)
/// </summary>
public Bitmap ColorTransf { get; set; }
public ThermoCamConf currConf { get; set; } = new ThermoCamConf();
/// <summary>
/// Ultima bitmap disegnata (con punti)
/// </summary>
public Bitmap Decorated { get; set; }
/// <summary>
/// Ultima immagine post trasformazione (perspective)
/// </summary>
public Bitmap GrayTransf { get; set; }
/// <summary>
/// Ultima bitmap acquisita
/// </summary>
public Bitmap Origin { get; set; }
/// <summary>
/// Ultima immagine recuperata
/// </summary>
public ThermalImage Thermal { get; set; }
#endregion Public Properties
#region Protected Methods
/// <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 (Origin != null)
{
// solo se il punto è entro limiti immagine --> 1 pixel entro bordo
if (reqPoint.X > 0 && reqPoint.X < Origin.Width)
{
if (reqPoint.Y > 0 && reqPoint.Y < Origin.Height)
{
int rgbValMain = Origin.GetPixel(lastPoint.X, lastPoint.Y).R;
int rgbValN = Origin.GetPixel(lastPoint.X, lastPoint.Y - 1).R;
int rgbValNO = Origin.GetPixel(lastPoint.X - 1, lastPoint.Y - 1).R;
int rgbValO = Origin.GetPixel(lastPoint.X - 1, lastPoint.Y).R;
int rgbValSO = Origin.GetPixel(lastPoint.X - 1, lastPoint.Y + 1).R;
int rgbValS = Origin.GetPixel(lastPoint.X, lastPoint.Y + 1).R;
int rgbValSE = Origin.GetPixel(lastPoint.X + 1, lastPoint.Y + 1).R;
int rgbValE = Origin.GetPixel(lastPoint.X + 1, lastPoint.Y).R;
int rgbValNE = Origin.GetPixel(lastPoint.X + 1, 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;
}
#endregion Protected Methods
#region Public Methods
/// <summary>
/// Effettua calcolo immagini target
/// </summary>
/// <param name="fastBitmap">Indica se processare bitmap in memoria (true) o con metodi standard (false)</param>
/// <param name="colorizeFirst">Indica se prima fare falsi colori poi trasformazione proiettiva</param>
public void calculateTarget(bool fastBitmap, bool colorizeFirst)
{
if (Thermal != null)
{
try
{
//lastTempRange = new Range<double>(lastThermalImage.GetValueFromSignal(lastThermalImage.MinSignalValue), lastThermalImage.GetValueFromSignal(lastThermalImage.MaxSignalValue));
lastTempRange = new Range<double>(Thermal.Scale.Range.Minimum, Thermal.Scale.Range.Maximum);
sw.Restart();
var pTransf = new PerspectiveTransform(currConf.origPoints.Coords, currConf.destPoints.Coords);
var rTrasf = new ReColorize(lastTempRange.Minimum, lastTempRange.Maximum, currConf.TargetRange.Min, currConf.TargetRange.Max);
var transfImg = pTransf.convertImage(Origin, currConf.TargetSize.X, currConf.TargetSize.Y);
GrayTransf = transfImg;
sw.Stop();
ExTime.recordData("ImageTransf", sw.ElapsedMilliseconds);
sw.Restart();
if (colorizeFirst)
{
// ora calcolo ricolorazione da immagine originale
var colImg = rTrasf.process(Origin, fastBitmap);
// e faccio la stessa trasformazione di riscalatura
var transfColImg = pTransf.convertImage(colImg, currConf.TargetSize.X, currConf.TargetSize.Y);
ColorTransf = transfColImg;
}
else
{
// old way da immagine BN full size
ColorTransf = rTrasf.process(GrayTransf, fastBitmap);
}
sw.Stop();
ExTime.recordData("ImageColor", sw.ElapsedMilliseconds);
}
catch (Exception exc)
{
}
}
}
/// <summary>
/// Recupera temperature coi 2 metodi da FLIR e da B/N
/// </summary>
/// <param name="readTemp"></param>
public void getTemperatures(bool readTemp)
{
if (Thermal != null)
{
lastReadTemp = 0;
if (readTemp)
{
// recupero temp da FLIR
lastReadTemp = Thermal.GetValueAt(lastPoint).Value;
// calcolo temp da RGB considerato limiti minMAX...
//int rgbVal = lastImageOrig.Image.GetPixel(lastPoint.X, lastPoint.Y).R;
int rgbVal = getRSmooth(lastPoint);
lastCalcTemp = lastTempRange.Minimum + ((lastTempRange.Maximum - lastTempRange.Minimum) * rgbVal / 255);
}
}
}
/// <summary>
/// Init iniziale immagini
/// </summary>
public void initImageFromFile()
{
if (Origin != null)
{
Decorated = (Bitmap)Origin.Clone();
}
}
/// <summary>
/// Init iniziale immagini
/// </summary>
public void initImagesFromThermo()
{
if (Thermal != null)
{
Origin = (Bitmap)Thermal.Image.Clone();
Decorated = (Bitmap)Thermal.Image.Clone();
}
}
#endregion Public Methods
}
}