diff --git a/TIASshot/Form1.cs b/TIASshot/Form1.cs index addd421..cf1953c 100644 --- a/TIASshot/Form1.cs +++ b/TIASshot/Form1.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Diagnostics; using System.Drawing; using System.Linq; using System.Reflection; @@ -9,6 +10,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Interop; +using System.Windows.Media.Media3D; using System.Xml.Serialization; namespace TIASshot { @@ -16,6 +18,7 @@ public static string APP_NAME = "TIAS Shot"; private Lucam _lucam; + private LightSource _light = new LightSource(); /// /// コンストラクタ @@ -44,11 +47,15 @@ Close(); return; } + + txtDeviceName.Text = _lucam.DeviceName; txtSerialNo.Text = _lucam.SerialNumber; txtSaveFolder.Text = Config.GetString("SaveFolder"); EnableShots(false); _lucam.StartStopPreview(); + + _light.Open(); } /// @@ -109,6 +116,7 @@ return; } txtMessage.Text = msg; + txtMessage.Update(); } /// diff --git a/TIASshot/LightSource.cs b/TIASshot/LightSource.cs new file mode 100644 index 0000000..60bb193 --- /dev/null +++ b/TIASshot/LightSource.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO.Ports; +using System.Management; +using System.Diagnostics; + +namespace TIASshot { + internal class LightSource { + SerialPort _serial; + + public LightSource() { + _serial = new SerialPort(); + } + + private string FindPort(string deviceName) { + var portname = ""; + var mcW32SerPort = new ManagementClass("Win32_SerialPort"); + foreach (var port in mcW32SerPort.GetInstances()) { + var devName = port.GetPropertyValue("Caption").ToString(); + Debug.WriteLine(devName); + if (devName.Contains(deviceName)) { + portname = port.GetPropertyValue("DeviceID").ToString(); + } + } + return portname; + } + + public bool Open() { + var portName = FindPort(Config.GetString("LightSourceDevice")); + //if (portName == "") return false; + //_serial.PortName = portName; + //_serial.BaudRate = baudRate; + //_serial.Open(); + return true; + } + } +} diff --git a/TIASshot/Lucam.cs b/TIASshot/Lucam.cs index b8d4175..1d218c1 100644 --- a/TIASshot/Lucam.cs +++ b/TIASshot/Lucam.cs @@ -20,6 +20,7 @@ using static System.Resources.ResXFileRef; using System.Windows.Shapes; using Path = System.IO.Path; +using OpenCvSharp.Dnn; namespace TIASshot { @@ -28,9 +29,9 @@ /// internal class Lucam { - // Todo: RGB->XYZ 変換行列算出 - // Todo: SRGB->XYZ 変換行列算出 // 光源の輝度設定 + // 連続撮影のマルチスレッド化 + // GUI更新はタイマー使用に変更 public string DeviceName { get; private set; } = "Unknown"; public string SerialNumber { get; private set; } @@ -65,7 +66,7 @@ int _detectionCount = 0; Point2f _lastPosition = new Point2f(0, 0); Mat _convRGB2SRGB; - Mat _convRGB2XYZ; + //Mat _convRGB2XYZ; Mat _tccRois; // TCCのROI検出結果画像 /// @@ -329,9 +330,21 @@ if (_bmps[_bmpIndex] != null) _bmps[_bmpIndex].Dispose(); } + /// + /// チャートに基づく変換行列の計算 + /// + /// private void CalcTcc(Mat img) { - _convRGB2SRGB = CalcConvertMatrix(img, TCC_SRGB); - _convRGB2XYZ = CalcConvertMatrix(img, TCC_XYZ); + // 変換行列の計算 + var tccRgb = GetTccRgb(img); + _convRGB2SRGB = CalcConvertMatrix(tccRgb, TCC_SRGB); + var _convRGB2XYZ = CalcConvertMatrix(tccRgb, TCC_XYZ); + var tccSrgb = ConvertColor(tccRgb, _convRGB2SRGB); + var convSrgb2Xyz = CalcConvertMatrix(tccSrgb, TCC_XYZ); + + // 変換精度検証 + var diff = Math.Sqrt(Cv2.Norm(TCC_SRGB, tccSrgb, NormTypes.L2)); + Debug.WriteLine($"RGB→SRGB 変換行列の誤差 = {diff:.000}"); // データ保存 var folder = GetSaveFolder("校正"); @@ -339,6 +352,7 @@ Cv2.ImWrite(Path.Combine(folder, Config.GetString("TccRoisFile")), _tccRois); SaveMatToCsv(Path.Combine(folder, Config.GetString("ConvSrgbSaveFile")), _convRGB2SRGB); SaveMatToCsv(Path.Combine(folder, Config.GetString("ConvXyzSaveFile")), _convRGB2XYZ); + SaveMatToCsv(Path.Combine(folder, Config.GetString("ConvSrgb2XyzSaveFile")), convSrgb2Xyz); _form.ShowMessage("自動校正完了"); _form.EnableShots(); @@ -346,12 +360,11 @@ } /// - /// 変換行列算出 + /// 画像からチャートのRGB値算出 /// - /// 画像 - /// 変換目標の24x3行列 - private Mat CalcConvertMatrix(Mat img, Mat target) { - // 画像からチャートのRGB値算出 + /// + /// + private Mat GetTccRgb(Mat img) { var arrRGB = new Mat(24, 3, MatType.CV_64FC1); for (int i = 0; i < _chartMasks.Count; i++) { var rgb = Cv2.Mean(img, _chartMasks[i]); @@ -359,31 +372,34 @@ arrRGB.At(i, 1) = rgb.Val1; arrRGB.At(i, 2) = rgb.Val2; } - var extended = ExtendMat(arrRGB); - //Debug.WriteLine("extended"); - //Debug.WriteLine(extended.Dump()); + return arrRGB; + } - // 変換行列算出 + /// + /// 変換行列算出 + /// + /// 画像 + /// 変換目標の24x3行列 + private Mat CalcConvertMatrix(Mat src, Mat target) { + var extended = ExtendMat(src); Mat convMat = new Mat(17, 3, MatType.CV_64FC1); Cv2.Solve(extended, target, convMat, DecompTypes.SVD); - //Debug.WriteLine("convMat"); - //Debug.WriteLine(convMat.Dump()); - - // 変換精度検証 - var converted = extended * convMat; - //Debug.WriteLine("converted"); - //Debug.WriteLine(converted.ToMat().Dump()); - - //Mat impSRGB = converted.ToMat().Reshape(3); - //Cv2.ImWrite("impSRGB.png", impSRGB); - - var diff = Math.Sqrt(Cv2.Norm(target, converted, NormTypes.L2)); - Debug.WriteLine($"変換行列の誤差 = {diff:.000}"); - return convMat; } /// + /// 色変換 + /// + /// + /// + /// + private Mat ConvertColor(Mat src, Mat convMat) { + var extended = ExtendMat(src); + var converted = extended * convMat; + return converted.ToMat(); + } + + /// /// 画像撮影1枚 /// public void ShotOne() { @@ -421,9 +437,13 @@ _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)) { using (Mat imgt = img.T()) { - Cv2.ImWrite(Path.Combine(folder, $"Shot{i + 1:0000}.bmp"), imgt); + var filename = Config.GetString("ImageRgbFile"); + filename = filename.Replace("0000", $"{i + 1:0000}"); + Cv2.ImWrite(Path.Combine(folder, filename), imgt); using (var converted = ConvertImage(imgt, _convRGB2SRGB)) { - Cv2.ImWrite(Path.Combine(folder, $"Srgb{i+1:0000}.jpg"), converted); + filename = Config.GetString("ImageSrgbFile"); + filename = filename.Replace("0000", $"{i + 1:0000}"); + Cv2.ImWrite(Path.Combine(folder, filename), converted); } } } diff --git a/TIASshot/TIASshot.csproj b/TIASshot/TIASshot.csproj index ff8353c..3c1dc17 100644 --- a/TIASshot/TIASshot.csproj +++ b/TIASshot/TIASshot.csproj @@ -78,6 +78,7 @@ ..\packages\System.Drawing.Common.8.0.0\lib\net462\System.Drawing.Common.dll + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll @@ -113,6 +114,7 @@ Form1.cs + diff --git a/TIASshot/config.xml b/TIASshot/config.xml index d66d0dd..92179a8 100644 --- a/TIASshot/config.xml +++ b/TIASshot/config.xml @@ -1,13 +1,13 @@ - 45.0 - 1.5 + 25.0 + 1.0 2.62 1.72 1.70 - 220 - 220 - 200 + 226 + 226 + 226 0.5 50 5 @@ -19,7 +19,11 @@ tcc_xyz.csv tcc.png tcc_rois.jpg + Shot0000.bmp + Srgb0000.bmp conv_rgb_srgb.csv conv_rgb_xyz.csv + conv_srgb_xyz.csv C:\TIAS_Data + Silicon Labs CP210x