diff --git a/TIASshot/Config.cs b/TIASshot/Config.cs new file mode 100644 index 0000000..06ac672 --- /dev/null +++ b/TIASshot/Config.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; + +namespace TIASshot { + internal static class Config { + static string configFile = "config.xml"; + static XmlDocument doc = new XmlDocument(); + + public static void Load() { + doc.Load(configFile); + } + + public static float GetFloat(string param) { + float value = 0.0f; + XmlNode node = doc.SelectSingleNode($"//Config/{param}"); + + if (node != null && float.TryParse(node.InnerText, out float result)) { + value = result; + } + return value; + } + + public static int GetInt(string param) { + int value = 0; + XmlNode node = doc.SelectSingleNode($"//Config/{param}"); + + if (node != null && int.TryParse(node.InnerText, out int result)) { + value = result; + } + return value; + } + } +} diff --git a/TIASshot/Lucam.cs b/TIASshot/Lucam.cs index e50b63b..18ce235 100644 --- a/TIASshot/Lucam.cs +++ b/TIASshot/Lucam.cs @@ -29,8 +29,8 @@ public string ErrorMsg { get; private set; } readonly Dictionary ARDict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryName.Dict4X4_50); - readonly float RefRGB = 230.0F; - readonly float UpdateRate = 0.5F; + readonly float RefRGB; + readonly float UpdateRate; readonly Point2f[] PointsDst40 = new Point2f[] { new Point2f(345, 130),new Point2f(465, 130),new Point2f(465, 250),new Point2f(345, 250), }; @@ -52,6 +52,8 @@ Bitmap[] _bmps = new Bitmap[2]; int _bmpIndex = 0; List _chartMasks = new List(); + int _detectionCount = 0; + Point2f _lastPosition = new Point2f(0, 0); /// /// コンストラクタ @@ -63,9 +65,13 @@ _picDisplay = display; _form = form; + Config.Load(); + RefRGB = Config.GetFloat("ReferenceValue"); + UpdateRate = Config.GetFloat("UpdateRate"); + // カメラパラメータの初期値 _snap.BufferLastFrame = false; - _snap.Exposure = 60; + _snap.Exposure = Config.GetFloat("Exposure"); _snap.ExposureDelay = 0; _snap.flReserved1 = 0; _snap.flReserved2 = 0; @@ -80,11 +86,11 @@ _snap.Format.Width = 1280; _snap.Format.X = 0; _snap.Format.Y = 0; - _snap.Gain = 1.5f; - _snap.GainBlue = 1.31f; - _snap.GainGrn1 = 1.57f; + _snap.Gain = Config.GetFloat("Gain"); + _snap.GainBlue = Config.GetFloat("GainB"); + _snap.GainGrn1 = Config.GetFloat("GainG"); _snap.GainGrn2 = _snap.GainGrn1; - _snap.GainRed = 3.0f; + _snap.GainRed = Config.GetFloat("GainR"); _snap.ShutterType = dll.LucamShutterType.GlobalShutter; _snap.StrobeDelay = 0.1f; _snap.StrobeFlags = 0; @@ -164,8 +170,8 @@ /// /// /// - private float GetRatio(float value) { - float ratio = RefRGB / value; + private float GetRatio(float value, float target) { + float ratio = target / value; ratio = (ratio - 1.0f) * (value == 255.0f ? 1.0f : UpdateRate) + 1.0f; return ratio; } @@ -176,17 +182,20 @@ /// private void DetectChart(Mat img) { + // ARマーカー検出 CvAruco.DetectMarkers(img, ARDict, out var corners, out var ids, new DetectorParameters(), out var rejectedImgPoints); if (ids.Length < 1) return; + // マーカー座標格納 var ptsPict = new List(); var ptsModel = new List(); - + Point2f position = new Point2f(); for (int i = 0; i < ids.Length; i++) { if (ids[i] == 40) { ptsPict.AddRange(corners[i]); ptsModel.AddRange(PointsDst40); + position = corners[i][3]; } if (ids[i] == 41) { ptsPict.AddRange(corners[i]); @@ -195,13 +204,24 @@ } if (ptsPict.Count < 8) return; + // チャートの固定判定 + var dist = (float)position.DistanceTo(_lastPosition); + if (dist < Config.GetFloat("ChartSetCriteria")) { + _detectionCount++; + } else { + _detectionCount = 0; + } + _lastPosition = position; + if (_detectionCount < Config.GetInt("ChartSetCount")) return; + + // ホモグラフィの計算 var matPtsPict = Mat.FromArray(ptsPict); var matPtsModel = Mat.FromArray(ptsModel); var matH = Cv2.FindHomography(matPtsModel, matPtsPict); - var imgF = new Mat(1545, 810, MatType.CV_8UC3); Cv2.WarpPerspective(img, imgF, matH, imgF.Size()); + // チャートマスク作成 _chartMasks.Clear(); var roiSize = ptsPict.Count < 8 ? 60 : 80; for (int i = 0; i < 24; i++) { @@ -215,14 +235,14 @@ var maskF = new Mat(img.Size(), MatType.CV_8U); Cv2.WarpPerspective(mask, maskF, matH, maskF.Size()); _chartMasks.Add(maskF); + img.SetTo(new Scalar(0, 200, 0), maskF); } } - img.SetTo(new Scalar(0, 200, 0), _chartMasks[12]); Cv2.ImWrite("チャート検出結果.jpg", img); Debug.WriteLine("チャート検出結果.jpg 保存"); _form.ShowMessage("舌診チャート検出 校正中"); - _calibrating = 30; + _calibrating = Config.GetInt("CalibrationFrames"); } /// @@ -233,18 +253,18 @@ /// データサイズ /// void PreviewCallback(IntPtr pContext, IntPtr pData, int n, uint unused) { - using (Mat img = Mat.FromPixelData(1024, 1280, MatType.CV_8UC3, pData)) { + using (Mat img = Mat.FromPixelData(_snap.Format.Height, _snap.Format.Width, MatType.CV_8UC3, pData)) { using (Mat imgt = img.T()) { _bmps[_bmpIndex] = imgt.ToBitmap(); if (_calibrating > 0) { var whitePatch = Cv2.Mean(imgt, _chartMasks[12]); Debug.WriteLine($"White patch R {whitePatch.Val2:.00} G {whitePatch.Val1:.00} B {whitePatch.Val0:.00}"); - if (_calibrating % 5 == 0) { - _snap.GainBlue *= GetRatio((float)whitePatch.Val0); - _snap.GainGrn1 *= GetRatio((float)whitePatch.Val1); + if (_calibrating % Config.GetInt("CalibrationUpdateInterval") == 0) { + _snap.GainBlue *= GetRatio((float)whitePatch.Val0, Config.GetFloat("ReferenceB")); + _snap.GainGrn1 *= GetRatio((float)whitePatch.Val1, Config.GetFloat("ReferenceG")); _snap.GainGrn2 = _snap.GainGrn1; - _snap.GainRed *= GetRatio((float)whitePatch.Val2); + _snap.GainRed *= GetRatio((float)whitePatch.Val2, Config.GetFloat("ReferenceR")); SetCameraParam(); } _calibrating--; @@ -276,7 +296,7 @@ /// 複数画像撮影 /// public void ShotMulti() { - Shot(5, 1000); + Shot(Config.GetInt("MultiShotCount"), Config.GetInt("MultiShotInterval")); } /// @@ -284,7 +304,7 @@ /// /// /// - private void Shot(int numImages=1, int interval = 1000) { + private void Shot(int numImages = 1, int interval = 1000) { SetSnapParam(); dll.LucamEnableFastFrames(_hCam, ref _snap); var imageSize = _snap.Format.Width * _snap.Format.Height; @@ -295,9 +315,10 @@ //Debug.WriteLine(ret); if (i < numImages - 1) Thread.Sleep(interval); - dll.LucamConvertFrameToRgb24(_hCam, rgbImage, rawImage, _snap.Format.Width, _snap.Format.Height, dll.LucamPixelFormat.PF_8, ref _convert); - using (Mat img = Mat.FromPixelData(1024, 1280, MatType.CV_8UC3, rgbImage)) { - Cv2.ImWrite($"orig_{i:00}.jpg", img); + dll.LucamConvertFrameToRgb24(_hCam, rgbImage, rawImage, + _snap.Format.Width, _snap.Format.Height, dll.LucamPixelFormat.PF_8, ref _convert); + using (Mat img = Mat.FromPixelData(_snap.Format.Height, _snap.Format.Width, MatType.CV_8UC3, rgbImage)) { + //Cv2.ImWrite($"orig_{i:00}.jpg", img); using (Mat imgt = img.T()) { Cv2.ImWrite($"snap_{i:00}.jpg", imgt); } diff --git a/TIASshot/TIASshot.csproj b/TIASshot/TIASshot.csproj index 1d1e1d2..44f81fa 100644 --- a/TIASshot/TIASshot.csproj +++ b/TIASshot/TIASshot.csproj @@ -106,6 +106,7 @@ + Form @@ -141,6 +142,9 @@ + + + @@ -148,4 +152,7 @@ + + copy /Y $(ProjectDir)config.xml $(TargetDir) + \ No newline at end of file diff --git a/TIASshot/config.xml b/TIASshot/config.xml new file mode 100644 index 0000000..3b5432f --- /dev/null +++ b/TIASshot/config.xml @@ -0,0 +1,18 @@ + + + 45.0 + 1.5 + 2.62 + 1.72 + 1.70 + 230 + 230 + 200 + 0.5 + 50 + 5 + 5 + 1000 + 4.0 + 30 +