void ThermalThreadProc() { while (!stopThread && thermal != null) { bool progress = false; lastFrame = thermal.GetFrameBlocking(); if (lastFrame.IsCalibrationFrame) { lastCalibrationFrame = lastFrame; } else { if (lastCalibrationFrame != null && lastFrame.IsUsableFrame) { lastUsableFrame = lastFrame.ProcessFrame(lastCalibrationFrame); progress = true; } } //System.Diagnostics.Debug.Print("Start of data: " + string.Join(" ", lastFrame.RawData.Take(64).Select(b => b.ToString("x2")).ToArray())); //System.Diagnostics.Debug.Print("End of data: " + string.Join(" ", lastFrame.RawData.Reverse().Take(32).Reverse().Select(b => b.ToString("x2")).ToArray())); // Do stuff frameCount++; if (progress) { Invalidate(); } } }
private void Form1_Paint(object sender, PaintEventArgs e) { CalibratedThermalFrame data = lastUsableFrame; if (data == null) { return; } int y; if (data != lastRenderedFrame) { lastRenderedFrame = data; // Process new frame Bitmap bmp = new Bitmap(data.Width, data.Height); int c = 0; for (y = 0; y < 156; y++) { for (int x = 0; x < 208; x++) { int v = data.PixelData[c++]; v = (v - data.MinValue) * 255 / (data.MaxValue - data.MinValue); if (v < 0) { v = 0; } if (v > 255) { v = 255; } bmp.SetPixel(x, y, Color.FromArgb(v, v, v)); } } bmpQueue.Enqueue(bmp); if (bmpQueue.Count > 5) { bmpQueue.Dequeue(); } } y = 10; foreach (Bitmap b in bmpQueue.Reverse()) { e.Graphics.DrawImage(b, 10, y); y += b.Height + 10; } }
void ThermalThreadProc() { BinaryWriter tw; DateTime currentFrameTime = DateTime.Now; DateTime previousFrameTime = currentFrameTime; DateTime currentTime = DateTime.Now; DateTime previousTime = currentTime; int framesToCapture = 100; // Initialize frame (1 based) frameCount = 1; // Create the output files to save first 20 frames and associated metadata. //bw = new BinaryWriter(new FileStream("data.dat", FileMode.Create)); tw = new BinaryWriter(new FileStream("data.txt", FileMode.Create)); while (!stopThread && thermal != null) { bool progress = false; // Get frame lastFrame = thermal.GetFrameBlocking(); // Keep the ID4 and ID1 frame switch (lastFrame.StatusByte) { case 1: //shutter cal frameID1 = lastFrame; firstAfterCal = true; break; case 4: //first frame gain cal frameID4 = lastFrame; break; default: break; } // Time after frame capture previousTime = currentTime; currentTime = DateTime.Now; // Save data and metadata for the first framesToCapture frames if (frameCount <= framesToCapture) { tw.Write(Encoding.ASCII.GetBytes(String.Format("Frame {0} ID {1}\n", frameCount, lastFrame.RawDataU16[10]))); tw.Write(Encoding.ASCII.GetBytes(String.Format(lastFrame.AvgValue.ToString()))); tw.Write(Encoding.ASCII.GetBytes(String.Format("\n"))); if (frameCount == framesToCapture) { tw.Close(); } } switch (lastFrame.StatusByte) { case 4: //prvi frame za izračuna gaina markBadPixels(); getGainCalibration(); //konec: prvi frame za izračuna gaina break; case 1: //shutter frame za izračun offseta markBadPixels(); applyGainCalibration(); if (!usignExternalCal) { getOffsetCalibration(); } lastCalibrationFrame = frameID1; saveExternalFrames = false; //konec: shutter frame break; case 3: //pravi slikovni frame markZeroPixels(); applyGainCalibration(); if (m_get_extra_cal) //if this pixel should be used as reference { m_get_extra_cal = false; usignExternalCal = true; getOffsetCalibration(); saveExternalFrames = true; } applyOffsetCalibration(); fixBadPixels(); lastUsableFrame = lastFrame.ProcessFrameU16(lastReferenceFrame, frameID4); progress = true; //konec: pravi slikovni frame break; default: break; } // Increase frame count. frameCount++; if (progress) { Invalidate();//ponovno izriši formo... } } }
private void Form1_Paint(object sender, PaintEventArgs e) { CalibratedThermalFrame data = lastUsableFrame; if (data == null) { return; } int y; if (data != lastRenderedFrame) { lastRenderedFrame = data; // Process new frame Bitmap bmp = new Bitmap((data.Width - 2), data.Height); Bitmap bigImage = new Bitmap(412, 312); int c = 0; int v; ushort maxValue, minValue; // Display last sensor min/max values. label2.Text = "Max: " + lastFrame.MaxValue; label3.Text = "Min: " + lastFrame.MinValue; // Display last calibration min/max values (internal or external) if (lastReferenceFrame != null && lastReferenceFrame.IsUsableFrame) { // Update label for calibration button functionality. label1.Text = "Push button to switch to default calibration"; button1.Text = "Calibraton: Use Internal"; label6.Text = "Max: " + lastReferenceFrame.MaxValue; label7.Text = "Min: " + lastReferenceFrame.MinValue; } else { // Update label for calibration button functionality. label1.Text = "Face camera down on an even heated surface"; button1.Text = "Calibraton: Use Frame"; label6.Text = "Max: " + lastCalibrationFrame.MaxValue; label7.Text = "Min: " + lastCalibrationFrame.MinValue; } //button2.Text = "Automatic"; maxValue = (ushort)trackBar1.Value; minValue = (ushort)trackBar2.Value; // Display displayed data min/max value. label9.Text = "Max: " + maxValue; label10.Text = "Min: " + minValue; for (y = 0; y < 156; y++) { for (int x = 0; x < 206; x++) { v = data.PixelData[y * 208 + x]; // + data.PixelData[y * 208 + 206] / 10; // no need to use column 207 since we already use frame id 4, max/min will be off if uncommented as well. // Scale data to be within [0-255] for LUT mapping. ushort maxmin = maxValue; maxmin -= minValue; // Avoid divide by 0 if (maxmin == 0) { maxmin = 1; } v = (v - minValue) * 999 / maxmin; if (v < 0) { v = 0; } if (v > 999) { v = 999; } // Greyscale output (would always be limited to 256 colors) bmp.SetPixel(x, y, paletteImg.GetPixel(v, 0)); } } using (Graphics gr = Graphics.FromImage(bigImage)) { gr.SmoothingMode = SmoothingMode.HighQuality; gr.InterpolationMode = InterpolationMode.HighQualityBicubic; gr.PixelOffsetMode = PixelOffsetMode.HighQuality; gr.DrawImage(bmp, new Rectangle(0, 0, 412, 312)); } //bigImage = new Bitmap(bmp, new Size(412, 312)); // Queue Image for display bmpQueue.Enqueue(bigImage); if (bmpQueue.Count > 1) { bmpQueue.Dequeue(); } if (autoSaveImg) { //if folder does not exists create it: DirectoryInfo di = Directory.CreateDirectory(localPath + "export"); //usignExternalCal mora bit true, if (saveExternalFrames && usignExternalCal) { string sDate = DateTime.Now.ToString("yyyyMMddhhmmssfff"); bmp.Save(localPath + @"export\img_" + sDate + ".png"); } else if (firstAfterCal) { string sDate = DateTime.Now.ToString("yyyyMMddhhmmss"); Random rnd = new Random(); bmp.Save(localPath + @"export\shutter_" + sDate + "_" + rnd.Next(100).ToString() + ".png"); firstAfterCal = false; } } } y = 10; foreach (Bitmap b in bmpQueue.Reverse()) { e.Graphics.DrawImage(b, 10, y); y += b.Height + 10; } }
void drawThermalFrame() { CalibratedThermalFrame data = lastUsableFrame; if (data == null) { return; } int y; if (data != lastRenderedFrame) { lastRenderedFrame = data; // Process new frame if (bmp == null) { bmp = new Bitmap((data.Width - 2), data.Height); bigImage = new Bitmap(412, 312); bmGr = Graphics.FromImage(bmp); gr = Graphics.FromImage(bigImage); } bmGr.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height); int c = 0; int v; //button2.Text = "Automatic"; if (!checkBox4.Checked) { maxValue = (ushort)trackBar1.Value; minValue = (ushort)trackBar2.Value; } int high_x = -1; int high_y = -1; int high_v = 0; int low_x = -1; int low_y = -1; int low_v = 12000; //draw the image pixel by pixel for (y = 1; y < 154; y++) { for (int x = 0; x < 206; x++) { v = data.PixelData[y * 208 + x]; // + data.PixelData[y * 208 + 206] / 10; // no need to use column 207 since we already use frame id 4, max/min will be off if uncommented as well. //Console.WriteLine(x + " : " + y + " : " + v); if (v > high_v) { high_v = v; high_x = x; high_y = y; } if (v < low_v) { low_v = v; low_x = x; low_y = y; } // Scale data to be within [0-255] for LUT mapping. ushort maxmin = maxValue; maxmin -= minValue; // Avoid divide by 0 if (maxmin == 0) { maxmin = 1; } v = (v - minValue) * 999 / maxmin; if (v < 0) { v = 0; } if (v > 999) { v = 999; } // Greyscale output (would always be limited to 256 colors) bmp.SetPixel(x, y, paletteImg.GetPixel(v, paletteIndex)); } } if (checkBox4.Checked) { maxValue = (ushort)((ushort)high_v + numericUpDown1.Value); minValue = (ushort)((ushort)low_v - numericUpDown1.Value); trackBar1.Value = high_v; trackBar2.Value = low_v; } if (high_x != -1 && checkBox2.Checked) { bmGr.DrawLine(Pens.Red, new Point(high_x, high_y + 5), new Point(high_x, high_y - 5)); bmGr.DrawLine(Pens.Red, new Point(high_x + 5, high_y), new Point(high_x - 5, high_y)); } if (low_x != -1 && checkBox3.Checked) { Console.WriteLine(low_x + ":" + low_y); bmGr.DrawLine(Pens.Blue, new Point(low_x, low_y + 5), new Point(low_x, low_y - 5)); bmGr.DrawLine(Pens.Blue, new Point(low_x + 5, low_y), new Point(low_x - 5, low_y)); } gr.SmoothingMode = SmoothingMode.HighQuality; gr.InterpolationMode = InterpolationMode.HighQualityBilinear; gr.PixelOffsetMode = PixelOffsetMode.HighQuality; gr.DrawImage(bmp, new Rectangle(0, 0, 412, 312)); //bigImage = new Bitmap(bmp, new Size(412, 312)); // Queue Image for display bmpQueue.Enqueue(bigImage); if (bmpQueue.Count > 1) { bmpQueue.Dequeue(); } frame++; if (checkBox1.Checked) { long time = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; if (!Directory.Exists(Application.StartupPath + "/VIDEO")) { Directory.CreateDirectory(Application.StartupPath + "/VIDEO"); } if (!File.Exists(Application.StartupPath + "/VIDEO/render.bat")) { string bScript = @"@echo off set rndName=%random%%random% set path={0} c:\ffmpeg -framerate 8 -i THERMAL_%%d.png %path%\video_%rndName%.mp4 echo %path%\video_%rndName%.mp4 start %path%\video_%rndName%.mp4 pause"; bScript = string.Format(bScript, Environment.GetFolderPath(Environment.SpecialFolder.MyVideos)); File.WriteAllText((Application.StartupPath + "/VIDEO/render.bat"), bScript); } string path = Application.StartupPath + "/VIDEO/THERMAL_" + frame.ToString() + ".png"; pictureBox2.Image.Save(path); } } y = 10; foreach (Bitmap b in bmpQueue.Reverse()) { //b.RotateFlip(RotateFlipType.Rotate90FlipNone); tmp = (Bitmap)b.Clone(); tmp.RotateFlip((RotateFlipType)Math.Floor((decimal)(comboBox1.SelectedIndex))); pictureBox2.Image = tmp; //os.pictureBox1.Image = tmp; y += b.Height + 10; } }