Skip to content

Commit d8fb22f

Browse files
Add majority replacement option for Reduce (#5670)
* Added option for majority replacement * Updated changelog
1 parent c9a429c commit d8fb22f

File tree

4 files changed

+41
-2
lines changed

4 files changed

+41
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ release.
4040
- Added Vectorize to ProcessGroundPolygon library
4141
- Added gtest files for the app and unit test
4242
- Added Chandrayaan2 template for isisimport
43+
- Added majority replacement for reduce app [#5101](https://github.com/DOI-USGS/ISIS3/issues/5101).
4344
- Added HRSC support in socetlinescankeywords [#5465](https://github.com/DOI-USGS/ISIS3/issues/5465)
4445

4546
### Changed

isis/src/base/apps/reduce/reduce.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,13 @@
334334
is closest to the center of the window being analyzed.
335335
</description>
336336
</option>
337+
<option value="MAJORITY">
338+
<brief>Majority replacement</brief>
339+
<description>
340+
When VALIDPER is not met, propagate the most commonly occurring special pixel
341+
within the input region to the output pixel.
342+
</description>
343+
</option>
337344
</list>
338345
</parameter>
339346
</group>

isis/src/base/objs/Reduce/Reduce.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,11 @@ namespace Isis {
171171
*/
172172
void Average::operator() (Isis::Buffer & out) const
173173
{
174+
// Index of the last input line that corresponds to this output line.
174175
double rline = (double)out.Line() * mdLineScale;
175176

176177
if(out.Line() == 1 && out.Band() == 1) {
178+
// Index of the last input sample that corresponds to the output sample.
177179
mdIncTab = new double[miOutputSamples];
178180
mdSum = new double[miOutputSamples];
179181
mdNpts = new double[miOutputSamples];
@@ -191,7 +193,9 @@ namespace Isis {
191193
mdIncTab[miOutputSamples-1] = miInputSamples;
192194
}
193195

194-
while(mdLine <= rline) {
196+
unordered_map<QString, int> specialPixelCounts[miOutputSamples];
197+
198+
while(mdLine < rline) {
195199
if((int)mdLine <= miInputLines) {
196200
m_iPortal->SetPosition(miStartSample, mdLine, miBandIndex);
197201
mInCube->read(*m_iPortal);
@@ -204,6 +208,9 @@ namespace Isis {
204208
mdSum[osamp] += (*m_iPortal)[isamp-1];
205209
mdNpts[osamp] += 1.0;
206210
}
211+
if (IsSpecial((*m_iPortal)[isamp-1])) {
212+
specialPixelCounts[osamp][PixelToString((*m_iPortal)[isamp-1])]++;
213+
}
207214
isamp++;
208215
}
209216

@@ -218,6 +225,12 @@ namespace Isis {
218225
mdNpts[osamp+1] += sdel;
219226
}
220227
}
228+
if (IsSpecial((*m_iPortal)[isamp-1])) {
229+
specialPixelCounts[osamp][PixelToString((*m_iPortal)[isamp-1])]++;
230+
if(osamp+1 <= miOutputSamples){
231+
specialPixelCounts[osamp+1][PixelToString((*m_iPortal)[isamp-1])]++;
232+
}
233+
}
221234
isamp++;
222235
}
223236
mdLine++;
@@ -238,6 +251,9 @@ namespace Isis {
238251
mdSum2[osamp] += (*m_iPortal)[isamp-1] * ldel;
239252
mdNpts2[osamp] += ldel;
240253
}
254+
if (IsSpecial((*m_iPortal)[isamp-1])) {
255+
specialPixelCounts[osamp][PixelToString((*m_iPortal)[isamp-1])]++;
256+
}
241257
isamp++;
242258
}
243259

@@ -257,6 +273,12 @@ namespace Isis {
257273
mdNpts2[osamp+1] += sdel * ldel;
258274
}
259275
}
276+
if (IsSpecial((*m_iPortal)[isamp-1])) {
277+
specialPixelCounts[osamp][PixelToString((*m_iPortal)[isamp-1])]++;
278+
if(osamp+1 <= miOutputSamples){
279+
specialPixelCounts[osamp+1][PixelToString((*m_iPortal)[isamp-1])]++;
280+
}
281+
}
260282
isamp++;
261283
}
262284

@@ -271,6 +293,14 @@ namespace Isis {
271293
if(msReplaceMode == "NEAREST") {
272294
out[osamp] = (*m_iPortal)[(int)(mdIncTab[osamp] + 0.5) - 1];
273295
}
296+
else if (msReplaceMode == "MAJORITY") {
297+
// Iterate over the map and compare element counts
298+
// Map iterator yields a pair: pair.first == pixel names, pair.second == pixel count.
299+
auto mode = std::max_element(specialPixelCounts[osamp].begin(),
300+
specialPixelCounts[osamp].end(),
301+
[](const pair<QString, int> &a, const pair<QString, int> &b) {return a.second < b.second;});
302+
out[osamp] = StringToPixel(mode->first);
303+
}
274304
else {
275305
out[osamp] = Isis::Null;
276306
}
@@ -281,6 +311,7 @@ namespace Isis {
281311
mdNpts2[osamp] = 0.0;
282312
}
283313

314+
// If this is the last line of the band, reset stats and increment band
284315
if(out.Line() == miOutputLines && out.Band() != miInputBands) {
285316
miBandIndex++;
286317
mdLine = 1;

isis/src/base/objs/Reduce/Reduce.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ namespace Isis {
111111
double pdValidPer, QString psReplaceMode)
112112
: Reduce(pInCube, pdSampleScale, pdLineScale){
113113
mdValidPer = pdValidPer;
114-
msReplaceMode = psReplaceMode;
114+
msReplaceMode = psReplaceMode.toUpper();
115115
}
116116

117117
//! Operator () overload

0 commit comments

Comments
 (0)