private void SpawnEyeProcessorTask() { Task.Run(() => { MonochromeImageData lastMonochromeImage = null; while (m_running) { byte[] data = null; lock (m_eyeDataLock) { data = m_eyeDataQueue.Count > 0 ? m_eyeDataQueue.Dequeue() : null; } if (data != null) { var width = BitConverter.ToInt32(data, 0); var height = BitConverter.ToInt32(data, 4); var channels = BitConverter.ToInt32(data, 8); if (width > 0 && height > 0 && channels > 0) { var pixels = new byte[width * height * channels]; Buffer.BlockCopy(data, 12, pixels, 0, pixels.Length); if (channels == 1) { int treshold = 0; lock (m_lock) { treshold = m_settingsModel.Treshold; } var currMonochromeImage = new MonochromeImageData(); currMonochromeImage.Width = width; currMonochromeImage.Height = height; currMonochromeImage.Pixels = pixels; if (lastMonochromeImage != null) { var factor = CompareInfraredImages(currMonochromeImage, lastMonochromeImage, treshold); if (factor < 1.0 && m_alarmIsArmed && !m_alarmIsPlaying) PushCommand(new Commands.ControlAlarm(this, true)); } lastMonochromeImage = currMonochromeImage; } } } else Thread.Sleep(50); } lock (m_lock) { lock (m_eyeDataLock) { m_eyeDataQueue = null; } } }); }
static double CompareInfraredImages(MonochromeImageData a, MonochromeImageData b, int treshold = 0) { if (a == null || b == null || a.Pixels == null || b.Pixels == null) return 0.0; if (a == b) return 1.0; if (a.Width != b.Width || a.Height != b.Height || a.Pixels.Length != b.Pixels.Length) return 0.0; var passed = 0; for (int i = 0, c = a.Pixels.Length; i < c; ++i) if (Math.Abs((int)a.Pixels[i] - (int)b.Pixels[i]) <= treshold) ++passed; return (double)passed / (double)a.Pixels.Length; }