1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
/*
* 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.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
using UVtools.Core.FileFormats;
namespace UVtools.Core.Operations
{
[Serializable]
public class OperationThreshold : Operation
{
#region Members
private byte _threshold = 127;
private byte _maximum = 255;
private ThresholdType _type = ThresholdType.Binary;
#endregion
#region Overrides
public override string Title => "Threshold pixels";
public override string Description =>
"Manipulate pixel values based on a threshold.\n\n" +
"Pixles brighter than the theshold will be set to the Max value, " +
"all other pixels will be set to 0.\n\n" +
"See https://docs.opencv.org/master/d7/d4d/tutorial_py_thresholding.html";
public override string ConfirmationText =>
$"apply threshold {Threshold} with max {Maximum} from layers {LayerIndexStart} through {LayerIndexEnd}";
public override string ProgressTitle =>
$"Applying threshold {Threshold} with max {Maximum} from layers {LayerIndexStart} through {LayerIndexEnd}";
public override string ProgressAction => "Thresholded layers";
public override string ToString()
{
var result = $"[{_type} = {_threshold} / {_maximum}]" + LayerRangeString;
if (!string.IsNullOrEmpty(ProfileName)) result = $"{ProfileName}: {result}";
return result;
}
#endregion
#region Constructor
public OperationThreshold() { }
public OperationThreshold(FileFormat slicerFile) : base(slicerFile) { }
#endregion
#region Properties
public byte Threshold
{
get => _threshold;
set => RaiseAndSetIfChanged(ref _threshold, value);
}
public byte Maximum
{
get => _maximum;
set => RaiseAndSetIfChanged(ref _maximum, value);
}
public ThresholdType Type
{
get => _type;
set => RaiseAndSetIfChanged(ref _type, value);
}
public static Array ThresholdTypes => Enum.GetValues(typeof(ThresholdType));
#endregion
#region Methods
protected override bool ExecuteInternally(OperationProgress progress)
{
Parallel.For(LayerIndexStart, LayerIndexEnd + 1, layerIndex =>
{
if (progress.Token.IsCancellationRequested) return;
using (var mat = SlicerFile[layerIndex].LayerMat)
{
Execute(mat);
SlicerFile[layerIndex].LayerMat = mat;
}
lock (progress.Mutex)
{
progress++;
}
});
return !progress.Token.IsCancellationRequested;
}
public override bool Execute(Mat mat, params object[] arguments)
{
using var original = mat.Clone();
var target = GetRoiOrDefault(mat);
CvInvoke.Threshold(target, target, Threshold, Maximum, Type);
ApplyMask(original, mat);
return true;
}
#endregion
#region Equality
protected bool Equals(OperationThreshold other)
{
return _threshold == other._threshold && _maximum == other._maximum && _type == other._type;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((OperationThreshold) obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = _threshold.GetHashCode();
hashCode = (hashCode * 397) ^ _maximum.GetHashCode();
hashCode = (hashCode * 397) ^ (int) _type;
return hashCode;
}
}
#endregion
}
}
|