diff options
author | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-05-20 07:12:18 +0300 |
---|---|---|
committer | Tiago Conceição <Tiago_caza@hotmail.com> | 2021-05-20 07:12:18 +0300 |
commit | ad92a0aa5cef5a9be46e2ba20ac5482fc9030015 (patch) | |
tree | 113d66f4d0b5f63924e3f089c412fb47f8f493bd /UVtools.Core | |
parent | c43badb9c15b22a27b1cae5e386f158c6c2f3b11 (diff) |
v2.12.2v2.12.2
- (Add) Layer action - Export layers to heat map: Export a layer range to a grayscale heat map image that represents the median of the mass in the Z depth/perception. The pixel brightness/intensity shows where the most mass are concentrated.
Diffstat (limited to 'UVtools.Core')
-rw-r--r-- | UVtools.Core/Operations/Operation.cs | 2 | ||||
-rw-r--r-- | UVtools.Core/Operations/OperationLayerExportHeatMap.cs | 159 | ||||
-rw-r--r-- | UVtools.Core/Operations/OperationLayerImport.cs | 2 | ||||
-rw-r--r-- | UVtools.Core/UVtools.Core.csproj | 2 |
4 files changed, 162 insertions, 3 deletions
diff --git a/UVtools.Core/Operations/Operation.cs b/UVtools.Core/Operations/Operation.cs index 5cb7cad..f8b9b10 100644 --- a/UVtools.Core/Operations/Operation.cs +++ b/UVtools.Core/Operations/Operation.cs @@ -405,7 +405,7 @@ namespace UVtools.Core.Operations { if (!HaveMask) return null; - var mask = mat.CloneBlank(); + var mask = EmguExtensions.InitMat(mat.Size); using VectorOfVectorOfPoint vec = new(points); CvInvoke.DrawContours(mask, vec, -1, EmguExtensions.WhiteByte, -1); return GetRoiOrDefault(mask); diff --git a/UVtools.Core/Operations/OperationLayerExportHeatMap.cs b/UVtools.Core/Operations/OperationLayerExportHeatMap.cs new file mode 100644 index 0000000..eb6482c --- /dev/null +++ b/UVtools.Core/Operations/OperationLayerExportHeatMap.cs @@ -0,0 +1,159 @@ +/* + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + */ + +using System; +using System.Text; +using System.Threading.Tasks; +using Emgu.CV; +using Emgu.CV.CvEnum; +using UVtools.Core.Extensions; +using UVtools.Core.FileFormats; + +namespace UVtools.Core.Operations +{ + [Serializable] + public sealed class OperationLayerExportHeatMap : Operation + { + #region Members + private string _filePath; + private bool _cropByRoi = true; + + #endregion + + #region Overrides + + public override bool CanHaveProfiles => false; + public override string Title => "Export layers to heat map"; + + public override string Description => + "Export a layer range to a grayscale heat map image that represents the median of the mass in the Z depth/perception\n" + + "The pixel brightness/intensity shows where the most mass are concentrated."; + + public override string ConfirmationText => + $"generate a heatmap from layers {LayerIndexStart} through {LayerIndexEnd}?"; + + public override string ProgressTitle => + $"Generating a heatmap from layers {LayerIndexStart} through {LayerIndexEnd}"; + + public override string ProgressAction => "Packed layers"; + + public override string ValidateInternally() + { + var sb = new StringBuilder(); + + if (LayerRangeCount < 2) + { + sb.AppendLine("To generate a heat map at least two layers are required."); + } + + return sb.ToString(); + } + + public override string ToString() + { + var result = $"[Crop by ROI: {_cropByRoi}]" + + LayerRangeString; + if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}"; + return result; + } + + #endregion + + #region Properties + + public string FilePath + { + get => _filePath; + set => RaiseAndSetIfChanged(ref _filePath, value); + } + + public bool CropByROI + { + get => _cropByRoi; + set => RaiseAndSetIfChanged(ref _cropByRoi, value); + } + + #endregion + + #region Constructor + + public OperationLayerExportHeatMap() + { } + + public OperationLayerExportHeatMap(FileFormat slicerFile) : base(slicerFile) + { + _filePath = SlicerFile.FileFullPath + ".heatmap.png"; + } + + #endregion + + #region Methods + + protected override bool ExecuteInternally(OperationProgress progress) + { + using var sumMat32 = EmguExtensions.InitMat(SlicerFile.Resolution, 1, DepthType.Cv32S); + var sumMat32Roi = GetRoiOrDefault(sumMat32); + using var mask = GetMask(sumMat32); + + + Parallel.For(LayerIndexStart, LayerIndexEnd+1, layerIndex => + { + if (progress.Token.IsCancellationRequested) return; + + using var mat = SlicerFile[layerIndex].LayerMat; + using var mat32 = new Mat(); + mat.ConvertTo(mat32, DepthType.Cv32S); + var mat32Roi = GetRoiOrDefault(mat32); + + lock (progress.Mutex) + { + CvInvoke.Add(sumMat32Roi, mat32Roi, sumMat32Roi, mask); + progress++; + } + }); + + if (!progress.Token.IsCancellationRequested) + { + using var sumMat = EmguExtensions.InitMat(sumMat32.Size); + sumMat32.ConvertTo(sumMat, DepthType.Cv8U, 1.0 / LayerRangeCount); + if (_cropByRoi && HaveROI) + { + var sumMatRoi = GetRoiOrDefault(sumMat); + sumMatRoi.Save(_filePath); + } + else + { + sumMat.Save(_filePath); + } + } + + return !progress.Token.IsCancellationRequested; + } + + #endregion + + #region Equality + + private bool Equals(OperationLayerExportHeatMap other) + { + return _filePath == other._filePath && _cropByRoi == other._cropByRoi; + } + + public override bool Equals(object obj) + { + return ReferenceEquals(this, obj) || obj is OperationLayerExportHeatMap other && Equals(other); + } + + public override int GetHashCode() + { + return HashCode.Combine(_filePath, _cropByRoi); + } + + #endregion + } +} diff --git a/UVtools.Core/Operations/OperationLayerImport.cs b/UVtools.Core/Operations/OperationLayerImport.cs index c1be566..5f10340 100644 --- a/UVtools.Core/Operations/OperationLayerImport.cs +++ b/UVtools.Core/Operations/OperationLayerImport.cs @@ -53,7 +53,7 @@ namespace UVtools.Core.Operations public override Enumerations.LayerRangeSelection StartLayerRangeSelection => Enumerations.LayerRangeSelection.None; public override bool CanROI => false; - public override string Title => "Import Layers"; + public override string Title => "Import layers"; public override string Description => "Import layers from local files into the model at a selected layer height.\n" + diff --git a/UVtools.Core/UVtools.Core.csproj b/UVtools.Core/UVtools.Core.csproj index 9dedee7..5a6763a 100644 --- a/UVtools.Core/UVtools.Core.csproj +++ b/UVtools.Core/UVtools.Core.csproj @@ -10,7 +10,7 @@ <RepositoryUrl>https://github.com/sn4k3/UVtools</RepositoryUrl> <PackageProjectUrl>https://github.com/sn4k3/UVtools</PackageProjectUrl> <Description>MSLA/DLP, file analysis, calibration, repair, conversion and manipulation</Description> - <Version>2.12.1</Version> + <Version>2.12.2</Version> <Copyright>Copyright © 2020 PTRTECH</Copyright> <PackageIcon>UVtools.png</PackageIcon> <Platforms>AnyCPU;x64</Platforms> |