25 Equalization::Equalization() {
38 loadInputs(fromListName);
42 Equalization::~Equalization() {
44 m_holdIndices.clear();
46 if (m_results != NULL) {
53 void Equalization::addHolds(QString holdListName) {
55 holdList.read(FileName(holdListName));
57 if (holdList.size() > m_imageList.size()) {
58 QString msg =
"The list of identifiers to be held must be less than or ";
59 msg +=
"equal to the total number of identitifers.";
60 throw IException(IException::User, msg,
_FILEINFO_);
64 for (
int i = 0; i < holdList.size(); i++) {
66 for (
int j = 0; j < m_imageList.size(); j++) {
67 if (holdList[i] == m_imageList[j]) {
69 m_holdIndices.push_back(j);
74 QString msg =
"The hold list file [" + holdList[i].toString() +
75 "] does not match a file in the from list";
76 throw IException(IException::User, msg,
_FILEINFO_);
91 void Equalization::calculateStatistics(
double percent,
int mincnt,
101 vector<OverlapNormalization *> oNormList;
102 for (
int band = 1; band <= m_maxBand; band++) {
103 vector<Statistics *> statsList;
104 for (
int img = 0; img < (int) m_imageList.size(); img++) {
107 QString statMsg =
"Calculating Statistics for Band " + bandStr +
112 QString inp = m_imageList[img].toString();
121 statsList.push_back(stats);
127 oNormList.push_back(oNorm);
132 vector<bool> doesOverlapList;
133 for (
int i = 0; i < m_imageList.size(); i++) {
134 doesOverlapList.push_back(
false);
139 vector<OverlapStatistics> overlapList;
140 for (
int i = 0; i < m_imageList.size(); i++) {
146 for (
int j = (i + 1); j < m_imageList.size(); j++) {
149 QString cubeStr1 =
toString((
int)(i + 1));
150 QString cubeStr2 =
toString((
int)(j + 1));
151 QString statMsg =
"Gathering Overlap Statisitcs for Cube " +
152 cubeStr1 +
" vs " + cubeStr2 +
" of " +
162 overlapList.push_back(oStats);
163 for (
int band = 1; band <= m_maxBand; band++) {
171 oNormList[band - 1]->AddOverlap(
174 doesOverlapList[i] =
true;
175 doesOverlapList[j] =
true;
184 QString badFiles =
"";
185 for (
int img = 0; img < m_imageList.size(); img++) {
187 if (!doesOverlapList[img]) {
188 badFiles +=
"[" + m_imageList[img].toString() +
"] ";
191 if (badFiles !=
"") {
192 QString msg =
"File(s) " + badFiles;
193 msg +=
" do(es) not overlap any other input images with enough valid pixels";
200 for (
int band = 0; band < m_maxBand; band++) {
201 oNormList[band]->Solve(m_sType, methodType);
203 for (
unsigned int img = 0; img < m_adjustments.size(); img++) {
204 m_adjustments[img]->addGain(oNormList[band]->Gain(img));
205 if (qFuzzyCompare(oNormList[band]->Gain(img), 0.0)) {
207 cout << band << endl;
208 cout << oNormList[band]->Gain(img) << endl;
210 "Calculation for equalization statistics failed. Gain = 0.",
213 m_adjustments[img]->addOffset(oNormList[band]->Offset(img));
214 m_adjustments[img]->addAverage(oNormList[band]->
Average(img));
220 string msg =
"Unable to calculate the equalization statistics. You may "
221 "want to try another LeastSquares::SolveMethod.";
225 for (
unsigned int o = 0; o < overlapList.size(); o++) {
226 for (
int band = 1; band <= m_maxBand; band++) {
227 (overlapList[o].IsValid(band)) ? m_validCnt++ : m_invalidCnt++;
231 setResults(overlapList);
235 void Equalization::setResults(vector<OverlapStatistics> &overlapStats) {
238 for (
unsigned int i = 0; i < overlapStats.size(); i++) {
239 m_results->addObject(overlapStats[i].toPvl());
244 void Equalization::setResults() {
245 if (m_results != NULL) {
250 m_results =
new Pvl();
251 m_results->setTerminator(
"");
253 PvlObject equ(
"EqualizationInformation");
254 PvlGroup gen(
"General");
255 gen += PvlKeyword(
"TotalOverlaps",
toString(m_validCnt + m_invalidCnt));
256 gen += PvlKeyword(
"ValidOverlaps",
toString(m_validCnt));
257 gen += PvlKeyword(
"InvalidOverlaps",
toString(m_invalidCnt));
258 gen += PvlKeyword(
"Weighted", (m_wtopt) ?
"true" :
"false");
259 gen += PvlKeyword(
"MinCount",
toString(m_mincnt));
261 for (
int img = 0; img < m_imageList.size(); img++) {
263 PvlGroup norm(
"Normalization");
264 norm.addComment(
"Formula: newDN = (oldDN - AVERAGE) * GAIN + AVERAGE + OFFSET");
265 norm.addComment(
"BandN = (GAIN, OFFSET, AVERAGE)");
266 norm += PvlKeyword(
"FileName", m_imageList[img].original());
269 for (
int band = 1; band <= m_maxBand; band++) {
270 QString mult =
toString(m_adjustments[img]->getGain(band - 1));
271 QString base =
toString(m_adjustments[img]->getOffset(band - 1));
272 QString avg =
toString(m_adjustments[img]->getAverage(band - 1));
274 QString bandStr =
"Band" + bandNum;
275 PvlKeyword bandStats(bandStr);
284 m_results->addObject(equ);
288 void Equalization::importStatistics(QString instatsFileName) {
290 vector<int> normIndices = validateInputStatistics(instatsFileName);
293 for (
int img = 0; img < (int) m_imageList.size(); img++) {
295 Pvl inStats(instatsFileName);
296 PvlObject &equalInfo = inStats.findObject(
"EqualizationInformation");
297 PvlGroup &normalization = equalInfo.group(normIndices[img]);
301 ImageAdjustment *adjustment =
new ImageAdjustment(m_sType);
304 for (
int band = 1; band < normalization.keywords(); band++) {
305 adjustment->addGain(
toDouble(normalization[band][0]));
306 adjustment->addOffset(
toDouble(normalization[band][1]));
307 adjustment->addAverage(
toDouble(normalization[band][2]));
310 addAdjustment(adjustment);
315 void Equalization::applyCorrection(QString toListName=
"") {
317 fillOutList(outList, toListName);
319 QString maxCubeStr =
toString((
int) m_imageList.size());
320 for (
int img = 0; img < m_imageList.size(); img++) {
323 p.Progress()->SetText(
"Equalizing Cube " +
toString((
int) img + 1) +
324 " of " + maxCubeStr);
327 CubeAttributeInput att;
328 const QString inp = m_imageList[img].toString();
329 Cube *icube = p.SetInputCube(inp, att);
332 QString out = outList[img].toString();
333 CubeAttributeOutput outAtt;
334 p.SetOutputCube(out, outAtt, icube->sampleCount(),
335 icube->lineCount(), icube->bandCount());
338 ApplyFunctor func(m_adjustments[img]);
339 p.ProcessCube(func,
false);
345 PvlGroup Equalization::getResults() {
347 PvlGroup results(
"Results");
348 results += PvlKeyword(
"TotalOverlaps",
toString(m_validCnt + m_invalidCnt));
349 results += PvlKeyword(
"ValidOverlaps",
toString(m_validCnt));
350 results += PvlKeyword(
"InvalidOverlaps",
toString(m_invalidCnt));
351 results += PvlKeyword(
"Weighted", (m_wtopt) ?
"true" :
"false");
352 results += PvlKeyword(
"MinCount",
toString(m_mincnt));
355 for (
int img = 0; img < m_imageList.size(); img++) {
356 results += PvlKeyword(
"FileName", m_imageList[img].
toString());
359 for (
int band = 1; band <= m_maxBand; band++) {
360 QString mult =
toString(m_adjustments[img]->getGain(band - 1));
361 QString base =
toString(m_adjustments[img]->getOffset(band - 1));
362 QString avg =
toString(m_adjustments[img]->getAverage(band - 1));
364 QString bandStr =
"Band" + bandNum;
365 PvlKeyword bandStats(bandStr);
369 results += bandStats;
377 void Equalization::write(QString outstatsFileName) {
379 m_results->write(outstatsFileName);
383 double Equalization::evaluate(
double dn,
384 int imageIndex,
int bandIndex)
const {
385 return m_adjustments[imageIndex]->evaluate(dn, bandIndex);
389 void Equalization::loadInputs(QString fromListName) {
391 m_imageList.read(fromListName);
392 m_maxCube = m_imageList.size();
394 if (m_imageList.size() < 2) {
395 QString msg =
"The input file [" + fromListName +
396 "] must contain at least 2 file names";
397 throw IException(IException::User, msg,
_FILEINFO_);
401 tempCube.open(m_imageList[0].
toString());
402 m_maxBand = tempCube.bandCount();
404 errorCheck(fromListName);
408 void Equalization::setInput(
int index, QString value) {
409 m_imageList[index] = value;
413 const FileList & Equalization::getInputs()
const {
418 void Equalization::fillOutList(FileList &outList, QString toListName) {
419 if (toListName.isEmpty()) {
420 generateOutputs(outList);
423 loadOutputs(outList, toListName);
428 void Equalization::errorCheck(QString fromListName) {
429 for (
int i = 0; i < m_imageList.size(); i++) {
431 cube1.open(m_imageList[i].
toString());
433 for (
int j = (i + 1); j < m_imageList.size(); j++) {
435 cube2.open(m_imageList[j].
toString());
438 if (m_maxBand != cube2.bandCount()) {
439 QString msg =
"Number of bands do not match between cubes [" +
440 m_imageList[i].toString() +
"] and [" + m_imageList[j].toString() +
"]";
441 throw IException(IException::User, msg,
_FILEINFO_);
445 Projection *proj1 = cube1.projection();
446 Projection *proj2 = cube2.projection();
449 if (*proj1 != *proj2) {
450 QString msg =
"Mapping groups do not match between cubes [" +
451 m_imageList[i].toString() +
"] and [" + m_imageList[j].toString() +
"]";
452 throw IException(IException::User, msg,
_FILEINFO_);
459 void Equalization::generateOutputs(FileList &outList) {
460 for (
int img = 0; img < m_imageList.size(); img++) {
461 FileName file(m_imageList[img]);
462 QString filename = file.path() +
"/" + file.baseName() +
463 ".equ." + file.extension();
464 outList.push_back(FileName(filename));
469 void Equalization::loadOutputs(FileList &outList, QString toListName) {
470 outList.read(FileName(toListName));
473 if (outList.size() != m_imageList.size()) {
474 QString msg =
"Each input file in the FROM LIST must have a ";
475 msg +=
"corresponding output file in the TO LIST.";
476 throw IException(IException::User, msg,
_FILEINFO_);
481 for (
int i = 0; i < outList.size(); i++) {
483 QString msg =
"The to list file [" + outList[i].toString() +
484 "] has the same name as its corresponding from list file.";
485 throw IException(IException::User, msg,
_FILEINFO_);
491 void Equalization::loadHolds(OverlapNormalization *oNorm) {
492 for (
unsigned int h = 0; h < m_holdIndices.size(); h++)
493 oNorm->AddHold(m_holdIndices[h]);
497 void Equalization::clearAdjustments() {
498 m_adjustments.clear();
502 void Equalization::addAdjustment(ImageAdjustment *adjustment) {
503 m_adjustments.push_back(adjustment);
507 void Equalization::addValid(
int count) {
512 void Equalization::addInvalid(
int count) {
513 m_invalidCnt += count;
517 void Equalization::init() {
527 m_sType = OverlapNormalization::Both;
533 vector<int> Equalization::validateInputStatistics(QString instatsFileName) {
534 Pvl inStats(instatsFileName);
535 PvlObject &equalInfo = inStats.findObject(
"EqualizationInformation");
538 if (m_imageList.size() > equalInfo.groups() - 1) {
539 QString msg =
"Each input file in the FROM LIST must have a ";
540 msg +=
"corresponding input file in the INPUT STATISTICS.";
541 throw IException(IException::User, msg,
_FILEINFO_);
544 vector<int> normIndices;
547 for (
int i = 0; i < m_imageList.size(); i++) {
548 QString fromFile = m_imageList[i].original();
549 bool foundFile =
false;
550 for (
int j = 1; j < equalInfo.groups(); j++) {
551 PvlGroup &normalization = equalInfo.group(j);
552 QString normFile = normalization[
"FileName"][0];
553 if (fromFile == normFile) {
557 normIndices.push_back(j);
562 QString msg =
"The from list file [" + fromFile +
563 "] does not have any corresponding file in the stats list.";
564 throw IException(IException::User, msg,
_FILEINFO_);
572 void Equalization::CalculateFunctor::operator()(Buffer &in)
const {
574 if ((in.Line() - 1) % m_linc == 0 || in.Line() == in.LineDimension()) {
580 void Equalization::CalculateFunctor::addStats(Buffer &in)
const {
582 m_stats->AddData(&in[0], in.size());
586 void Equalization::ApplyFunctor::operator()(Buffer &in, Buffer &out)
const {
587 int index = in.Band() - 1;
588 for (
int i = 0; i < in.size(); i++) {
590 in[i] : m_adjustment->evaluate(in[i], index);