123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #include <math.h>
- #include "Transform.h"
- void EtmDN(int iwave, float asol, bool before, float &lmin, float &lmax)
- {
- if (before) /* ETM+ digital numbers taken before July 1, 2000 */
- {
- switch(iwave)
- {
- case 61:
- {
- lmin = -6.2f;
- lmax = 194.3f;
- break;
- }
- case 62:
- {
- lmin = -6.0f;
- lmax = 202.4f;
- break;
- }
- case 63:
- {
- lmin = -4.5f;
- lmax = 158.6f;
- break;
- }
- case 64:
- {
- if (asol < 45.)
- {
- lmin = -4.5f;
- lmax = 235.0f;
- }
- else
- {
- lmin = -4.5f;
- lmax = 157.5f;
- }
- break;
- }
- case 65:
- {
- lmin = -1.0f;
- lmax = 31.76f;
- break;
- }
- case 66:
- {
- lmin = -0.35f;
- lmax = 10.932f;
- break;
- }
- case 67:
- {
- lmin = -5.0f;
- lmax = 244.00f;
- break;
- }
- }
- }
- else /* ETM+ digital numbers taken after July 1, 2000 */
- {
- switch(iwave)
- {
- case 61:
- {
- lmin = -6.2f;
- lmax = 191.6f;
- break;
- }
- case 62:
- {
- lmin = -6.4f;
- lmax = 196.5f;
- break;
- }
- case 63:
- {
- lmin = -5.0f;
- lmax = 152.9f;
- break;
- }
- case 64:
- {
- if (asol < 45.)
- {
- lmin = -5.1f;
- lmax = 241.1f;
- }
- else
- {
- lmin = -5.1f;
- lmax = 157.4f;
- }
- break;
- }
- case 65:
- {
- lmin = -1.0f;
- lmax = 31.06f;
- break;
- }
- case 66:
- {
- lmin = -0.35f;
- lmax = 10.80f;
- break;
- }
- case 67:
- {
- lmin = -4.7f;
- lmax = 243.1f;
- break;
- }
- }
- }
- }
- /* Assuming input value between 0 and 1
- if rad is true, idn should first be converted to a reflectance value
- returns adjusted value also between 0 and 1 */
- float transform(const TransformInput ti, InputMask imask, float idn)
- {
- /* convert from radiance to reflectance */
- if((imask & ETM_BEFORE) || (imask & ETM_AFTER))
- {
- /* http://ltpwww.gsfc.nas */
- float lmin, lmax;
- EtmDN(ti.iwave, ti.asol, imask & ETM_BEFORE, lmin, lmax);
- /* multiply idn by 255.f to correct precondition that idn lies in [0, 255] */
- idn = (lmax - lmin) / 254.f * (idn * 255.f - 1.f) + lmin;
- if (idn < 0.f) idn = 0.f;
- idn /= 255.f;
- }
- if(imask & RADIANCE) idn += (float)M_PI * idn * 255.f * ti.sb / ti.xmus / ti.seb;
-
- float rapp = idn;
- float ainrpix = ti.ainr[0][0];
- float xa = 0.0f;
- float xb = 0.0f;
- float xc = 0.0f;
- float rog = rapp / ti.tgasm;
- /* The if below was added to avoid ground reflectances lower than
- zero when ainr(1,1) greater than rapp/tgasm
- In such case either the choice of atmospheric model was not
- adequate for that image or the calculated apparent reflectance
- was too low. Run the model again for other conditions.
- The lines below just decrease ainr(1,1)/tgasm to avoid too
- bright pixels in the image. Check the output file to see if that
- has happened. */
- float decrfact = 1.0f;
- if (rog < (ainrpix / ti.tgasm))
- {
- do
- {
- decrfact = decrfact - 0.1f;
- ainrpix = decrfact * ainrpix;
- }
- while(rog < (ainrpix / ti.tgasm));
- }
- rog = (rog - ainrpix / ti.tgasm) / ti.sutott / ti.sdtott;
- rog = rog / (1.f + rog * ti.sast);
- xa = (float)M_PI * ti.sb / ti.xmus / ti.seb / ti.tgasm / ti.sutott / ti.sdtott;
- xb = ti.srotot / ti.sutott / ti.sdtott / ti.tgasm;
- xc = ti.sast;
- if (rog > 1) rog = 1;
- if (rog < 0) rog = 0;
- return rog;
- }
|