diff --git a/Windows/CS/Framework4.0/Camera/Camera/Camera.cs b/Windows/CS/Framework4.0/Camera/Camera/Camera.cs index 0f1cb06..726212d 100644 --- a/Windows/CS/Framework4.0/Camera/Camera/Camera.cs +++ b/Windows/CS/Framework4.0/Camera/Camera/Camera.cs @@ -8,6 +8,9 @@ using System.IO; using System.Security.Cryptography; using System.Text.RegularExpressions; using System.Threading; +using Emgu.CV; +using Emgu.CV.CvEnum; +using Emgu.CV.Structure; namespace Camera { @@ -30,6 +33,7 @@ namespace Camera private ConcurrentDictionary _ledZones = new ConcurrentDictionary(); private ConcurrentDictionary _ledZoneColors = new ConcurrentDictionary(); private ConcurrentDictionary _ledZoneDetectionResults = new ConcurrentDictionary(); + private LedDetector _ledDetector = new LedDetector(); private Color _detectionZoneColor = Color.Black; // 检测状态 @@ -81,11 +85,48 @@ namespace Camera } } + private static bool _isEmguCvAvailable = false; + private static string _emguCvError = ""; + + public static bool CheckEmguCv() + { + try + { + using (var testImage = new Image(1, 1)) + { + testImage.Dispose(); + } + _isEmguCvAvailable = true; + return true; + } + catch (Exception ex) + { + _isEmguCvAvailable = false; + _emguCvError = ex.Message; + return false; + } + } + + public static bool IsEmguCvAvailable() + { + return _isEmguCvAvailable; + } + + public static string GetEmguCvError() + { + return _emguCvError; + } + /// /// 开始获取图像 /// public void Start() { + if (!CheckEmguCv()) + { + throw new InvalidOperationException("Emgu CV 初始化失败:" + _emguCvError); + } + Stop(); _timer = new System.Timers.Timer(200); @@ -523,51 +564,53 @@ namespace Camera private void DetectLedZones(Image image) { if (image == null || _ledZones.Count == 0) return; + if (_detectionZone.Width <= 0 || _detectionZone.Height <= 0) return; try { using (Bitmap bmp = new Bitmap(image)) { - foreach (var kvp in _ledZones) + if (_detectionZone.X < 0 || _detectionZone.Y < 0 || + _detectionZone.X + _detectionZone.Width > bmp.Width || + _detectionZone.Y + _detectionZone.Height > bmp.Height) + return; + + using (var imageBgr = new Image(bmp)) { - int index = kvp.Key; - Rectangle zone = kvp.Value; - - if (zone.Width <= 0 || zone.Height <= 0) continue; - if (zone.X < 0 || zone.Y < 0 || zone.X + zone.Width > bmp.Width || zone.Y + zone.Height > bmp.Height) - continue; - - int redPixelCount = 0; - int greenPixelCount = 0; - int totalPixels = 0; - - for (int x = zone.X; x < zone.X + zone.Width; x++) + foreach (var kvp in _ledZones) { - for (int y = zone.Y; y < zone.Y + zone.Height; y++) + int index = kvp.Key; + Rectangle zone = kvp.Value; + + if (zone.Width <= 0 || zone.Height <= 0) continue; + Rectangle ledRect = new Rectangle( + _detectionZone.X + zone.X, + _detectionZone.Y + zone.Y, + zone.Width, + zone.Height); + + if (ledRect.X < 0 || ledRect.Y < 0 || + ledRect.X + ledRect.Width > bmp.Width || + ledRect.Y + ledRect.Height > bmp.Height) + continue; + + var detectResult = _ledDetector.Detect(imageBgr, ledRect); + string result = ""; + if (detectResult.Item1 == LedState.On) { - Color pixel = bmp.GetPixel(x, y); - if (pixel.R > 150 && pixel.G < 100 && pixel.B < 100) - { - redPixelCount++; - } - else if (pixel.G > 150 && pixel.R < 100 && pixel.B < 100) - { - greenPixelCount++; - } - totalPixels++; + if (detectResult.Item2 == LedColor.Red) + result = "Red"; + else if (detectResult.Item2 == LedColor.Green) + result = "Green"; + else if (detectResult.Item2 == LedColor.Blue) + result = "Blue"; } + else + { + result = "Off"; + } + _ledZoneDetectionResults[index] = result; } - - string result = ""; - if (totalPixels > 0) - { - if (redPixelCount * 100 / totalPixels > 30) - result = "Red"; - else if (greenPixelCount * 100 / totalPixels > 30) - result = "Green"; - } - - _ledZoneDetectionResults[index] = result; } } } diff --git a/Windows/CS/Framework4.0/Camera/Camera/Camera.csproj b/Windows/CS/Framework4.0/Camera/Camera/Camera.csproj index 7c4f9d4..c70e147 100644 --- a/Windows/CS/Framework4.0/Camera/Camera/Camera.csproj +++ b/Windows/CS/Framework4.0/Camera/Camera/Camera.csproj @@ -1,5 +1,6 @@  + Debug @@ -11,6 +12,8 @@ v4.0 512 true + + AnyCPU @@ -35,6 +38,21 @@ + + ..\packages\EmguCV.3.1.0.1\lib\net30\Emgu.CV.UI.dll + + + ..\packages\EmguCV.3.1.0.1\lib\net30\Emgu.CV.UI.GL.dll + + + ..\packages\EmguCV.3.1.0.1\lib\net30\Emgu.CV.World.dll + + + ..\packages\OpenTK.1.1.2225.0\lib\net20\OpenTK.dll + + + ..\packages\OpenTK.GLControl.1.1.2225.0\lib\net20\OpenTK.GLControl.dll + @@ -45,9 +63,13 @@ + + ..\packages\ZedGraph.5.1.5\lib\ZedGraph.dll + + Setting.cs @@ -66,6 +88,8 @@ True Resources.resx + + SettingsSingleFileGenerator Settings.Designer.cs @@ -76,5 +100,19 @@ True + + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + \ No newline at end of file diff --git a/Windows/CS/Framework4.0/Camera/Camera/LedDetector.cs b/Windows/CS/Framework4.0/Camera/Camera/LedDetector.cs new file mode 100644 index 0000000..1160801 --- /dev/null +++ b/Windows/CS/Framework4.0/Camera/Camera/LedDetector.cs @@ -0,0 +1,45 @@ +using System; +using System.Drawing; +using Emgu.CV; +using Emgu.CV.CvEnum; +using Emgu.CV.Structure; + +public enum LedState { Off, On } + +public enum LedColor { Unknown, Red, Green, Blue } + +public class LedDetector +{ + public Tuple Detect(Image image, Rectangle roi) + { + using (Image subImg = image.GetSubRect(roi)) + using (Image hsv = subImg.Convert()) + { + Image H = hsv[0]; + Image S = hsv[1]; + Image V = hsv[2]; + + double avgH = CvInvoke.Mean(H).V0; + double avgS = CvInvoke.Mean(S).V0; + double avgV = CvInvoke.Mean(V).V0; + + H.Dispose(); + S.Dispose(); + V.Dispose(); + + bool isOff = (avgS < 38) || (avgV < 55); + if (isOff) + return new Tuple(LedState.Off, LedColor.Unknown); + + LedColor color = LedColor.Unknown; + if ((avgH >= 0 && avgH <= 10) || (avgH >= 170 && avgH <= 180)) + color = LedColor.Red; + else if (avgH >= 35 && avgH <= 75) + color = LedColor.Green; + else if (avgH >= 90 && avgH <= 130) + color = LedColor.Blue; + + return new Tuple(LedState.On, color); + } + } +} diff --git a/Windows/CS/Framework4.0/Camera/Camera/OpenTK.dll.config b/Windows/CS/Framework4.0/Camera/Camera/OpenTK.dll.config new file mode 100644 index 0000000..7098d39 --- /dev/null +++ b/Windows/CS/Framework4.0/Camera/Camera/OpenTK.dll.config @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Windows/CS/Framework4.0/Camera/Camera/packages.config b/Windows/CS/Framework4.0/Camera/Camera/packages.config new file mode 100644 index 0000000..364fbe5 --- /dev/null +++ b/Windows/CS/Framework4.0/Camera/Camera/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Windows/CS/Framework4.0/Camera/Test/Form1.cs b/Windows/CS/Framework4.0/Camera/Test/Form1.cs index f8e0518..13a6c15 100644 --- a/Windows/CS/Framework4.0/Camera/Test/Form1.cs +++ b/Windows/CS/Framework4.0/Camera/Test/Form1.cs @@ -50,8 +50,15 @@ namespace Test { if (button1.Text == "获取摄像头图像") { - button1.Text = "停止获取"; - _camera.Start(); + try + { + _camera.Start(); + button1.Text = "停止获取"; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } else { diff --git a/Windows/CS/Framework4.0/Camera/Test/Test.csproj b/Windows/CS/Framework4.0/Camera/Test/Test.csproj index 4b45671..8335d07 100644 --- a/Windows/CS/Framework4.0/Camera/Test/Test.csproj +++ b/Windows/CS/Framework4.0/Camera/Test/Test.csproj @@ -13,7 +13,7 @@ true - AnyCPU + x86 true full false