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 { /// /// Classe gestione aree di memoria immagini (thermo, trasformate, ...) /// public class ImageData { #region Protected Fields /// /// Ultimo range di temperature osservato /// protected Range lastTempRange = new Range(0, 5000); /// /// Stopwatch x benchmarking /// protected Stopwatch sw = new Stopwatch(); #endregion Protected Fields #region Public Fields /// /// Statistiche esecuzione task /// public ExecTime ExTime = new ExecTime(); /// /// Ultima temp calcolata da immagine B/N /// public double lastCalcTemp = 0; /// /// Ultimo punto acquisito /// public Point lastPoint = new Point(); /// /// Ultima temp letta da FLIR /// public double lastReadTemp = 0; #endregion Public Fields #region Public Properties /// /// Ultima immagine ricolorata e trasformata (perspective) /// public Bitmap ColorTransf { get; set; } public ThermoCamConf currConf { get; set; } = new ThermoCamConf(); /// /// Ultima bitmap disegnata (con punti) /// public Bitmap Decorated { get; set; } /// /// Ultima immagine post trasformazione (perspective) /// public Bitmap GrayTransf { get; set; } /// /// Ultima bitmap acquisita /// public Bitmap Origin { get; set; } /// /// Ultima immagine recuperata /// public ThermalImage Thermal { get; set; } #endregion Public Properties #region Protected Methods /// /// Calcola valore R ponderato dato un punto + intorno /// /// /// 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 /// /// Effettua calcolo immagini target /// /// Indica se processare bitmap in memoria (true) o con metodi standard (false) /// Indica se prima fare falsi colori poi trasformazione proiettiva public void calculateTarget(bool fastBitmap, bool colorizeFirst) { if (Thermal != null) { try { //lastTempRange = new Range(lastThermalImage.GetValueFromSignal(lastThermalImage.MinSignalValue), lastThermalImage.GetValueFromSignal(lastThermalImage.MaxSignalValue)); lastTempRange = new Range(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) { } } } /// /// Recupera temperature coi 2 metodi da FLIR e da B/N /// /// 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); } } } /// /// Init iniziale immagini /// public void initImageFromFile() { if (Origin != null) { Decorated = (Bitmap)Origin.Clone(); } } /// /// Init iniziale immagini /// public void initImagesFromThermo() { if (Thermal != null) { Origin = (Bitmap)Thermal.Image.Clone(); Decorated = (Bitmap)Thermal.Image.Clone(); } } #endregion Public Methods } }