00001 #include "TePDIPrincoMixModelStrategy.hpp"
00002
00003 TePDIPrincoMixModelStrategy::TePDIPrincoMixModelStrategy()
00004 {
00005 };
00006
00007 TePDIPrincoMixModelStrategy::~TePDIPrincoMixModelStrategy()
00008 {
00009 };
00010
00011 bool TePDIPrincoMixModelStrategy::CheckParameters(const TePDIParameters& parameters) const
00012 {
00013
00014
00015 TePDIMixModelComponentList componentList;
00016 TEAGN_TRUE_OR_RETURN(parameters.GetParameter("component_list", componentList), "Missing parameter: component_list");
00017
00018 TePDIMixModelSpectralBandList spectralBandList;
00019 TEAGN_TRUE_OR_RETURN(parameters.GetParameter("spectral_band_list", spectralBandList), "Missing parameter: spectral_band_list");
00020
00021 TEAGN_TRUE_OR_RETURN(componentList.getSize() <= spectralBandList.getSize(), "Invalid parameter: componentsNumber greater than spectralBandsNumber");
00022 for (unsigned int nc = 0; nc < componentList.getSize(); nc++)
00023 TEAGN_TRUE_OR_RETURN(componentList.getComponentSize(nc) ==
00024 (int)spectralBandList.getSize(),
00025 "Invalid parameter: components bands diferred from spectralBandsNumber");
00026
00027
00028
00029
00030 TePDITypes::TePDIRasterVectorType input_rasters;
00031 TEAGN_TRUE_OR_RETURN(parameters.GetParameter("input_rasters", input_rasters), "Missing parameter: input_rasters");
00032 TEAGN_TRUE_OR_RETURN(input_rasters.size() > 1, "Invalid input rasters number");
00033
00034 TEAGN_TRUE_OR_RETURN(input_rasters.size() == spectralBandList.getSize(), "Invalid parameter: input_raster number diferred from spectralBandsNumber");
00035
00036 std::vector<int> bands;
00037 TEAGN_TRUE_OR_RETURN(parameters.GetParameter("bands", bands), "Missing parameter: bands");
00038 TEAGN_TRUE_OR_RETURN(bands.size() == input_rasters.size(), Te2String(input_rasters.size()) + " Invalid parameter: bands number " + Te2String(bands.size()));
00039
00040 for (unsigned int input_rasters_index = 0 ; input_rasters_index < input_rasters.size(); input_rasters_index++)
00041 {
00042 TEAGN_TRUE_OR_RETURN(input_rasters[input_rasters_index].isActive(), "Invalid parameter: input_raster " + Te2String(input_rasters_index) + " inactive");
00043 TEAGN_TRUE_OR_RETURN(input_rasters[input_rasters_index]->params().status_ != TeRasterParams::TeNotReady, "Invalid parameter: input_raster " + Te2String(input_rasters_index) + " not ready");
00044 TEAGN_TRUE_OR_RETURN(bands[input_rasters_index] < input_rasters[input_rasters_index]->nBands(), "Invalid parameter: bands[" + Te2String(input_rasters_index) + "]");
00045 TEAGN_TRUE_OR_RETURN(input_rasters[input_rasters_index]->params().nlines_ == input_rasters[0]->params().nlines_, "Invalid parameter: input_raster " + Te2String(input_rasters_index) + " with imcompatible number of lines");
00046 TEAGN_TRUE_OR_RETURN(input_rasters[input_rasters_index]->params().ncols_ == input_rasters[0]->params().ncols_, "Invalid parameter: input_raster " + Te2String(input_rasters_index) + " with imcompatible number of columns" );
00047 }
00048
00049
00050
00051 TePDITypes::TePDIRasterVectorType output_rasters;
00052 TEAGN_TRUE_OR_RETURN(parameters.GetParameter("output_rasters", output_rasters), "Missing parameter: output_rasters");
00053 TEAGN_TRUE_OR_RETURN(output_rasters.size() > 1, "Invalid output rasters number");
00054
00055
00056 int computeErrorRasters;
00057 TEAGN_TRUE_OR_RETURN(parameters.GetParameter("compute_error_rasters", computeErrorRasters), "Missing parameter: compute error rasters");
00058 if (computeErrorRasters)
00059 {
00060 TePDITypes::TePDIRasterVectorType output_error_rasters;
00061 TEAGN_TRUE_OR_RETURN(parameters.GetParameter("output_error_rasters", output_error_rasters), "Missing parameter: output_error_rasters");
00062 TEAGN_TRUE_OR_RETURN(output_error_rasters.size() > 1, "Invalid output error rasters number");
00063 }
00064
00065
00066 int normalize;
00067 TEAGN_TRUE_OR_RETURN(parameters.GetParameter("normalize", normalize), "Missing parameter: normalize");
00068 TEAGN_TRUE_OR_RETURN((normalize >= 0) && (normalize <= 1) , "Inavlid parameter value: normalize");
00069
00070 return true;
00071 }
00072
00073 int SGaussElimination (TeMatrix& Z, std::vector<int>& line, unsigned int componentsNumber)
00074 {
00075 int i, j, k,
00076 aux;
00077 double auxd, m;
00078
00079 int nrows = Z.Nrow();
00080
00081
00082 TEAGN_TRUE_OR_RETURN(nrows >= Z.Ncol(), "Matrix not square");
00083 TEAGN_TRUE_OR_RETURN( ((int)componentsNumber) >= nrows, "Vector Size");
00084
00085
00086 for (i = 0; i < nrows; i++)
00087 line[i] = i;
00088
00089
00090 for (k = 0; k < nrows; k++)
00091 {
00092 i = k;
00093 while (Z(i, k) == 0.0)
00094 {
00095 TEAGN_TRUE_OR_RETURN(i != nrows-1, "Singular Matrix");
00096 i++;
00097 }
00098
00099 if (k != i)
00100 {
00101
00102 aux = line[i];
00103 line[i] = line[k];
00104 line[k] = aux;
00105
00106
00107 for (j=0; j < nrows; j ++)
00108 {
00109 auxd = Z(k,j);
00110 Z(k,j) = Z (i, j);
00111 Z (i, j) = auxd;
00112 }
00113 }
00114
00115
00116 for (i = k + 1; i < nrows; i++)
00117 {
00118 m = Z(i, k)/Z(k, k);
00119 Z(i, k) = m;
00120 for (j = k + 1; j < nrows; j++)
00121 Z (i, j) = Z (i, j) - m * Z(k,j);
00122 }
00123
00124 }
00125
00126 TEAGN_TRUE_OR_RETURN(Z(nrows-1, nrows-1) != 0.0, "Singular Matrix");
00127
00128 return true;
00129 }
00130
00131 int SFowardBackSubstitution (TeMatrix& Z, std::vector<double>& y, int ys, std::vector<int>& line, int lines, std::vector<double>& x, int xs)
00132 {
00133 int nrows = Z.Nrow();
00134
00135
00136 TEAGN_TRUE_OR_RETURN(nrows >= Z.Ncol(), "Matriz not square");
00137 TEAGN_TRUE_OR_RETURN(!((lines < nrows) || (ys < nrows) || (xs < nrows)), "Vector Size");
00138
00139 int k, j;
00140 double aux;
00141 std::vector<double> F(nrows, 0.0);
00142
00143
00144 for (k = 0; k < nrows; k++)
00145 {
00146 aux = 0.;
00147 for (j = 0; j <= k - 1; j ++)
00148 aux = aux + Z(k,j) * F[j];
00149 F[k] = y[line[k]] - aux;
00150 }
00151
00152
00153 for (k= nrows - 1; k >= 0; k--)
00154 {
00155 aux = 0.;
00156 for (j = k + 1; j < nrows; j++)
00157 aux = aux + Z(k,j) * x[j];
00158 x[k] = (F[k] - aux)/Z(k,k);
00159 }
00160
00161 return true;
00162 }
00163
00164 bool TePDIPrincoMixModelStrategy::Implementation(const TePDIParameters& params)
00165 {
00166
00167 TePDIMixModelComponentList componentList;
00168 TEAGN_TRUE_OR_RETURN(params.GetParameter("component_list", componentList), "Missing parameter: component_list");
00169
00170 TePDIMixModelSpectralBandList spectralBandList;
00171 TEAGN_TRUE_OR_RETURN(params.GetParameter("spectral_band_list", spectralBandList), "Missing parameter: spectral_band_list");
00172
00173 unsigned int componentsNumber = componentList.getSize(),
00174 spectralBandsNumber = spectralBandList.getSize(),
00175 componentsNumberLessOne = componentsNumber - 1;
00176
00177
00178 TePDITypes::TePDIRasterVectorType input_rasters;
00179 TEAGN_TRUE_OR_RETURN(params.GetParameter("input_rasters", input_rasters), "Missing parameter: input_rasters");
00180
00181 std::vector<int> bands;
00182 TEAGN_TRUE_OR_RETURN(params.GetParameter("bands", bands),
00183 "Missing parameter: bands");
00184
00185
00186 TePDITypes::TePDIRasterVectorType output_rasters;
00187 TEAGN_TRUE_OR_RETURN(params.GetParameter("output_rasters", output_rasters), "Missing parameter: output_rasters");
00188
00189
00190
00191 TeRasterParams base_raster_params = input_rasters[0]->params();
00192 base_raster_params.setDataType( TeDOUBLE, -1 );
00193 base_raster_params.nBands( 1 );
00194
00195 for(unsigned int outrasterindex = 0; outrasterindex < output_rasters.size();
00196 ++outrasterindex )
00197 {
00198 TeRasterParams outRasterParams = output_rasters[outrasterindex]->params();
00199 outRasterParams.nBands( 1 );
00200 outRasterParams.boundingBoxLinesColumns(
00201 base_raster_params.boundingBox().x1(),
00202 base_raster_params.boundingBox().y1(),
00203 base_raster_params.boundingBox().x2(),
00204 base_raster_params.boundingBox().y2(),
00205 base_raster_params.nlines_,
00206 base_raster_params.ncols_,
00207 TeBox::TeUPPERLEFT );
00208 outRasterParams.projection( base_raster_params.projection() );
00209
00210 TEAGN_TRUE_OR_THROW(
00211 output_rasters[outrasterindex]->init( outRasterParams ),
00212 "Output raster init error");
00213 }
00214
00215
00216 int computeErrorRasters;
00217 TEAGN_TRUE_OR_RETURN(params.GetParameter("compute_error_rasters", computeErrorRasters), "Missing parameter: compute_error_asters");
00218 TePDITypes::TePDIRasterVectorType output_error_rasters;
00219 if (computeErrorRasters)
00220 {
00221 TEAGN_TRUE_OR_RETURN(params.GetParameter("output_error_rasters",
00222 output_error_rasters), "Missing parameter: output_error_rasters");
00223
00224 for(unsigned int outrasterindex = 0; outrasterindex <
00225 output_error_rasters.size(); ++outrasterindex )
00226 {
00227 TeRasterParams outRasterParams =
00228 output_error_rasters[outrasterindex]->params();
00229 outRasterParams.nBands( 1 );
00230 outRasterParams.boundingBoxLinesColumns(
00231 base_raster_params.boundingBox().x1(),
00232 base_raster_params.boundingBox().y1(),
00233 base_raster_params.boundingBox().x2(),
00234 base_raster_params.boundingBox().y2(),
00235 base_raster_params.nlines_,
00236 base_raster_params.ncols_,
00237 TeBox::TeUPPERLEFT );
00238 outRasterParams.projection( base_raster_params.projection() );
00239
00240 TEAGN_TRUE_OR_THROW(
00241 output_error_rasters[outrasterindex]->init( outRasterParams ),
00242 "Output raster init error");
00243 }
00244 }
00245
00246
00247 int computeAverageError;
00248 TEAGN_TRUE_OR_RETURN(params.GetParameter("compute_average_error", computeAverageError), "Missing parameter: compute_average_error_");
00249 double averageError;
00250 if (computeAverageError)
00251 TEAGN_TRUE_OR_RETURN(params.GetParameter("average_error", averageError), "Missing parameter: average_error");
00252
00253
00254 int normalize;
00255 TEAGN_TRUE_OR_RETURN(params.GetParameter("normalize", normalize), "Missing parameter: normalize");
00256
00257
00258 int rastersLines = base_raster_params.nlines_;
00259 int rastersColumns = base_raster_params.ncols_;
00260
00261
00262 unsigned int i,
00263 j,
00264 k,
00265 m;
00266
00267
00268 TeMatrix SpectralBandsComponents;
00269 SpectralBandsComponents.Init(spectralBandsNumber, componentsNumber, 0.0);
00270 for(i = 0; i < spectralBandsNumber; i++)
00271 for (j = 0; j < componentsNumber; j++)
00272 SpectralBandsComponents(i, j) = componentList.getPixel(j, i);
00273
00274
00275
00276
00277
00278
00279
00280 TeMatrix SpectralBandsComponentsTransposed;
00281
00282 TEAGN_TRUE_OR_RETURN(SpectralBandsComponentsTransposed.Init(componentsNumber, spectralBandsNumber, 0.0), "Error initializing SpectralBandsComponentsTransposed Matrix");
00283
00284 TEAGN_TRUE_OR_RETURN(SpectralBandsComponents.Transpose(SpectralBandsComponentsTransposed), "Error transposing SpectralBandsComponents to SpectralBandsComponentsTransposed");
00285
00286
00287
00288
00289
00290
00291
00292 std::vector<double> componentsMean(spectralBandsNumber, 0.0),
00293 componentsMeanAfter(spectralBandsNumber, 0.0);
00294 for (j = 0; j < spectralBandsNumber; j++)
00295 {
00296
00297 componentsMean[j] = 0;
00298 for(i = 0; i < componentsNumber; i++)
00299 componentsMean[j] = componentsMean[j] + SpectralBandsComponentsTransposed(i,j);
00300 componentsMean[j] = componentsMean[j] / (double)componentsNumber;
00301
00302
00303 componentsMeanAfter[j] = 0;
00304 for(i = 0; i < componentsNumber; i++)
00305 {
00306 SpectralBandsComponentsTransposed(i,j) = SpectralBandsComponentsTransposed(i,j) - componentsMean[j];
00307 componentsMeanAfter[j] = componentsMeanAfter[j] + SpectralBandsComponentsTransposed(i,j);
00308 }
00309 componentsMeanAfter[j] = componentsMeanAfter[j]/ (double)componentsNumber;
00310 }
00311
00312
00313
00314
00315
00316
00317 std::vector<double> covarianceVector(spectralBandsNumber*spectralBandsNumber, 0.0);
00318 for(k = 0; k < spectralBandsNumber*spectralBandsNumber; k++)
00319 covarianceVector[k] = 0;
00320 k = 0 ;
00321 for(j = 0; j < spectralBandsNumber; j++)
00322 {
00323 for(m = 0; m < j + 1; m++)
00324 {
00325 for(i = 0; i < componentsNumber; i++)
00326 covarianceVector[k] = covarianceVector[k] + (SpectralBandsComponentsTransposed(i, j) - componentsMeanAfter[j]) * (SpectralBandsComponentsTransposed(i, m) - componentsMeanAfter[m]);
00327 covarianceVector[k] = covarianceVector[k]/(double)componentsNumber ;
00328 k++;
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337 TeMatrix covarianceMatrix;
00338 TEAGN_TRUE_OR_RETURN(covarianceMatrix.Init(spectralBandsNumber, spectralBandsNumber, 0.0), "Error initializing covarianceMatrix");
00339
00340 k = 0;
00341 for (i = 0; i< spectralBandsNumber; i++)
00342 for (j = 0; j <= i; j++)
00343 covarianceMatrix(i, j) = covarianceVector[k++];
00344
00345
00346
00347
00348
00349 TeMatrix auxMatrix;
00350 TEAGN_TRUE_OR_RETURN(covarianceMatrix.EigenVectors(auxMatrix), "Error in eigenvectors calcule of auxMatrix")
00351
00352
00353
00354
00355
00356
00357 TeMatrix eigenreducted;
00358 TEAGN_TRUE_OR_RETURN(eigenreducted.Init(spectralBandsNumber, componentsNumberLessOne, 0.0), "Error initializing eigenreducted matrix")
00359 for (j = 0; j < spectralBandsNumber; j++)
00360 for (i = 0; i < componentsNumberLessOne; i++)
00361 eigenreducted(j, i) = auxMatrix(j, i);
00362
00363
00364
00365
00366
00367
00368 auxMatrix.Clear();
00369
00370
00371 TeMatrix SpectralBandsComponentsPCA;
00372 TEAGN_TRUE_OR_RETURN(SpectralBandsComponentsPCA.Init(SpectralBandsComponentsTransposed.Nrow(), eigenreducted.Ncol()), "Error initializing SpectralBandsComponentsPCA");
00373
00374 SpectralBandsComponentsPCA = SpectralBandsComponentsTransposed * eigenreducted;
00375
00376
00377
00378
00379
00380
00381 SpectralBandsComponentsTransposed.Clear();
00382
00383
00384 TEAGN_TRUE_OR_RETURN(auxMatrix.Init(SpectralBandsComponentsPCA.Nrow(), SpectralBandsComponentsPCA.Ncol() + 1), "Error initializing auxMatrix");
00385
00386 for (j = 0; j < ((unsigned int)SpectralBandsComponentsPCA.Nrow()); j++)
00387 {
00388 for (i = 0; i < ((unsigned int)SpectralBandsComponentsPCA.Ncol() ); i++)
00389 auxMatrix(j, i) = SpectralBandsComponentsPCA(j, i);
00390 auxMatrix (j, SpectralBandsComponentsPCA.Ncol()) = 1.0;
00391 }
00392
00393
00394
00395
00396
00397 SpectralBandsComponentsPCA.Clear();
00398
00399
00400 TEAGN_TRUE_OR_RETURN(auxMatrix.Transpose(SpectralBandsComponentsPCA), "Error transposing auxMatrix to SpectralBandsComponentsPCA");
00401
00402
00403
00404
00405
00406
00407 auxMatrix.Clear();
00408
00409
00410 std::vector<int> lines(componentsNumber, 0);
00411
00412 TEAGN_TRUE_OR_RETURN(SGaussElimination(SpectralBandsComponentsPCA, lines, componentsNumber), "Error in gauss elimination");
00413
00414
00415
00416
00417
00418
00419
00420
00421 TEAGN_TRUE_OR_RETURN(auxMatrix.Init(1, spectralBandsNumber, 0.0), "Error initializing auxMatrix");
00422
00423 TeMatrix ymat;
00424 TEAGN_TRUE_OR_RETURN(ymat.Init(componentsNumberLessOne, componentsNumberLessOne, 0.0), "Error initializing ymat");
00425
00426
00427 std::vector<double> x(componentsNumber, 0.0),
00428 y(componentsNumber, 0.0);
00429 for (i = 0; i < componentsNumber; i++)
00430 {
00431 x[i] = 0.0;
00432 y[i] = 0.0;
00433 }
00434
00435
00436 std::vector<int> colin(spectralBandsNumber, 0);
00437 int colout,
00438
00439 prop;
00440
00441
00442 std::vector<int> linesIn(spectralBandsNumber, 0),
00443 colsIn(spectralBandsNumber, 0);
00444
00445
00446 TeMatrix rasterLinesIn,
00447 rasterLinesOut;
00448 rasterLinesIn.Init(spectralBandsNumber, rastersColumns, 0.0);
00449 rasterLinesOut.Init(componentsNumber, rastersColumns, 0.0);
00450 std::vector<double> spectralBandsError(spectralBandsNumber, 0.0);
00451
00452
00453 for (i = 0; i < spectralBandsNumber; i++)
00454 {
00455 colin[i] = 0;
00456 linesIn[i] = 0;
00457 colsIn[i] = 0;
00458 spectralBandsError[i] = 0.0;
00459 }
00460
00461
00462 TePDIPIManager progress( "Computing MixModel proportions", rastersLines,
00463 progress_interface_enabled_ );
00464
00465 for (int linout = 0; linout < rastersLines; linout++)
00466 {
00467
00468 for (i = 0; i < spectralBandsNumber; i++)
00469 {
00470 for (j = 0; j < ( (unsigned int)rastersColumns ); j++)
00471 {
00472 double p;
00473 input_rasters[i]->getElement(j, linesIn[i], p, bands[ i ] );
00474 rasterLinesIn(i, j) = p;
00475 }
00476
00477 linesIn[i]++;
00478
00479
00480 colin[i] = colsIn[i];
00481 }
00482
00483
00484 for (colout = 0; colout < rastersColumns; colout++)
00485 {
00486
00487 for (i = 0; i < spectralBandsNumber; i++)
00488 auxMatrix(0,i) = (double) (rasterLinesIn(i, colin[i]))/255. - componentsMean[i];
00489
00490 ymat = auxMatrix * eigenreducted;
00491
00492 for (i = 0; i < componentsNumber - 1; i++)
00493 y[i] = ymat(0,i);
00494
00495
00496 SFowardBackSubstitution(SpectralBandsComponentsPCA, y, componentsNumber, lines, componentsNumber, x, componentsNumber);
00497
00498
00499 for (i = 0; i < componentsNumber; i++)
00500 {
00501 prop = (short) (x[i]*100 + 100);
00502 rasterLinesOut(i, colout) = (unsigned char)prop;
00503 }
00504
00505
00506
00507 double aux, error;
00508
00509 if (computeErrorRasters || computeAverageError)
00510 {
00511 for (i = 0; i < spectralBandsNumber; i++)
00512 {
00513
00514 aux = 0.0;
00515 for (j = 0; j < componentsNumber; j++)
00516 aux += x[j] * SpectralBandsComponents(i,j);
00517
00518
00519 error = (long)(rasterLinesIn(i, colin[i]))/255.0 - aux;
00520 if (error < 0)
00521 error = -1 * error;
00522 if (computeErrorRasters)
00523 rasterLinesIn(i, colout) = error * 255.0;
00524 if (computeAverageError)
00525 spectralBandsError[i] += error*255.;
00526 }
00527 }
00528
00529
00530
00531 for (i = 0; i < spectralBandsNumber; i++)
00532 colin[i]++;
00533
00534 }
00535
00536
00537 for (i = 0; i < componentsNumber; i++)
00538 for (j = 0; j < ((unsigned int)rastersColumns); j++)
00539 output_rasters[i]->setElement(j, linout, rasterLinesOut(i, j));
00540
00541
00542
00543
00544 if (computeErrorRasters)
00545 {
00546
00547 for (i = 0; i < componentsNumber; i++)
00548 for (j = 0; j < ((unsigned int)rastersColumns); j++)
00549 output_error_rasters[i]->setElement(j, linout, rasterLinesIn(i, j));
00550 }
00551
00552
00553 progress.Increment();
00554 }
00555
00556 progress.Toggle( false );
00557
00558
00559
00560 averageError = 0.0;
00561 if (computeAverageError)
00562 {
00563
00564 int numpix = rastersLines*rastersColumns;
00565 for (i = 0; i < spectralBandsNumber; i++)
00566 {
00567
00568 spectralBandsError[i] = spectralBandsError[i]/numpix;
00569
00570 averageError += spectralBandsError[i];
00571 }
00572
00573 if (!(spectralBandsNumber == 0))
00574 {
00575 averageError = averageError/spectralBandsNumber;
00576 }
00577
00578
00579 }
00580
00581
00582
00583
00584
00585
00586
00587 return true;
00588 }