diff --git a/TIASshot/CameraBase.cs b/TIASshot/CameraBase.cs index 3bb12d5..dfd58a2 100644 --- a/TIASshot/CameraBase.cs +++ b/TIASshot/CameraBase.cs @@ -168,10 +168,22 @@ protected void SaveThread(int numImages) { int saveCount = 0; while (saveCount < numImages) { - while(_shots.Count <= saveCount) { - Thread.Sleep(1); + Mat m = null; + lock (_shots) { + if (_shots.Count > 0) { + m = _shots[0]; + _shots.RemoveAt(0); + } } - SaveImages(_shots[saveCount], saveCount); + if (m is null) { + Thread.Sleep(1); + continue; + } + try { + SaveImages(m, saveCount); + } finally { + m.Dispose(); + } saveCount++; _form.ShowMessage($"画像{saveCount}/{numImages}枚目保存"); } @@ -282,37 +294,54 @@ Cv2.ImWrite(Path.Combine(_saveFolder, Config.GetString("File/TccRoisImage")), imgRois); SaveMatToCsv(Path.Combine(_saveFolder, Config.GetString("File/TccRgbValues")), tccRgb); + // Dispose any existing conversion matrices before overwriting + foreach (var kv in _convRGB2SRGB) { + kv.Value?.Dispose(); + } _convRGB2SRGB.Clear(); + foreach (var channel in ChannelList) { var convRGB2SRGB = CalcConvertMatrix(tccRgb, TCC_SRGB, channel); SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/ConvRgb2Srgb", channel)), convRGB2SRGB); var convRGB2XYZ = CalcConvertMatrix(tccRgb, TCC_XYZ, channel); - SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/ConvRgb2Xyz", channel)), convRGB2XYZ); - if (channel == 17) { - var convOld = new Mat(convRGB2XYZ.Size(), MatType.CV_64FC1); - for (var row = 0; row < convRGB2XYZ.Rows; row++) { - var rowFrom = (row + 1) % convRGB2XYZ.Rows; // 1行ずらす - for (var col = 0; col < convRGB2XYZ.Cols; col++) { - convOld.At(row, col) = convRGB2XYZ.At(rowFrom, col); + try { + SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/ConvRgb2Xyz", channel)), convRGB2XYZ); + + if (channel == 17) { + var convOld = new Mat(convRGB2XYZ.Size(), MatType.CV_64FC1); + for (var row = 0; row < convRGB2XYZ.Rows; row++) { + var rowFrom = (row + 1) % convRGB2XYZ.Rows; // 1行ずらす + for (var col = 0; col < convRGB2XYZ.Cols; col++) { + convOld.At(row, col) = convRGB2XYZ.At(rowFrom, col); + } } + SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/ConvRgb2XyzOld", channel)), convOld); + convOld.Dispose(); } - SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/ConvRgb2XyzOld", channel)), convOld); - } - var tccSrgb = ConvertColor(tccRgb, convRGB2SRGB); - SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/TccSrgbValues", channel)), tccSrgb); + var tccSrgb = ConvertColor(tccRgb, convRGB2SRGB); + try { + SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/TccSrgbValues", channel)), tccSrgb); - var convSrgb2Xyz = CalcConvertMatrix(tccSrgb, TCC_XYZ, channel); - SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/ConvSrgb2Xyz", channel)), convSrgb2Xyz); + var convSrgb2Xyz = CalcConvertMatrix(tccSrgb, TCC_XYZ, channel); + try { + SaveMatToCsv(Path.Combine(_saveFolder, GetFilenameWithChannel("File/ConvSrgb2Xyz", channel)), convSrgb2Xyz); + } finally { convSrgb2Xyz.Dispose(); } - // 変換精度検証 - var diff = Math.Sqrt(Cv2.Norm(TCC_SRGB, tccSrgb, NormTypes.L2)); - Debug.WriteLine($"{channel}次元 RGB→SRGB 変換行列の誤差 = {diff:.000}"); + // 変換精度検証 + var diff = Math.Sqrt(Cv2.Norm(TCC_SRGB, tccSrgb, NormTypes.L2)); + Debug.WriteLine($"{channel}次元 RGB→SRGB 変換行列の誤差 = {diff:.000}"); + } finally { tccSrgb.Dispose(); } + } finally { convRGB2XYZ.Dispose(); } _convRGB2SRGB.Add(channel, convRGB2SRGB); } + // Dispose temporary mats + tccRgb.Dispose(); + imgRois.Dispose(); + EventSound(Config.GetString("Sound/CalibDone")); _form.ShowMessage("自動校正完了"); _form.EnableShots(); diff --git a/TIASshot/IScam.cs b/TIASshot/IScam.cs index 08823d7..67d1d37 100644 --- a/TIASshot/IScam.cs +++ b/TIASshot/IScam.cs @@ -167,12 +167,10 @@ _ic.LiveStart(); var snapSink = _ic.Sink as FrameSnapSink; - _shots.Clear(); - snapSink.SnapSingle(TimeSpan.FromSeconds(5)); // 最初のフレームを捨てる + // 最初のフレームを捨てる + snapSink.SnapSingle(TimeSpan.FromSeconds(5)); - var thread = new Thread(() => SaveThread(numImages)); - thread.Start(); - + // 画像をその場で保存してメモリに溜めないようにする var filename = Config.GetString("File/Info"); using (var csv = new StreamWriter(Path.Combine(_saveFolder, filename))) { WriteInfo(csv); @@ -183,13 +181,17 @@ var shotTime = watch.ElapsedMilliseconds; csv.WriteLine($"{i+1},{shotTime}"); _form.ShowMessage($"撮影 {i + 1} / {numImages} 枚目"); - var buffer = snapSink.SnapSingle(TimeSpan.FromSeconds(5)); + var buffer = snapSink.SnapSingle(TimeSpan.FromSeconds(5)); using (Mat img = Mat.FromPixelData(buffer.FrameType.Height, buffer.FrameType.Width, MatType.CV_8UC3, buffer.GetIntPtr())) { using (Mat imgt_full = img.T()) { - _shots.Add(new Mat(imgt_full, _roi)); + using (Mat imgt = new Mat(imgt_full, _roi)) { + // 即座に保存しメモリに保持しない + SaveImages(imgt, i); + } } } + while (watch.ElapsedMilliseconds < interval * (i+1) && i < numImages - 1) { Thread.Sleep(1); } @@ -199,6 +201,8 @@ _ic.LiveStop(); _ic.Sink = _queueSink; _ic.LiveStart(); + // 撮影と保存が完了したため、撮影ボタンを再有効化 + _form.EnableShots(true); } } } diff --git a/TIASshot/Properties/AssemblyInfo.cs b/TIASshot/Properties/AssemblyInfo.cs index 5dce7a9..de9601b 100644 --- a/TIASshot/Properties/AssemblyInfo.cs +++ b/TIASshot/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ // ビルド番号 // リビジョン // -[assembly: AssemblyVersion("1.6.0.0")] -[assembly: AssemblyFileVersion("1.6.0.0")] +[assembly: AssemblyVersion("1.7.0.0")] +[assembly: AssemblyFileVersion("1.7.0.0")]